@veridex/sdk 1.0.0-beta.5 → 1.0.0-beta.6
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/dist/chains/aptos/index.js.map +1 -1
- package/dist/chains/aptos/index.mjs.map +1 -1
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/evm/index.mjs.map +1 -1
- package/dist/chains/solana/index.js.map +1 -1
- package/dist/chains/solana/index.mjs.map +1 -1
- package/dist/chains/starknet/index.js.map +1 -1
- package/dist/chains/starknet/index.mjs.map +1 -1
- package/dist/chains/sui/index.js.map +1 -1
- package/dist/chains/sui/index.mjs.map +1 -1
- package/dist/constants.js +4 -4
- package/dist/constants.js.map +1 -1
- package/dist/constants.mjs +4 -4
- package/dist/constants.mjs.map +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/index.mjs.map +1 -1
- package/dist/payload.js.map +1 -1
- package/dist/payload.mjs.map +1 -1
- package/dist/queries/index.js +4 -4
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/index.mjs +4 -4
- package/dist/queries/index.mjs.map +1 -1
- package/dist/utils.js +4 -4
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +4 -4
- package/dist/utils.mjs.map +1 -1
- package/dist/wormhole.js.map +1 -1
- package/dist/wormhole.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/queries/constants.ts","../../src/queries/hubState.ts","../../src/constants.ts","../../src/queries/portfolio.ts","../../src/core/WalletManager.ts","../../src/utils.ts","../../src/constants/tokens.ts"],"sourcesContent":["export const WORMHOLE_QUERY_PROXY_URLS = {\n mainnet: 'https://query.wormhole.com/v1/query',\n testnet: 'https://testnet.query.wormhole.com/v1/query',\n} as const;\n\n/**\n * Wormhole Query Proxy rate limit: 6 queries per second.\n * SDK callers should throttle requests accordingly.\n */\nexport const WORMHOLE_QUERY_RATE_LIMIT_PER_SECOND = 6;\n\n/**\n * Convenience set of Wormhole chain IDs commonly supported by Queries.\n * This is not an exhaustive list of all Wormhole chains.\n */\nexport const WORMHOLE_QUERY_CHAIN_IDS = {\n ETHEREUM: 2,\n POLYGON: 5,\n ARBITRUM: 23,\n OPTIMISM: 24,\n BASE: 30,\n} as const;\n","import axios, { AxiosError } from 'axios';\nimport { Buffer } from 'buffer';\nimport { ethers } from 'ethers';\nimport {\n EthCallQueryRequest,\n EthCallQueryResponse,\n PerChainQueryRequest,\n QueryRequest,\n QueryResponse,\n hexToUint8Array,\n isValidHexString,\n} from '@wormhole-foundation/wormhole-query-sdk';\n\nimport { MAINNET_CHAINS, TESTNET_CHAINS } from '../constants.js';\nimport { WORMHOLE_QUERY_PROXY_URLS } from './constants.js';\n\nexport type QueryHubStateNetwork = 'testnet' | 'mainnet';\n\nexport type QueryHubStateOptions = {\n /** Max response age in seconds (default: 60). */\n maxAge?: number;\n network?: QueryHubStateNetwork;\n /** Maximum attempts including the first try (default: 4). */\n maxAttempts?: number;\n};\n\nexport type HubStateResult = {\n nonce: bigint;\n isRegistered: boolean;\n blockTime: number;\n proof: Uint8Array;\n /** Last action hash (Issue #9/#10 - for action-hash binding) */\n lastActionHash?: string;\n};\n\nexport type QueryHubStateErrorCode =\n | 'INVALID_ARGUMENT'\n | 'UNSUPPORTED_NETWORK'\n | 'MISSING_HUB_ADDRESS'\n | 'PROXY_HTTP_ERROR'\n | 'PROXY_RESPONSE_INVALID'\n | 'ATTESTATION_STALE'\n | 'QUERY_RESPONSE_INVALID';\n\nexport class QueryHubStateError extends Error {\n code: QueryHubStateErrorCode;\n cause?: unknown;\n\n constructor(code: QueryHubStateErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'QueryHubStateError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nfunction resolveNetwork(options?: QueryHubStateOptions): QueryHubStateNetwork {\n if (options?.network) return options.network;\n\n const envCandidates = [\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,\n (globalThis as any)?.process?.env?.WORMHOLE_NETWORK,\n ].filter(Boolean);\n\n const env = (envCandidates[0] as string | undefined)?.toLowerCase();\n if (env === 'mainnet' || env === 'testnet') return env;\n\n // Default to testnet to support Base Sepolia out-of-the-box.\n return 'testnet';\n}\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction signaturesToProofBytes(signatures: string[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n for (const sig of signatures) {\n if (typeof sig !== 'string' || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {\n throw new QueryHubStateError(\n 'PROXY_RESPONSE_INVALID',\n `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`\n );\n }\n // Avoid Node Buffer-backed Uint8Array (can surface as SharedArrayBuffer in DTS types).\n chunks.push(hexToUint8Array(`0x${sig}`));\n }\n\n return concatBytes(chunks);\n}\n\nfunction decodeQueryBytes(bytes: string): Uint8Array {\n if (typeof bytes !== 'string' || bytes.length === 0) {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Missing query response bytes');\n }\n\n // Query Proxy commonly returns a 0x-prefixed hex string.\n if (isValidHexString(bytes)) {\n return hexToUint8Array(bytes);\n }\n\n // Fallback: attempt base64 decoding.\n try {\n if (typeof atob === 'function') {\n const raw = atob(bytes);\n const arr = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);\n return arr;\n }\n } catch {\n // ignore\n }\n\n try {\n return new Uint8Array(Buffer.from(bytes, 'base64'));\n } catch (cause) {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Unrecognized query response bytes encoding', cause);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function withExponentialBackoff<T>(\n fn: () => Promise<T>,\n maxAttempts: number\n): Promise<T> {\n let attempt = 0;\n let lastError: unknown;\n\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts) break;\n\n const baseMs = 250;\n const backoffMs = Math.min(5_000, baseMs * 2 ** (attempt - 1));\n const jitterMs = Math.floor(Math.random() * 100);\n await sleep(backoffMs + jitterMs);\n }\n }\n\n throw lastError;\n}\n\nfunction getHubConfig(network: QueryHubStateNetwork): {\n wormholeChainId: number;\n hubAddress: string;\n endpoint: string;\n rpcUrl: string;\n} {\n if (network === 'testnet') {\n const baseSepolia = TESTNET_CHAINS.baseSepolia;\n if (!baseSepolia?.contracts?.hub) {\n throw new QueryHubStateError('MISSING_HUB_ADDRESS', 'Missing Base Sepolia hub address in SDK constants');\n }\n\n return {\n wormholeChainId: baseSepolia.wormholeChainId,\n hubAddress: baseSepolia.contracts.hub,\n endpoint: WORMHOLE_QUERY_PROXY_URLS.testnet,\n rpcUrl: baseSepolia.rpcUrl,\n };\n }\n\n if (network === 'mainnet') {\n const base = MAINNET_CHAINS.base;\n const hubAddress = (base?.contracts as any)?.hub as string | undefined;\n\n if (!hubAddress) {\n throw new QueryHubStateError(\n 'MISSING_HUB_ADDRESS',\n 'Missing mainnet hub address in SDK constants (MAINNET_CHAINS.base.contracts.hub)'\n );\n }\n\n return {\n wormholeChainId: base.wormholeChainId,\n hubAddress,\n endpoint: WORMHOLE_QUERY_PROXY_URLS.mainnet,\n rpcUrl: base.rpcUrl,\n };\n }\n\n throw new QueryHubStateError('UNSUPPORTED_NETWORK', `Unsupported network: ${network}`);\n}\n\nfunction encodeHubCalls(hubAddress: string, userKeyHash: string): { to: string; data: string }[] {\n // Support both the spec name and known on-chain variants.\n const nonceAbiCandidates = [\n 'function getUserNonce(bytes32 userKeyHash) view returns (uint256)',\n 'function userNonces(bytes32 userKeyHash) view returns (uint256)',\n 'function getNonceByHash(bytes32 userKeyHash) view returns (uint256)',\n ];\n\n const registeredAbiCandidates = [\n 'function registeredKeys(bytes32 userKeyHash) view returns (bool)',\n 'function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)',\n ];\n\n // Issue #9/#10: Add getUserLastActionHash for action-hash binding\n const actionHashAbiCandidates = [\n 'function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n 'function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n ];\n\n // We encode *all* candidates; the proxy will execute each call, and we decode the first successful one.\n // This makes the client resilient to Hub ABI differences across deployments.\n const iface = new ethers.Interface([\n ...nonceAbiCandidates,\n ...registeredAbiCandidates,\n ...actionHashAbiCandidates,\n ]);\n\n const nonceFnNames = ['getUserNonce', 'userNonces', 'getNonceByHash'] as const;\n const regFnNames = ['registeredKeys', 'isKeyRegisteredByHash'] as const;\n const actionHashFnNames = ['getUserLastActionHash', 'userLastActionHash'] as const;\n\n return [\n ...nonceFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ...regFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ...actionHashFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ];\n}\n\nfunction decodeFirstNonce(results: string[]): bigint {\n const candidates = [\n 'function getUserNonce(bytes32 userKeyHash) view returns (uint256)',\n 'function userNonces(bytes32 userKeyHash) view returns (uint256)',\n 'function getNonceByHash(bytes32 userKeyHash) view returns (uint256)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['getUserNonce', 'userNonces', 'getNonceByHash'] as const;\n\n for (let idx = 0; idx < fnNames.length; idx++) {\n const fnName = fnNames[idx];\n try {\n const data = results[idx];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return decoded[0] as bigint;\n } catch {\n // keep trying\n }\n }\n\n throw new QueryHubStateError('QUERY_RESPONSE_INVALID', 'Unable to decode user nonce from query response');\n}\n\nfunction decodeFirstIsRegistered(results: string[]): boolean {\n const nonceCandidateCount = 3;\n const candidates = [\n 'function registeredKeys(bytes32 userKeyHash) view returns (bool)',\n 'function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['registeredKeys', 'isKeyRegisteredByHash'] as const;\n\n for (let i = 0; i < fnNames.length; i++) {\n const fnName = fnNames[i];\n try {\n const data = results[nonceCandidateCount + i];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return Boolean(decoded[0]);\n } catch {\n // keep trying\n }\n }\n\n // If the hub deployment doesn’t support registration, treat as false.\n return false;\n}\n\n/** * Decode last action hash from query results (Issue #9/#10)\n * Returns zero hash if not available (backwards compatibility)\n */\nfunction decodeLastActionHash(results: string[]): string {\n const nonceCandidateCount = 3;\n const registeredCandidateCount = 2;\n const actionHashOffset = nonceCandidateCount + registeredCandidateCount;\n\n const candidates = [\n 'function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n 'function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['getUserLastActionHash', 'userLastActionHash'] as const;\n\n for (let i = 0; i < fnNames.length; i++) {\n const fnName = fnNames[i];\n try {\n const data = results[actionHashOffset + i];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return decoded[0] as string;\n } catch {\n // keep trying\n }\n }\n\n // Backwards compatibility: return zero hash if not available\n return ethers.ZeroHash;\n}\n\n/** * Fetch Guardian-attested Hub state directly from the Wormhole Query Proxy.\n *\n * Client-side only: this avoids relayer API costs and produces a Guardian-signed proof\n * that can be forwarded to the relayer for on-chain verification/submission.\n */\nexport async function queryHubState(\n userKeyHash: string,\n apiKey: string,\n options?: QueryHubStateOptions\n): Promise<HubStateResult> {\n if (typeof userKeyHash !== 'string' || userKeyHash.length === 0) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'userKeyHash is required');\n }\n if (!isValidHexString(userKeyHash) || hexToUint8Array(userKeyHash).length !== 32) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'userKeyHash must be a 32-byte hex string');\n }\n if (typeof apiKey !== 'string' || apiKey.length === 0) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'apiKey is required');\n }\n\n const network = resolveNetwork(options);\n const maxAgeSeconds = options?.maxAge ?? 60;\n const maxAttempts = options?.maxAttempts ?? 4;\n\n const { wormholeChainId, hubAddress, endpoint, rpcUrl } = getHubConfig(network);\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const callData = encodeHubCalls(hubAddress, userKeyHash);\n\n const doFetch = async () => {\n try {\n const latestBlock = await provider.getBlockNumber();\n const blockTag = Math.max(0, latestBlock - 2);\n\n const request = new QueryRequest(Date.now() & 0xffffffff, [\n new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, callData)),\n ]);\n\n // Wormhole Query Proxy expects raw hex WITHOUT 0x prefix\n const requestHex = Buffer.from(request.serialize()).toString('hex');\n\n const response = await axios.post(\n endpoint,\n { bytes: requestHex },\n {\n headers: {\n 'X-API-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n timeout: 10_000,\n }\n );\n\n const data = response.data as any;\n const signatures = data?.signatures as string[] | undefined;\n const bytes = data?.bytes as string | undefined;\n\n if (!Array.isArray(signatures) || typeof bytes !== 'string') {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Query Proxy response missing signatures/bytes');\n }\n\n const proof = signaturesToProofBytes(signatures);\n const queryBytes = decodeQueryBytes(bytes);\n const parsed = QueryResponse.from(queryBytes);\n\n const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);\n if (!perChain) {\n throw new QueryHubStateError('QUERY_RESPONSE_INVALID', 'Missing per-chain response for hub chain');\n }\n\n // The SDK provides a parser for the chain-specific response.\n const chainResp = EthCallQueryResponse.from(perChain.response.serialize());\n const blockTime = Number(chainResp.blockTime);\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n if (nowSeconds - blockTime > maxAgeSeconds) {\n throw new QueryHubStateError(\n 'ATTESTATION_STALE',\n `Guardian attestation is stale (blockTime=${blockTime}, now=${nowSeconds}, maxAge=${maxAgeSeconds}s)`\n );\n }\n\n const nonce = decodeFirstNonce(chainResp.results);\n const isRegistered = decodeFirstIsRegistered(chainResp.results);\n const lastActionHash = decodeLastActionHash(chainResp.results);\n\n return {\n nonce,\n isRegistered,\n blockTime,\n proof,\n lastActionHash,\n } satisfies HubStateResult;\n } catch (err) {\n if (err instanceof QueryHubStateError) throw err;\n if (axios.isAxiosError(err)) {\n const ax = err as AxiosError;\n const status = ax.response?.status;\n const statusText = ax.response?.statusText;\n const details = typeof ax.response?.data === 'string' ? ax.response?.data : undefined;\n\n throw new QueryHubStateError(\n 'PROXY_HTTP_ERROR',\n `Query Proxy request failed${status ? ` (${status} ${statusText ?? ''})` : ''}${details ? `: ${details}` : ''}`,\n err\n );\n }\n\n throw new QueryHubStateError('PROXY_HTTP_ERROR', 'Query Proxy request failed', err);\n }\n };\n\n return await withExponentialBackoff(doFetch, maxAttempts);\n}\n","/**\n * Veridex Protocol SDK - Constants and Chain Configurations\n */\n\nimport type { ChainConfig } from './types.js';\n\n// ============================================================================\n// Action Type Constants\n// ============================================================================\n\nexport const ACTION_TYPES = {\n TRANSFER: 1,\n EXECUTE: 2,\n CONFIG: 3,\n BRIDGE: 4,\n} as const;\n\nexport const ACTION_TRANSFER = 1;\nexport const ACTION_EXECUTE = 2;\nexport const ACTION_CONFIG = 3;\nexport const ACTION_BRIDGE = 4;\n\n// Protocol version\nexport const PROTOCOL_VERSION = 1;\n\n// ============================================================================\n// Wormhole Chain IDs\n// ============================================================================\n\n/**\n * Wormhole Chain IDs organized by network\n * @see https://docs.wormhole.com/wormhole/reference/constants\n */\nexport const WORMHOLE_CHAIN_IDS = {\n MAINNET: {\n SOLANA: 1,\n ETHEREUM: 2,\n TERRA: 3,\n BSC: 4,\n POLYGON: 5,\n AVALANCHE: 6,\n OASIS: 7,\n ALGORAND: 8,\n AURORA: 9,\n FANTOM: 10,\n KARURA: 11,\n ACALA: 12,\n KLAYTN: 13,\n CELO: 14,\n NEAR: 15,\n MOONBEAM: 16,\n NEON: 17,\n TERRA2: 18,\n INJECTIVE: 19,\n OSMOSIS: 20,\n SUI: 21,\n APTOS: 22,\n ARBITRUM: 23,\n OPTIMISM: 24,\n GNOSIS: 25,\n PYTHNET: 26,\n XPLA: 28,\n BASE: 30,\n SEI: 32,\n ROOTSTOCK: 33,\n SCROLL: 34,\n MANTLE: 35,\n BLAST: 36,\n XLAYER: 37,\n LINEA: 38,\n BERACHAIN: 39,\n SEIEVM: 40,\n },\n TESTNET: {\n SOLANA_DEVNET: 1,\n GOERLI: 2,\n BSC_TESTNET: 4,\n POLYGON_MUMBAI: 5,\n AVALANCHE_FUJI: 6,\n FANTOM_TESTNET: 10,\n CELO_ALFAJORES: 14,\n MOONBASE_ALPHA: 16,\n SUI_TESTNET: 21,\n APTOS_TESTNET: 22,\n SEPOLIA: 10002,\n ARBITRUM_SEPOLIA: 10003,\n BASE_SEPOLIA: 10004,\n OPTIMISM_SEPOLIA: 10005,\n HOLESKY: 10006,\n POLYGON_SEPOLIA: 10007,\n SEI_ATLANTIC_2: 10066, // Sei Arctic-1 testnet (EVM)\n STARKNET_SEPOLIA: 50001, // Custom bridge (non-Wormhole, relayer-attested)\n },\n} as const;\n\n// Legacy flat exports for backward compatibility\nexport const WORMHOLE_CHAIN_IDS_FLAT = {\n // Mainnets\n SOLANA: 1,\n ETHEREUM: 2,\n TERRA: 3,\n BSC: 4,\n POLYGON: 5,\n AVALANCHE: 6,\n OASIS: 7,\n ALGORAND: 8,\n AURORA: 9,\n FANTOM: 10,\n KARURA: 11,\n ACALA: 12,\n KLAYTN: 13,\n CELO: 14,\n NEAR: 15,\n MOONBEAM: 16,\n NEON: 17,\n TERRA2: 18,\n INJECTIVE: 19,\n OSMOSIS: 20,\n SUI: 21,\n APTOS: 22,\n ARBITRUM: 23,\n OPTIMISM: 24,\n GNOSIS: 25,\n PYTHNET: 26,\n XPLA: 28,\n BASE: 30,\n SEI: 32,\n ROOTSTOCK: 33,\n SCROLL: 34,\n MANTLE: 35,\n BLAST: 36,\n XLAYER: 37,\n LINEA: 38,\n BERACHAIN: 39,\n SEIEVM: 40,\n\n // Testnets\n SOLANA_DEVNET: 1,\n GOERLI: 2,\n BSC_TESTNET: 4,\n POLYGON_MUMBAI: 5,\n AVALANCHE_FUJI: 6,\n FANTOM_TESTNET: 10,\n CELO_ALFAJORES: 14,\n MOONBASE_ALPHA: 16,\n SUI_TESTNET: 21,\n APTOS_TESTNET: 22,\n ARBITRUM_SEPOLIA: 10003,\n BASE_SEPOLIA: 10004,\n OPTIMISM_SEPOLIA: 10005,\n POLYGON_SEPOLIA: 10007,\n HOLESKY: 10006,\n STARKNET_SEPOLIA: 50001, // Custom bridge (non-Wormhole)\n} as const;\n\n// ============================================================================\n// Testnet Chain Configurations\n// ============================================================================\n\nexport const TESTNET_CHAINS: Record<string, ChainConfig> = {\n baseSepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n wormholeChainId: 10004,\n rpcUrl: 'https://sepolia.base.org', // Public CORS-friendly RPC\n explorerUrl: 'https://sepolia.basescan.org',\n isEvm: true,\n contracts: {\n hub: '0x66D87dE68327f48A099c5B9bE97020Feab9a7c82',\n vaultFactory: '0x40D9B16094808Fa48e73598E31AB964Cf15b475f',\n vaultImplementation: '0xcBEb49b0109E61c1C69C51D5D9483A3aD6D18258',\n wormholeCoreBridge: '0x79A1027a6A159502049F10906D333EC57E95F083',\n tokenBridge: '0x86F55A04690fd7815A3D802bD587e83eA888B239',\n },\n },\n optimismSepolia: {\n name: 'Optimism Sepolia',\n chainId: 11155420,\n wormholeChainId: 10005,\n rpcUrl: 'https://sepolia.optimism.io',\n explorerUrl: 'https://sepolia-optimism.etherscan.io',\n isEvm: true,\n contracts: {\n vaultFactory: '0xAbB421166E648953CDBE93c0078a0A794c56Fb84',\n vaultImplementation: '0xDCD7daEf1AC06f4a8392957cca4834F7a16c058D',\n wormholeCoreBridge: '0x31377888146f3253211EFEf5c676D41ECe7D58Fe',\n tokenBridge: '0x99737Ec4B815d816c49A385943baf0380e75c0Ac',\n },\n },\n arbitrumSepolia: {\n name: 'Arbitrum Sepolia',\n chainId: 421614,\n wormholeChainId: 10003,\n rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc',\n explorerUrl: 'https://sepolia.arbiscan.io',\n isEvm: true,\n contracts: {\n vaultFactory: '0xd36D3D5DB59d78f1E33813490F72DABC15C9B07c',\n vaultImplementation: '0xB10ACf39eBF17fc33F722cBD955b7aeCB0611bc4',\n wormholeCoreBridge: '0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35',\n tokenBridge: '0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e',\n },\n },\n seiTestnet: {\n name: 'Sei Atlantic-2',\n chainId: 1328,\n wormholeChainId: 40,\n rpcUrl: 'https://evm-rpc-testnet.sei-apis.com',\n explorerUrl: 'https://seitrace.com/?chain=atlantic-2',\n isEvm: true,\n contracts: {\n vaultFactory: '0x07F608AFf6d63b68029488b726d895c4Bb593038',\n vaultImplementation: '0xD66153fccFB6731fB6c4944FbD607ba86A76a1f6',\n wormholeCoreBridge: '0x0000000000000000000000000000000000000000', // Mock - not yet deployed\n },\n },\n solanaDevnet: {\n name: 'Solana Devnet',\n chainId: 0,\n wormholeChainId: 1,\n rpcUrl: 'https://api.devnet.solana.com',\n explorerUrl: 'https://explorer.solana.com',\n isEvm: false,\n contracts: {\n hub: 'AnyXHsqq9c2BiW4WgBcj6Aye7Ua7a7L7iSuwpfJxECJM',\n wormholeCoreBridge: '3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5',\n tokenBridge: 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe',\n },\n },\n aptosTestnet: {\n name: 'Aptos Testnet',\n chainId: 0,\n wormholeChainId: 22,\n rpcUrl: 'https://fullnode.testnet.aptoslabs.com/v1',\n explorerUrl: 'https://explorer.aptoslabs.com',\n isEvm: false,\n contracts: {\n hub: '0x1a89da9e9f8f0bc90d8d492890bd55fb261c6277d2a95dfcac70c268d0c23dcc',\n wormholeCoreBridge: '0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625',\n tokenBridge: '0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f',\n },\n },\n suiTestnet: {\n name: 'Sui Testnet',\n chainId: 0,\n wormholeChainId: 21,\n rpcUrl: 'https://fullnode.testnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/testnet',\n isEvm: false,\n contracts: {\n hub: '0x35e99fdbbc1cde7e093da6f9e758ba2c4a077904bd64caee2fa6db5e6c4e9e37',\n wormholeCoreBridge: '0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790',\n },\n },\n starknetSepolia: {\n name: 'Starknet Sepolia',\n chainId: 0, // Native Starknet chain ID (SN_SEPOLIA = 0x534e5f5345504f4c4941)\n wormholeChainId: 50001, // Custom chain ID (50000+ reserved for non-Wormhole chains)\n rpcUrl: 'https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/tsOnfTBZDKMXcUA26OED-',\n explorerUrl: 'https://sepolia.starkscan.co',\n isEvm: false,\n contracts: {\n // Starknet spoke contract\n hub: '0x68adcc730ed6c355200d00f763825448497b9cdf7936ca121711e078c88e811',\n // Custom bridge contract (NOT Wormhole)\n wormholeCoreBridge: '0x2c458c1ae64556482b05cc2d3ee5b032ed114d68429dda2062c9849a5a725f8',\n },\n // Hub chain ID that Starknet bridge validates (Base Sepolia = 10004)\n hubChainId: 10004,\n },\n};\n\n// ============================================================================\n// Mainnet Chain Configurations\n// ============================================================================\n\nexport const MAINNET_CHAINS: Record<string, ChainConfig> = {\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n wormholeChainId: 2,\n rpcUrl: 'https://eth.llamarpc.com',\n explorerUrl: 'https://etherscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B',\n tokenBridge: '0x3ee18B2214AFF97000D974cf647E7C347E8fa585',\n },\n },\n base: {\n name: 'Base',\n chainId: 8453,\n wormholeChainId: 30,\n rpcUrl: 'https://mainnet.base.org',\n explorerUrl: 'https://basescan.org',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627',\n },\n },\n optimism: {\n name: 'Optimism',\n chainId: 10,\n wormholeChainId: 24,\n rpcUrl: 'https://mainnet.optimism.io',\n explorerUrl: 'https://optimistic.etherscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722',\n tokenBridge: '0x1D68124e65faFC907325e3EDbF8c4d84499DAa8b',\n },\n },\n arbitrum: {\n name: 'Arbitrum',\n chainId: 42161,\n wormholeChainId: 23,\n rpcUrl: 'https://arb1.arbitrum.io/rpc',\n explorerUrl: 'https://arbiscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xa5f208e072434bC67592E4C49C1B991BA79BCA46',\n tokenBridge: '0x0b2402144Bb366A632D14B83F244D2e0e21bD39c',\n },\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n wormholeChainId: 5,\n rpcUrl: 'https://polygon-rpc.com',\n explorerUrl: 'https://polygonscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7',\n tokenBridge: '0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE',\n },\n },\n solana: {\n name: 'Solana',\n chainId: 0,\n wormholeChainId: 1,\n rpcUrl: 'https://api.mainnet-beta.solana.com',\n explorerUrl: 'https://explorer.solana.com',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: 'worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth',\n tokenBridge: 'wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb',\n },\n },\n aptos: {\n name: 'Aptos',\n chainId: 0,\n wormholeChainId: 22,\n rpcUrl: 'https://fullnode.mainnet.aptoslabs.com/v1',\n explorerUrl: 'https://explorer.aptoslabs.com',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: '0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625',\n tokenBridge: '0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f',\n },\n },\n sui: {\n name: 'Sui',\n chainId: 0,\n wormholeChainId: 21,\n rpcUrl: 'https://fullnode.mainnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/mainnet',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: '0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c',\n },\n },\n};\n\n// ============================================================================\n// Wormhole API Endpoints\n// ============================================================================\n\nexport const WORMHOLE_API = {\n MAINNET: 'https://api.wormholescan.io',\n TESTNET: 'https://api.testnet.wormholescan.io',\n GUARDIAN_RPC_MAINNET: 'https://wormhole-v2-mainnet-api.certus.one',\n GUARDIAN_RPC_TESTNET: 'https://wormhole-v2-testnet-api.certus.one',\n} as const;\n\n// ============================================================================\n// Hub Contract ABI (minimal)\n// ============================================================================\n\nexport const HUB_ABI = [\n 'function authenticateAndDispatch((bytes authenticatorData, string clientDataJSON, uint256 challengeIndex, uint256 typeIndex, uint256 r, uint256 s) auth, uint256 publicKeyX, uint256 publicKeyY, uint16 targetChain, bytes actionPayload) external payable returns (uint64 sequence)',\n 'function authenticateRawAndDispatch(uint256 r, uint256 s, bytes32 messageHash, uint256 publicKeyX, uint256 publicKeyY, uint16 targetChain, bytes actionPayload, uint256 nonce) external payable returns (uint64 sequence)',\n 'function getNonce(bytes32 userKeyHash) external view returns (uint256)',\n 'function encodeTransferAction(address token, address recipient, uint256 amount) external pure returns (bytes)',\n 'function encodeExecuteAction(address target, uint256 value, bytes data) external pure returns (bytes)',\n 'function encodeBridgeAction(bytes32 token, uint256 amount, uint16 targetChain, bytes32 recipient) external pure returns (bytes)',\n 'function messageFee() external view returns (uint256)',\n 'event Dispatched(bytes32 indexed userKeyHash, uint16 targetChain, uint256 nonce, uint64 sequence, bytes actionPayload)',\n] as const;\n\n// ============================================================================\n// Vault Factory ABI (minimal)\n// ============================================================================\n\nexport const VAULT_FACTORY_ABI = [\n 'function createVault(bytes32 userKeyHash) external returns (address)',\n 'function getVault(bytes32 userKeyHash) external view returns (address)',\n 'function vaultExists(bytes32 userKeyHash) external view returns (bool)',\n 'event VaultCreated(bytes32 indexed userKeyHash, address vault)',\n] as const;\n\n// ============================================================================\n// Vault ABI (minimal)\n// ============================================================================\n\nexport const VAULT_ABI = [\n 'function execute(address target, uint256 value, bytes data) external returns (bytes)',\n 'function executeFromHub(bytes32 vaaHash, uint16 emitterChain, bytes32 emitterAddress, bytes payload) external',\n 'function owner() external view returns (bytes32)',\n 'function hub() external view returns (address)',\n 'receive() external payable',\n] as const;\n","import axios, { AxiosError } from 'axios';\nimport { Buffer } from 'buffer';\nimport { ethers } from 'ethers';\nimport { PublicKey } from '@solana/web3.js';\nimport {\n EthCallQueryRequest,\n EthCallQueryResponse,\n PerChainQueryRequest,\n QueryRequest,\n QueryResponse,\n SolanaAccountQueryRequest,\n SolanaAccountQueryResponse,\n hexToUint8Array,\n isValidHexString,\n} from '@wormhole-foundation/wormhole-query-sdk';\n\nimport { MAINNET_CHAINS, TESTNET_CHAINS } from '../constants.js';\nimport { WalletManager } from '../core/WalletManager.js';\nimport { getAllTokens, isNativeToken } from '../constants/tokens.js';\nimport { WORMHOLE_QUERY_PROXY_URLS } from './constants.js';\n\nexport type QueryPortfolioNetwork = 'testnet' | 'mainnet';\n\nexport type QueryPortfolioOptions = {\n /** Max response age in seconds (default: 60). */\n maxAge?: number;\n network?: QueryPortfolioNetwork;\n /** Maximum attempts including the first try (default: 4). */\n maxAttempts?: number;\n /** Cache TTL in ms (default: 30_000). */\n cacheTtlMs?: number;\n /** Request timeout in ms (default: 15_000 for testnet, 10_000 for mainnet). */\n timeout?: number;\n /** Override Query Proxy endpoint. */\n endpoint?: string;\n /** Override per-chain RPC URLs used for block tag lookups. */\n rpcUrls?: Record<number, string>;\n /** Override derived vault addresses for specific Wormhole chain IDs. */\n vaultAddresses?: Record<number, string>;\n /** Override token lists (ERC20 only) for specific Wormhole chain IDs. */\n evmTokenAddresses?: Record<number, string[]>;\n /** Additional Solana accounts to include in the Solana account query (base58). */\n solanaAccounts?: string[];\n /** Optional USD prices by symbol/address for aggregation (e.g. { USDC: 1 }). */\n pricesUsd?: Record<string, number>;\n};\n\nexport type PortfolioBalance = {\n assetId: string;\n amount: bigint;\n decimals?: number;\n symbol?: string;\n usdValue?: number;\n};\n\nexport type PortfolioChainErrorCode =\n | 'UNSUPPORTED_CHAIN'\n | 'MISSING_VAULT'\n | 'MISSING_TOKENS'\n | 'ATTESTATION_STALE'\n | 'DECODE_ERROR';\n\nexport type PortfolioChainResult = {\n wormholeChainId: number;\n chainName?: string;\n vaultAddress?: string;\n blockTime?: number;\n balances: PortfolioBalance[];\n error?: {\n code: PortfolioChainErrorCode;\n message: string;\n };\n};\n\nexport type PortfolioResult = {\n proof: Uint8Array;\n totalUsd?: number;\n chains: PortfolioChainResult[];\n};\n\nexport type QueryPortfolioErrorCode =\n | 'INVALID_ARGUMENT'\n | 'NETWORK_ERROR'\n | 'PROXY_HTTP_ERROR'\n | 'PROXY_RESPONSE_INVALID'\n | 'QUERY_RESPONSE_INVALID';\n\nexport class QueryPortfolioError extends Error {\n code: QueryPortfolioErrorCode;\n cause?: unknown;\n\n constructor(code: QueryPortfolioErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'QueryPortfolioError';\n this.code = code;\n this.cause = cause;\n }\n}\n\ntype CacheEntry = { expiresAt: number; value: PortfolioResult };\nconst PORTFOLIO_CACHE = new Map<string, CacheEntry>();\n\nfunction resolveNetwork(options?: QueryPortfolioOptions): QueryPortfolioNetwork {\n if (options?.network) return options.network;\n\n const envCandidates = [\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,\n (globalThis as any)?.process?.env?.WORMHOLE_NETWORK,\n ].filter(Boolean);\n\n const env = (envCandidates[0] as string | undefined)?.toLowerCase();\n if (env === 'mainnet' || env === 'testnet') return env;\n\n return 'testnet';\n}\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction signaturesToProofBytes(signatures: string[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n for (const sig of signatures) {\n if (typeof sig !== 'string' || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {\n throw new QueryPortfolioError(\n 'PROXY_RESPONSE_INVALID',\n `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`\n );\n }\n // Avoid Node Buffer-backed Uint8Array (can surface as SharedArrayBuffer in DTS types).\n chunks.push(hexToUint8Array(`0x${sig}`));\n }\n\n return concatBytes(chunks);\n}\n\nfunction decodeQueryBytes(bytes: string): Uint8Array {\n if (typeof bytes !== 'string' || bytes.length === 0) {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Missing query response bytes');\n }\n\n if (isValidHexString(bytes)) {\n return hexToUint8Array(bytes);\n }\n\n try {\n if (typeof atob === 'function') {\n const raw = atob(bytes);\n const arr = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);\n return arr;\n }\n } catch {\n // ignore\n }\n\n try {\n return new Uint8Array(Buffer.from(bytes, 'base64'));\n } catch (cause) {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Unrecognized query response bytes encoding', cause);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Simple rate limiter for Wormhole Query Proxy (6 requests/second limit).\n * Queues requests and releases them at the allowed rate.\n */\nconst rateLimiter = {\n queue: [] as Array<() => void>,\n lastRequest: 0,\n minInterval: 170, // ~6 req/s with buffer\n \n async acquire(): Promise<void> {\n return new Promise((resolve) => {\n const tryAcquire = () => {\n const now = Date.now();\n const elapsed = now - rateLimiter.lastRequest;\n if (elapsed >= rateLimiter.minInterval) {\n rateLimiter.lastRequest = now;\n resolve();\n } else {\n setTimeout(tryAcquire, rateLimiter.minInterval - elapsed);\n }\n };\n tryAcquire();\n });\n }\n};\n\nasync function withExponentialBackoff<T>(fn: () => Promise<T>, maxAttempts: number): Promise<T> {\n let attempt = 0;\n let lastError: unknown;\n\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts) break;\n\n const baseMs = 250;\n const backoffMs = Math.min(5_000, baseMs * 2 ** (attempt - 1));\n const jitterMs = Math.floor(Math.random() * 100);\n await sleep(backoffMs + jitterMs);\n }\n }\n\n throw lastError;\n}\n\nfunction getChainConfigs(network: QueryPortfolioNetwork) {\n return network === 'testnet' ? TESTNET_CHAINS : MAINNET_CHAINS;\n}\n\nfunction getProxyEndpoint(network: QueryPortfolioNetwork, options?: QueryPortfolioOptions): string {\n if (options?.endpoint) return options.endpoint;\n return network === 'testnet' ? WORMHOLE_QUERY_PROXY_URLS.testnet : WORMHOLE_QUERY_PROXY_URLS.mainnet;\n}\n\nfunction getDefaultPortfolioChains(network: QueryPortfolioNetwork): number[] {\n // Include hub (Base Sepolia 10004) and spoke chains\n return network === 'testnet' ? [10004, 10005, 10003, 1] : [30, 24, 23, 1];\n}\n\nfunction normalizeHex32(hex: string): Uint8Array {\n if (typeof hex !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(hex)) {\n throw new QueryPortfolioError('INVALID_ARGUMENT', `Invalid userKeyHash (expected 0x + 32 bytes hex): ${hex}`);\n }\n return new Uint8Array(Buffer.from(hex.slice(2), 'hex'));\n}\n\nfunction deriveSolanaVaultAddress(programIdBase58: string, userKeyHash: string): string {\n const programId = new PublicKey(programIdBase58);\n const keyHashBytes = normalizeHex32(userKeyHash);\n const [vaultPda] = PublicKey.findProgramAddressSync([Buffer.from('vault'), Buffer.from(keyHashBytes)], programId);\n return vaultPda.toBase58();\n}\n\nfunction makeCacheKey(userKeyHash: string, apiKey: string, options: QueryPortfolioOptions | undefined, chainIds: number[]) {\n // Do not include apiKey in the cache key; it should not affect the data.\n const payload = {\n userKeyHash,\n network: resolveNetwork(options),\n chainIds: [...chainIds].sort((a, b) => a - b),\n vaultAddresses: options?.vaultAddresses ?? null,\n evmTokenAddresses: options?.evmTokenAddresses ?? null,\n solanaAccounts: options?.solanaAccounts ?? null,\n endpoint: options?.endpoint ?? null,\n };\n\n void apiKey;\n return JSON.stringify(payload);\n}\n\nfunction safeNumberFromBigint(b: bigint): number {\n const n = Number(b);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction priceLookup(pricesUsd: Record<string, number> | undefined, symbol?: string, assetId?: string): number | undefined {\n if (!pricesUsd) return undefined;\n if (symbol && pricesUsd[symbol] != null) return pricesUsd[symbol];\n if (assetId && pricesUsd[assetId] != null) return pricesUsd[assetId];\n return undefined;\n}\n\nfunction sumUsd(balances: PortfolioBalance[], pricesUsd?: Record<string, number>): number | undefined {\n let total = 0;\n let any = false;\n\n for (const b of balances) {\n const p = priceLookup(pricesUsd, b.symbol, b.assetId);\n if (p == null) continue;\n if (b.decimals == null) continue;\n\n const denom = 10 ** b.decimals;\n const amount = Number(b.amount) / denom;\n if (!Number.isFinite(amount)) continue;\n total += amount * p;\n any = true;\n }\n\n return any ? total : undefined;\n}\n\nasync function getRecentBlockTag(rpcUrl: string): Promise<number> {\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const latest = await provider.getBlockNumber();\n return Math.max(0, latest - 2);\n}\n\nfunction encodeErc20BalanceCalls(vaultAddress: string, tokenAddresses: string[]): { to: string; data: string }[] {\n const iface = new ethers.Interface(['function balanceOf(address owner) view returns (uint256)']);\n return tokenAddresses.map((token) => ({\n to: token,\n data: iface.encodeFunctionData('balanceOf', [vaultAddress]),\n }));\n}\n\nfunction decodeErc20Balances(results: string[], tokenAddresses: string[]): bigint[] {\n const iface = new ethers.Interface(['function balanceOf(address owner) view returns (uint256)']);\n const out: bigint[] = [];\n for (let i = 0; i < tokenAddresses.length; i++) {\n const data = results[i];\n if (!data || data === '0x') {\n out.push(0n);\n continue;\n }\n const decoded = iface.decodeFunctionResult('balanceOf', data);\n out.push(decoded[0] as bigint);\n }\n return out;\n}\n\n/**\n * Fetch Guardian-attested vault balances across multiple chains in one Query Proxy request.\n *\n * Notes:\n * - EVM balances are ERC20-only via `eth_call` (native ETH is not queryable via this query type).\n * - Solana balance uses lamports of the Veridex vault PDA (plus optional extra accounts).\n * - Aptos is included only if/when Wormhole Queries adds Aptos query types (currently returned as unsupported).\n */\nexport async function queryPortfolio(\n userKeyHash: string,\n apiKey: string,\n options?: QueryPortfolioOptions\n): Promise<PortfolioResult> {\n const network = resolveNetwork(options);\n const maxAgeSeconds = options?.maxAge ?? 60;\n const maxAttempts = options?.maxAttempts ?? 4;\n const cacheTtlMs = options?.cacheTtlMs ?? 30_000;\n const endpoint = getProxyEndpoint(network, options);\n\n const chainIds = options?.rpcUrls ? Object.keys(options.rpcUrls).map(Number) : undefined;\n void chainIds;\n\n const requestedChains = options?.vaultAddresses\n ? Object.keys(options.vaultAddresses).map(Number)\n : undefined;\n\n const defaultChains = getDefaultPortfolioChains(network);\n const wormholeChainIds = options?.evmTokenAddresses\n ? Array.from(new Set([...defaultChains, ...Object.keys(options.evmTokenAddresses).map(Number)]))\n : defaultChains;\n\n // If the caller provided explicit vault overrides, include those chain IDs even if not in defaults.\n const finalChainIds = requestedChains\n ? Array.from(new Set([...wormholeChainIds, ...requestedChains]))\n : wormholeChainIds;\n\n if (!apiKey || typeof apiKey !== 'string') {\n throw new QueryPortfolioError('INVALID_ARGUMENT', 'Missing Query Proxy apiKey');\n }\n\n const cacheKey = makeCacheKey(userKeyHash, apiKey, options, finalChainIds);\n const cached = PORTFOLIO_CACHE.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.value;\n }\n\n const chains = getChainConfigs(network);\n const walletManager = new WalletManager({ cacheAddresses: true, persistToStorage: false });\n\n const pricesUsd: Record<string, number> | undefined = {\n USDC: 1,\n ...(options?.pricesUsd ?? {}),\n };\n\n const doFetch = async (): Promise<PortfolioResult> => {\n try {\n const perChainRequests: PerChainQueryRequest[] = [];\n const chainMeta: Record<number, { vaultAddress?: string; chainName?: string; kind: 'evm' | 'solana' | 'unsupported' }> = {};\n\n // Precompute any EVM block tags in parallel to keep total latency down.\n const evmChainIds = finalChainIds.filter((id) => {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === id);\n return cfg?.isEvm;\n });\n\n const blockTagsByChainId = new Map<number, number>();\n await Promise.all(\n evmChainIds.map(async (wormholeChainId) => {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n if (!cfg) return;\n const rpcUrl = options?.rpcUrls?.[wormholeChainId] ?? cfg.rpcUrl;\n const blockTag = await getRecentBlockTag(rpcUrl);\n blockTagsByChainId.set(wormholeChainId, blockTag);\n })\n );\n\n for (const wormholeChainId of finalChainIds) {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n\n if (wormholeChainId === 22) {\n chainMeta[wormholeChainId] = { kind: 'unsupported', chainName: cfg?.name };\n continue;\n }\n\n if (!cfg) {\n chainMeta[wormholeChainId] = { kind: 'unsupported' };\n continue;\n }\n\n if (cfg.isEvm) {\n const vaultAddress = options?.vaultAddresses?.[wormholeChainId]\n ?? (cfg.contracts.vaultFactory && cfg.contracts.vaultImplementation\n ? walletManager.computeVaultAddress(userKeyHash, cfg.contracts.vaultFactory, cfg.contracts.vaultImplementation)\n : undefined);\n\n chainMeta[wormholeChainId] = { kind: 'evm', vaultAddress, chainName: cfg.name };\n\n if (!vaultAddress) {\n continue;\n }\n\n const tokenAddresses = options?.evmTokenAddresses?.[wormholeChainId]\n ?? getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address)).map((t) => t.address);\n\n if (!tokenAddresses.length) {\n continue;\n }\n\n const blockTag = blockTagsByChainId.get(wormholeChainId);\n if (blockTag == null) {\n continue;\n }\n\n const calls = encodeErc20BalanceCalls(vaultAddress, tokenAddresses);\n perChainRequests.push(new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, calls)));\n continue;\n }\n\n // Solana\n if (wormholeChainId === 1) {\n const programId = options?.vaultAddresses?.[wormholeChainId] ?? cfg.contracts.hub;\n chainMeta[wormholeChainId] = { kind: 'solana', chainName: cfg.name };\n\n if (!programId) {\n continue;\n }\n\n const vaultAddress = deriveSolanaVaultAddress(programId, userKeyHash);\n chainMeta[wormholeChainId] = { kind: 'solana', chainName: cfg.name, vaultAddress };\n\n const accounts = [vaultAddress, ...(options?.solanaAccounts ?? [])];\n perChainRequests.push(\n new PerChainQueryRequest(\n wormholeChainId,\n new SolanaAccountQueryRequest('finalized', accounts, undefined, 0n, 0n)\n )\n );\n continue;\n }\n\n chainMeta[wormholeChainId] = { kind: 'unsupported', chainName: cfg.name };\n }\n\n if (perChainRequests.length > 255) {\n throw new QueryPortfolioError(\n 'INVALID_ARGUMENT',\n `Too many per-chain requests (${perChainRequests.length}); max is 255 per Query Proxy request`\n );\n }\n\n // If no per-chain requests were built (e.g., missing vaults or tokens), return early with empty results\n if (perChainRequests.length === 0) {\n const chainsOut: PortfolioChainResult[] = finalChainIds.map((wormholeChainId) => {\n const meta = chainMeta[wormholeChainId] ?? { kind: 'unsupported' as const };\n return {\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { \n code: 'MISSING_VAULT' as const, \n message: 'Unable to build query: missing vault address or no tokens configured' \n },\n };\n });\n return { proof: new Uint8Array(), totalUsd: 0, chains: chainsOut };\n }\n\n const request = new QueryRequest(Date.now() & 0xffffffff, perChainRequests);\n // Wormhole Query Proxy expects raw hex WITHOUT 0x prefix\n const requestHex = Buffer.from(request.serialize()).toString('hex');\n\n // Respect rate limit before making request\n await rateLimiter.acquire();\n\n let response;\n try {\n console.log('[queryPortfolio] Sending request to:', endpoint);\n console.log('[queryPortfolio] Request bytes length:', requestHex.length);\n \n // Use provided timeout, or default to 15s for testnet (slower), 10s for mainnet\n const defaultTimeout = network === 'testnet' ? 15_000 : 10_000;\n const requestTimeout = options?.timeout ?? defaultTimeout;\n \n response = await axios.post(\n endpoint,\n { bytes: requestHex },\n {\n headers: {\n 'X-API-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n timeout: requestTimeout,\n }\n );\n } catch (axiosErr) {\n const err = axiosErr as AxiosError;\n // Network errors (CORS, timeout, no connection) have no response\n if (!err.response) {\n console.error('[queryPortfolio] Network error:', {\n message: err.message,\n code: err.code,\n name: err.name,\n });\n throw new QueryPortfolioError(\n 'NETWORK_ERROR',\n `Network error: ${err.message} (code: ${err.code})`\n );\n }\n const status = err.response.status;\n const errData = err.response.data;\n console.error('[queryPortfolio] Wormhole Query Proxy error:', { status, data: errData });\n throw new QueryPortfolioError(\n 'PROXY_RESPONSE_INVALID',\n `Query Proxy returned ${status}: ${JSON.stringify(errData)}`\n );\n }\n\n const data = response.data as any;\n const signatures = data?.signatures as string[] | undefined;\n const bytes = data?.bytes as string | undefined;\n\n if (!Array.isArray(signatures) || typeof bytes !== 'string') {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Query Proxy response missing signatures/bytes');\n }\n\n const proof = signaturesToProofBytes(signatures);\n const queryBytes = decodeQueryBytes(bytes);\n const parsed = QueryResponse.from(queryBytes);\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n const chainsOut: PortfolioChainResult[] = [];\n\n for (const wormholeChainId of finalChainIds) {\n const meta = chainMeta[wormholeChainId] ?? { kind: 'unsupported' as const };\n\n if (meta.kind === 'unsupported') {\n const msg = wormholeChainId === 22\n ? 'Aptos Queries are not supported by the Wormhole Query SDK yet'\n : 'Chain is not supported by this portfolio query implementation';\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n balances: [],\n error: { code: 'UNSUPPORTED_CHAIN', message: msg },\n });\n continue;\n }\n\n if (!meta.vaultAddress) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n balances: [],\n error: { code: 'MISSING_VAULT', message: 'Unable to derive vault address for chain' },\n });\n continue;\n }\n\n const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);\n if (!perChain) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'DECODE_ERROR', message: 'Missing per-chain response from Query Proxy' },\n });\n continue;\n }\n\n try {\n if (meta.kind === 'evm') {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n const tokenAddresses = options?.evmTokenAddresses?.[wormholeChainId]\n ?? getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address)).map((t) => t.address);\n\n if (!tokenAddresses.length) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'MISSING_TOKENS', message: 'No ERC20 tokens configured for EVM portfolio query' },\n });\n continue;\n }\n\n const chainResp = EthCallQueryResponse.from(perChain.response.serialize());\n const blockTime = Number(chainResp.blockTime);\n const age = nowSeconds - blockTime;\n if (age > maxAgeSeconds) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances: [],\n error: { code: 'ATTESTATION_STALE', message: `Attestation stale by ${age}s (maxAge=${maxAgeSeconds}s)` },\n });\n continue;\n }\n\n const amounts = decodeErc20Balances(chainResp.results, tokenAddresses);\n const tokenInfos = getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address));\n\n const balances: PortfolioBalance[] = tokenAddresses.map((addr, i) => {\n const info = tokenInfos.find((t) => t.address.toLowerCase() === addr.toLowerCase());\n const symbol = info?.symbol;\n const decimals = info?.decimals;\n const usdPrice = priceLookup(pricesUsd, symbol, addr);\n const usdValue = usdPrice != null && decimals != null\n ? (Number(amounts[i]) / 10 ** decimals) * usdPrice\n : undefined;\n\n return {\n assetId: addr,\n amount: amounts[i],\n symbol,\n decimals,\n usdValue: Number.isFinite(usdValue ?? NaN) ? usdValue : undefined,\n };\n });\n\n void cfg;\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances,\n });\n continue;\n }\n\n // Solana\n const chainResp = SolanaAccountQueryResponse.from(perChain.response.serialize());\n const blockTime = safeNumberFromBigint(chainResp.blockTime);\n const age = nowSeconds - blockTime;\n if (age > maxAgeSeconds) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances: [],\n error: { code: 'ATTESTATION_STALE', message: `Attestation stale by ${age}s (maxAge=${maxAgeSeconds}s)` },\n });\n continue;\n }\n\n const vaultResult = chainResp.results[0];\n const lamports = vaultResult?.lamports ?? 0n;\n\n const balances: PortfolioBalance[] = [\n {\n assetId: 'SOL',\n amount: lamports,\n decimals: 9,\n symbol: 'SOL',\n usdValue: priceLookup(pricesUsd, 'SOL', 'SOL') != null\n ? (Number(lamports) / 1e9) * (priceLookup(pricesUsd, 'SOL', 'SOL') as number)\n : undefined,\n },\n ];\n\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances,\n });\n } catch (cause) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'DECODE_ERROR', message: `Failed to decode chain response: ${String((cause as any)?.message ?? cause)}` },\n });\n }\n }\n\n const allBalances = chainsOut.flatMap((c) => c.balances);\n const totalUsd = sumUsd(allBalances, pricesUsd);\n\n const result: PortfolioResult = { proof, totalUsd, chains: chainsOut };\n\n PORTFOLIO_CACHE.set(cacheKey, { expiresAt: Date.now() + cacheTtlMs, value: result });\n return result;\n } catch (err) {\n if (err instanceof QueryPortfolioError) throw err;\n if (axios.isAxiosError(err)) {\n const ax = err as AxiosError;\n const status = ax.response?.status;\n const statusText = ax.response?.statusText;\n const details = typeof ax.response?.data === 'string' ? ax.response?.data : undefined;\n\n throw new QueryPortfolioError(\n 'PROXY_HTTP_ERROR',\n `Query Proxy request failed${status ? ` (${status} ${statusText ?? ''})` : ''}${details ? `: ${details}` : ''}`,\n err\n );\n }\n\n throw new QueryPortfolioError('PROXY_HTTP_ERROR', 'Query Proxy request failed', err);\n }\n };\n\n const result = await withExponentialBackoff(doFetch, maxAttempts);\n PORTFOLIO_CACHE.set(cacheKey, { expiresAt: Date.now() + cacheTtlMs, value: result });\n return result;\n}\n","/**\n * Veridex Protocol SDK - Wallet Manager\n * \n * Manages deterministic wallet addresses across multiple chains.\n * Vault addresses are computed using CREATE2 on EVM chains and chain-specific\n * derivation on non-EVM chains, all based on the user's passkey public key.\n */\n\nimport { ethers } from 'ethers';\nimport type { \n PasskeyCredential,\n UnifiedIdentity,\n ChainAddress,\n WalletManagerConfig,\n} from './types.js';\nimport { computeKeyHash } from '../utils.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * EIP-1167 minimal proxy bytecode prefix (before implementation address)\n * 3d602d80600a3d3981f3363d3d373d3d3d363d73\n */\nconst PROXY_BYTECODE_PREFIX = '0x3d602d80600a3d3981f3363d3d373d3d3d363d73';\n\n/**\n * EIP-1167 minimal proxy bytecode suffix (after implementation address)\n * 5af43d82803e903d91602b57fd5bf3\n */\nconst PROXY_BYTECODE_SUFFIX = '5af43d82803e903d91602b57fd5bf3';\n\n// ============================================================================\n// WalletManager Class\n// ============================================================================\n\n/**\n * Manages wallet address derivation and storage for Veridex Protocol\n * \n * @example\n * ```typescript\n * const manager = new WalletManager();\n * \n * // Compute vault address for a credential\n * const address = await manager.computeVaultAddress(\n * credential.keyHash,\n * factoryAddress,\n * implementationAddress\n * );\n * \n * // Get unified identity with addresses on all chains\n * const identity = await manager.getUnifiedIdentity(credential, chainConfigs);\n * ```\n */\nexport class WalletManager {\n private config: WalletManagerConfig;\n private addressCache: Map<string, ChainAddress[]> = new Map();\n\n constructor(config: WalletManagerConfig = {}) {\n this.config = {\n cacheAddresses: config.cacheAddresses ?? true,\n persistToStorage: config.persistToStorage ?? false,\n storageKey: config.storageKey ?? 'veridex_wallet_addresses',\n };\n\n // Load cached addresses from storage if enabled\n if (this.config.persistToStorage && typeof window !== 'undefined') {\n this.loadFromStorage();\n }\n }\n\n // ========================================================================\n // Address Computation\n // ========================================================================\n\n /**\n * Compute the deterministic vault address for an EVM chain\n * \n * Uses CREATE2 with EIP-1167 minimal proxy pattern:\n * - Salt = keccak256(factoryAddress, ownerKeyHash)\n * - InitCode = EIP-1167 proxy bytecode with implementation address\n * \n * @param keyHash - The owner's key hash (keccak256 of public key coordinates)\n * @param factoryAddress - The vault factory contract address\n * @param implementationAddress - The vault implementation contract address\n * @returns The deterministic vault address\n */\n computeVaultAddress(\n keyHash: string,\n factoryAddress: string,\n implementationAddress: string\n ): string {\n // Compute salt: keccak256(abi.encodePacked(factory, keyHash))\n const salt = ethers.keccak256(\n ethers.solidityPacked(\n ['address', 'bytes32'],\n [factoryAddress, keyHash]\n )\n );\n\n // Build EIP-1167 initcode\n const initCode = this.buildProxyInitCode(implementationAddress);\n const initCodeHash = ethers.keccak256(initCode);\n\n // CREATE2 address computation:\n // address = keccak256(0xff ++ factory ++ salt ++ initCodeHash)[12:]\n const create2Data = ethers.solidityPacked(\n ['bytes1', 'address', 'bytes32', 'bytes32'],\n ['0xff', factoryAddress, salt, initCodeHash]\n );\n\n const hash = ethers.keccak256(create2Data);\n // Take last 20 bytes as address\n return ethers.getAddress('0x' + hash.slice(26));\n }\n\n /**\n * Compute vault address from public key coordinates\n * \n * @param publicKeyX - P-256 public key X coordinate\n * @param publicKeyY - P-256 public key Y coordinate\n * @param factoryAddress - The vault factory contract address\n * @param implementationAddress - The vault implementation contract address\n * @returns The deterministic vault address\n */\n computeVaultAddressFromPublicKey(\n publicKeyX: bigint,\n publicKeyY: bigint,\n factoryAddress: string,\n implementationAddress: string\n ): string {\n const keyHash = computeKeyHash(publicKeyX, publicKeyY);\n return this.computeVaultAddress(keyHash, factoryAddress, implementationAddress);\n }\n\n /**\n * Build EIP-1167 minimal proxy initcode\n */\n private buildProxyInitCode(implementationAddress: string): string {\n // Remove 0x prefix if present and lowercase\n const impl = implementationAddress.toLowerCase().replace('0x', '');\n \n // EIP-1167 bytecode format\n return PROXY_BYTECODE_PREFIX + impl + PROXY_BYTECODE_SUFFIX;\n }\n\n // ========================================================================\n // Unified Identity\n // ========================================================================\n\n /**\n * Get unified identity with addresses across all configured chains\n * \n * @param credential - The passkey credential\n * @param chainConfigs - Map of chain configurations with factory/implementation addresses\n * @returns Unified identity with addresses on each chain\n */\n async getUnifiedIdentity(\n credential: PasskeyCredential,\n chainConfigs: Map<number, ChainAddressConfig>\n ): Promise<UnifiedIdentity> {\n const addresses: ChainAddress[] = [];\n\n for (const [wormholeChainId, config] of chainConfigs) {\n const address = await this.deriveAddressForChain(\n credential,\n wormholeChainId,\n config\n );\n \n if (address) {\n addresses.push(address);\n }\n }\n\n const identity: UnifiedIdentity = {\n keyHash: credential.keyHash,\n publicKeyX: credential.publicKeyX,\n publicKeyY: credential.publicKeyY,\n credentialId: credential.credentialId,\n addresses,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n // Cache the identity\n if (this.config.cacheAddresses) {\n this.addressCache.set(credential.keyHash, addresses);\n }\n\n // Persist to storage if enabled\n if (this.config.persistToStorage) {\n this.saveToStorage(identity);\n }\n\n return identity;\n }\n\n /**\n * Derive address for a specific chain\n */\n private async deriveAddressForChain(\n credential: PasskeyCredential,\n wormholeChainId: number,\n config: ChainAddressConfig\n ): Promise<ChainAddress | null> {\n if (config.isEvm) {\n // EVM chains use CREATE2\n if (!config.factoryAddress || !config.implementationAddress) {\n return null;\n }\n\n const address = this.computeVaultAddress(\n credential.keyHash,\n config.factoryAddress,\n config.implementationAddress\n );\n\n return {\n wormholeChainId,\n chainName: config.chainName,\n address,\n isEvm: true,\n deployed: false, // Will be checked separately\n };\n } else {\n // Non-EVM chains have chain-specific address derivation\n return this.deriveNonEvmAddress(credential, wormholeChainId, config);\n }\n }\n\n /**\n * Derive address for non-EVM chains\n * \n * Each chain has its own address format:\n * - Solana: Base58 encoded public key hash\n * - Aptos: 32-byte hex address\n * - Sui: 32-byte hex address with 0x prefix\n */\n private deriveNonEvmAddress(\n credential: PasskeyCredential,\n wormholeChainId: number,\n _config: ChainAddressConfig\n ): ChainAddress | null {\n switch (wormholeChainId) {\n case 1: // Solana\n // Solana uses the key hash directly as a seed for PDA derivation\n // The actual address depends on the program ID\n return {\n wormholeChainId: 1,\n chainName: 'Solana',\n address: credential.keyHash, // PDA will be derived from this\n isEvm: false,\n derivationType: 'pda',\n deployed: false,\n };\n\n case 22: // Aptos\n // Aptos uses the key hash as the resource account address\n return {\n wormholeChainId: 22,\n chainName: 'Aptos',\n address: credential.keyHash,\n isEvm: false,\n derivationType: 'resource_account',\n deployed: false,\n };\n\n case 21: // Sui\n // Sui uses the key hash with 0x prefix\n return {\n wormholeChainId: 21,\n chainName: 'Sui',\n address: credential.keyHash,\n isEvm: false,\n derivationType: 'object',\n deployed: false,\n };\n\n default:\n // Unknown chain\n return null;\n }\n }\n\n // ========================================================================\n // Address Lookup\n // ========================================================================\n\n /**\n * Get cached address for a chain\n */\n getAddressForChain(keyHash: string, wormholeChainId: number): ChainAddress | undefined {\n const addresses = this.addressCache.get(keyHash);\n return addresses?.find(a => a.wormholeChainId === wormholeChainId);\n }\n\n /**\n * Get all cached addresses for a key hash\n */\n getAddresses(keyHash: string): ChainAddress[] {\n return this.addressCache.get(keyHash) ?? [];\n }\n\n /**\n * Update deployment status for an address\n */\n updateDeploymentStatus(\n keyHash: string,\n wormholeChainId: number,\n deployed: boolean,\n deploymentTxHash?: string\n ): void {\n const addresses = this.addressCache.get(keyHash);\n if (!addresses) return;\n\n const address = addresses.find(a => a.wormholeChainId === wormholeChainId);\n if (address) {\n address.deployed = deployed;\n address.deploymentTxHash = deploymentTxHash;\n }\n\n // Persist update if enabled\n if (this.config.persistToStorage) {\n this.saveAddressesToStorage(keyHash, addresses);\n }\n }\n\n // ========================================================================\n // Storage\n // ========================================================================\n\n /**\n * Load addresses from localStorage\n */\n private loadFromStorage(): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!);\n if (!stored) return;\n\n const data = JSON.parse(stored) as StoredWalletData;\n \n for (const [keyHash, addresses] of Object.entries(data.addresses)) {\n this.addressCache.set(keyHash, addresses);\n }\n } catch (error) {\n console.warn('Failed to load wallet addresses from storage:', error);\n }\n }\n\n /**\n * Save identity to localStorage\n */\n private saveToStorage(identity: UnifiedIdentity): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!) ?? '{}';\n const data = JSON.parse(stored) as StoredWalletData;\n\n if (!data.addresses) {\n data.addresses = {};\n }\n\n // Store identity with serialized bigints\n data.addresses[identity.keyHash] = identity.addresses;\n data.identities = data.identities ?? {};\n data.identities[identity.keyHash] = {\n keyHash: identity.keyHash,\n publicKeyX: identity.publicKeyX.toString(),\n publicKeyY: identity.publicKeyY.toString(),\n credentialId: identity.credentialId,\n createdAt: identity.createdAt,\n updatedAt: identity.updatedAt,\n };\n\n localStorage.setItem(this.config.storageKey!, JSON.stringify(data));\n } catch (error) {\n console.warn('Failed to save wallet addresses to storage:', error);\n }\n }\n\n /**\n * Save addresses to localStorage\n */\n private saveAddressesToStorage(keyHash: string, addresses: ChainAddress[]): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!) ?? '{}';\n const data = JSON.parse(stored) as StoredWalletData;\n\n if (!data.addresses) {\n data.addresses = {};\n }\n\n data.addresses[keyHash] = addresses;\n localStorage.setItem(this.config.storageKey!, JSON.stringify(data));\n } catch (error) {\n console.warn('Failed to save wallet addresses to storage:', error);\n }\n }\n\n /**\n * Clear all cached data\n */\n clearCache(): void {\n this.addressCache.clear();\n \n if (this.config.persistToStorage && typeof window !== 'undefined') {\n localStorage.removeItem(this.config.storageKey!);\n }\n }\n\n /**\n * Load identity from storage\n */\n loadIdentityFromStorage(keyHash: string): UnifiedIdentity | null {\n if (typeof window === 'undefined') return null;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!);\n if (!stored) return null;\n\n const data = JSON.parse(stored) as StoredWalletData;\n const storedIdentity = data.identities?.[keyHash];\n const addresses = data.addresses?.[keyHash];\n\n if (!storedIdentity || !addresses) return null;\n\n return {\n keyHash: storedIdentity.keyHash,\n publicKeyX: BigInt(storedIdentity.publicKeyX),\n publicKeyY: BigInt(storedIdentity.publicKeyY),\n credentialId: storedIdentity.credentialId,\n addresses,\n createdAt: storedIdentity.createdAt,\n updatedAt: storedIdentity.updatedAt,\n };\n } catch (error) {\n console.warn('Failed to load identity from storage:', error);\n return null;\n }\n }\n}\n\n// ============================================================================\n// Helper Types (Internal)\n// ============================================================================\n\ninterface ChainAddressConfig {\n chainName: string;\n isEvm: boolean;\n factoryAddress?: string;\n implementationAddress?: string;\n}\n\ninterface StoredWalletData {\n addresses: Record<string, ChainAddress[]>;\n identities?: Record<string, {\n keyHash: string;\n publicKeyX: string;\n publicKeyY: string;\n credentialId: string;\n createdAt: number;\n updatedAt: number;\n }>;\n}\n\n// Export the helper type for external use\nexport type { ChainAddressConfig };\n","/**\n * Veridex Protocol SDK - Utility Functions\n */\n\nimport { ethers } from 'ethers';\nimport type { ChainConfig } from './types.js';\nimport { TESTNET_CHAINS, MAINNET_CHAINS } from './constants.js';\n\n// ============================================================================\n// Base64URL Encoding/Decoding (WebAuthn compatible)\n// ============================================================================\n\n/**\n * Base64URL encode a buffer\n */\nexport function base64URLEncode(buffer: Uint8Array): string {\n // Convert Uint8Array to base64 using browser APIs\n const bytes = Array.from(buffer);\n const binary = String.fromCharCode(...bytes);\n const base64 = btoa(binary);\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Base64URL decode a string\n */\nexport function base64URLDecode(str: string): Uint8Array {\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n // Use browser's atob for base64 decoding\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n// ============================================================================\n// Signature Utilities\n// ============================================================================\n\n/**\n * Parse DER-encoded ECDSA signature to r and s values\n */\nexport function parseDERSignature(signature: Uint8Array): { r: Uint8Array; s: Uint8Array } {\n let offset = 0;\n\n if (signature[offset++] !== 0x30) {\n throw new Error('Invalid signature format');\n }\n\n // Skip total length\n offset++;\n\n if (signature[offset++] !== 0x02) {\n throw new Error('Invalid signature format');\n }\n\n const rLength = signature[offset++];\n if (rLength === undefined) {\n throw new Error('Invalid signature format: missing r length');\n }\n let r = signature.slice(offset, offset + rLength);\n offset += rLength;\n\n // Remove leading zero if present (for positive number representation)\n if (r[0] === 0x00 && r.length > 32) {\n r = r.slice(1);\n }\n // Pad to 32 bytes if needed\n if (r.length < 32) {\n const padded = new Uint8Array(32);\n padded.set(r, 32 - r.length);\n r = padded;\n }\n\n if (signature[offset++] !== 0x02) {\n throw new Error('Invalid signature format');\n }\n\n const sLength = signature[offset++];\n if (sLength === undefined) {\n throw new Error('Invalid signature format: missing s length');\n }\n let s = signature.slice(offset, offset + sLength);\n\n // Remove leading zero if present\n if (s[0] === 0x00 && s.length > 32) {\n s = s.slice(1);\n }\n // Pad to 32 bytes if needed\n if (s.length < 32) {\n const padded = new Uint8Array(32);\n padded.set(s, 32 - s.length);\n s = padded;\n }\n\n return { r, s };\n}\n\n/**\n * Encode signature for Solidity verification\n */\nexport function encodeSignatureForSolidity(r: bigint, s: bigint): string {\n return ethers.solidityPacked(['uint256', 'uint256'], [r, s]);\n}\n\n// ============================================================================\n// Key Hash Utilities\n// ============================================================================\n\n/**\n * Compute key hash from public key coordinates\n */\nexport function computeKeyHash(publicKeyX: bigint, publicKeyY: bigint): string {\n return ethers.keccak256(\n ethers.solidityPacked(['uint256', 'uint256'], [publicKeyX, publicKeyY])\n );\n}\n\n// ============================================================================\n// Chain Utilities\n// ============================================================================\n\n/**\n * Get chain config by name\n */\nexport function getChainConfig(chainName: string, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return chains[chainName];\n}\n\n/**\n * Get chain config by Wormhole chain ID\n */\nexport function getChainByWormholeId(wormholeChainId: number, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains).find(chain => chain.wormholeChainId === wormholeChainId);\n}\n\n/**\n * Get chain config by EVM chain ID\n */\nexport function getChainByEvmId(evmChainId: number, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains).find(chain => chain.chainId === evmChainId);\n}\n\n/**\n * Check if a chain is EVM-compatible\n */\nexport function isEvmChain(wormholeChainId: number): boolean {\n // Non-EVM chains\n const nonEvmChains = new Set([1, 8, 15, 21, 22]); // Solana, Algorand, NEAR, Sui, Aptos\n return !nonEvmChains.has(wormholeChainId);\n}\n\n/**\n * Get all supported chains\n */\nexport function getSupportedChains(testnet = true): ChainConfig[] {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains);\n}\n\n// ============================================================================\n// Explorer URL Utilities\n// ============================================================================\n\n/**\n * Get transaction explorer URL\n */\nexport function getTxExplorerUrl(chain: ChainConfig, txHash: string): string {\n if (chain.isEvm) {\n return `${chain.explorerUrl}/tx/${txHash}`;\n }\n\n // Non-EVM chains have different URL patterns\n switch (chain.wormholeChainId) {\n case 1: // Solana\n return `${chain.explorerUrl}/tx/${txHash}?cluster=devnet`;\n case 21: // Sui\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 22: // Aptos\n return `${chain.explorerUrl}/txn/${txHash}?network=testnet`;\n default:\n return `${chain.explorerUrl}/tx/${txHash}`;\n }\n}\n\n/**\n * Get address explorer URL\n */\nexport function getAddressExplorerUrl(chain: ChainConfig, address: string): string {\n if (chain.isEvm) {\n return `${chain.explorerUrl}/address/${address}`;\n }\n\n switch (chain.wormholeChainId) {\n case 1: // Solana\n return `${chain.explorerUrl}/address/${address}?cluster=devnet`;\n case 21: // Sui\n return `${chain.explorerUrl}/account/${address}`;\n case 22: // Aptos\n return `${chain.explorerUrl}/account/${address}?network=testnet`;\n default:\n return `${chain.explorerUrl}/address/${address}`;\n }\n}\n\n// ============================================================================\n// Validation Utilities\n// ============================================================================\n\n/**\n * Validate an EVM address\n */\nexport function isValidEvmAddress(address: string): boolean {\n return ethers.isAddress(address);\n}\n\n/**\n * Validate a bytes32 hex string\n */\nexport function isValidBytes32(hex: string): boolean {\n const clean = hex.replace('0x', '');\n return /^[0-9a-fA-F]{64}$/.test(clean);\n}\n\n/**\n * Validate a Wormhole chain ID\n */\nexport function isValidWormholeChainId(chainId: number): boolean {\n // Valid Wormhole chain IDs range from 1 to ~10007 (testnets)\n return chainId >= 1 && chainId <= 50000;\n}\n\n// ============================================================================\n// Retry Utilities\n// ============================================================================\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function retryWithBackoff<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n onRetry?: (attempt: number, error: Error) => void;\n } = {}\n): Promise<T> {\n const {\n maxRetries = 5,\n initialDelayMs = 1000,\n maxDelayMs = 30000,\n backoffMultiplier = 2,\n onRetry,\n } = options;\n\n let lastError: Error | undefined;\n let delay = initialDelayMs;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n if (attempt < maxRetries) {\n onRetry?.(attempt, lastError);\n await sleep(delay);\n delay = Math.min(delay * backoffMultiplier, maxDelayMs);\n }\n }\n }\n\n throw lastError ?? new Error('Retry failed');\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","/**\n * Veridex Protocol SDK - Token Constants\n * \n * Known tokens per chain for balance fetching and transfers\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TokenInfo {\n /** Token symbol (e.g., 'USDC', 'ETH') */\n symbol: string;\n /** Token name (e.g., 'USD Coin') */\n name: string;\n /** Token address (use 'native' for native token) */\n address: string;\n /** Number of decimals */\n decimals: number;\n /** Optional logo URL */\n logoUrl?: string;\n /** Whether this is the native token */\n isNative: boolean;\n /** Wormhole-wrapped token address on other chains (by wormhole chain ID) */\n wrappedAddresses?: Record<number, string>;\n}\n\nexport interface ChainTokenList {\n /** Wormhole chain ID */\n wormholeChainId: number;\n /** Chain name */\n chainName: string;\n /** Native token info */\n nativeToken: TokenInfo;\n /** ERC20/SPL/etc tokens */\n tokens: TokenInfo[];\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Native token address constant\n */\nexport const NATIVE_TOKEN_ADDRESS = 'native';\n\n/**\n * Zero address for EVM chains\n */\nexport const EVM_ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n\n// ============================================================================\n// Base Sepolia (Hub Chain) - Wormhole Chain ID 10004\n// ============================================================================\n\nexport const BASE_SEPOLIA_TOKENS: ChainTokenList = {\n wormholeChainId: 10004,\n chainName: 'Base Sepolia',\n nativeToken: {\n symbol: 'ETH',\n name: 'Ether',\n address: NATIVE_TOKEN_ADDRESS,\n decimals: 18,\n isNative: true,\n },\n tokens: [\n {\n symbol: 'USDC',\n name: 'USD Coin (Test)',\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Circle test USDC\n decimals: 6,\n isNative: false,\n },\n {\n symbol: 'WETH',\n name: 'Wrapped Ether',\n address: '0x4200000000000000000000000000000000000006',\n decimals: 18,\n isNative: false,\n },\n ],\n};\n\n// ============================================================================\n// Optimism Sepolia (Spoke Chain) - Wormhole Chain ID 10005\n// ============================================================================\n\nexport const OPTIMISM_SEPOLIA_TOKENS: ChainTokenList = {\n wormholeChainId: 10005,\n chainName: 'Optimism Sepolia',\n nativeToken: {\n symbol: 'ETH',\n name: 'Ether',\n address: NATIVE_TOKEN_ADDRESS,\n decimals: 18,\n isNative: true,\n },\n tokens: [\n {\n symbol: 'USDC',\n name: 'USD Coin (Test)',\n address: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7', // Test USDC\n decimals: 6,\n isNative: false,\n },\n {\n symbol: 'WETH',\n name: 'Wrapped Ether',\n address: '0x4200000000000000000000000000000000000006',\n decimals: 18,\n isNative: false,\n },\n ],\n};\n\n// ============================================================================\n// Arbitrum Sepolia (Spoke Chain) - Wormhole Chain ID 10003\n// ============================================================================\n\nexport const ARBITRUM_SEPOLIA_TOKENS: ChainTokenList = {\n wormholeChainId: 10003,\n chainName: 'Arbitrum Sepolia',\n nativeToken: {\n symbol: 'ETH',\n name: 'Ether',\n address: NATIVE_TOKEN_ADDRESS,\n decimals: 18,\n isNative: true,\n },\n tokens: [\n {\n symbol: 'USDC',\n name: 'USD Coin (Test)',\n address: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d', // Circle USDC Arbitrum Sepolia\n decimals: 6,\n isNative: false,\n },\n {\n symbol: 'WETH',\n name: 'Wrapped Ether',\n address: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73',\n decimals: 18,\n isNative: false,\n },\n ],\n};\n\n// ============================================================================\n// Token Registry\n// ============================================================================\n\n/**\n * All token lists indexed by Wormhole chain ID\n */\nexport const TOKEN_REGISTRY: Record<number, ChainTokenList> = {\n 10004: BASE_SEPOLIA_TOKENS,\n 10005: OPTIMISM_SEPOLIA_TOKENS,\n 10003: ARBITRUM_SEPOLIA_TOKENS,\n};\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get token list for a chain\n */\nexport function getTokenList(wormholeChainId: number): ChainTokenList | null {\n return TOKEN_REGISTRY[wormholeChainId] ?? null;\n}\n\n/**\n * Get all tokens for a chain (native + ERC20)\n */\nexport function getAllTokens(wormholeChainId: number): TokenInfo[] {\n const list = getTokenList(wormholeChainId);\n if (!list) return [];\n return [list.nativeToken, ...list.tokens];\n}\n\n/**\n * Get token info by symbol\n */\nexport function getTokenBySymbol(wormholeChainId: number, symbol: string): TokenInfo | null {\n const tokens = getAllTokens(wormholeChainId);\n return tokens.find(t => t.symbol.toLowerCase() === symbol.toLowerCase()) ?? null;\n}\n\n/**\n * Get token info by address\n */\nexport function getTokenByAddress(wormholeChainId: number, address: string): TokenInfo | null {\n const tokens = getAllTokens(wormholeChainId);\n const normalizedAddress = address.toLowerCase();\n return tokens.find(t => t.address.toLowerCase() === normalizedAddress) ?? null;\n}\n\n/**\n * Check if an address is the native token\n */\nexport function isNativeToken(address: string): boolean {\n return address.toLowerCase() === NATIVE_TOKEN_ADDRESS || \n address === EVM_ZERO_ADDRESS;\n}\n\n/**\n * Get supported chain IDs\n */\nexport function getSupportedChainIds(): number[] {\n return Object.keys(TOKEN_REGISTRY).map(Number);\n}\n\n/**\n * Get chain name by Wormhole chain ID\n */\nexport function getChainName(wormholeChainId: number): string | null {\n return TOKEN_REGISTRY[wormholeChainId]?.chainName ?? null;\n}\n"],"mappings":"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","names":["axios","Buffer","ethers","EthCallQueryRequest","EthCallQueryResponse","PerChainQueryRequest","QueryRequest","QueryResponse","hexToUint8Array","isValidHexString","ethers","ethers","ethers","ethers","resolveNetwork","concatBytes","signaturesToProofBytes","hexToUint8Array","decodeQueryBytes","isValidHexString","Buffer","sleep","withExponentialBackoff","ethers","PerChainQueryRequest","EthCallQueryRequest","chainsOut","QueryRequest","axios","QueryResponse","chainResp","EthCallQueryResponse","blockTime","age","balances","result"]}
|
|
1
|
+
{"version":3,"sources":["../../src/queries/constants.ts","../../src/queries/hubState.ts","../../src/constants.ts","../../src/queries/portfolio.ts","../../src/core/WalletManager.ts","../../src/utils.ts","../../src/constants/tokens.ts"],"sourcesContent":["export const WORMHOLE_QUERY_PROXY_URLS = {\n mainnet: 'https://query.wormhole.com/v1/query',\n testnet: 'https://testnet.query.wormhole.com/v1/query',\n} as const;\n\n/**\n * Wormhole Query Proxy rate limit: 6 queries per second.\n * SDK callers should throttle requests accordingly.\n */\nexport const WORMHOLE_QUERY_RATE_LIMIT_PER_SECOND = 6;\n\n/**\n * Convenience set of Wormhole chain IDs commonly supported by Queries.\n * This is not an exhaustive list of all Wormhole chains.\n */\nexport const WORMHOLE_QUERY_CHAIN_IDS = {\n ETHEREUM: 2,\n POLYGON: 5,\n ARBITRUM: 23,\n OPTIMISM: 24,\n BASE: 30,\n} as const;\n","import axios, { AxiosError } from 'axios';\nimport { Buffer } from 'buffer';\nimport { ethers } from 'ethers';\nimport {\n EthCallQueryRequest,\n EthCallQueryResponse,\n PerChainQueryRequest,\n QueryRequest,\n QueryResponse,\n hexToUint8Array,\n isValidHexString,\n} from '@wormhole-foundation/wormhole-query-sdk';\n\nimport { MAINNET_CHAINS, TESTNET_CHAINS } from '../constants.js';\nimport { WORMHOLE_QUERY_PROXY_URLS } from './constants.js';\n\nexport type QueryHubStateNetwork = 'testnet' | 'mainnet';\n\nexport type QueryHubStateOptions = {\n /** Max response age in seconds (default: 60). */\n maxAge?: number;\n network?: QueryHubStateNetwork;\n /** Maximum attempts including the first try (default: 4). */\n maxAttempts?: number;\n};\n\nexport type HubStateResult = {\n nonce: bigint;\n isRegistered: boolean;\n blockTime: number;\n proof: Uint8Array;\n /** Last action hash (Issue #9/#10 - for action-hash binding) */\n lastActionHash?: string;\n};\n\nexport type QueryHubStateErrorCode =\n | 'INVALID_ARGUMENT'\n | 'UNSUPPORTED_NETWORK'\n | 'MISSING_HUB_ADDRESS'\n | 'PROXY_HTTP_ERROR'\n | 'PROXY_RESPONSE_INVALID'\n | 'ATTESTATION_STALE'\n | 'QUERY_RESPONSE_INVALID';\n\nexport class QueryHubStateError extends Error {\n code: QueryHubStateErrorCode;\n cause?: unknown;\n\n constructor(code: QueryHubStateErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'QueryHubStateError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nfunction resolveNetwork(options?: QueryHubStateOptions): QueryHubStateNetwork {\n if (options?.network) return options.network;\n\n const envCandidates = [\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,\n (globalThis as any)?.process?.env?.WORMHOLE_NETWORK,\n ].filter(Boolean);\n\n const env = (envCandidates[0] as string | undefined)?.toLowerCase();\n if (env === 'mainnet' || env === 'testnet') return env;\n\n // Default to testnet to support Base Sepolia out-of-the-box.\n return 'testnet';\n}\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction signaturesToProofBytes(signatures: string[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n for (const sig of signatures) {\n if (typeof sig !== 'string' || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {\n throw new QueryHubStateError(\n 'PROXY_RESPONSE_INVALID',\n `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`\n );\n }\n // Avoid Node Buffer-backed Uint8Array (can surface as SharedArrayBuffer in DTS types).\n chunks.push(hexToUint8Array(`0x${sig}`));\n }\n\n return concatBytes(chunks);\n}\n\nfunction decodeQueryBytes(bytes: string): Uint8Array {\n if (typeof bytes !== 'string' || bytes.length === 0) {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Missing query response bytes');\n }\n\n // Query Proxy commonly returns a 0x-prefixed hex string.\n if (isValidHexString(bytes)) {\n return hexToUint8Array(bytes);\n }\n\n // Fallback: attempt base64 decoding.\n try {\n if (typeof atob === 'function') {\n const raw = atob(bytes);\n const arr = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);\n return arr;\n }\n } catch {\n // ignore\n }\n\n try {\n return new Uint8Array(Buffer.from(bytes, 'base64'));\n } catch (cause) {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Unrecognized query response bytes encoding', cause);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function withExponentialBackoff<T>(\n fn: () => Promise<T>,\n maxAttempts: number\n): Promise<T> {\n let attempt = 0;\n let lastError: unknown;\n\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts) break;\n\n const baseMs = 250;\n const backoffMs = Math.min(5_000, baseMs * 2 ** (attempt - 1));\n const jitterMs = Math.floor(Math.random() * 100);\n await sleep(backoffMs + jitterMs);\n }\n }\n\n throw lastError;\n}\n\nfunction getHubConfig(network: QueryHubStateNetwork): {\n wormholeChainId: number;\n hubAddress: string;\n endpoint: string;\n rpcUrl: string;\n} {\n if (network === 'testnet') {\n const baseSepolia = TESTNET_CHAINS.baseSepolia;\n if (!baseSepolia?.contracts?.hub) {\n throw new QueryHubStateError('MISSING_HUB_ADDRESS', 'Missing Base Sepolia hub address in SDK constants');\n }\n\n return {\n wormholeChainId: baseSepolia.wormholeChainId,\n hubAddress: baseSepolia.contracts.hub,\n endpoint: WORMHOLE_QUERY_PROXY_URLS.testnet,\n rpcUrl: baseSepolia.rpcUrl,\n };\n }\n\n if (network === 'mainnet') {\n const base = MAINNET_CHAINS.base;\n const hubAddress = (base?.contracts as any)?.hub as string | undefined;\n\n if (!hubAddress) {\n throw new QueryHubStateError(\n 'MISSING_HUB_ADDRESS',\n 'Missing mainnet hub address in SDK constants (MAINNET_CHAINS.base.contracts.hub)'\n );\n }\n\n return {\n wormholeChainId: base.wormholeChainId,\n hubAddress,\n endpoint: WORMHOLE_QUERY_PROXY_URLS.mainnet,\n rpcUrl: base.rpcUrl,\n };\n }\n\n throw new QueryHubStateError('UNSUPPORTED_NETWORK', `Unsupported network: ${network}`);\n}\n\nfunction encodeHubCalls(hubAddress: string, userKeyHash: string): { to: string; data: string }[] {\n // Support both the spec name and known on-chain variants.\n const nonceAbiCandidates = [\n 'function getUserNonce(bytes32 userKeyHash) view returns (uint256)',\n 'function userNonces(bytes32 userKeyHash) view returns (uint256)',\n 'function getNonceByHash(bytes32 userKeyHash) view returns (uint256)',\n ];\n\n const registeredAbiCandidates = [\n 'function registeredKeys(bytes32 userKeyHash) view returns (bool)',\n 'function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)',\n ];\n\n // Issue #9/#10: Add getUserLastActionHash for action-hash binding\n const actionHashAbiCandidates = [\n 'function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n 'function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n ];\n\n // We encode *all* candidates; the proxy will execute each call, and we decode the first successful one.\n // This makes the client resilient to Hub ABI differences across deployments.\n const iface = new ethers.Interface([\n ...nonceAbiCandidates,\n ...registeredAbiCandidates,\n ...actionHashAbiCandidates,\n ]);\n\n const nonceFnNames = ['getUserNonce', 'userNonces', 'getNonceByHash'] as const;\n const regFnNames = ['registeredKeys', 'isKeyRegisteredByHash'] as const;\n const actionHashFnNames = ['getUserLastActionHash', 'userLastActionHash'] as const;\n\n return [\n ...nonceFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ...regFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ...actionHashFnNames.map((fn) => ({\n to: hubAddress,\n data: iface.encodeFunctionData(fn, [userKeyHash]),\n })),\n ];\n}\n\nfunction decodeFirstNonce(results: string[]): bigint {\n const candidates = [\n 'function getUserNonce(bytes32 userKeyHash) view returns (uint256)',\n 'function userNonces(bytes32 userKeyHash) view returns (uint256)',\n 'function getNonceByHash(bytes32 userKeyHash) view returns (uint256)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['getUserNonce', 'userNonces', 'getNonceByHash'] as const;\n\n for (let idx = 0; idx < fnNames.length; idx++) {\n const fnName = fnNames[idx];\n try {\n const data = results[idx];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return decoded[0] as bigint;\n } catch {\n // keep trying\n }\n }\n\n throw new QueryHubStateError('QUERY_RESPONSE_INVALID', 'Unable to decode user nonce from query response');\n}\n\nfunction decodeFirstIsRegistered(results: string[]): boolean {\n const nonceCandidateCount = 3;\n const candidates = [\n 'function registeredKeys(bytes32 userKeyHash) view returns (bool)',\n 'function isKeyRegisteredByHash(bytes32 userKeyHash) view returns (bool)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['registeredKeys', 'isKeyRegisteredByHash'] as const;\n\n for (let i = 0; i < fnNames.length; i++) {\n const fnName = fnNames[i];\n try {\n const data = results[nonceCandidateCount + i];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return Boolean(decoded[0]);\n } catch {\n // keep trying\n }\n }\n\n // If the hub deployment doesn’t support registration, treat as false.\n return false;\n}\n\n/** * Decode last action hash from query results (Issue #9/#10)\n * Returns zero hash if not available (backwards compatibility)\n */\nfunction decodeLastActionHash(results: string[]): string {\n const nonceCandidateCount = 3;\n const registeredCandidateCount = 2;\n const actionHashOffset = nonceCandidateCount + registeredCandidateCount;\n\n const candidates = [\n 'function getUserLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n 'function userLastActionHash(bytes32 userKeyHash) view returns (bytes32)',\n ];\n const iface = new ethers.Interface(candidates);\n const fnNames = ['getUserLastActionHash', 'userLastActionHash'] as const;\n\n for (let i = 0; i < fnNames.length; i++) {\n const fnName = fnNames[i];\n try {\n const data = results[actionHashOffset + i];\n if (!data || data === '0x') continue;\n const decoded = iface.decodeFunctionResult(fnName, data);\n return decoded[0] as string;\n } catch {\n // keep trying\n }\n }\n\n // Backwards compatibility: return zero hash if not available\n return ethers.ZeroHash;\n}\n\n/** * Fetch Guardian-attested Hub state directly from the Wormhole Query Proxy.\n *\n * Client-side only: this avoids relayer API costs and produces a Guardian-signed proof\n * that can be forwarded to the relayer for on-chain verification/submission.\n */\nexport async function queryHubState(\n userKeyHash: string,\n apiKey: string,\n options?: QueryHubStateOptions\n): Promise<HubStateResult> {\n if (typeof userKeyHash !== 'string' || userKeyHash.length === 0) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'userKeyHash is required');\n }\n if (!isValidHexString(userKeyHash) || hexToUint8Array(userKeyHash).length !== 32) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'userKeyHash must be a 32-byte hex string');\n }\n if (typeof apiKey !== 'string' || apiKey.length === 0) {\n throw new QueryHubStateError('INVALID_ARGUMENT', 'apiKey is required');\n }\n\n const network = resolveNetwork(options);\n const maxAgeSeconds = options?.maxAge ?? 60;\n const maxAttempts = options?.maxAttempts ?? 4;\n\n const { wormholeChainId, hubAddress, endpoint, rpcUrl } = getHubConfig(network);\n\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n\n const callData = encodeHubCalls(hubAddress, userKeyHash);\n\n const doFetch = async () => {\n try {\n const latestBlock = await provider.getBlockNumber();\n const blockTag = Math.max(0, latestBlock - 2);\n\n const request = new QueryRequest(Date.now() & 0xffffffff, [\n new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, callData)),\n ]);\n\n // Wormhole Query Proxy expects raw hex WITHOUT 0x prefix\n const requestHex = Buffer.from(request.serialize()).toString('hex');\n\n const response = await axios.post(\n endpoint,\n { bytes: requestHex },\n {\n headers: {\n 'X-API-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n timeout: 10_000,\n }\n );\n\n const data = response.data as any;\n const signatures = data?.signatures as string[] | undefined;\n const bytes = data?.bytes as string | undefined;\n\n if (!Array.isArray(signatures) || typeof bytes !== 'string') {\n throw new QueryHubStateError('PROXY_RESPONSE_INVALID', 'Query Proxy response missing signatures/bytes');\n }\n\n const proof = signaturesToProofBytes(signatures);\n const queryBytes = decodeQueryBytes(bytes);\n const parsed = QueryResponse.from(queryBytes);\n\n const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);\n if (!perChain) {\n throw new QueryHubStateError('QUERY_RESPONSE_INVALID', 'Missing per-chain response for hub chain');\n }\n\n // The SDK provides a parser for the chain-specific response.\n const chainResp = EthCallQueryResponse.from(perChain.response.serialize());\n const blockTime = Number(chainResp.blockTime);\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n if (nowSeconds - blockTime > maxAgeSeconds) {\n throw new QueryHubStateError(\n 'ATTESTATION_STALE',\n `Guardian attestation is stale (blockTime=${blockTime}, now=${nowSeconds}, maxAge=${maxAgeSeconds}s)`\n );\n }\n\n const nonce = decodeFirstNonce(chainResp.results);\n const isRegistered = decodeFirstIsRegistered(chainResp.results);\n const lastActionHash = decodeLastActionHash(chainResp.results);\n\n return {\n nonce,\n isRegistered,\n blockTime,\n proof,\n lastActionHash,\n } satisfies HubStateResult;\n } catch (err) {\n if (err instanceof QueryHubStateError) throw err;\n if (axios.isAxiosError(err)) {\n const ax = err as AxiosError;\n const status = ax.response?.status;\n const statusText = ax.response?.statusText;\n const details = typeof ax.response?.data === 'string' ? ax.response?.data : undefined;\n\n throw new QueryHubStateError(\n 'PROXY_HTTP_ERROR',\n `Query Proxy request failed${status ? ` (${status} ${statusText ?? ''})` : ''}${details ? `: ${details}` : ''}`,\n err\n );\n }\n\n throw new QueryHubStateError('PROXY_HTTP_ERROR', 'Query Proxy request failed', err);\n }\n };\n\n return await withExponentialBackoff(doFetch, maxAttempts);\n}\n","/**\n * Veridex Protocol SDK - Constants and Chain Configurations\n */\n\nimport type { ChainConfig } from './types.js';\n\n// ============================================================================\n// Action Type Constants\n// ============================================================================\n\nexport const ACTION_TYPES = {\n TRANSFER: 1,\n EXECUTE: 2,\n CONFIG: 3,\n BRIDGE: 4,\n} as const;\n\nexport const ACTION_TRANSFER = 1;\nexport const ACTION_EXECUTE = 2;\nexport const ACTION_CONFIG = 3;\nexport const ACTION_BRIDGE = 4;\n\n// Protocol version\nexport const PROTOCOL_VERSION = 1;\n\n// ============================================================================\n// Wormhole Chain IDs\n// ============================================================================\n\n/**\n * Wormhole Chain IDs organized by network\n * @see https://docs.wormhole.com/wormhole/reference/constants\n */\nexport const WORMHOLE_CHAIN_IDS = {\n MAINNET: {\n SOLANA: 1,\n ETHEREUM: 2,\n TERRA: 3,\n BSC: 4,\n POLYGON: 5,\n AVALANCHE: 6,\n OASIS: 7,\n ALGORAND: 8,\n AURORA: 9,\n FANTOM: 10,\n KARURA: 11,\n ACALA: 12,\n KLAYTN: 13,\n CELO: 14,\n NEAR: 15,\n MOONBEAM: 16,\n NEON: 17,\n TERRA2: 18,\n INJECTIVE: 19,\n OSMOSIS: 20,\n SUI: 21,\n APTOS: 22,\n ARBITRUM: 23,\n OPTIMISM: 24,\n GNOSIS: 25,\n PYTHNET: 26,\n XPLA: 28,\n BASE: 30,\n SEI: 32,\n ROOTSTOCK: 33,\n SCROLL: 34,\n MANTLE: 35,\n BLAST: 36,\n XLAYER: 37,\n LINEA: 38,\n BERACHAIN: 39,\n SEIEVM: 40,\n },\n TESTNET: {\n SOLANA_DEVNET: 1,\n GOERLI: 2,\n BSC_TESTNET: 4,\n POLYGON_MUMBAI: 5,\n AVALANCHE_FUJI: 6,\n FANTOM_TESTNET: 10,\n CELO_ALFAJORES: 14,\n MOONBASE_ALPHA: 16,\n SUI_TESTNET: 21,\n APTOS_TESTNET: 22,\n SEPOLIA: 10002,\n ARBITRUM_SEPOLIA: 10003,\n BASE_SEPOLIA: 10004,\n OPTIMISM_SEPOLIA: 10005,\n HOLESKY: 10006,\n POLYGON_SEPOLIA: 10007,\n SEI_ATLANTIC_2: 10066, // Sei Arctic-1 testnet (EVM)\n STARKNET_SEPOLIA: 50001, // Custom bridge (non-Wormhole, relayer-attested)\n },\n} as const;\n\n// Legacy flat exports for backward compatibility\nexport const WORMHOLE_CHAIN_IDS_FLAT = {\n // Mainnets\n SOLANA: 1,\n ETHEREUM: 2,\n TERRA: 3,\n BSC: 4,\n POLYGON: 5,\n AVALANCHE: 6,\n OASIS: 7,\n ALGORAND: 8,\n AURORA: 9,\n FANTOM: 10,\n KARURA: 11,\n ACALA: 12,\n KLAYTN: 13,\n CELO: 14,\n NEAR: 15,\n MOONBEAM: 16,\n NEON: 17,\n TERRA2: 18,\n INJECTIVE: 19,\n OSMOSIS: 20,\n SUI: 21,\n APTOS: 22,\n ARBITRUM: 23,\n OPTIMISM: 24,\n GNOSIS: 25,\n PYTHNET: 26,\n XPLA: 28,\n BASE: 30,\n SEI: 32,\n ROOTSTOCK: 33,\n SCROLL: 34,\n MANTLE: 35,\n BLAST: 36,\n XLAYER: 37,\n LINEA: 38,\n BERACHAIN: 39,\n SEIEVM: 40,\n\n // Testnets\n SOLANA_DEVNET: 1,\n GOERLI: 2,\n BSC_TESTNET: 4,\n POLYGON_MUMBAI: 5,\n AVALANCHE_FUJI: 6,\n FANTOM_TESTNET: 10,\n CELO_ALFAJORES: 14,\n MOONBASE_ALPHA: 16,\n SUI_TESTNET: 21,\n APTOS_TESTNET: 22,\n ARBITRUM_SEPOLIA: 10003,\n BASE_SEPOLIA: 10004,\n OPTIMISM_SEPOLIA: 10005,\n POLYGON_SEPOLIA: 10007,\n HOLESKY: 10006,\n STARKNET_SEPOLIA: 50001, // Custom bridge (non-Wormhole)\n} as const;\n\n// ============================================================================\n// Testnet Chain Configurations\n// ============================================================================\n\nexport const TESTNET_CHAINS: Record<string, ChainConfig> = {\n baseSepolia: {\n name: 'Base Sepolia',\n chainId: 84532,\n wormholeChainId: 10004,\n rpcUrl: 'https://sepolia.base.org', // Public CORS-friendly RPC\n explorerUrl: 'https://sepolia.basescan.org',\n isEvm: true,\n contracts: {\n hub: '0x66D87dE68327f48A099c5B9bE97020Feab9a7c82',\n vaultFactory: '0xCFaEb5652aa2Ee60b2229dC8895B4159749C7e53',\n vaultImplementation: '0x0d13367C16c6f0B24eD275CC67C7D9f42878285c',\n wormholeCoreBridge: '0x79A1027a6A159502049F10906D333EC57E95F083',\n tokenBridge: '0x86F55A04690fd7815A3D802bD587e83eA888B239',\n },\n },\n optimismSepolia: {\n name: 'Optimism Sepolia',\n chainId: 11155420,\n wormholeChainId: 10005,\n rpcUrl: 'https://sepolia.optimism.io',\n explorerUrl: 'https://sepolia-optimism.etherscan.io',\n isEvm: true,\n contracts: {\n vaultFactory: '0xA5653d54079ABeCe780F8d9597B2bc4B09fe464A',\n vaultImplementation: '0x8099b1406485d2255ff89Ce5Ea18520802AFC150',\n wormholeCoreBridge: '0x31377888146f3253211EFEf5c676D41ECe7D58Fe',\n tokenBridge: '0x99737Ec4B815d816c49A385943baf0380e75c0Ac',\n },\n },\n arbitrumSepolia: {\n name: 'Arbitrum Sepolia',\n chainId: 421614,\n wormholeChainId: 10003,\n rpcUrl: 'https://sepolia-rollup.arbitrum.io/rpc',\n explorerUrl: 'https://sepolia.arbiscan.io',\n isEvm: true,\n contracts: {\n vaultFactory: '0xd36D3D5DB59d78f1E33813490F72DABC15C9B07c',\n vaultImplementation: '0xB10ACf39eBF17fc33F722cBD955b7aeCB0611bc4',\n wormholeCoreBridge: '0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35',\n tokenBridge: '0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e',\n },\n },\n seiTestnet: {\n name: 'Sei Atlantic-2',\n chainId: 1328,\n wormholeChainId: 40,\n rpcUrl: 'https://evm-rpc-testnet.sei-apis.com',\n explorerUrl: 'https://seitrace.com/?chain=atlantic-2',\n isEvm: true,\n contracts: {\n vaultFactory: '0x07F608AFf6d63b68029488b726d895c4Bb593038',\n vaultImplementation: '0xD66153fccFB6731fB6c4944FbD607ba86A76a1f6',\n wormholeCoreBridge: '0x0000000000000000000000000000000000000000', // Mock - not yet deployed\n },\n },\n solanaDevnet: {\n name: 'Solana Devnet',\n chainId: 0,\n wormholeChainId: 1,\n rpcUrl: 'https://api.devnet.solana.com',\n explorerUrl: 'https://explorer.solana.com',\n isEvm: false,\n contracts: {\n hub: 'AnyXHsqq9c2BiW4WgBcj6Aye7Ua7a7L7iSuwpfJxECJM',\n wormholeCoreBridge: '3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5',\n tokenBridge: 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe',\n },\n },\n aptosTestnet: {\n name: 'Aptos Testnet',\n chainId: 0,\n wormholeChainId: 22,\n rpcUrl: 'https://fullnode.testnet.aptoslabs.com/v1',\n explorerUrl: 'https://explorer.aptoslabs.com',\n isEvm: false,\n contracts: {\n hub: '0x1a89da9e9f8f0bc90d8d492890bd55fb261c6277d2a95dfcac70c268d0c23dcc',\n wormholeCoreBridge: '0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625',\n tokenBridge: '0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f',\n },\n },\n suiTestnet: {\n name: 'Sui Testnet',\n chainId: 0,\n wormholeChainId: 21,\n rpcUrl: 'https://fullnode.testnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/testnet',\n isEvm: false,\n contracts: {\n hub: '0x35e99fdbbc1cde7e093da6f9e758ba2c4a077904bd64caee2fa6db5e6c4e9e37',\n wormholeCoreBridge: '0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790',\n },\n },\n starknetSepolia: {\n name: 'Starknet Sepolia',\n chainId: 0, // Native Starknet chain ID (SN_SEPOLIA = 0x534e5f5345504f4c4941)\n wormholeChainId: 50001, // Custom chain ID (50000+ reserved for non-Wormhole chains)\n rpcUrl: 'https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/tsOnfTBZDKMXcUA26OED-',\n explorerUrl: 'https://sepolia.starkscan.co',\n isEvm: false,\n contracts: {\n // Starknet spoke contract\n hub: '0x68adcc730ed6c355200d00f763825448497b9cdf7936ca121711e078c88e811',\n // Custom bridge contract (NOT Wormhole)\n wormholeCoreBridge: '0x2c458c1ae64556482b05cc2d3ee5b032ed114d68429dda2062c9849a5a725f8',\n },\n // Hub chain ID that Starknet bridge validates (Base Sepolia = 10004)\n hubChainId: 10004,\n },\n};\n\n// ============================================================================\n// Mainnet Chain Configurations\n// ============================================================================\n\nexport const MAINNET_CHAINS: Record<string, ChainConfig> = {\n ethereum: {\n name: 'Ethereum',\n chainId: 1,\n wormholeChainId: 2,\n rpcUrl: 'https://eth.llamarpc.com',\n explorerUrl: 'https://etherscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B',\n tokenBridge: '0x3ee18B2214AFF97000D974cf647E7C347E8fa585',\n },\n },\n base: {\n name: 'Base',\n chainId: 8453,\n wormholeChainId: 30,\n rpcUrl: 'https://mainnet.base.org',\n explorerUrl: 'https://basescan.org',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627',\n },\n },\n optimism: {\n name: 'Optimism',\n chainId: 10,\n wormholeChainId: 24,\n rpcUrl: 'https://mainnet.optimism.io',\n explorerUrl: 'https://optimistic.etherscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722',\n tokenBridge: '0x1D68124e65faFC907325e3EDbF8c4d84499DAa8b',\n },\n },\n arbitrum: {\n name: 'Arbitrum',\n chainId: 42161,\n wormholeChainId: 23,\n rpcUrl: 'https://arb1.arbitrum.io/rpc',\n explorerUrl: 'https://arbiscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xa5f208e072434bC67592E4C49C1B991BA79BCA46',\n tokenBridge: '0x0b2402144Bb366A632D14B83F244D2e0e21bD39c',\n },\n },\n polygon: {\n name: 'Polygon',\n chainId: 137,\n wormholeChainId: 5,\n rpcUrl: 'https://polygon-rpc.com',\n explorerUrl: 'https://polygonscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7',\n tokenBridge: '0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE',\n },\n },\n solana: {\n name: 'Solana',\n chainId: 0,\n wormholeChainId: 1,\n rpcUrl: 'https://api.mainnet-beta.solana.com',\n explorerUrl: 'https://explorer.solana.com',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: 'worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth',\n tokenBridge: 'wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb',\n },\n },\n aptos: {\n name: 'Aptos',\n chainId: 0,\n wormholeChainId: 22,\n rpcUrl: 'https://fullnode.mainnet.aptoslabs.com/v1',\n explorerUrl: 'https://explorer.aptoslabs.com',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: '0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625',\n tokenBridge: '0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f',\n },\n },\n sui: {\n name: 'Sui',\n chainId: 0,\n wormholeChainId: 21,\n rpcUrl: 'https://fullnode.mainnet.sui.io:443',\n explorerUrl: 'https://suiscan.xyz/mainnet',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: '0xaeab97f96cf9877fee2883315d459552b2b921edc16d7ceac6eab944dd88919c',\n },\n },\n};\n\n// ============================================================================\n// Wormhole API Endpoints\n// ============================================================================\n\nexport const WORMHOLE_API = {\n MAINNET: 'https://api.wormholescan.io',\n TESTNET: 'https://api.testnet.wormholescan.io',\n GUARDIAN_RPC_MAINNET: 'https://wormhole-v2-mainnet-api.certus.one',\n GUARDIAN_RPC_TESTNET: 'https://wormhole-v2-testnet-api.certus.one',\n} as const;\n\n// ============================================================================\n// Hub Contract ABI (minimal)\n// ============================================================================\n\nexport const HUB_ABI = [\n 'function authenticateAndDispatch((bytes authenticatorData, string clientDataJSON, uint256 challengeIndex, uint256 typeIndex, uint256 r, uint256 s) auth, uint256 publicKeyX, uint256 publicKeyY, uint16 targetChain, bytes actionPayload) external payable returns (uint64 sequence)',\n 'function authenticateRawAndDispatch(uint256 r, uint256 s, bytes32 messageHash, uint256 publicKeyX, uint256 publicKeyY, uint16 targetChain, bytes actionPayload, uint256 nonce) external payable returns (uint64 sequence)',\n 'function getNonce(bytes32 userKeyHash) external view returns (uint256)',\n 'function encodeTransferAction(address token, address recipient, uint256 amount) external pure returns (bytes)',\n 'function encodeExecuteAction(address target, uint256 value, bytes data) external pure returns (bytes)',\n 'function encodeBridgeAction(bytes32 token, uint256 amount, uint16 targetChain, bytes32 recipient) external pure returns (bytes)',\n 'function messageFee() external view returns (uint256)',\n 'event Dispatched(bytes32 indexed userKeyHash, uint16 targetChain, uint256 nonce, uint64 sequence, bytes actionPayload)',\n] as const;\n\n// ============================================================================\n// Vault Factory ABI (minimal)\n// ============================================================================\n\nexport const VAULT_FACTORY_ABI = [\n 'function createVault(bytes32 userKeyHash) external returns (address)',\n 'function getVault(bytes32 userKeyHash) external view returns (address)',\n 'function vaultExists(bytes32 userKeyHash) external view returns (bool)',\n 'event VaultCreated(bytes32 indexed userKeyHash, address vault)',\n] as const;\n\n// ============================================================================\n// Vault ABI (minimal)\n// ============================================================================\n\nexport const VAULT_ABI = [\n 'function execute(address target, uint256 value, bytes data) external returns (bytes)',\n 'function executeFromHub(bytes32 vaaHash, uint16 emitterChain, bytes32 emitterAddress, bytes payload) external',\n 'function owner() external view returns (bytes32)',\n 'function hub() external view returns (address)',\n 'receive() external payable',\n] as const;\n","import axios, { AxiosError } from 'axios';\nimport { Buffer } from 'buffer';\nimport { ethers } from 'ethers';\nimport { PublicKey } from '@solana/web3.js';\nimport {\n EthCallQueryRequest,\n EthCallQueryResponse,\n PerChainQueryRequest,\n QueryRequest,\n QueryResponse,\n SolanaAccountQueryRequest,\n SolanaAccountQueryResponse,\n hexToUint8Array,\n isValidHexString,\n} from '@wormhole-foundation/wormhole-query-sdk';\n\nimport { MAINNET_CHAINS, TESTNET_CHAINS } from '../constants.js';\nimport { WalletManager } from '../core/WalletManager.js';\nimport { getAllTokens, isNativeToken } from '../constants/tokens.js';\nimport { WORMHOLE_QUERY_PROXY_URLS } from './constants.js';\n\nexport type QueryPortfolioNetwork = 'testnet' | 'mainnet';\n\nexport type QueryPortfolioOptions = {\n /** Max response age in seconds (default: 60). */\n maxAge?: number;\n network?: QueryPortfolioNetwork;\n /** Maximum attempts including the first try (default: 4). */\n maxAttempts?: number;\n /** Cache TTL in ms (default: 30_000). */\n cacheTtlMs?: number;\n /** Request timeout in ms (default: 15_000 for testnet, 10_000 for mainnet). */\n timeout?: number;\n /** Override Query Proxy endpoint. */\n endpoint?: string;\n /** Override per-chain RPC URLs used for block tag lookups. */\n rpcUrls?: Record<number, string>;\n /** Override derived vault addresses for specific Wormhole chain IDs. */\n vaultAddresses?: Record<number, string>;\n /** Override token lists (ERC20 only) for specific Wormhole chain IDs. */\n evmTokenAddresses?: Record<number, string[]>;\n /** Additional Solana accounts to include in the Solana account query (base58). */\n solanaAccounts?: string[];\n /** Optional USD prices by symbol/address for aggregation (e.g. { USDC: 1 }). */\n pricesUsd?: Record<string, number>;\n};\n\nexport type PortfolioBalance = {\n assetId: string;\n amount: bigint;\n decimals?: number;\n symbol?: string;\n usdValue?: number;\n};\n\nexport type PortfolioChainErrorCode =\n | 'UNSUPPORTED_CHAIN'\n | 'MISSING_VAULT'\n | 'MISSING_TOKENS'\n | 'ATTESTATION_STALE'\n | 'DECODE_ERROR';\n\nexport type PortfolioChainResult = {\n wormholeChainId: number;\n chainName?: string;\n vaultAddress?: string;\n blockTime?: number;\n balances: PortfolioBalance[];\n error?: {\n code: PortfolioChainErrorCode;\n message: string;\n };\n};\n\nexport type PortfolioResult = {\n proof: Uint8Array;\n totalUsd?: number;\n chains: PortfolioChainResult[];\n};\n\nexport type QueryPortfolioErrorCode =\n | 'INVALID_ARGUMENT'\n | 'NETWORK_ERROR'\n | 'PROXY_HTTP_ERROR'\n | 'PROXY_RESPONSE_INVALID'\n | 'QUERY_RESPONSE_INVALID';\n\nexport class QueryPortfolioError extends Error {\n code: QueryPortfolioErrorCode;\n cause?: unknown;\n\n constructor(code: QueryPortfolioErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'QueryPortfolioError';\n this.code = code;\n this.cause = cause;\n }\n}\n\ntype CacheEntry = { expiresAt: number; value: PortfolioResult };\nconst PORTFOLIO_CACHE = new Map<string, CacheEntry>();\n\nfunction resolveNetwork(options?: QueryPortfolioOptions): QueryPortfolioNetwork {\n if (options?.network) return options.network;\n\n const envCandidates = [\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,\n (globalThis as any)?.process?.env?.WORMHOLE_NETWORK,\n ].filter(Boolean);\n\n const env = (envCandidates[0] as string | undefined)?.toLowerCase();\n if (env === 'mainnet' || env === 'testnet') return env;\n\n return 'testnet';\n}\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction signaturesToProofBytes(signatures: string[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n for (const sig of signatures) {\n if (typeof sig !== 'string' || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {\n throw new QueryPortfolioError(\n 'PROXY_RESPONSE_INVALID',\n `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`\n );\n }\n // Avoid Node Buffer-backed Uint8Array (can surface as SharedArrayBuffer in DTS types).\n chunks.push(hexToUint8Array(`0x${sig}`));\n }\n\n return concatBytes(chunks);\n}\n\nfunction decodeQueryBytes(bytes: string): Uint8Array {\n if (typeof bytes !== 'string' || bytes.length === 0) {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Missing query response bytes');\n }\n\n if (isValidHexString(bytes)) {\n return hexToUint8Array(bytes);\n }\n\n try {\n if (typeof atob === 'function') {\n const raw = atob(bytes);\n const arr = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);\n return arr;\n }\n } catch {\n // ignore\n }\n\n try {\n return new Uint8Array(Buffer.from(bytes, 'base64'));\n } catch (cause) {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Unrecognized query response bytes encoding', cause);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Simple rate limiter for Wormhole Query Proxy (6 requests/second limit).\n * Queues requests and releases them at the allowed rate.\n */\nconst rateLimiter = {\n queue: [] as Array<() => void>,\n lastRequest: 0,\n minInterval: 170, // ~6 req/s with buffer\n \n async acquire(): Promise<void> {\n return new Promise((resolve) => {\n const tryAcquire = () => {\n const now = Date.now();\n const elapsed = now - rateLimiter.lastRequest;\n if (elapsed >= rateLimiter.minInterval) {\n rateLimiter.lastRequest = now;\n resolve();\n } else {\n setTimeout(tryAcquire, rateLimiter.minInterval - elapsed);\n }\n };\n tryAcquire();\n });\n }\n};\n\nasync function withExponentialBackoff<T>(fn: () => Promise<T>, maxAttempts: number): Promise<T> {\n let attempt = 0;\n let lastError: unknown;\n\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts) break;\n\n const baseMs = 250;\n const backoffMs = Math.min(5_000, baseMs * 2 ** (attempt - 1));\n const jitterMs = Math.floor(Math.random() * 100);\n await sleep(backoffMs + jitterMs);\n }\n }\n\n throw lastError;\n}\n\nfunction getChainConfigs(network: QueryPortfolioNetwork) {\n return network === 'testnet' ? TESTNET_CHAINS : MAINNET_CHAINS;\n}\n\nfunction getProxyEndpoint(network: QueryPortfolioNetwork, options?: QueryPortfolioOptions): string {\n if (options?.endpoint) return options.endpoint;\n return network === 'testnet' ? WORMHOLE_QUERY_PROXY_URLS.testnet : WORMHOLE_QUERY_PROXY_URLS.mainnet;\n}\n\nfunction getDefaultPortfolioChains(network: QueryPortfolioNetwork): number[] {\n // Include hub (Base Sepolia 10004) and spoke chains\n return network === 'testnet' ? [10004, 10005, 10003, 1] : [30, 24, 23, 1];\n}\n\nfunction normalizeHex32(hex: string): Uint8Array {\n if (typeof hex !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(hex)) {\n throw new QueryPortfolioError('INVALID_ARGUMENT', `Invalid userKeyHash (expected 0x + 32 bytes hex): ${hex}`);\n }\n return new Uint8Array(Buffer.from(hex.slice(2), 'hex'));\n}\n\nfunction deriveSolanaVaultAddress(programIdBase58: string, userKeyHash: string): string {\n const programId = new PublicKey(programIdBase58);\n const keyHashBytes = normalizeHex32(userKeyHash);\n const [vaultPda] = PublicKey.findProgramAddressSync([Buffer.from('vault'), Buffer.from(keyHashBytes)], programId);\n return vaultPda.toBase58();\n}\n\nfunction makeCacheKey(userKeyHash: string, apiKey: string, options: QueryPortfolioOptions | undefined, chainIds: number[]) {\n // Do not include apiKey in the cache key; it should not affect the data.\n const payload = {\n userKeyHash,\n network: resolveNetwork(options),\n chainIds: [...chainIds].sort((a, b) => a - b),\n vaultAddresses: options?.vaultAddresses ?? null,\n evmTokenAddresses: options?.evmTokenAddresses ?? null,\n solanaAccounts: options?.solanaAccounts ?? null,\n endpoint: options?.endpoint ?? null,\n };\n\n void apiKey;\n return JSON.stringify(payload);\n}\n\nfunction safeNumberFromBigint(b: bigint): number {\n const n = Number(b);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction priceLookup(pricesUsd: Record<string, number> | undefined, symbol?: string, assetId?: string): number | undefined {\n if (!pricesUsd) return undefined;\n if (symbol && pricesUsd[symbol] != null) return pricesUsd[symbol];\n if (assetId && pricesUsd[assetId] != null) return pricesUsd[assetId];\n return undefined;\n}\n\nfunction sumUsd(balances: PortfolioBalance[], pricesUsd?: Record<string, number>): number | undefined {\n let total = 0;\n let any = false;\n\n for (const b of balances) {\n const p = priceLookup(pricesUsd, b.symbol, b.assetId);\n if (p == null) continue;\n if (b.decimals == null) continue;\n\n const denom = 10 ** b.decimals;\n const amount = Number(b.amount) / denom;\n if (!Number.isFinite(amount)) continue;\n total += amount * p;\n any = true;\n }\n\n return any ? total : undefined;\n}\n\nasync function getRecentBlockTag(rpcUrl: string): Promise<number> {\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const latest = await provider.getBlockNumber();\n return Math.max(0, latest - 2);\n}\n\nfunction encodeErc20BalanceCalls(vaultAddress: string, tokenAddresses: string[]): { to: string; data: string }[] {\n const iface = new ethers.Interface(['function balanceOf(address owner) view returns (uint256)']);\n return tokenAddresses.map((token) => ({\n to: token,\n data: iface.encodeFunctionData('balanceOf', [vaultAddress]),\n }));\n}\n\nfunction decodeErc20Balances(results: string[], tokenAddresses: string[]): bigint[] {\n const iface = new ethers.Interface(['function balanceOf(address owner) view returns (uint256)']);\n const out: bigint[] = [];\n for (let i = 0; i < tokenAddresses.length; i++) {\n const data = results[i];\n if (!data || data === '0x') {\n out.push(0n);\n continue;\n }\n const decoded = iface.decodeFunctionResult('balanceOf', data);\n out.push(decoded[0] as bigint);\n }\n return out;\n}\n\n/**\n * Fetch Guardian-attested vault balances across multiple chains in one Query Proxy request.\n *\n * Notes:\n * - EVM balances are ERC20-only via `eth_call` (native ETH is not queryable via this query type).\n * - Solana balance uses lamports of the Veridex vault PDA (plus optional extra accounts).\n * - Aptos is included only if/when Wormhole Queries adds Aptos query types (currently returned as unsupported).\n */\nexport async function queryPortfolio(\n userKeyHash: string,\n apiKey: string,\n options?: QueryPortfolioOptions\n): Promise<PortfolioResult> {\n const network = resolveNetwork(options);\n const maxAgeSeconds = options?.maxAge ?? 60;\n const maxAttempts = options?.maxAttempts ?? 4;\n const cacheTtlMs = options?.cacheTtlMs ?? 30_000;\n const endpoint = getProxyEndpoint(network, options);\n\n const chainIds = options?.rpcUrls ? Object.keys(options.rpcUrls).map(Number) : undefined;\n void chainIds;\n\n const requestedChains = options?.vaultAddresses\n ? Object.keys(options.vaultAddresses).map(Number)\n : undefined;\n\n const defaultChains = getDefaultPortfolioChains(network);\n const wormholeChainIds = options?.evmTokenAddresses\n ? Array.from(new Set([...defaultChains, ...Object.keys(options.evmTokenAddresses).map(Number)]))\n : defaultChains;\n\n // If the caller provided explicit vault overrides, include those chain IDs even if not in defaults.\n const finalChainIds = requestedChains\n ? Array.from(new Set([...wormholeChainIds, ...requestedChains]))\n : wormholeChainIds;\n\n if (!apiKey || typeof apiKey !== 'string') {\n throw new QueryPortfolioError('INVALID_ARGUMENT', 'Missing Query Proxy apiKey');\n }\n\n const cacheKey = makeCacheKey(userKeyHash, apiKey, options, finalChainIds);\n const cached = PORTFOLIO_CACHE.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.value;\n }\n\n const chains = getChainConfigs(network);\n const walletManager = new WalletManager({ cacheAddresses: true, persistToStorage: false });\n\n const pricesUsd: Record<string, number> | undefined = {\n USDC: 1,\n ...(options?.pricesUsd ?? {}),\n };\n\n const doFetch = async (): Promise<PortfolioResult> => {\n try {\n const perChainRequests: PerChainQueryRequest[] = [];\n const chainMeta: Record<number, { vaultAddress?: string; chainName?: string; kind: 'evm' | 'solana' | 'unsupported' }> = {};\n\n // Precompute any EVM block tags in parallel to keep total latency down.\n const evmChainIds = finalChainIds.filter((id) => {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === id);\n return cfg?.isEvm;\n });\n\n const blockTagsByChainId = new Map<number, number>();\n await Promise.all(\n evmChainIds.map(async (wormholeChainId) => {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n if (!cfg) return;\n const rpcUrl = options?.rpcUrls?.[wormholeChainId] ?? cfg.rpcUrl;\n const blockTag = await getRecentBlockTag(rpcUrl);\n blockTagsByChainId.set(wormholeChainId, blockTag);\n })\n );\n\n for (const wormholeChainId of finalChainIds) {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n\n if (wormholeChainId === 22) {\n chainMeta[wormholeChainId] = { kind: 'unsupported', chainName: cfg?.name };\n continue;\n }\n\n if (!cfg) {\n chainMeta[wormholeChainId] = { kind: 'unsupported' };\n continue;\n }\n\n if (cfg.isEvm) {\n const vaultAddress = options?.vaultAddresses?.[wormholeChainId]\n ?? (cfg.contracts.vaultFactory && cfg.contracts.vaultImplementation\n ? walletManager.computeVaultAddress(userKeyHash, cfg.contracts.vaultFactory, cfg.contracts.vaultImplementation)\n : undefined);\n\n chainMeta[wormholeChainId] = { kind: 'evm', vaultAddress, chainName: cfg.name };\n\n if (!vaultAddress) {\n continue;\n }\n\n const tokenAddresses = options?.evmTokenAddresses?.[wormholeChainId]\n ?? getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address)).map((t) => t.address);\n\n if (!tokenAddresses.length) {\n continue;\n }\n\n const blockTag = blockTagsByChainId.get(wormholeChainId);\n if (blockTag == null) {\n continue;\n }\n\n const calls = encodeErc20BalanceCalls(vaultAddress, tokenAddresses);\n perChainRequests.push(new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, calls)));\n continue;\n }\n\n // Solana\n if (wormholeChainId === 1) {\n const programId = options?.vaultAddresses?.[wormholeChainId] ?? cfg.contracts.hub;\n chainMeta[wormholeChainId] = { kind: 'solana', chainName: cfg.name };\n\n if (!programId) {\n continue;\n }\n\n const vaultAddress = deriveSolanaVaultAddress(programId, userKeyHash);\n chainMeta[wormholeChainId] = { kind: 'solana', chainName: cfg.name, vaultAddress };\n\n const accounts = [vaultAddress, ...(options?.solanaAccounts ?? [])];\n perChainRequests.push(\n new PerChainQueryRequest(\n wormholeChainId,\n new SolanaAccountQueryRequest('finalized', accounts, undefined, 0n, 0n)\n )\n );\n continue;\n }\n\n chainMeta[wormholeChainId] = { kind: 'unsupported', chainName: cfg.name };\n }\n\n if (perChainRequests.length > 255) {\n throw new QueryPortfolioError(\n 'INVALID_ARGUMENT',\n `Too many per-chain requests (${perChainRequests.length}); max is 255 per Query Proxy request`\n );\n }\n\n // If no per-chain requests were built (e.g., missing vaults or tokens), return early with empty results\n if (perChainRequests.length === 0) {\n const chainsOut: PortfolioChainResult[] = finalChainIds.map((wormholeChainId) => {\n const meta = chainMeta[wormholeChainId] ?? { kind: 'unsupported' as const };\n return {\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { \n code: 'MISSING_VAULT' as const, \n message: 'Unable to build query: missing vault address or no tokens configured' \n },\n };\n });\n return { proof: new Uint8Array(), totalUsd: 0, chains: chainsOut };\n }\n\n const request = new QueryRequest(Date.now() & 0xffffffff, perChainRequests);\n // Wormhole Query Proxy expects raw hex WITHOUT 0x prefix\n const requestHex = Buffer.from(request.serialize()).toString('hex');\n\n // Respect rate limit before making request\n await rateLimiter.acquire();\n\n let response;\n try {\n console.log('[queryPortfolio] Sending request to:', endpoint);\n console.log('[queryPortfolio] Request bytes length:', requestHex.length);\n \n // Use provided timeout, or default to 15s for testnet (slower), 10s for mainnet\n const defaultTimeout = network === 'testnet' ? 15_000 : 10_000;\n const requestTimeout = options?.timeout ?? defaultTimeout;\n \n response = await axios.post(\n endpoint,\n { bytes: requestHex },\n {\n headers: {\n 'X-API-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n timeout: requestTimeout,\n }\n );\n } catch (axiosErr) {\n const err = axiosErr as AxiosError;\n // Network errors (CORS, timeout, no connection) have no response\n if (!err.response) {\n console.error('[queryPortfolio] Network error:', {\n message: err.message,\n code: err.code,\n name: err.name,\n });\n throw new QueryPortfolioError(\n 'NETWORK_ERROR',\n `Network error: ${err.message} (code: ${err.code})`\n );\n }\n const status = err.response.status;\n const errData = err.response.data;\n console.error('[queryPortfolio] Wormhole Query Proxy error:', { status, data: errData });\n throw new QueryPortfolioError(\n 'PROXY_RESPONSE_INVALID',\n `Query Proxy returned ${status}: ${JSON.stringify(errData)}`\n );\n }\n\n const data = response.data as any;\n const signatures = data?.signatures as string[] | undefined;\n const bytes = data?.bytes as string | undefined;\n\n if (!Array.isArray(signatures) || typeof bytes !== 'string') {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Query Proxy response missing signatures/bytes');\n }\n\n const proof = signaturesToProofBytes(signatures);\n const queryBytes = decodeQueryBytes(bytes);\n const parsed = QueryResponse.from(queryBytes);\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n const chainsOut: PortfolioChainResult[] = [];\n\n for (const wormholeChainId of finalChainIds) {\n const meta = chainMeta[wormholeChainId] ?? { kind: 'unsupported' as const };\n\n if (meta.kind === 'unsupported') {\n const msg = wormholeChainId === 22\n ? 'Aptos Queries are not supported by the Wormhole Query SDK yet'\n : 'Chain is not supported by this portfolio query implementation';\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n balances: [],\n error: { code: 'UNSUPPORTED_CHAIN', message: msg },\n });\n continue;\n }\n\n if (!meta.vaultAddress) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n balances: [],\n error: { code: 'MISSING_VAULT', message: 'Unable to derive vault address for chain' },\n });\n continue;\n }\n\n const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);\n if (!perChain) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'DECODE_ERROR', message: 'Missing per-chain response from Query Proxy' },\n });\n continue;\n }\n\n try {\n if (meta.kind === 'evm') {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n const tokenAddresses = options?.evmTokenAddresses?.[wormholeChainId]\n ?? getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address)).map((t) => t.address);\n\n if (!tokenAddresses.length) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'MISSING_TOKENS', message: 'No ERC20 tokens configured for EVM portfolio query' },\n });\n continue;\n }\n\n const chainResp = EthCallQueryResponse.from(perChain.response.serialize());\n const blockTime = Number(chainResp.blockTime);\n const age = nowSeconds - blockTime;\n if (age > maxAgeSeconds) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances: [],\n error: { code: 'ATTESTATION_STALE', message: `Attestation stale by ${age}s (maxAge=${maxAgeSeconds}s)` },\n });\n continue;\n }\n\n const amounts = decodeErc20Balances(chainResp.results, tokenAddresses);\n const tokenInfos = getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address));\n\n const balances: PortfolioBalance[] = tokenAddresses.map((addr, i) => {\n const info = tokenInfos.find((t) => t.address.toLowerCase() === addr.toLowerCase());\n const symbol = info?.symbol;\n const decimals = info?.decimals;\n const usdPrice = priceLookup(pricesUsd, symbol, addr);\n const usdValue = usdPrice != null && decimals != null\n ? (Number(amounts[i]) / 10 ** decimals) * usdPrice\n : undefined;\n\n return {\n assetId: addr,\n amount: amounts[i],\n symbol,\n decimals,\n usdValue: Number.isFinite(usdValue ?? NaN) ? usdValue : undefined,\n };\n });\n\n void cfg;\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances,\n });\n continue;\n }\n\n // Solana\n const chainResp = SolanaAccountQueryResponse.from(perChain.response.serialize());\n const blockTime = safeNumberFromBigint(chainResp.blockTime);\n const age = nowSeconds - blockTime;\n if (age > maxAgeSeconds) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances: [],\n error: { code: 'ATTESTATION_STALE', message: `Attestation stale by ${age}s (maxAge=${maxAgeSeconds}s)` },\n });\n continue;\n }\n\n const vaultResult = chainResp.results[0];\n const lamports = vaultResult?.lamports ?? 0n;\n\n const balances: PortfolioBalance[] = [\n {\n assetId: 'SOL',\n amount: lamports,\n decimals: 9,\n symbol: 'SOL',\n usdValue: priceLookup(pricesUsd, 'SOL', 'SOL') != null\n ? (Number(lamports) / 1e9) * (priceLookup(pricesUsd, 'SOL', 'SOL') as number)\n : undefined,\n },\n ];\n\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances,\n });\n } catch (cause) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'DECODE_ERROR', message: `Failed to decode chain response: ${String((cause as any)?.message ?? cause)}` },\n });\n }\n }\n\n const allBalances = chainsOut.flatMap((c) => c.balances);\n const totalUsd = sumUsd(allBalances, pricesUsd);\n\n const result: PortfolioResult = { proof, totalUsd, chains: chainsOut };\n\n PORTFOLIO_CACHE.set(cacheKey, { expiresAt: Date.now() + cacheTtlMs, value: result });\n return result;\n } catch (err) {\n if (err instanceof QueryPortfolioError) throw err;\n if (axios.isAxiosError(err)) {\n const ax = err as AxiosError;\n const status = ax.response?.status;\n const statusText = ax.response?.statusText;\n const details = typeof ax.response?.data === 'string' ? ax.response?.data : undefined;\n\n throw new QueryPortfolioError(\n 'PROXY_HTTP_ERROR',\n `Query Proxy request failed${status ? ` (${status} ${statusText ?? ''})` : ''}${details ? `: ${details}` : ''}`,\n err\n );\n }\n\n throw new QueryPortfolioError('PROXY_HTTP_ERROR', 'Query Proxy request failed', err);\n }\n };\n\n const result = await withExponentialBackoff(doFetch, maxAttempts);\n PORTFOLIO_CACHE.set(cacheKey, { expiresAt: Date.now() + cacheTtlMs, value: result });\n return result;\n}\n","/**\n * Veridex Protocol SDK - Wallet Manager\n * \n * Manages deterministic wallet addresses across multiple chains.\n * Vault addresses are computed using CREATE2 on EVM chains and chain-specific\n * derivation on non-EVM chains, all based on the user's passkey public key.\n */\n\nimport { ethers } from 'ethers';\nimport type { \n PasskeyCredential,\n UnifiedIdentity,\n ChainAddress,\n WalletManagerConfig,\n} from './types.js';\nimport { computeKeyHash } from '../utils.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * EIP-1167 minimal proxy bytecode prefix (before implementation address)\n * 3d602d80600a3d3981f3363d3d373d3d3d363d73\n */\nconst PROXY_BYTECODE_PREFIX = '0x3d602d80600a3d3981f3363d3d373d3d3d363d73';\n\n/**\n * EIP-1167 minimal proxy bytecode suffix (after implementation address)\n * 5af43d82803e903d91602b57fd5bf3\n */\nconst PROXY_BYTECODE_SUFFIX = '5af43d82803e903d91602b57fd5bf3';\n\n// ============================================================================\n// WalletManager Class\n// ============================================================================\n\n/**\n * Manages wallet address derivation and storage for Veridex Protocol\n * \n * @example\n * ```typescript\n * const manager = new WalletManager();\n * \n * // Compute vault address for a credential\n * const address = await manager.computeVaultAddress(\n * credential.keyHash,\n * factoryAddress,\n * implementationAddress\n * );\n * \n * // Get unified identity with addresses on all chains\n * const identity = await manager.getUnifiedIdentity(credential, chainConfigs);\n * ```\n */\nexport class WalletManager {\n private config: WalletManagerConfig;\n private addressCache: Map<string, ChainAddress[]> = new Map();\n\n constructor(config: WalletManagerConfig = {}) {\n this.config = {\n cacheAddresses: config.cacheAddresses ?? true,\n persistToStorage: config.persistToStorage ?? false,\n storageKey: config.storageKey ?? 'veridex_wallet_addresses',\n };\n\n // Load cached addresses from storage if enabled\n if (this.config.persistToStorage && typeof window !== 'undefined') {\n this.loadFromStorage();\n }\n }\n\n // ========================================================================\n // Address Computation\n // ========================================================================\n\n /**\n * Compute the deterministic vault address for an EVM chain\n * \n * Uses CREATE2 with EIP-1167 minimal proxy pattern:\n * - Salt = keccak256(factoryAddress, ownerKeyHash)\n * - InitCode = EIP-1167 proxy bytecode with implementation address\n * \n * @param keyHash - The owner's key hash (keccak256 of public key coordinates)\n * @param factoryAddress - The vault factory contract address\n * @param implementationAddress - The vault implementation contract address\n * @returns The deterministic vault address\n */\n computeVaultAddress(\n keyHash: string,\n factoryAddress: string,\n implementationAddress: string\n ): string {\n // Compute salt: keccak256(abi.encodePacked(factory, keyHash))\n const salt = ethers.keccak256(\n ethers.solidityPacked(\n ['address', 'bytes32'],\n [factoryAddress, keyHash]\n )\n );\n\n // Build EIP-1167 initcode\n const initCode = this.buildProxyInitCode(implementationAddress);\n const initCodeHash = ethers.keccak256(initCode);\n\n // CREATE2 address computation:\n // address = keccak256(0xff ++ factory ++ salt ++ initCodeHash)[12:]\n const create2Data = ethers.solidityPacked(\n ['bytes1', 'address', 'bytes32', 'bytes32'],\n ['0xff', factoryAddress, salt, initCodeHash]\n );\n\n const hash = ethers.keccak256(create2Data);\n // Take last 20 bytes as address\n return ethers.getAddress('0x' + hash.slice(26));\n }\n\n /**\n * Compute vault address from public key coordinates\n * \n * @param publicKeyX - P-256 public key X coordinate\n * @param publicKeyY - P-256 public key Y coordinate\n * @param factoryAddress - The vault factory contract address\n * @param implementationAddress - The vault implementation contract address\n * @returns The deterministic vault address\n */\n computeVaultAddressFromPublicKey(\n publicKeyX: bigint,\n publicKeyY: bigint,\n factoryAddress: string,\n implementationAddress: string\n ): string {\n const keyHash = computeKeyHash(publicKeyX, publicKeyY);\n return this.computeVaultAddress(keyHash, factoryAddress, implementationAddress);\n }\n\n /**\n * Build EIP-1167 minimal proxy initcode\n */\n private buildProxyInitCode(implementationAddress: string): string {\n // Remove 0x prefix if present and lowercase\n const impl = implementationAddress.toLowerCase().replace('0x', '');\n \n // EIP-1167 bytecode format\n return PROXY_BYTECODE_PREFIX + impl + PROXY_BYTECODE_SUFFIX;\n }\n\n // ========================================================================\n // Unified Identity\n // ========================================================================\n\n /**\n * Get unified identity with addresses across all configured chains\n * \n * @param credential - The passkey credential\n * @param chainConfigs - Map of chain configurations with factory/implementation addresses\n * @returns Unified identity with addresses on each chain\n */\n async getUnifiedIdentity(\n credential: PasskeyCredential,\n chainConfigs: Map<number, ChainAddressConfig>\n ): Promise<UnifiedIdentity> {\n const addresses: ChainAddress[] = [];\n\n for (const [wormholeChainId, config] of chainConfigs) {\n const address = await this.deriveAddressForChain(\n credential,\n wormholeChainId,\n config\n );\n \n if (address) {\n addresses.push(address);\n }\n }\n\n const identity: UnifiedIdentity = {\n keyHash: credential.keyHash,\n publicKeyX: credential.publicKeyX,\n publicKeyY: credential.publicKeyY,\n credentialId: credential.credentialId,\n addresses,\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n // Cache the identity\n if (this.config.cacheAddresses) {\n this.addressCache.set(credential.keyHash, addresses);\n }\n\n // Persist to storage if enabled\n if (this.config.persistToStorage) {\n this.saveToStorage(identity);\n }\n\n return identity;\n }\n\n /**\n * Derive address for a specific chain\n */\n private async deriveAddressForChain(\n credential: PasskeyCredential,\n wormholeChainId: number,\n config: ChainAddressConfig\n ): Promise<ChainAddress | null> {\n if (config.isEvm) {\n // EVM chains use CREATE2\n if (!config.factoryAddress || !config.implementationAddress) {\n return null;\n }\n\n const address = this.computeVaultAddress(\n credential.keyHash,\n config.factoryAddress,\n config.implementationAddress\n );\n\n return {\n wormholeChainId,\n chainName: config.chainName,\n address,\n isEvm: true,\n deployed: false, // Will be checked separately\n };\n } else {\n // Non-EVM chains have chain-specific address derivation\n return this.deriveNonEvmAddress(credential, wormholeChainId, config);\n }\n }\n\n /**\n * Derive address for non-EVM chains\n * \n * Each chain has its own address format:\n * - Solana: Base58 encoded public key hash\n * - Aptos: 32-byte hex address\n * - Sui: 32-byte hex address with 0x prefix\n */\n private deriveNonEvmAddress(\n credential: PasskeyCredential,\n wormholeChainId: number,\n _config: ChainAddressConfig\n ): ChainAddress | null {\n switch (wormholeChainId) {\n case 1: // Solana\n // Solana uses the key hash directly as a seed for PDA derivation\n // The actual address depends on the program ID\n return {\n wormholeChainId: 1,\n chainName: 'Solana',\n address: credential.keyHash, // PDA will be derived from this\n isEvm: false,\n derivationType: 'pda',\n deployed: false,\n };\n\n case 22: // Aptos\n // Aptos uses the key hash as the resource account address\n return {\n wormholeChainId: 22,\n chainName: 'Aptos',\n address: credential.keyHash,\n isEvm: false,\n derivationType: 'resource_account',\n deployed: false,\n };\n\n case 21: // Sui\n // Sui uses the key hash with 0x prefix\n return {\n wormholeChainId: 21,\n chainName: 'Sui',\n address: credential.keyHash,\n isEvm: false,\n derivationType: 'object',\n deployed: false,\n };\n\n default:\n // Unknown chain\n return null;\n }\n }\n\n // ========================================================================\n // Address Lookup\n // ========================================================================\n\n /**\n * Get cached address for a chain\n */\n getAddressForChain(keyHash: string, wormholeChainId: number): ChainAddress | undefined {\n const addresses = this.addressCache.get(keyHash);\n return addresses?.find(a => a.wormholeChainId === wormholeChainId);\n }\n\n /**\n * Get all cached addresses for a key hash\n */\n getAddresses(keyHash: string): ChainAddress[] {\n return this.addressCache.get(keyHash) ?? [];\n }\n\n /**\n * Update deployment status for an address\n */\n updateDeploymentStatus(\n keyHash: string,\n wormholeChainId: number,\n deployed: boolean,\n deploymentTxHash?: string\n ): void {\n const addresses = this.addressCache.get(keyHash);\n if (!addresses) return;\n\n const address = addresses.find(a => a.wormholeChainId === wormholeChainId);\n if (address) {\n address.deployed = deployed;\n address.deploymentTxHash = deploymentTxHash;\n }\n\n // Persist update if enabled\n if (this.config.persistToStorage) {\n this.saveAddressesToStorage(keyHash, addresses);\n }\n }\n\n // ========================================================================\n // Storage\n // ========================================================================\n\n /**\n * Load addresses from localStorage\n */\n private loadFromStorage(): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!);\n if (!stored) return;\n\n const data = JSON.parse(stored) as StoredWalletData;\n \n for (const [keyHash, addresses] of Object.entries(data.addresses)) {\n this.addressCache.set(keyHash, addresses);\n }\n } catch (error) {\n console.warn('Failed to load wallet addresses from storage:', error);\n }\n }\n\n /**\n * Save identity to localStorage\n */\n private saveToStorage(identity: UnifiedIdentity): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!) ?? '{}';\n const data = JSON.parse(stored) as StoredWalletData;\n\n if (!data.addresses) {\n data.addresses = {};\n }\n\n // Store identity with serialized bigints\n data.addresses[identity.keyHash] = identity.addresses;\n data.identities = data.identities ?? {};\n data.identities[identity.keyHash] = {\n keyHash: identity.keyHash,\n publicKeyX: identity.publicKeyX.toString(),\n publicKeyY: identity.publicKeyY.toString(),\n credentialId: identity.credentialId,\n createdAt: identity.createdAt,\n updatedAt: identity.updatedAt,\n };\n\n localStorage.setItem(this.config.storageKey!, JSON.stringify(data));\n } catch (error) {\n console.warn('Failed to save wallet addresses to storage:', error);\n }\n }\n\n /**\n * Save addresses to localStorage\n */\n private saveAddressesToStorage(keyHash: string, addresses: ChainAddress[]): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!) ?? '{}';\n const data = JSON.parse(stored) as StoredWalletData;\n\n if (!data.addresses) {\n data.addresses = {};\n }\n\n data.addresses[keyHash] = addresses;\n localStorage.setItem(this.config.storageKey!, JSON.stringify(data));\n } catch (error) {\n console.warn('Failed to save wallet addresses to storage:', error);\n }\n }\n\n /**\n * Clear all cached data\n */\n clearCache(): void {\n this.addressCache.clear();\n \n if (this.config.persistToStorage && typeof window !== 'undefined') {\n localStorage.removeItem(this.config.storageKey!);\n }\n }\n\n /**\n * Load identity from storage\n */\n loadIdentityFromStorage(keyHash: string): UnifiedIdentity | null {\n if (typeof window === 'undefined') return null;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey!);\n if (!stored) return null;\n\n const data = JSON.parse(stored) as StoredWalletData;\n const storedIdentity = data.identities?.[keyHash];\n const addresses = data.addresses?.[keyHash];\n\n if (!storedIdentity || !addresses) return null;\n\n return {\n keyHash: storedIdentity.keyHash,\n publicKeyX: BigInt(storedIdentity.publicKeyX),\n publicKeyY: BigInt(storedIdentity.publicKeyY),\n credentialId: storedIdentity.credentialId,\n addresses,\n createdAt: storedIdentity.createdAt,\n updatedAt: storedIdentity.updatedAt,\n };\n } catch (error) {\n console.warn('Failed to load identity from storage:', error);\n return null;\n }\n }\n}\n\n// ============================================================================\n// Helper Types (Internal)\n// ============================================================================\n\ninterface ChainAddressConfig {\n chainName: string;\n isEvm: boolean;\n factoryAddress?: string;\n implementationAddress?: string;\n}\n\ninterface StoredWalletData {\n addresses: Record<string, ChainAddress[]>;\n identities?: Record<string, {\n keyHash: string;\n publicKeyX: string;\n publicKeyY: string;\n credentialId: string;\n createdAt: number;\n updatedAt: number;\n }>;\n}\n\n// Export the helper type for external use\nexport type { ChainAddressConfig };\n","/**\n * Veridex Protocol SDK - Utility Functions\n */\n\nimport { ethers } from 'ethers';\nimport type { ChainConfig } from './types.js';\nimport { TESTNET_CHAINS, MAINNET_CHAINS } from './constants.js';\n\n// ============================================================================\n// Base64URL Encoding/Decoding (WebAuthn compatible)\n// ============================================================================\n\n/**\n * Base64URL encode a buffer\n */\nexport function base64URLEncode(buffer: Uint8Array): string {\n // Convert Uint8Array to base64 using browser APIs\n const bytes = Array.from(buffer);\n const binary = String.fromCharCode(...bytes);\n const base64 = btoa(binary);\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Base64URL decode a string\n */\nexport function base64URLDecode(str: string): Uint8Array {\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n // Use browser's atob for base64 decoding\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n// ============================================================================\n// Signature Utilities\n// ============================================================================\n\n/**\n * Parse DER-encoded ECDSA signature to r and s values\n */\nexport function parseDERSignature(signature: Uint8Array): { r: Uint8Array; s: Uint8Array } {\n let offset = 0;\n\n if (signature[offset++] !== 0x30) {\n throw new Error('Invalid signature format');\n }\n\n // Skip total length\n offset++;\n\n if (signature[offset++] !== 0x02) {\n throw new Error('Invalid signature format');\n }\n\n const rLength = signature[offset++];\n if (rLength === undefined) {\n throw new Error('Invalid signature format: missing r length');\n }\n let r = signature.slice(offset, offset + rLength);\n offset += rLength;\n\n // Remove leading zero if present (for positive number representation)\n if (r[0] === 0x00 && r.length > 32) {\n r = r.slice(1);\n }\n // Pad to 32 bytes if needed\n if (r.length < 32) {\n const padded = new Uint8Array(32);\n padded.set(r, 32 - r.length);\n r = padded;\n }\n\n if (signature[offset++] !== 0x02) {\n throw new Error('Invalid signature format');\n }\n\n const sLength = signature[offset++];\n if (sLength === undefined) {\n throw new Error('Invalid signature format: missing s length');\n }\n let s = signature.slice(offset, offset + sLength);\n\n // Remove leading zero if present\n if (s[0] === 0x00 && s.length > 32) {\n s = s.slice(1);\n }\n // Pad to 32 bytes if needed\n if (s.length < 32) {\n const padded = new Uint8Array(32);\n padded.set(s, 32 - s.length);\n s = padded;\n }\n\n return { r, s };\n}\n\n/**\n * Encode signature for Solidity verification\n */\nexport function encodeSignatureForSolidity(r: bigint, s: bigint): string {\n return ethers.solidityPacked(['uint256', 'uint256'], [r, s]);\n}\n\n// ============================================================================\n// Key Hash Utilities\n// ============================================================================\n\n/**\n * Compute key hash from public key coordinates\n */\nexport function computeKeyHash(publicKeyX: bigint, publicKeyY: bigint): string {\n return ethers.keccak256(\n ethers.solidityPacked(['uint256', 'uint256'], [publicKeyX, publicKeyY])\n );\n}\n\n// ============================================================================\n// Chain Utilities\n// ============================================================================\n\n/**\n * Get chain config by name\n */\nexport function getChainConfig(chainName: string, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return chains[chainName];\n}\n\n/**\n * Get chain config by Wormhole chain ID\n */\nexport function getChainByWormholeId(wormholeChainId: number, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains).find(chain => chain.wormholeChainId === wormholeChainId);\n}\n\n/**\n * Get chain config by EVM chain ID\n */\nexport function getChainByEvmId(evmChainId: number, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains).find(chain => chain.chainId === evmChainId);\n}\n\n/**\n * Check if a chain is EVM-compatible\n */\nexport function isEvmChain(wormholeChainId: number): boolean {\n // Non-EVM chains\n const nonEvmChains = new Set([1, 8, 15, 21, 22]); // Solana, Algorand, NEAR, Sui, Aptos\n return !nonEvmChains.has(wormholeChainId);\n}\n\n/**\n * Get all supported chains\n */\nexport function getSupportedChains(testnet = true): ChainConfig[] {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains);\n}\n\n// ============================================================================\n// Explorer URL Utilities\n// ============================================================================\n\n/**\n * Get transaction explorer URL\n */\nexport function getTxExplorerUrl(chain: ChainConfig, txHash: string): string {\n if (chain.isEvm) {\n return `${chain.explorerUrl}/tx/${txHash}`;\n }\n\n // Non-EVM chains have different URL patterns\n switch (chain.wormholeChainId) {\n case 1: // Solana\n return `${chain.explorerUrl}/tx/${txHash}?cluster=devnet`;\n case 21: // Sui\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 22: // Aptos\n return `${chain.explorerUrl}/txn/${txHash}?network=testnet`;\n default:\n return `${chain.explorerUrl}/tx/${txHash}`;\n }\n}\n\n/**\n * Get address explorer URL\n */\nexport function getAddressExplorerUrl(chain: ChainConfig, address: string): string {\n if (chain.isEvm) {\n return `${chain.explorerUrl}/address/${address}`;\n }\n\n switch (chain.wormholeChainId) {\n case 1: // Solana\n return `${chain.explorerUrl}/address/${address}?cluster=devnet`;\n case 21: // Sui\n return `${chain.explorerUrl}/account/${address}`;\n case 22: // Aptos\n return `${chain.explorerUrl}/account/${address}?network=testnet`;\n default:\n return `${chain.explorerUrl}/address/${address}`;\n }\n}\n\n// ============================================================================\n// Validation Utilities\n// ============================================================================\n\n/**\n * Validate an EVM address\n */\nexport function isValidEvmAddress(address: string): boolean {\n return ethers.isAddress(address);\n}\n\n/**\n * Validate a bytes32 hex string\n */\nexport function isValidBytes32(hex: string): boolean {\n const clean = hex.replace('0x', '');\n return /^[0-9a-fA-F]{64}$/.test(clean);\n}\n\n/**\n * Validate a Wormhole chain ID\n */\nexport function isValidWormholeChainId(chainId: number): boolean {\n // Valid Wormhole chain IDs range from 1 to ~10007 (testnets)\n return chainId >= 1 && chainId <= 50000;\n}\n\n// ============================================================================\n// Retry Utilities\n// ============================================================================\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function retryWithBackoff<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n onRetry?: (attempt: number, error: Error) => void;\n } = {}\n): Promise<T> {\n const {\n maxRetries = 5,\n initialDelayMs = 1000,\n maxDelayMs = 30000,\n backoffMultiplier = 2,\n onRetry,\n } = options;\n\n let lastError: Error | undefined;\n let delay = initialDelayMs;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n if (attempt < maxRetries) {\n onRetry?.(attempt, lastError);\n await sleep(delay);\n delay = Math.min(delay * backoffMultiplier, maxDelayMs);\n }\n }\n }\n\n throw lastError ?? new Error('Retry failed');\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","/**\n * Veridex Protocol SDK - Token Constants\n * \n * Known tokens per chain for balance fetching and transfers\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface TokenInfo {\n /** Token symbol (e.g., 'USDC', 'ETH') */\n symbol: string;\n /** Token name (e.g., 'USD Coin') */\n name: string;\n /** Token address (use 'native' for native token) */\n address: string;\n /** Number of decimals */\n decimals: number;\n /** Optional logo URL */\n logoUrl?: string;\n /** Whether this is the native token */\n isNative: boolean;\n /** Wormhole-wrapped token address on other chains (by wormhole chain ID) */\n wrappedAddresses?: Record<number, string>;\n}\n\nexport interface ChainTokenList {\n /** Wormhole chain ID */\n wormholeChainId: number;\n /** Chain name */\n chainName: string;\n /** Native token info */\n nativeToken: TokenInfo;\n /** ERC20/SPL/etc tokens */\n tokens: TokenInfo[];\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * Native token address constant\n */\nexport const NATIVE_TOKEN_ADDRESS = 'native';\n\n/**\n * Zero address for EVM chains\n */\nexport const EVM_ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';\n\n// ============================================================================\n// Base Sepolia (Hub Chain) - Wormhole Chain ID 10004\n// ============================================================================\n\nexport const BASE_SEPOLIA_TOKENS: ChainTokenList = {\n wormholeChainId: 10004,\n chainName: 'Base Sepolia',\n nativeToken: {\n symbol: 'ETH',\n name: 'Ether',\n address: NATIVE_TOKEN_ADDRESS,\n decimals: 18,\n isNative: true,\n },\n tokens: [\n {\n symbol: 'USDC',\n name: 'USD Coin (Test)',\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // Circle test USDC\n decimals: 6,\n isNative: false,\n },\n {\n symbol: 'WETH',\n name: 'Wrapped Ether',\n address: '0x4200000000000000000000000000000000000006',\n decimals: 18,\n isNative: false,\n },\n ],\n};\n\n// ============================================================================\n// Optimism Sepolia (Spoke Chain) - Wormhole Chain ID 10005\n// ============================================================================\n\nexport const OPTIMISM_SEPOLIA_TOKENS: ChainTokenList = {\n wormholeChainId: 10005,\n chainName: 'Optimism Sepolia',\n nativeToken: {\n symbol: 'ETH',\n name: 'Ether',\n address: NATIVE_TOKEN_ADDRESS,\n decimals: 18,\n isNative: true,\n },\n tokens: [\n {\n symbol: 'USDC',\n name: 'USD Coin (Test)',\n address: '0x5fd84259d66Cd46123540766Be93DFE6D43130D7', // Test USDC\n decimals: 6,\n isNative: false,\n },\n {\n symbol: 'WETH',\n name: 'Wrapped Ether',\n address: '0x4200000000000000000000000000000000000006',\n decimals: 18,\n isNative: false,\n },\n ],\n};\n\n// ============================================================================\n// Arbitrum Sepolia (Spoke Chain) - Wormhole Chain ID 10003\n// ============================================================================\n\nexport const ARBITRUM_SEPOLIA_TOKENS: ChainTokenList = {\n wormholeChainId: 10003,\n chainName: 'Arbitrum Sepolia',\n nativeToken: {\n symbol: 'ETH',\n name: 'Ether',\n address: NATIVE_TOKEN_ADDRESS,\n decimals: 18,\n isNative: true,\n },\n tokens: [\n {\n symbol: 'USDC',\n name: 'USD Coin (Test)',\n address: '0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d', // Circle USDC Arbitrum Sepolia\n decimals: 6,\n isNative: false,\n },\n {\n symbol: 'WETH',\n name: 'Wrapped Ether',\n address: '0x980B62Da83eFf3D4576C647993b0c1D7faf17c73',\n decimals: 18,\n isNative: false,\n },\n ],\n};\n\n// ============================================================================\n// Token Registry\n// ============================================================================\n\n/**\n * All token lists indexed by Wormhole chain ID\n */\nexport const TOKEN_REGISTRY: Record<number, ChainTokenList> = {\n 10004: BASE_SEPOLIA_TOKENS,\n 10005: OPTIMISM_SEPOLIA_TOKENS,\n 10003: ARBITRUM_SEPOLIA_TOKENS,\n};\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get token list for a chain\n */\nexport function getTokenList(wormholeChainId: number): ChainTokenList | null {\n return TOKEN_REGISTRY[wormholeChainId] ?? null;\n}\n\n/**\n * Get all tokens for a chain (native + ERC20)\n */\nexport function getAllTokens(wormholeChainId: number): TokenInfo[] {\n const list = getTokenList(wormholeChainId);\n if (!list) return [];\n return [list.nativeToken, ...list.tokens];\n}\n\n/**\n * Get token info by symbol\n */\nexport function getTokenBySymbol(wormholeChainId: number, symbol: string): TokenInfo | null {\n const tokens = getAllTokens(wormholeChainId);\n return tokens.find(t => t.symbol.toLowerCase() === symbol.toLowerCase()) ?? null;\n}\n\n/**\n * Get token info by address\n */\nexport function getTokenByAddress(wormholeChainId: number, address: string): TokenInfo | null {\n const tokens = getAllTokens(wormholeChainId);\n const normalizedAddress = address.toLowerCase();\n return tokens.find(t => t.address.toLowerCase() === normalizedAddress) ?? null;\n}\n\n/**\n * Check if an address is the native token\n */\nexport function isNativeToken(address: string): boolean {\n return address.toLowerCase() === NATIVE_TOKEN_ADDRESS || \n address === EVM_ZERO_ADDRESS;\n}\n\n/**\n * Get supported chain IDs\n */\nexport function getSupportedChainIds(): number[] {\n return Object.keys(TOKEN_REGISTRY).map(Number);\n}\n\n/**\n * Get chain name by Wormhole chain ID\n */\nexport function getChainName(wormholeChainId: number): string | null {\n return TOKEN_REGISTRY[wormholeChainId]?.chainName ?? null;\n}\n"],"mappings":"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","names":["axios","Buffer","ethers","EthCallQueryRequest","EthCallQueryResponse","PerChainQueryRequest","QueryRequest","QueryResponse","hexToUint8Array","isValidHexString","ethers","ethers","ethers","ethers","resolveNetwork","concatBytes","signaturesToProofBytes","hexToUint8Array","decodeQueryBytes","isValidHexString","Buffer","sleep","withExponentialBackoff","ethers","PerChainQueryRequest","EthCallQueryRequest","chainsOut","QueryRequest","axios","QueryResponse","chainResp","EthCallQueryResponse","blockTime","age","balances","result"]}
|