@veridex/sdk 1.1.2 → 1.1.4
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/auth/prepareAuth.js +25 -25
- package/dist/auth/prepareAuth.js.map +1 -1
- package/dist/auth/prepareAuth.mjs +6 -6
- package/dist/chains/aptos/index.js.map +1 -1
- package/dist/chains/aptos/index.mjs +3 -3
- package/dist/chains/avalanche/index.js +22 -8
- package/dist/chains/avalanche/index.js.map +1 -1
- package/dist/chains/avalanche/index.mjs +4 -4
- package/dist/chains/evm/index.js +22 -8
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/evm/index.mjs +3 -3
- package/dist/chains/solana/index.js.map +1 -1
- package/dist/chains/solana/index.mjs +3 -3
- package/dist/chains/stacks/index.js.map +1 -1
- package/dist/chains/stacks/index.mjs +3 -3
- package/dist/chains/starknet/index.d.mts +1 -1
- package/dist/chains/starknet/index.js.map +1 -1
- package/dist/chains/starknet/index.mjs +3 -3
- package/dist/chains/stellar/index.mjs +2 -2
- package/dist/chains/sui/index.js.map +1 -1
- package/dist/chains/sui/index.mjs +3 -3
- package/dist/{chunk-AFHWA4CZ.mjs → chunk-5FH67KLG.mjs} +2 -2
- package/dist/{chunk-UPO55SBK.mjs → chunk-6QYJKK4L.mjs} +2 -2
- package/dist/{chunk-CSU4IV2F.mjs → chunk-7KN6Y4GX.mjs} +2 -2
- package/dist/{chunk-CTYDGO6E.mjs → chunk-BJH5HJL5.mjs} +2 -2
- package/dist/{chunk-E3SU36C2.mjs → chunk-D57UJ4L5.mjs} +2 -2
- package/dist/{chunk-TPEP6XUA.mjs → chunk-DQOW3G7M.mjs} +2 -2
- package/dist/{chunk-YYT3V7CI.mjs → chunk-GEVTBQH2.mjs} +2 -2
- package/dist/{chunk-5FDOTI5G.mjs → chunk-GXJUY2SC.mjs} +2 -2
- package/dist/{chunk-RD6ZYUVG.mjs → chunk-KYOOTSRA.mjs} +8 -8
- package/dist/{chunk-RD6ZYUVG.mjs.map → chunk-KYOOTSRA.mjs.map} +1 -1
- package/dist/{chunk-GOWXQPTW.mjs → chunk-NVRAQPSF.mjs} +3 -3
- package/dist/{chunk-2TS375ET.mjs → chunk-QVTADARB.mjs} +2 -2
- package/dist/{chunk-DZUNCSI5.mjs → chunk-USVZH4QC.mjs} +24 -10
- package/dist/{chunk-DZUNCSI5.mjs.map → chunk-USVZH4QC.mjs.map} +1 -1
- package/dist/{chunk-EFIXFA6V.mjs → chunk-VABK3ID3.mjs} +2 -2
- package/dist/{chunk-ICGB3AHI.mjs → chunk-XDIIFIW6.mjs} +2 -2
- package/dist/{chunk-GM5DKEHD.mjs → chunk-ZNIVNPGF.mjs} +2 -2
- package/dist/{chunk-GM5DKEHD.mjs.map → chunk-ZNIVNPGF.mjs.map} +1 -1
- package/dist/{chunk-M3GUNREX.mjs → chunk-ZXMTPBSP.mjs} +19 -19
- package/dist/{chunk-M3GUNREX.mjs.map → chunk-ZXMTPBSP.mjs.map} +1 -1
- package/dist/constants.js +7 -7
- package/dist/constants.js.map +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/index.js +51 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -20
- package/dist/index.mjs.map +1 -1
- package/dist/passkey.mjs +3 -3
- package/dist/payload.js.map +1 -1
- package/dist/payload.mjs +2 -2
- package/dist/portfolio-W2FQ2G3O.mjs +13 -0
- package/dist/queries/index.js +7 -7
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/index.mjs +5 -5
- package/dist/utils.js +7 -7
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +2 -2
- package/dist/wormhole.js.map +1 -1
- package/dist/wormhole.mjs +2 -2
- package/package.json +4 -4
- package/dist/portfolio-JA4OTF7Y.mjs +0 -13
- /package/dist/{chunk-AFHWA4CZ.mjs.map → chunk-5FH67KLG.mjs.map} +0 -0
- /package/dist/{chunk-UPO55SBK.mjs.map → chunk-6QYJKK4L.mjs.map} +0 -0
- /package/dist/{chunk-CSU4IV2F.mjs.map → chunk-7KN6Y4GX.mjs.map} +0 -0
- /package/dist/{chunk-CTYDGO6E.mjs.map → chunk-BJH5HJL5.mjs.map} +0 -0
- /package/dist/{chunk-E3SU36C2.mjs.map → chunk-D57UJ4L5.mjs.map} +0 -0
- /package/dist/{chunk-TPEP6XUA.mjs.map → chunk-DQOW3G7M.mjs.map} +0 -0
- /package/dist/{chunk-YYT3V7CI.mjs.map → chunk-GEVTBQH2.mjs.map} +0 -0
- /package/dist/{chunk-5FDOTI5G.mjs.map → chunk-GXJUY2SC.mjs.map} +0 -0
- /package/dist/{chunk-GOWXQPTW.mjs.map → chunk-NVRAQPSF.mjs.map} +0 -0
- /package/dist/{chunk-2TS375ET.mjs.map → chunk-QVTADARB.mjs.map} +0 -0
- /package/dist/{chunk-EFIXFA6V.mjs.map → chunk-VABK3ID3.mjs.map} +0 -0
- /package/dist/{chunk-ICGB3AHI.mjs.map → chunk-XDIIFIW6.mjs.map} +0 -0
- /package/dist/{portfolio-JA4OTF7Y.mjs.map → portfolio-W2FQ2G3O.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chains/starknet/StarknetClient.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Starknet Chain Client\n *\n * Production-grade implementation of ChainClient interface for Starknet.\n * Supports custom bridge attestation, gasless execution via Hub dispatch.\n *\n * Security:\n * - Native starknet::eth_signature::verify_eth_signature for validation\n * - Custom bridge with multi-relayer threshold attestations\n * - Replay protection via nonce verification on Hub\n * - Bridge validates source_chain == hub_chain_id (10004 = Base Sepolia)\n *\n * Architecture:\n * - Starknet actions MUST be dispatched via Hub (Base Sepolia)\n * - Hub publishes Wormhole message → relayer monitors → relayer submits attestation\n * - Bridge accumulates attestations → threshold reached → spoke executes\n * - Spoke validates source_chain == hubChainId (NOT targetChain)\n * \n * Custom Bridge:\n * - Bridge address: 0x700488242f8f03248b2311edddc394f0408a18c36181446eabd265067809c83\n * - Chain ID: 50001 (custom range 50000+, reserved for non-Wormhole chains)\n * - Hub Chain ID: 10004 (Base Sepolia - what bridge validates as source)\n */\n\nimport type { SessionKey } from '../../sessions/types.js';\nimport type {\n ChainClient,\n ChainConfig,\n TransferParams,\n ExecuteParams,\n BridgeParams,\n DispatchResult,\n WebAuthnSignature,\n VaultCreationResult,\n RegisterSessionParams,\n RevokeSessionParams,\n SessionValidationResult,\n} from '../../core/types.js';\nimport { createHash } from 'crypto';\nimport { RpcProvider } from 'starknet';\nimport { encodeTransferAction, encodeExecuteAction, encodeBridgeAction } from '../../payload.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n// 2^128 for splitting u256 into low/high\nconst U128_MAX = BigInt('0x100000000000000000000000000000000');\n\n/**\n * Convert a 256-bit keyHash to Starknet u256 format (low, high felt252 pair).\n * Starknet u256 is represented as two felt252 values: (low_128_bits, high_128_bits)\n * \n * @param keyHash - 256-bit hex string (with or without 0x prefix)\n * @returns Array of two hex strings [low, high] for Starknet calldata\n */\nfunction toStarknetU256(keyHash: string): [string, string] {\n const cleanHash = keyHash.replace('0x', '').padStart(64, '0');\n const value = BigInt('0x' + cleanHash);\n \n // Split into low 128 bits and high 128 bits\n const low = value % U128_MAX;\n const high = value / U128_MAX;\n \n return [\n '0x' + low.toString(16),\n '0x' + high.toString(16)\n ];\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface StarknetClientConfig {\n wormholeChainId: number;\n rpcUrl: string;\n spokeContractAddress?: string;\n bridgeContractAddress?: string;\n network?: 'mainnet' | 'sepolia' | 'testnet';\n hubRpcUrl?: string; // Hub chain RPC for session management\n hubContractAddress?: string; // Hub contract for session management\n}\n\n// ============================================================================\n// StarknetClient\n// ============================================================================\n\nexport class StarknetClient implements ChainClient {\n private config: ChainConfig;\n private provider: RpcProvider;\n private hubRpcUrl?: string;\n private hubContractAddress?: string;\n\n constructor(config: StarknetClientConfig) {\n this.config = {\n name: `Starknet ${config.network || 'mainnet'}`,\n chainId: 0,\n wormholeChainId: config.wormholeChainId,\n rpcUrl: config.rpcUrl,\n explorerUrl: config.network === 'sepolia'\n ? 'https://sepolia.starkscan.co'\n : 'https://starkscan.co',\n isEvm: false,\n contracts: {\n hub: config.spokeContractAddress,\n wormholeCoreBridge: config.bridgeContractAddress ?? '',\n },\n };\n\n this.hubRpcUrl = config.hubRpcUrl;\n this.hubContractAddress = config.hubContractAddress;\n\n this.provider = new RpcProvider({ nodeUrl: config.rpcUrl });\n }\n\n getConfig(): ChainConfig {\n return this.config;\n }\n\n async getNonce(_userKeyHash: string): Promise<bigint> {\n return 0n;\n }\n\n async getMessageFee(): Promise<bigint> {\n return 0n;\n }\n\n async buildTransferPayload(params: TransferParams): Promise<string> {\n return encodeTransferAction(params.token, params.recipient, params.amount);\n }\n\n async buildExecutePayload(params: ExecuteParams): Promise<string> {\n return encodeExecuteAction(params.target, params.value, params.data);\n }\n\n async buildBridgePayload(params: BridgeParams): Promise<string> {\n return encodeBridgeAction(params.token, params.amount, params.destinationChain, params.recipient);\n }\n\n async dispatch(\n signature: WebAuthnSignature,\n publicKeyX: bigint,\n publicKeyY: bigint,\n targetChain: number,\n actionPayload: string,\n nonce: bigint,\n signer: any\n ): Promise<DispatchResult> {\n void signature;\n void publicKeyX;\n void publicKeyY;\n void targetChain;\n void actionPayload;\n void nonce;\n void signer;\n throw new Error(\n 'Direct dispatch not supported on Starknet. ' +\n 'Starknet actions are executed via the Veridex Hub (Base Sepolia) + custom bridge. ' +\n 'Use dispatchGasless() to route through relayer, which will submit attestations to the bridge.'\n );\n }\n\n async dispatchGasless(\n signature: WebAuthnSignature,\n publicKeyX: bigint,\n publicKeyY: bigint,\n targetChain: number,\n actionPayload: string,\n nonce: bigint,\n relayerUrl: string\n ): Promise<DispatchResult> {\n /**\n * Starknet gasless execution flow:\n * 1. User signs action with passkey (on client)\n * 2. SDK submits to relayer with targetChain=50001 (Starknet)\n * 3. Relayer dispatches to Hub (Base Sepolia) with targetChain=50001\n * 4. Hub publishes Wormhole message\n * 5. Relayer monitors Hub Dispatch event\n * 6. Relayer submits attestation to Starknet Bridge\n * 7. Bridge accumulates attestations from multiple relayers\n * 8. When threshold reached, Bridge calls spoke.execute()\n * 9. Spoke validates source_chain == hubChainId (10004)\n * 10. Spoke executes action on user's vault\n * \n * Result: Completely gasless for user - relayer pays all fees\n */\n const keyHash = this.computeKeyHash(publicKeyX, publicKeyY);\n\n // Submit to relayer for Hub dispatch + bridge attestation\n const request = {\n signature: {\n r: '0x' + signature.r.toString(16).padStart(64, '0'),\n s: '0x' + signature.s.toString(16).padStart(64, '0'),\n authenticatorData: signature.authenticatorData,\n clientDataJSON: signature.clientDataJSON,\n challengeIndex: signature.challengeIndex,\n typeIndex: signature.typeIndex,\n },\n publicKeyX: '0x' + publicKeyX.toString(16).padStart(64, '0'),\n publicKeyY: '0x' + publicKeyY.toString(16).padStart(64, '0'),\n targetChain, // 50001 for Starknet\n actionPayload,\n userNonce: Number(nonce),\n };\n\n const response = await fetch(`${relayerUrl}/api/v1/submit`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(\n `Relayer submission failed: ${response.status} ${response.statusText}. ` +\n `Error: ${errorText}`\n );\n }\n\n const result = await response.json();\n\n return {\n transactionHash: result.transactionHash ?? result.txHash ?? result.hubTxHash,\n sequence: BigInt(result.sequence || 0),\n userKeyHash: keyHash,\n targetChain,\n };\n }\n\n // Note: getVaultAddress is now defined in the Social Recovery section below\n // with enhanced spoke contract querying support.\n\n computeVaultAddress(userKeyHash: string): string {\n /**\n * Starknet vault derivation:\n * - Vaults are created via spoke contract\n * - Address is deterministic from userKeyHash\n * - Uses keyHash directly as vault identifier (felt252)\n * \n * Note: Actual vault address on Starknet may differ based on\n * spoke implementation. This is a best-effort derivation.\n */\n const clean = userKeyHash.replace(/^0x/, '');\n return '0x' + clean;\n }\n\n async vaultExists(userKeyHash: string): Promise<boolean> {\n /**\n * Check if vault exists on Starknet spoke\n * Best-effort: queries spoke contract if available\n */\n if (!this.config.contracts.hub) {\n return false;\n }\n\n try {\n const vaultAddress = await this.getVaultAddress(userKeyHash);\n if (!vaultAddress) {\n return false;\n }\n\n // Query Starknet RPC for contract code at vault address\n const anyProvider = this.provider as any;\n if (typeof anyProvider.getClassHashAt === 'function') {\n await anyProvider.getClassHashAt(vaultAddress);\n return true;\n }\n } catch {\n // Vault doesn't exist or RPC doesn't support query\n }\n\n return false;\n }\n\n async createVault(userKeyHash: string, signer: any): Promise<VaultCreationResult> {\n void signer;\n throw new Error(\n 'Vault creation on Starknet must be done via Hub dispatch + custom bridge attestation. ' +\n 'Use Hub client (Base Sepolia) to dispatch a CREATE_VAULT action with targetChain=50001. ' +\n `KeyHash=${userKeyHash}`\n );\n }\n\n async createVaultSponsored?(userKeyHash: string, sponsorPrivateKey: string, rpcUrl?: string): Promise<VaultCreationResult> {\n void userKeyHash;\n void sponsorPrivateKey;\n void rpcUrl;\n throw new Error(\n 'Vault creation on Starknet must be done via Hub dispatch + custom bridge attestation. ' +\n 'Use Hub client (Base Sepolia) with sponsor key to dispatch CREATE_VAULT action.'\n );\n }\n\n /**\n * Create a vault via the relayer (sponsored/gasless)\n * This is the recommended way to create Starknet vaults\n * \n * The relayer will dispatch a vault creation action from Hub via custom bridge to Starknet spoke\n */\n async createVaultViaRelayer(\n userKeyHash: string,\n relayerUrl: string\n ): Promise<VaultCreationResult> {\n const response = await fetch(`${relayerUrl}/api/v1/starknet/vault`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n userKeyHash,\n chainId: this.config.wormholeChainId,\n }),\n });\n\n const result = await response.json();\n\n if (!response.ok || !result.success) {\n throw new Error(result.error || 'Failed to create vault via relayer');\n }\n\n return {\n address: result.vaultAddress,\n transactionHash: result.transactionHash || '',\n blockNumber: 0,\n gasUsed: 0n,\n alreadyExisted: result.alreadyExists || false,\n sponsoredBy: 'relayer',\n };\n }\n\n /**\n * Get vault info via relayer (includes existence check)\n */\n async getVaultViaRelayer(\n userKeyHash: string,\n relayerUrl: string\n ): Promise<{ vaultAddress: string; exists: boolean }> {\n const response = await fetch(\n `${relayerUrl}/api/v1/starknet/vault/${userKeyHash}?chainId=${this.config.wormholeChainId}`\n );\n\n if (!response.ok) {\n throw new Error('Failed to get vault info from relayer');\n }\n\n const result = await response.json();\n return {\n vaultAddress: result.vaultAddress,\n exists: result.exists,\n };\n }\n\n async estimateVaultCreationGas(_userKeyHash: string): Promise<bigint> {\n return 0n;\n }\n\n getFactoryAddress(): string | undefined {\n return undefined;\n }\n\n getImplementationAddress(): string | undefined {\n return undefined;\n }\n\n // ========================================================================\n // Balance utility (best-effort)\n // ========================================================================\n\n async getNativeBalance(address: string): Promise<bigint> {\n // Best-effort: some Starknet RPCs support getBalance, but it is not universal.\n try {\n const anyProvider = this.provider as any;\n if (typeof anyProvider.getBalance === 'function') {\n const res = await anyProvider.getBalance(address);\n return BigInt(res);\n }\n } catch {\n // ignore\n }\n return 0n;\n }\n\n getProvider(): RpcProvider {\n return this.provider;\n }\n\n // ========================================================================\n // Session Management (Issue #13)\n // ========================================================================\n\n /**\n * Register a session key on the Hub (must be called via Hub client)\n * Starknet spokes validate sessions via CCQ, but registration happens on Hub\n * \n * @throws Error - Session management must be done via Hub chain\n */\n async registerSession(_params: RegisterSessionParams): Promise<void> {\n throw new Error(\n 'Session registration must be performed on the Hub chain (Base). ' +\n 'Use EVMClient connected to the Hub to call registerSession().'\n );\n }\n\n /**\n * Revoke a session key on the Hub (must be called via Hub client)\n * \n * @throws Error - Session management must be done via Hub chain\n */\n async revokeSession(_params: RevokeSessionParams): Promise<void> {\n throw new Error(\n 'Session revocation must be performed on the Hub chain (Base). ' +\n 'Use EVMClient connected to the Hub to call revokeSession().'\n );\n }\n\n /**\n * Check if a session is active by querying the Hub\n * This method queries the Hub contract directly for session validation\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @param sessionKeyHash - Hash of session key to validate\n * @returns Session validation result with expiry and limits\n */\n async isSessionActive(\n _userKeyHash: string,\n _sessionKeyHash: string\n ): Promise<SessionValidationResult> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for session validation. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for session status\n throw new Error(\n 'isSessionActive requires Hub client integration. ' +\n 'Use EVMClient.isSessionActive() on the Hub chain, ' +\n 'then pass the result to session execution on Starknet.'\n );\n }\n\n /**\n * Get all sessions for a user from the Hub\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @returns Array of all sessions (active and expired/revoked)\n */\n async getUserSessions(userKeyHash: string): Promise<SessionKey[]> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for session queries. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for user sessions\n throw new Error(\n 'getUserSessions requires Hub client integration. ' +\n 'Use EVMClient.getUserSessions() on the Hub chain. ' +\n `User: ${userKeyHash}`\n );\n }\n\n // ========================================================================\n // Query-Based Execution (Issue #9/#10)\n // ========================================================================\n\n /**\n * Get user state from Hub (comprehensive state query)\n * Returns key hash, nonce, and last action hash for CCQ validation\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @returns User state with nonce and last action hash\n */\n async getUserState(userKeyHash: string): Promise<{\n keyHash: string;\n nonce: bigint;\n lastActionHash: string;\n }> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for state queries. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for user state\n throw new Error(\n 'getUserState requires Hub client integration. ' +\n 'Use EVMClient.getUserState() on the Hub chain. ' +\n `User: ${userKeyHash}`\n );\n }\n\n /**\n * Get user's last action hash from Hub\n * Used for optimistic execution and nonce validation\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @returns Last action hash (zero hash if no actions)\n */\n async getUserLastActionHash(userKeyHash: string): Promise<string> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for action hash queries. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for last action hash\n throw new Error(\n 'getUserLastActionHash requires Hub client integration. ' +\n 'Use EVMClient.getUserLastActionHash() on the Hub chain. ' +\n `User: ${userKeyHash}`\n );\n }\n\n /**\n * Execute with query-based validation (faster than VAA, ~23s vs 60-90s)\n * Uses Wormhole CCQ to validate Hub state, then executes on Starknet\n * \n * @param params Query execution parameters with CCQ response\n * @returns Dispatch result with transaction hash\n * \n * @remarks\n * Query-based execution flow:\n * 1. Query Hub state via Wormhole CCQ\n * 2. Validate Guardian signatures on query response\n * 3. Execute on Starknet with validated state\n * 4. Hub state must be < 60s stale (enforced by QueryVerifier)\n */\n async executeWithQuery(\n _params: {\n userKeyHash: string;\n queryResponse: Uint8Array; // CCQ Guardian response\n actionType: number;\n actionPayload: Uint8Array;\n relayerUrl?: string;\n }\n ): Promise<DispatchResult> {\n throw new Error(\n 'Query-based execution on Starknet requires relayer integration. ' +\n 'Use relayer API to submit query-validated transactions. ' +\n 'Relayer will call veridex_spoke::execute_with_query on Starknet.'\n );\n }\n\n // ========================================================================\n // Internal helpers\n // ========================================================================\n\n private computeKeyHash(publicKeyX: bigint, publicKeyY: bigint): string {\n const xHex = publicKeyX.toString(16).padStart(64, '0');\n const yHex = publicKeyY.toString(16).padStart(64, '0');\n const combined = Buffer.from(xHex + yHex, 'hex');\n const hash = createHash('sha256').update(combined).digest('hex');\n return '0x' + hash;\n }\n\n // ============================================================================\n // Social Recovery Methods (Issue #23)\n // ============================================================================\n // \n // Note: Social recovery is managed on the Hub chain (EVM).\n // Starknet spokes receive and execute recovery VAAs broadcast from the Hub.\n // The relayer service handles submitting recovery transactions to Starknet.\n //\n // SDK users should use EVMClient methods for guardian management and\n // recovery initiation on the Hub chain.\n // ============================================================================\n\n /**\n * Get vault address by owner key hash\n * \n * @param ownerKeyHash - Owner's passkey hash\n * @returns Vault address on Starknet (felt252 as hex string)\n */\n async getVaultAddress(ownerKeyHash: string): Promise<string | null> {\n try {\n const spokeAddress = this.config.contracts.hub;\n if (!spokeAddress) {\n throw new Error('Spoke contract address not configured');\n }\n\n // Starknet spoke expects u256 (low, high) format for keyHash\n const [low, high] = toStarknetU256(ownerKeyHash);\n\n // Call get_vault on spoke contract with u256 split into [low, high]\n const result = await this.provider.callContract({\n contractAddress: spokeAddress,\n entrypoint: 'get_vault',\n calldata: [low, high],\n });\n\n // result[0] is the vault address (0 if not found)\n const vaultAddress = result[0];\n if (vaultAddress === '0x0' || vaultAddress === '0') {\n return null;\n }\n\n return vaultAddress;\n } catch (error) {\n console.error('Error getting vault address:', error);\n return null;\n }\n }\n\n /**\n * Check if vault exists and get basic info\n * \n * @param ownerKeyHash - Owner's passkey hash \n * @returns Vault info or null if not found\n */\n async getVaultInfo(ownerKeyHash: string): Promise<{\n address: string;\n ownerKeyHash: string;\n } | null> {\n const vaultAddress = await this.getVaultAddress(ownerKeyHash);\n if (!vaultAddress) {\n return null;\n }\n\n return {\n address: vaultAddress,\n ownerKeyHash,\n };\n }\n\n /**\n * Check if spoke contract is paused\n * \n * @returns Whether the protocol is paused\n */\n async isProtocolPaused(): Promise<boolean> {\n try {\n const spokeAddress = this.config.contracts.hub;\n if (!spokeAddress) {\n throw new Error('Spoke contract address not configured');\n }\n\n const result = await this.provider.callContract({\n contractAddress: spokeAddress,\n entrypoint: 'is_paused',\n calldata: [],\n });\n\n return result[0] === '0x1' || result[0] === '1';\n } catch (error) {\n console.error('Error checking pause status:', error);\n return false;\n }\n }\n}\n"],"mappings":";;;;;;;AAsCA,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAQ5B,IAAM,WAAW,OAAO,qCAAqC;AAS7D,SAAS,eAAe,SAAmC;AACvD,QAAM,YAAY,QAAQ,QAAQ,MAAM,EAAE,EAAE,SAAS,IAAI,GAAG;AAC5D,QAAM,QAAQ,OAAO,OAAO,SAAS;AAGrC,QAAM,MAAM,QAAQ;AACpB,QAAM,OAAO,QAAQ;AAErB,SAAO;AAAA,IACH,OAAO,IAAI,SAAS,EAAE;AAAA,IACtB,OAAO,KAAK,SAAS,EAAE;AAAA,EAC3B;AACJ;AAoBO,IAAM,iBAAN,MAA4C;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,QAA8B;AACtC,SAAK,SAAS;AAAA,MACV,MAAM,YAAY,OAAO,WAAW,SAAS;AAAA,MAC7C,SAAS;AAAA,MACT,iBAAiB,OAAO;AAAA,MACxB,QAAQ,OAAO;AAAA,MACf,aAAa,OAAO,YAAY,YAC1B,iCACA;AAAA,MACN,OAAO;AAAA,MACP,WAAW;AAAA,QACP,KAAK,OAAO;AAAA,QACZ,oBAAoB,OAAO,yBAAyB;AAAA,MACxD;AAAA,IACJ;AAEA,SAAK,YAAY,OAAO;AACxB,SAAK,qBAAqB,OAAO;AAEjC,SAAK,WAAW,IAAI,YAAY,EAAE,SAAS,OAAO,OAAO,CAAC;AAAA,EAC9D;AAAA,EAEA,YAAyB;AACrB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,SAAS,cAAuC;AAClD,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,gBAAiC;AACnC,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,qBAAqB,QAAyC;AAChE,WAAO,qBAAqB,OAAO,OAAO,OAAO,WAAW,OAAO,MAAM;AAAA,EAC7E;AAAA,EAEA,MAAM,oBAAoB,QAAwC;AAC9D,WAAO,oBAAoB,OAAO,QAAQ,OAAO,OAAO,OAAO,IAAI;AAAA,EACvE;AAAA,EAEA,MAAM,mBAAmB,QAAuC;AAC5D,WAAO,mBAAmB,OAAO,OAAO,OAAO,QAAQ,OAAO,kBAAkB,OAAO,SAAS;AAAA,EACpG;AAAA,EAEA,MAAM,SACF,WACA,YACA,YACA,aACA,eACA,OACA,QACuB;AACvB,SAAK;AACL,SAAK;AACL,SAAK;AACL,SAAK;AACL,SAAK;AACL,SAAK;AACL,SAAK;AACL,UAAM,IAAI;AAAA,MACN;AAAA,IAGJ;AAAA,EACJ;AAAA,EAEA,MAAM,gBACF,WACA,YACA,YACA,aACA,eACA,OACA,YACuB;AAgBvB,UAAM,UAAU,KAAK,eAAe,YAAY,UAAU;AAG1D,UAAM,UAAU;AAAA,MACZ,WAAW;AAAA,QACP,GAAG,OAAO,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAAA,QACnD,GAAG,OAAO,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAAA,QACnD,mBAAmB,UAAU;AAAA,QAC7B,gBAAgB,UAAU;AAAA,QAC1B,gBAAgB,UAAU;AAAA,QAC1B,WAAW,UAAU;AAAA,MACzB;AAAA,MACA,YAAY,OAAO,WAAW,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAAA,MAC3D,YAAY,OAAO,WAAW,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAAA,MAC3D;AAAA;AAAA,MACA;AAAA,MACA,WAAW,OAAO,KAAK;AAAA,IAC3B;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,UAAU,kBAAkB;AAAA,MACxD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,IAChC,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,eAAe;AACnE,YAAM,IAAI;AAAA,QACN,8BAA8B,SAAS,MAAM,IAAI,SAAS,UAAU,YAC1D,SAAS;AAAA,MACvB;AAAA,IACJ;AAEA,UAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,WAAO;AAAA,MACH,iBAAiB,OAAO,mBAAmB,OAAO,UAAU,OAAO;AAAA,MACnE,UAAU,OAAO,OAAO,YAAY,CAAC;AAAA,MACrC,aAAa;AAAA,MACb;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA,EAKA,oBAAoB,aAA6B;AAU7C,UAAM,QAAQ,YAAY,QAAQ,OAAO,EAAE;AAC3C,WAAO,OAAO;AAAA,EAClB;AAAA,EAEA,MAAM,YAAY,aAAuC;AAKrD,QAAI,CAAC,KAAK,OAAO,UAAU,KAAK;AAC5B,aAAO;AAAA,IACX;AAEA,QAAI;AACA,YAAM,eAAe,MAAM,KAAK,gBAAgB,WAAW;AAC3D,UAAI,CAAC,cAAc;AACf,eAAO;AAAA,MACX;AAGA,YAAM,cAAc,KAAK;AACzB,UAAI,OAAO,YAAY,mBAAmB,YAAY;AAClD,cAAM,YAAY,eAAe,YAAY;AAC7C,eAAO;AAAA,MACX;AAAA,IACJ,QAAQ;AAAA,IAER;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,YAAY,aAAqB,QAA2C;AAC9E,SAAK;AACL,UAAM,IAAI;AAAA,MACN,yLAEW,WAAW;AAAA,IAC1B;AAAA,EACJ;AAAA,EAEA,MAAM,qBAAsB,aAAqB,mBAA2B,QAA+C;AACvH,SAAK;AACL,SAAK;AACL,SAAK;AACL,UAAM,IAAI;AAAA,MACN;AAAA,IAEJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,sBACF,aACA,YAC4B;AAC5B,UAAM,WAAW,MAAM,MAAM,GAAG,UAAU,0BAA0B;AAAA,MAChE,QAAQ;AAAA,MACR,SAAS;AAAA,QACL,gBAAgB;AAAA,MACpB;AAAA,MACA,MAAM,KAAK,UAAU;AAAA,QACjB;AAAA,QACA,SAAS,KAAK,OAAO;AAAA,MACzB,CAAC;AAAA,IACL,CAAC;AAED,UAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,QAAI,CAAC,SAAS,MAAM,CAAC,OAAO,SAAS;AACjC,YAAM,IAAI,MAAM,OAAO,SAAS,oCAAoC;AAAA,IACxE;AAEA,WAAO;AAAA,MACH,SAAS,OAAO;AAAA,MAChB,iBAAiB,OAAO,mBAAmB;AAAA,MAC3C,aAAa;AAAA,MACb,SAAS;AAAA,MACT,gBAAgB,OAAO,iBAAiB;AAAA,MACxC,aAAa;AAAA,IACjB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,mBACF,aACA,YACkD;AAClD,UAAM,WAAW,MAAM;AAAA,MACnB,GAAG,UAAU,0BAA0B,WAAW,YAAY,KAAK,OAAO,eAAe;AAAA,IAC7F;AAEA,QAAI,CAAC,SAAS,IAAI;AACd,YAAM,IAAI,MAAM,uCAAuC;AAAA,IAC3D;AAEA,UAAM,SAAS,MAAM,SAAS,KAAK;AACnC,WAAO;AAAA,MACH,cAAc,OAAO;AAAA,MACrB,QAAQ,OAAO;AAAA,IACnB;AAAA,EACJ;AAAA,EAEA,MAAM,yBAAyB,cAAuC;AAClE,WAAO;AAAA,EACX;AAAA,EAEA,oBAAwC;AACpC,WAAO;AAAA,EACX;AAAA,EAEA,2BAA+C;AAC3C,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,iBAAiB,SAAkC;AAErD,QAAI;AACA,YAAM,cAAc,KAAK;AACzB,UAAI,OAAO,YAAY,eAAe,YAAY;AAC9C,cAAM,MAAM,MAAM,YAAY,WAAW,OAAO;AAChD,eAAO,OAAO,GAAG;AAAA,MACrB;AAAA,IACJ,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACX;AAAA,EAEA,cAA2B;AACvB,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,gBAAgB,SAA+C;AACjE,UAAM,IAAI;AAAA,MACN;AAAA,IAEJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAAc,SAA6C;AAC7D,UAAM,IAAI;AAAA,MACN;AAAA,IAEJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBACF,cACA,iBACgC;AAChC,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,oBAAoB;AAC7C,YAAM,IAAI;AAAA,QACN;AAAA,MAEJ;AAAA,IACJ;AAGA,UAAM,IAAI;AAAA,MACN;AAAA,IAGJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBAAgB,aAA4C;AAC9D,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,oBAAoB;AAC7C,YAAM,IAAI;AAAA,QACN;AAAA,MAEJ;AAAA,IACJ;AAGA,UAAM,IAAI;AAAA,MACN,4GAES,WAAW;AAAA,IACxB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,aAAa,aAIhB;AACC,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,oBAAoB;AAC7C,YAAM,IAAI;AAAA,QACN;AAAA,MAEJ;AAAA,IACJ;AAGA,UAAM,IAAI;AAAA,MACN,sGAES,WAAW;AAAA,IACxB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,sBAAsB,aAAsC;AAC9D,QAAI,CAAC,KAAK,aAAa,CAAC,KAAK,oBAAoB;AAC7C,YAAM,IAAI;AAAA,QACN;AAAA,MAEJ;AAAA,IACJ;AAGA,UAAM,IAAI;AAAA,MACN,wHAES,WAAW;AAAA,IACxB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,MAAM,iBACF,SAOuB;AACvB,UAAM,IAAI;AAAA,MACN;AAAA,IAGJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAe,YAAoB,YAA4B;AACnE,UAAM,OAAO,WAAW,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AACrD,UAAM,OAAO,WAAW,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AACrD,UAAM,WAAW,OAAO,KAAK,OAAO,MAAM,KAAK;AAC/C,UAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAK;AAC/D,WAAO,OAAO;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBA,MAAM,gBAAgB,cAA8C;AAChE,QAAI;AACA,YAAM,eAAe,KAAK,OAAO,UAAU;AAC3C,UAAI,CAAC,cAAc;AACf,cAAM,IAAI,MAAM,uCAAuC;AAAA,MAC3D;AAGA,YAAM,CAAC,KAAK,IAAI,IAAI,eAAe,YAAY;AAG/C,YAAM,SAAS,MAAM,KAAK,SAAS,aAAa;AAAA,QAC5C,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU,CAAC,KAAK,IAAI;AAAA,MACxB,CAAC;AAGD,YAAM,eAAe,OAAO,CAAC;AAC7B,UAAI,iBAAiB,SAAS,iBAAiB,KAAK;AAChD,eAAO;AAAA,MACX;AAEA,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,cAAQ,MAAM,gCAAgC,KAAK;AACnD,aAAO;AAAA,IACX;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,aAAa,cAGT;AACN,UAAM,eAAe,MAAM,KAAK,gBAAgB,YAAY;AAC5D,QAAI,CAAC,cAAc;AACf,aAAO;AAAA,IACX;AAEA,WAAO;AAAA,MACH,SAAS;AAAA,MACT;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,mBAAqC;AACvC,QAAI;AACA,YAAM,eAAe,KAAK,OAAO,UAAU;AAC3C,UAAI,CAAC,cAAc;AACf,cAAM,IAAI,MAAM,uCAAuC;AAAA,MAC3D;AAEA,YAAM,SAAS,MAAM,KAAK,SAAS,aAAa;AAAA,QAC5C,iBAAiB;AAAA,QACjB,YAAY;AAAA,QACZ,UAAU,CAAC;AAAA,MACf,CAAC;AAED,aAAO,OAAO,CAAC,MAAM,SAAS,OAAO,CAAC,MAAM;AAAA,IAChD,SAAS,OAAO;AACZ,cAAQ,MAAM,gCAAgC,KAAK;AACnD,aAAO;AAAA,IACX;AAAA,EACJ;AACJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/chains/starknet/StarknetClient.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Starknet Chain Client\n *\n * Production-grade implementation of ChainClient interface for Starknet.\n * Supports custom bridge attestation, gasless execution via Hub dispatch.\n *\n * Security:\n * - Native starknet::eth_signature::verify_eth_signature for validation\n * - Custom bridge with multi-relayer threshold attestations\n * - Replay protection via nonce verification on Hub\n * - Bridge validates source_chain == hub_chain_id (10004 = Base Sepolia)\n *\n * Architecture:\n * - Starknet actions MUST be dispatched via Hub (Base Sepolia)\n * - Hub publishes Wormhole message → relayer monitors → relayer submits attestation\n * - Bridge accumulates attestations → threshold reached → spoke executes\n * - Spoke validates source_chain == hubChainId (NOT targetChain)\n * \n * Custom Bridge:\n * - Bridge address: 0x30d2e7f26dc75819cfddcd7caa26a76b681d5918f219c99060c42ce1e3f69e4\n * - Chain ID: 50001 (custom range 50000+, reserved for non-Wormhole chains)\n * - Hub Chain ID: 10004 (Base Sepolia - what bridge validates as source)\n */\n\nimport type { SessionKey } from '../../sessions/types.js';\nimport type {\n ChainClient,\n ChainConfig,\n TransferParams,\n ExecuteParams,\n BridgeParams,\n DispatchResult,\n WebAuthnSignature,\n VaultCreationResult,\n RegisterSessionParams,\n RevokeSessionParams,\n SessionValidationResult,\n} from '../../core/types.js';\nimport { createHash } from 'crypto';\nimport { RpcProvider } from 'starknet';\nimport { encodeTransferAction, encodeExecuteAction, encodeBridgeAction } from '../../payload.js';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n// 2^128 for splitting u256 into low/high\nconst U128_MAX = BigInt('0x100000000000000000000000000000000');\n\n/**\n * Convert a 256-bit keyHash to Starknet u256 format (low, high felt252 pair).\n * Starknet u256 is represented as two felt252 values: (low_128_bits, high_128_bits)\n * \n * @param keyHash - 256-bit hex string (with or without 0x prefix)\n * @returns Array of two hex strings [low, high] for Starknet calldata\n */\nfunction toStarknetU256(keyHash: string): [string, string] {\n const cleanHash = keyHash.replace('0x', '').padStart(64, '0');\n const value = BigInt('0x' + cleanHash);\n \n // Split into low 128 bits and high 128 bits\n const low = value % U128_MAX;\n const high = value / U128_MAX;\n \n return [\n '0x' + low.toString(16),\n '0x' + high.toString(16)\n ];\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface StarknetClientConfig {\n wormholeChainId: number;\n rpcUrl: string;\n spokeContractAddress?: string;\n bridgeContractAddress?: string;\n network?: 'mainnet' | 'sepolia' | 'testnet';\n hubRpcUrl?: string; // Hub chain RPC for session management\n hubContractAddress?: string; // Hub contract for session management\n}\n\n// ============================================================================\n// StarknetClient\n// ============================================================================\n\nexport class StarknetClient implements ChainClient {\n private config: ChainConfig;\n private provider: RpcProvider;\n private hubRpcUrl?: string;\n private hubContractAddress?: string;\n\n constructor(config: StarknetClientConfig) {\n this.config = {\n name: `Starknet ${config.network || 'mainnet'}`,\n chainId: 0,\n wormholeChainId: config.wormholeChainId,\n rpcUrl: config.rpcUrl,\n explorerUrl: config.network === 'sepolia'\n ? 'https://sepolia.starkscan.co'\n : 'https://starkscan.co',\n isEvm: false,\n contracts: {\n hub: config.spokeContractAddress,\n wormholeCoreBridge: config.bridgeContractAddress ?? '',\n },\n };\n\n this.hubRpcUrl = config.hubRpcUrl;\n this.hubContractAddress = config.hubContractAddress;\n\n this.provider = new RpcProvider({ nodeUrl: config.rpcUrl });\n }\n\n getConfig(): ChainConfig {\n return this.config;\n }\n\n async getNonce(_userKeyHash: string): Promise<bigint> {\n return 0n;\n }\n\n async getMessageFee(): Promise<bigint> {\n return 0n;\n }\n\n async buildTransferPayload(params: TransferParams): Promise<string> {\n return encodeTransferAction(params.token, params.recipient, params.amount);\n }\n\n async buildExecutePayload(params: ExecuteParams): Promise<string> {\n return encodeExecuteAction(params.target, params.value, params.data);\n }\n\n async buildBridgePayload(params: BridgeParams): Promise<string> {\n return encodeBridgeAction(params.token, params.amount, params.destinationChain, params.recipient);\n }\n\n async dispatch(\n signature: WebAuthnSignature,\n publicKeyX: bigint,\n publicKeyY: bigint,\n targetChain: number,\n actionPayload: string,\n nonce: bigint,\n signer: any\n ): Promise<DispatchResult> {\n void signature;\n void publicKeyX;\n void publicKeyY;\n void targetChain;\n void actionPayload;\n void nonce;\n void signer;\n throw new Error(\n 'Direct dispatch not supported on Starknet. ' +\n 'Starknet actions are executed via the Veridex Hub (Base Sepolia) + custom bridge. ' +\n 'Use dispatchGasless() to route through relayer, which will submit attestations to the bridge.'\n );\n }\n\n async dispatchGasless(\n signature: WebAuthnSignature,\n publicKeyX: bigint,\n publicKeyY: bigint,\n targetChain: number,\n actionPayload: string,\n nonce: bigint,\n relayerUrl: string\n ): Promise<DispatchResult> {\n /**\n * Starknet gasless execution flow:\n * 1. User signs action with passkey (on client)\n * 2. SDK submits to relayer with targetChain=50001 (Starknet)\n * 3. Relayer dispatches to Hub (Base Sepolia) with targetChain=50001\n * 4. Hub publishes Wormhole message\n * 5. Relayer monitors Hub Dispatch event\n * 6. Relayer submits attestation to Starknet Bridge\n * 7. Bridge accumulates attestations from multiple relayers\n * 8. When threshold reached, Bridge calls spoke.execute()\n * 9. Spoke validates source_chain == hubChainId (10004)\n * 10. Spoke executes action on user's vault\n * \n * Result: Completely gasless for user - relayer pays all fees\n */\n const keyHash = this.computeKeyHash(publicKeyX, publicKeyY);\n\n // Submit to relayer for Hub dispatch + bridge attestation\n const request = {\n signature: {\n r: '0x' + signature.r.toString(16).padStart(64, '0'),\n s: '0x' + signature.s.toString(16).padStart(64, '0'),\n authenticatorData: signature.authenticatorData,\n clientDataJSON: signature.clientDataJSON,\n challengeIndex: signature.challengeIndex,\n typeIndex: signature.typeIndex,\n },\n publicKeyX: '0x' + publicKeyX.toString(16).padStart(64, '0'),\n publicKeyY: '0x' + publicKeyY.toString(16).padStart(64, '0'),\n targetChain, // 50001 for Starknet\n actionPayload,\n userNonce: Number(nonce),\n };\n\n const response = await fetch(`${relayerUrl}/api/v1/submit`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => 'Unknown error');\n throw new Error(\n `Relayer submission failed: ${response.status} ${response.statusText}. ` +\n `Error: ${errorText}`\n );\n }\n\n const result = await response.json();\n\n return {\n transactionHash: result.transactionHash ?? result.txHash ?? result.hubTxHash,\n sequence: BigInt(result.sequence || 0),\n userKeyHash: keyHash,\n targetChain,\n };\n }\n\n // Note: getVaultAddress is now defined in the Social Recovery section below\n // with enhanced spoke contract querying support.\n\n computeVaultAddress(userKeyHash: string): string {\n /**\n * Starknet vault derivation:\n * - Vaults are created via spoke contract\n * - Address is deterministic from userKeyHash\n * - Uses keyHash directly as vault identifier (felt252)\n * \n * Note: Actual vault address on Starknet may differ based on\n * spoke implementation. This is a best-effort derivation.\n */\n const clean = userKeyHash.replace(/^0x/, '');\n return '0x' + clean;\n }\n\n async vaultExists(userKeyHash: string): Promise<boolean> {\n /**\n * Check if vault exists on Starknet spoke\n * Best-effort: queries spoke contract if available\n */\n if (!this.config.contracts.hub) {\n return false;\n }\n\n try {\n const vaultAddress = await this.getVaultAddress(userKeyHash);\n if (!vaultAddress) {\n return false;\n }\n\n // Query Starknet RPC for contract code at vault address\n const anyProvider = this.provider as any;\n if (typeof anyProvider.getClassHashAt === 'function') {\n await anyProvider.getClassHashAt(vaultAddress);\n return true;\n }\n } catch {\n // Vault doesn't exist or RPC doesn't support query\n }\n\n return false;\n }\n\n async createVault(userKeyHash: string, signer: any): Promise<VaultCreationResult> {\n void signer;\n throw new Error(\n 'Vault creation on Starknet must be done via Hub dispatch + custom bridge attestation. ' +\n 'Use Hub client (Base Sepolia) to dispatch a CREATE_VAULT action with targetChain=50001. ' +\n `KeyHash=${userKeyHash}`\n );\n }\n\n async createVaultSponsored?(userKeyHash: string, sponsorPrivateKey: string, rpcUrl?: string): Promise<VaultCreationResult> {\n void userKeyHash;\n void sponsorPrivateKey;\n void rpcUrl;\n throw new Error(\n 'Vault creation on Starknet must be done via Hub dispatch + custom bridge attestation. ' +\n 'Use Hub client (Base Sepolia) with sponsor key to dispatch CREATE_VAULT action.'\n );\n }\n\n /**\n * Create a vault via the relayer (sponsored/gasless)\n * This is the recommended way to create Starknet vaults\n * \n * The relayer will dispatch a vault creation action from Hub via custom bridge to Starknet spoke\n */\n async createVaultViaRelayer(\n userKeyHash: string,\n relayerUrl: string\n ): Promise<VaultCreationResult> {\n const response = await fetch(`${relayerUrl}/api/v1/starknet/vault`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n userKeyHash,\n chainId: this.config.wormholeChainId,\n }),\n });\n\n const result = await response.json();\n\n if (!response.ok || !result.success) {\n throw new Error(result.error || 'Failed to create vault via relayer');\n }\n\n return {\n address: result.vaultAddress,\n transactionHash: result.transactionHash || '',\n blockNumber: 0,\n gasUsed: 0n,\n alreadyExisted: result.alreadyExists || false,\n sponsoredBy: 'relayer',\n };\n }\n\n /**\n * Get vault info via relayer (includes existence check)\n */\n async getVaultViaRelayer(\n userKeyHash: string,\n relayerUrl: string\n ): Promise<{ vaultAddress: string; exists: boolean }> {\n const response = await fetch(\n `${relayerUrl}/api/v1/starknet/vault/${userKeyHash}?chainId=${this.config.wormholeChainId}`\n );\n\n if (!response.ok) {\n throw new Error('Failed to get vault info from relayer');\n }\n\n const result = await response.json();\n return {\n vaultAddress: result.vaultAddress,\n exists: result.exists,\n };\n }\n\n async estimateVaultCreationGas(_userKeyHash: string): Promise<bigint> {\n return 0n;\n }\n\n getFactoryAddress(): string | undefined {\n return undefined;\n }\n\n getImplementationAddress(): string | undefined {\n return undefined;\n }\n\n // ========================================================================\n // Balance utility (best-effort)\n // ========================================================================\n\n async getNativeBalance(address: string): Promise<bigint> {\n // Best-effort: some Starknet RPCs support getBalance, but it is not universal.\n try {\n const anyProvider = this.provider as any;\n if (typeof anyProvider.getBalance === 'function') {\n const res = await anyProvider.getBalance(address);\n return BigInt(res);\n }\n } catch {\n // ignore\n }\n return 0n;\n }\n\n getProvider(): RpcProvider {\n return this.provider;\n }\n\n // ========================================================================\n // Session Management (Issue #13)\n // ========================================================================\n\n /**\n * Register a session key on the Hub (must be called via Hub client)\n * Starknet spokes validate sessions via CCQ, but registration happens on Hub\n * \n * @throws Error - Session management must be done via Hub chain\n */\n async registerSession(_params: RegisterSessionParams): Promise<void> {\n throw new Error(\n 'Session registration must be performed on the Hub chain (Base). ' +\n 'Use EVMClient connected to the Hub to call registerSession().'\n );\n }\n\n /**\n * Revoke a session key on the Hub (must be called via Hub client)\n * \n * @throws Error - Session management must be done via Hub chain\n */\n async revokeSession(_params: RevokeSessionParams): Promise<void> {\n throw new Error(\n 'Session revocation must be performed on the Hub chain (Base). ' +\n 'Use EVMClient connected to the Hub to call revokeSession().'\n );\n }\n\n /**\n * Check if a session is active by querying the Hub\n * This method queries the Hub contract directly for session validation\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @param sessionKeyHash - Hash of session key to validate\n * @returns Session validation result with expiry and limits\n */\n async isSessionActive(\n _userKeyHash: string,\n _sessionKeyHash: string\n ): Promise<SessionValidationResult> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for session validation. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for session status\n throw new Error(\n 'isSessionActive requires Hub client integration. ' +\n 'Use EVMClient.isSessionActive() on the Hub chain, ' +\n 'then pass the result to session execution on Starknet.'\n );\n }\n\n /**\n * Get all sessions for a user from the Hub\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @returns Array of all sessions (active and expired/revoked)\n */\n async getUserSessions(userKeyHash: string): Promise<SessionKey[]> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for session queries. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for user sessions\n throw new Error(\n 'getUserSessions requires Hub client integration. ' +\n 'Use EVMClient.getUserSessions() on the Hub chain. ' +\n `User: ${userKeyHash}`\n );\n }\n\n // ========================================================================\n // Query-Based Execution (Issue #9/#10)\n // ========================================================================\n\n /**\n * Get user state from Hub (comprehensive state query)\n * Returns key hash, nonce, and last action hash for CCQ validation\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @returns User state with nonce and last action hash\n */\n async getUserState(userKeyHash: string): Promise<{\n keyHash: string;\n nonce: bigint;\n lastActionHash: string;\n }> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for state queries. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for user state\n throw new Error(\n 'getUserState requires Hub client integration. ' +\n 'Use EVMClient.getUserState() on the Hub chain. ' +\n `User: ${userKeyHash}`\n );\n }\n\n /**\n * Get user's last action hash from Hub\n * Used for optimistic execution and nonce validation\n * \n * @param userKeyHash - Hash of user's Passkey public key\n * @returns Last action hash (zero hash if no actions)\n */\n async getUserLastActionHash(userKeyHash: string): Promise<string> {\n if (!this.hubRpcUrl || !this.hubContractAddress) {\n throw new Error(\n 'Hub configuration required for action hash queries. ' +\n 'Provide hubRpcUrl and hubContractAddress in StarknetClientConfig.'\n );\n }\n\n // Query Hub contract for last action hash\n throw new Error(\n 'getUserLastActionHash requires Hub client integration. ' +\n 'Use EVMClient.getUserLastActionHash() on the Hub chain. ' +\n `User: ${userKeyHash}`\n );\n }\n\n /**\n * Execute with query-based validation (faster than VAA, ~23s vs 60-90s)\n * Uses Wormhole CCQ to validate Hub state, then executes on Starknet\n * \n * @param params Query execution parameters with CCQ response\n * @returns Dispatch result with transaction hash\n * \n * @remarks\n * Query-based execution flow:\n * 1. Query Hub state via Wormhole CCQ\n * 2. Validate Guardian signatures on query response\n * 3. Execute on Starknet with validated state\n * 4. Hub state must be < 60s stale (enforced by QueryVerifier)\n */\n async executeWithQuery(\n _params: {\n userKeyHash: string;\n queryResponse: Uint8Array; // CCQ Guardian response\n actionType: number;\n actionPayload: Uint8Array;\n relayerUrl?: string;\n }\n ): Promise<DispatchResult> {\n throw new Error(\n 'Query-based execution on Starknet requires relayer integration. ' +\n 'Use relayer API to submit query-validated transactions. ' +\n 'Relayer will call veridex_spoke::execute_with_query on Starknet.'\n );\n }\n\n // ========================================================================\n // Internal helpers\n // ========================================================================\n\n private computeKeyHash(publicKeyX: bigint, publicKeyY: bigint): string {\n const xHex = publicKeyX.toString(16).padStart(64, '0');\n const yHex = publicKeyY.toString(16).padStart(64, '0');\n const combined = Buffer.from(xHex + yHex, 'hex');\n const hash = createHash('sha256').update(combined).digest('hex');\n return '0x' + hash;\n }\n\n // ============================================================================\n // Social Recovery Methods (Issue #23)\n // ============================================================================\n // \n // Note: Social recovery is managed on the Hub chain (EVM).\n // Starknet spokes receive and execute recovery VAAs broadcast from the Hub.\n // The relayer service handles submitting recovery transactions to Starknet.\n //\n // SDK users should use EVMClient methods for guardian management and\n // recovery initiation on the Hub chain.\n // ============================================================================\n\n /**\n * Get vault address by owner key hash\n * \n * @param ownerKeyHash - Owner's passkey hash\n * @returns Vault address on Starknet (felt252 as hex string)\n */\n async getVaultAddress(ownerKeyHash: string): Promise<string | null> {\n try {\n const spokeAddress = this.config.contracts.hub;\n if (!spokeAddress) {\n throw new Error('Spoke contract address not configured');\n }\n\n // Starknet spoke expects u256 (low, high) format for keyHash\n const [low, high] = toStarknetU256(ownerKeyHash);\n\n // Call get_vault on spoke contract with u256 split into [low, high]\n const result = await this.provider.callContract({\n contractAddress: spokeAddress,\n entrypoint: 'get_vault',\n calldata: [low, high],\n });\n\n // result[0] is the vault address (0 if not found)\n const vaultAddress = result[0];\n if (vaultAddress === '0x0' || vaultAddress === '0') {\n return null;\n }\n\n return vaultAddress;\n } catch (error) {\n console.error('Error getting vault address:', error);\n return null;\n }\n }\n\n /**\n * Check if vault exists and get basic info\n * \n * @param ownerKeyHash - Owner's passkey hash \n * @returns Vault info or null if not found\n */\n async getVaultInfo(ownerKeyHash: string): Promise<{\n address: string;\n ownerKeyHash: string;\n } | null> {\n const vaultAddress = await this.getVaultAddress(ownerKeyHash);\n if (!vaultAddress) {\n return null;\n }\n\n return {\n address: vaultAddress,\n ownerKeyHash,\n };\n }\n\n /**\n * Check if spoke contract is paused\n * \n * @returns Whether the protocol is paused\n */\n async isProtocolPaused(): Promise<boolean> {\n try {\n const spokeAddress = this.config.contracts.hub;\n if (!spokeAddress) {\n throw new Error('Spoke contract address not configured');\n }\n\n const result = await this.provider.callContract({\n contractAddress: spokeAddress,\n entrypoint: 'is_paused',\n calldata: [],\n });\n\n return result[0] === '0x1' || result[0] === '1';\n } catch (error) {\n console.error('Error checking pause status:', error);\n return false;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -67,9 +67,9 @@ var CHAIN_PRESETS = {
|
|
|
67
67
|
explorerUrl: "https://sepolia.basescan.org",
|
|
68
68
|
isEvm: true,
|
|
69
69
|
contracts: {
|
|
70
|
-
hub: "
|
|
71
|
-
vaultFactory: "
|
|
72
|
-
vaultImplementation: "
|
|
70
|
+
hub: "0xD5D29b6EaeE6FF4b765e704298a7e48D22607059",
|
|
71
|
+
vaultFactory: "0xb25b73D5FeD5693dcd1Bb78f8e33387B59A022EC",
|
|
72
|
+
vaultImplementation: "0x2CB8397df988c1880d9e5cFfF65bfC22D7D90EE6",
|
|
73
73
|
wormholeCoreBridge: "0x79A1027a6A159502049F10906D333EC57E95F083",
|
|
74
74
|
tokenBridge: "0x86F55A04690fd7815A3D802bD587e83eA888B239"
|
|
75
75
|
}
|
|
@@ -103,8 +103,8 @@ var CHAIN_PRESETS = {
|
|
|
103
103
|
explorerUrl: "https://sepolia-optimism.etherscan.io",
|
|
104
104
|
isEvm: true,
|
|
105
105
|
contracts: {
|
|
106
|
-
vaultFactory: "
|
|
107
|
-
vaultImplementation: "
|
|
106
|
+
vaultFactory: "0x3c5e4aCdC8Cd53ae5ae603B4c511885191fBb868",
|
|
107
|
+
vaultImplementation: "0xA45dBF322c5A3028687fEEB161603d3BCe02e119",
|
|
108
108
|
wormholeCoreBridge: "0x31377888146f3253211EFEf5c676D41ECe7D58Fe",
|
|
109
109
|
tokenBridge: "0x99737Ec4B815d816c49A385943baf0380e75c0Ac"
|
|
110
110
|
}
|
|
@@ -137,8 +137,8 @@ var CHAIN_PRESETS = {
|
|
|
137
137
|
explorerUrl: "https://sepolia.arbiscan.io",
|
|
138
138
|
isEvm: true,
|
|
139
139
|
contracts: {
|
|
140
|
-
vaultFactory: "
|
|
141
|
-
vaultImplementation: "
|
|
140
|
+
vaultFactory: "0xB9C3e6bad3c6f26956be4a4bb5a366376Fd3045D",
|
|
141
|
+
vaultImplementation: "0x8601881b94B68B09b485f407317686103d3CB681",
|
|
142
142
|
wormholeCoreBridge: "0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35",
|
|
143
143
|
tokenBridge: "0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e"
|
|
144
144
|
}
|
|
@@ -171,8 +171,8 @@ var CHAIN_PRESETS = {
|
|
|
171
171
|
explorerUrl: "https://sepolia.etherscan.io",
|
|
172
172
|
isEvm: true,
|
|
173
173
|
contracts: {
|
|
174
|
-
vaultFactory: "
|
|
175
|
-
vaultImplementation: "
|
|
174
|
+
vaultFactory: "0x265c10763B4d16AD970bC3d7670c645e37f63AF4",
|
|
175
|
+
vaultImplementation: "0x942426C94652ebC48f4f404928016B95ADb1DA25",
|
|
176
176
|
wormholeCoreBridge: "0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78",
|
|
177
177
|
tokenBridge: "0xDB5492265f6038831E89f495670FF909aDe94bd9"
|
|
178
178
|
}
|
|
@@ -585,7 +585,7 @@ var CHAIN_PRESETS = {
|
|
|
585
585
|
explorerUrl: "https://explorer.solana.com",
|
|
586
586
|
isEvm: false,
|
|
587
587
|
contracts: {
|
|
588
|
-
hub: "
|
|
588
|
+
hub: "64ZZBdmGd1YT6Fok7PELvAdfoXyR4PHxHnRqHNqZHJ13",
|
|
589
589
|
wormholeCoreBridge: "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5",
|
|
590
590
|
tokenBridge: "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe"
|
|
591
591
|
}
|
|
@@ -618,7 +618,7 @@ var CHAIN_PRESETS = {
|
|
|
618
618
|
explorerUrl: "https://explorer.aptoslabs.com",
|
|
619
619
|
isEvm: false,
|
|
620
620
|
contracts: {
|
|
621
|
-
hub: "
|
|
621
|
+
hub: "0x9e8641143245ab8b93af1417a1fbc698d40fd351a25f6c17e4210e59bf82c9c7",
|
|
622
622
|
wormholeCoreBridge: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
|
|
623
623
|
tokenBridge: "0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f"
|
|
624
624
|
}
|
|
@@ -651,7 +651,7 @@ var CHAIN_PRESETS = {
|
|
|
651
651
|
explorerUrl: "https://suiscan.xyz/testnet",
|
|
652
652
|
isEvm: false,
|
|
653
653
|
contracts: {
|
|
654
|
-
hub: "
|
|
654
|
+
hub: "0xaf36d8bc349883b23e78b00a342a656c799319508600583eaee9121ffaa7f5f7",
|
|
655
655
|
wormholeCoreBridge: "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
|
|
656
656
|
}
|
|
657
657
|
},
|
|
@@ -683,8 +683,8 @@ var CHAIN_PRESETS = {
|
|
|
683
683
|
explorerUrl: "https://sepolia.starkscan.co",
|
|
684
684
|
isEvm: false,
|
|
685
685
|
contracts: {
|
|
686
|
-
hub: "
|
|
687
|
-
wormholeCoreBridge: "
|
|
686
|
+
hub: "0x7bb7cbe7d82e910b296611b582035a207343431f98bdd7b692bddfdd6f28737",
|
|
687
|
+
wormholeCoreBridge: "0x30d2e7f26dc75819cfddcd7caa26a76b681d5918f219c99060c42ce1e3f69e4"
|
|
688
688
|
},
|
|
689
689
|
hubChainId: 10004
|
|
690
690
|
// Base Sepolia
|
|
@@ -720,13 +720,13 @@ var CHAIN_PRESETS = {
|
|
|
720
720
|
isEvm: false,
|
|
721
721
|
contracts: {
|
|
722
722
|
// Spoke contract: identity + session management
|
|
723
|
-
hub: "
|
|
723
|
+
hub: "STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-spoke",
|
|
724
724
|
// Vault contract: STX/sBTC custody
|
|
725
|
-
vaultFactory: "
|
|
725
|
+
vaultFactory: "STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-vault",
|
|
726
726
|
wormholeCoreBridge: "",
|
|
727
727
|
// Phase 2: Wormhole integration contracts
|
|
728
|
-
wormholeVerifier: "
|
|
729
|
-
vaultVaa: "
|
|
728
|
+
wormholeVerifier: "STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-wormhole-verifier",
|
|
729
|
+
vaultVaa: "STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-vault-vaa"
|
|
730
730
|
},
|
|
731
731
|
hubChainId: 10004
|
|
732
732
|
// Base Sepolia
|
|
@@ -854,4 +854,4 @@ export {
|
|
|
854
854
|
isHubChain,
|
|
855
855
|
getDefaultHub
|
|
856
856
|
};
|
|
857
|
-
//# sourceMappingURL=chunk-
|
|
857
|
+
//# sourceMappingURL=chunk-ZXMTPBSP.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/featureFlags.ts","../src/presets.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Feature Flags\n * \n * Centralized feature flag management for toggling SDK capabilities.\n * These flags allow operators to enable/disable features at runtime,\n * which is critical for:\n * - Hackathon demos (Avalanche Build Games: single hub for simplicity)\n * - Enterprise deployments (controlled rollout of multi-hub)\n * - Compliance (restrict routing to audited chains only)\n * \n * ## Multi-Hub Feature\n * \n * When `multiHub` is **disabled** (default):\n * - Only the primary hub chain (Base) is used for identity and session management\n * - `getHubChains()` returns only `['base']`\n * - `getDefaultHub()` returns Base config\n * - Avalanche operates as a spoke chain (payments only, identity on Base)\n * \n * When `multiHub` is **enabled**:\n * - All chains marked `canBeHub: true` are available as hubs\n * - `getHubChains()` returns all hub-capable chains\n * - `getDefaultHub()` can be overridden to point at any hub chain\n * - Avalanche can operate as a secondary hub with its own identity registry\n * \n * ## Enterprise Risk Alignment\n * \n * Feature flags enable the \"Enterprise Trust Firewall\" narrative:\n * - Single hub = single source of truth = simpler audit trail\n * - Multi-hub = horizontal scaling for enterprise multi-region deployments\n * - Trace logging integration points are hub-aware\n * \n * @example\n * ```typescript\n * import { setFeatureFlags, getFeatureFlags } from '@veridex/sdk';\n * \n * // Disable multi-hub (default for hackathon demos)\n * setFeatureFlags({ multiHub: false });\n * \n * // Enable multi-hub for enterprise deployment\n * setFeatureFlags({ multiHub: true });\n * \n * // Check current flags\n * const flags = getFeatureFlags();\n * console.log(flags.multiHub); // false\n * ```\n */\n\nimport type { ChainName } from './presets.js';\n\n// ============================================================================\n// Feature Flag Types\n// ============================================================================\n\nexport interface FeatureFlags {\n /**\n * Enable multi-hub architecture.\n * \n * When false (default), only 'base' is treated as a hub chain.\n * When true, all chains with `canBeHub: true` in presets are available.\n * \n * @default false\n */\n multiHub: boolean;\n\n /**\n * Primary hub chain override.\n * \n * When multiHub is false, this is ignored (always 'base').\n * When multiHub is true, this sets the preferred hub chain.\n * \n * @default 'base'\n */\n primaryHub: ChainName;\n}\n\n// ============================================================================\n// Default Flags\n// ============================================================================\n\nconst DEFAULT_FLAGS: FeatureFlags = {\n multiHub: false,\n primaryHub: 'base' as ChainName,\n};\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet _flags: FeatureFlags = { ...DEFAULT_FLAGS };\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Get current feature flags (immutable copy).\n */\nexport function getFeatureFlags(): Readonly<FeatureFlags> {\n return { ..._flags };\n}\n\n/**\n * Set feature flags. Merges with current flags.\n * \n * @param flags - Partial flags to merge\n * \n * @example\n * ```typescript\n * // Enable multi-hub\n * setFeatureFlags({ multiHub: true });\n * \n * // Set Avalanche as primary hub\n * setFeatureFlags({ multiHub: true, primaryHub: 'avalanche' });\n * ```\n */\nexport function setFeatureFlags(flags: Partial<FeatureFlags>): void {\n _flags = { ..._flags, ...flags };\n}\n\n/**\n * Reset feature flags to defaults.\n * Useful for testing and cleanup.\n */\nexport function resetFeatureFlags(): void {\n _flags = { ...DEFAULT_FLAGS };\n}\n\n/**\n * Check if multi-hub is enabled.\n * Convenience function used throughout the SDK.\n */\nexport function isMultiHubEnabled(): boolean {\n return _flags.multiHub;\n}\n\n/**\n * Get the effective primary hub chain name.\n * \n * When multiHub is false, always returns 'base'.\n * When multiHub is true, returns the configured primaryHub.\n */\nexport function getEffectivePrimaryHub(): ChainName {\n if (!_flags.multiHub) {\n return 'base' as ChainName;\n }\n return _flags.primaryHub;\n}\n","/**\n * Veridex Protocol SDK - Chain Presets\n * \n * Pre-configured chain settings for easy SDK initialization.\n * Developers only need to specify chain name and network type.\n * \n * @example\n * ```typescript\n * import { createSDK } from '@veridex/sdk';\n * \n * // Simple initialization - testnet by default\n * const sdk = await createSDK('base');\n * \n * // Or specify mainnet\n * const mainnetSdk = await createSDK('base', { network: 'mainnet' });\n * ```\n */\n\nimport type { ChainConfig } from './types.js';\nimport { isMultiHubEnabled, getEffectivePrimaryHub } from './featureFlags.js';\n\n// ============================================================================\n// Supported Chain Names\n// ============================================================================\n\n/**\n * All supported chain names for easy reference\n */\nexport const CHAIN_NAMES = {\n // EVM L2s (Hub-capable)\n BASE: 'base',\n OPTIMISM: 'optimism',\n ARBITRUM: 'arbitrum',\n SCROLL: 'scroll',\n BLAST: 'blast',\n MANTLE: 'mantle',\n \n // EVM L1s\n ETHEREUM: 'ethereum',\n POLYGON: 'polygon',\n BSC: 'bsc',\n AVALANCHE: 'avalanche',\n FANTOM: 'fantom',\n CELO: 'celo',\n MOONBEAM: 'moonbeam',\n \n // EVM L1s (High Performance)\n MONAD: 'monad',\n \n // Non-EVM\n SOLANA: 'solana',\n APTOS: 'aptos',\n SUI: 'sui',\n STARKNET: 'starknet',\n STACKS: 'stacks',\n NEAR: 'near',\n SEI: 'sei',\n} as const;\n\nexport type ChainName = typeof CHAIN_NAMES[keyof typeof CHAIN_NAMES];\nexport type NetworkType = 'mainnet' | 'testnet';\n\n// ============================================================================\n// Chain Preset Interface\n// ============================================================================\n\nexport interface ChainPreset {\n /** Human-readable chain name */\n displayName: string;\n /** Chain type for client selection */\n type: 'evm' | 'solana' | 'aptos' | 'sui' | 'starknet' | 'stacks' | 'near' | 'cosmos';\n /** Whether this chain can be a hub */\n canBeHub: boolean;\n /** Testnet configuration */\n testnet: ChainConfig;\n /** Mainnet configuration */\n mainnet: ChainConfig;\n}\n\n// ============================================================================\n// EVM Chain Presets\n// ============================================================================\n\nexport const CHAIN_PRESETS: Record<ChainName, ChainPreset> = {\n // ────────────────────────────────────────────────────────────────────────\n // BASE - Primary Hub Chain\n // ────────────────────────────────────────────────────────────────────────\n base: {\n displayName: 'Base',\n type: 'evm',\n canBeHub: true,\n testnet: {\n name: 'Base Sepolia',\n chainId: 84532,\n wormholeChainId: 10004,\n rpcUrl: 'https://sepolia.base.org',\n explorerUrl: 'https://sepolia.basescan.org',\n isEvm: true,\n contracts: {\n hub: '0x23a39c294891703146c3607e1FEEB5Fe78F7F28d',\n vaultFactory: '0x31e8dc9428575334739754Ab2bdB0E8b9Dc707FD',\n vaultImplementation: '0xD65E996CD6d5B01689dc54ad30B51f1D88a100f5',\n wormholeCoreBridge: '0x79A1027a6A159502049F10906D333EC57E95F083',\n tokenBridge: '0x86F55A04690fd7815A3D802bD587e83eA888B239',\n },\n },\n mainnet: {\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 // TODO: Deploy mainnet contracts\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // OPTIMISM - Secondary Hub / Spoke\n // ────────────────────────────────────────────────────────────────────────\n optimism: {\n displayName: 'Optimism',\n type: 'evm',\n canBeHub: true,\n testnet: {\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: '0x347feeaBB5655a7a80b56D8D554DA30BE6c28225',\n vaultImplementation: '0x26C4FD8fC66150ef5964562F7A69271fB0cd02A4',\n wormholeCoreBridge: '0x31377888146f3253211EFEf5c676D41ECe7D58Fe',\n tokenBridge: '0x99737Ec4B815d816c49A385943baf0380e75c0Ac',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // ARBITRUM\n // ────────────────────────────────────────────────────────────────────────\n arbitrum: {\n displayName: 'Arbitrum',\n type: 'evm',\n canBeHub: true,\n testnet: {\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: '0x708eEE22621A64CDF51d98d3e8D97902D7dF52dD',\n vaultImplementation: '0x9f74Dc14A98E59df7AEC5571a2B9E329153dF5Cd',\n wormholeCoreBridge: '0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35',\n tokenBridge: '0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // ETHEREUM\n // ────────────────────────────────────────────────────────────────────────\n ethereum: {\n displayName: 'Ethereum',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Sepolia',\n chainId: 11155111,\n wormholeChainId: 10002,\n rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n explorerUrl: 'https://sepolia.etherscan.io',\n isEvm: true,\n contracts: {\n vaultFactory: '0x52a6dc19C11b3B53B434Fc7f6D31F8b62ed18F0a',\n vaultImplementation: '0xfab72dd1fd3AD79f738B49506f32251B60c95f01',\n wormholeCoreBridge: '0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78',\n tokenBridge: '0xDB5492265f6038831E89f495670FF909aDe94bd9',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // POLYGON\n // ────────────────────────────────────────────────────────────────────────\n polygon: {\n displayName: 'Polygon',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Polygon Amoy',\n chainId: 80002,\n wormholeChainId: 10007,\n rpcUrl: 'https://rpc-amoy.polygon.technology',\n explorerUrl: 'https://amoy.polygonscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x0CBE91CF822c73C2315FB05100C2F714765d5c20',\n tokenBridge: '0x0290FB167208Af455bB137780163b7B7a9a10C16',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // BSC\n // ────────────────────────────────────────────────────────────────────────\n bsc: {\n displayName: 'BNB Chain',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'BSC Testnet',\n chainId: 97,\n wormholeChainId: 4,\n rpcUrl: 'https://data-seed-prebsc-1-s1.binance.org:8545',\n explorerUrl: 'https://testnet.bscscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x68605AD7b15c732a30b1BbC62BE8F2A509D74b4D',\n tokenBridge: '0x9dcF9D205C9De35334D646BeE44b2D2859712A09',\n },\n },\n mainnet: {\n name: 'BNB Chain',\n chainId: 56,\n wormholeChainId: 4,\n rpcUrl: 'https://bsc-dataseed.binance.org',\n explorerUrl: 'https://bscscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B',\n tokenBridge: '0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // AVALANCHE — ACP-204 Native P-256 + ICM Teleporter + Hub-Capable\n // ────────────────────────────────────────────────────────────────────────\n avalanche: {\n displayName: 'Avalanche',\n type: 'evm',\n canBeHub: true, // ACP-204 provides native P-256 at 0x0100 (6,900 gas)\n testnet: {\n name: 'Avalanche Fuji',\n chainId: 43113,\n wormholeChainId: 6,\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n explorerUrl: 'https://testnet.snowtrace.io',\n isEvm: true,\n contracts: {\n // Veridex Hub (deployed via deploy-avalanche.ts)\n hub: '', // No Hub on Fuji — Hub is on Base Sepolia\n vaultFactory: '0x9e9716442e908A9b61F11432cC38024DD390cd2a',\n vaultImplementation: '0xE0b9919ffDf3415355Db369C8FfA5Dd4e000052c',\n // Wormhole bridges (canonical Fuji addresses)\n wormholeCoreBridge: '0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C',\n tokenBridge: '0x61E44E506Ca5659E6c0bba9b678586fA2d729756',\n // Avalanche-specific: ACP-204 P-256 verifier wrapper\n p256Verifier: '0xB5d29EA1E2e90A24D6506E2a6a269506a12974CC',\n // Avalanche-specific: ICM Spoke for cross-L1 session bridging\n icmSpoke: '0x9fCFC608086539A69839EfA9628884dB75ac07D0',\n // Chainlink price feeds (Fuji testnet)\n chainlinkAvaxUsd: '0x5498BB86BC934c8D34FDA08E81D444153d0D06aD',\n chainlinkUsdcUsd: '0x7898AcCC83587C3C55116c5230C17a6Cd9C71bad',\n chainlinkUsdtUsd: '0x7898AcCC83587C3C55116c5230C17a6Cd9C71bad',\n },\n hubChainId: 10004, // Base Sepolia (primary Hub)\n },\n mainnet: {\n name: 'Avalanche',\n chainId: 43114,\n wormholeChainId: 6,\n rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',\n explorerUrl: 'https://snowtrace.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x54a8e5f9c4CbA08F9943965859F6c34eAF03E26c',\n tokenBridge: '0x0e082F06FF657D94310cB8cE8B0D9a04541d8052',\n // Chainlink price feeds (Avalanche mainnet)\n chainlinkAvaxUsd: '0x0A77230d17318075983913bC2145DB16C7366156',\n chainlinkUsdcUsd: '0xF096872672F44d6EBA71458D74fe67F9a77a23B9',\n chainlinkUsdtUsd: '0xEBE676ee90Fe1112671f19b6B7459bC678B67e8a',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // SCROLL\n // ────────────────────────────────────────────────────────────────────────\n scroll: {\n displayName: 'Scroll',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Scroll Sepolia',\n chainId: 534351,\n wormholeChainId: 34,\n rpcUrl: 'https://sepolia-rpc.scroll.io',\n explorerUrl: 'https://sepolia.scrollscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x055F47F1250012C6B20c436570a76e52c17Af2D5',\n tokenBridge: '0x22427d90B7dA3fA4642F7025A854c7254E4e45BF',\n },\n },\n mainnet: {\n name: 'Scroll',\n chainId: 534352,\n wormholeChainId: 34,\n rpcUrl: 'https://rpc.scroll.io',\n explorerUrl: 'https://scrollscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // BLAST\n // ────────────────────────────────────────────────────────────────────────\n blast: {\n displayName: 'Blast',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Blast Sepolia',\n chainId: 168587773,\n wormholeChainId: 36,\n rpcUrl: 'https://sepolia.blast.io',\n explorerUrl: 'https://sepolia.blastscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x473e002D7add6fB67a4964F13bFd61280Ca46886',\n tokenBridge: '0x430855B4D43b8AEB9D2B9869B74d58dda79C0dB2',\n },\n },\n mainnet: {\n name: 'Blast',\n chainId: 81457,\n wormholeChainId: 36,\n rpcUrl: 'https://rpc.blast.io',\n explorerUrl: 'https://blastscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // MANTLE\n // ────────────────────────────────────────────────────────────────────────\n mantle: {\n displayName: 'Mantle',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Mantle Sepolia',\n chainId: 5003,\n wormholeChainId: 35,\n rpcUrl: 'https://rpc.sepolia.mantle.xyz',\n explorerUrl: 'https://sepolia.mantlescan.xyz',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x376428e7f26D5867e69201b275553C45B09EE090',\n tokenBridge: '0x75Bfa155a9D7A3714b0861c8a8aF0C4633c45b5D',\n },\n },\n mainnet: {\n name: 'Mantle',\n chainId: 5000,\n wormholeChainId: 35,\n rpcUrl: 'https://rpc.mantle.xyz',\n explorerUrl: 'https://mantlescan.xyz',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // FANTOM\n // ────────────────────────────────────────────────────────────────────────\n fantom: {\n displayName: 'Fantom',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Fantom Testnet',\n chainId: 4002,\n wormholeChainId: 10,\n rpcUrl: 'https://rpc.testnet.fantom.network',\n explorerUrl: 'https://testnet.ftmscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x1BB3B4119b7BA9dfad76B0545fb3F531383c3bB7',\n tokenBridge: '0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8',\n },\n },\n mainnet: {\n name: 'Fantom',\n chainId: 250,\n wormholeChainId: 10,\n rpcUrl: 'https://rpcapi.fantom.network',\n explorerUrl: 'https://ftmscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x126783A6Cb203a3E35344528B26ca3a0489a1485',\n tokenBridge: '0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // CELO\n // ────────────────────────────────────────────────────────────────────────\n celo: {\n displayName: 'Celo',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Celo Alfajores',\n chainId: 44787,\n wormholeChainId: 14,\n rpcUrl: 'https://alfajores-forno.celo-testnet.org',\n explorerUrl: 'https://alfajores.celoscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56',\n tokenBridge: '0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153',\n },\n },\n mainnet: {\n name: 'Celo',\n chainId: 42220,\n wormholeChainId: 14,\n rpcUrl: 'https://forno.celo.org',\n explorerUrl: 'https://celoscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xa321448d90d4e5b0A732867c18eA198e75CAC48E',\n tokenBridge: '0x796Dff6D74F3E27060B71255Fe517BFb23C93eed',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // MOONBEAM\n // ────────────────────────────────────────────────────────────────────────\n moonbeam: {\n displayName: 'Moonbeam',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Moonbase Alpha',\n chainId: 1287,\n wormholeChainId: 16,\n rpcUrl: 'https://rpc.api.moonbase.moonbeam.network',\n explorerUrl: 'https://moonbase.moonscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xa5B7D85a8f27dd7907dc8FdC21FA5657D5E2F901',\n tokenBridge: '0xbc976D4b9D57E57c3cA52e1Fd136C45FF7955A96',\n },\n },\n mainnet: {\n name: 'Moonbeam',\n chainId: 1284,\n wormholeChainId: 16,\n rpcUrl: 'https://rpc.api.moonbeam.network',\n explorerUrl: 'https://moonscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xC8e2b0cD52Cf01b0Ce87d389Daa3d414d4cE29f3',\n tokenBridge: '0xb1731c586ca89a23809861c6103F0b96B3F57D92',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // MONAD - High-Performance L1 with EIP-7951 P256 + Agent Gateway\n // ────────────────────────────────────────────────────────────────────────\n monad: {\n displayName: 'Monad',\n type: 'evm',\n canBeHub: true, // Has native P-256 precompile (EIP-7951)\n testnet: {\n name: 'Monad Testnet',\n chainId: 10143,\n wormholeChainId: 10048,\n rpcUrl: 'https://testnet-rpc.monad.xyz',\n explorerUrl: 'https://testnet.monadvision.com',\n isEvm: true,\n contracts: {\n vaultFactory: '0x50F2c37584823A6cc293bd0d7647D558d05CA4C1',\n vaultImplementation: '0x53d4D3943d0E524836f0B1955AbB216449F538fF',\n wormholeCoreBridge: '0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd',\n // Agent Gateway contracts\n serviceDirectory: '0x2d20f29E1f5B24294B3F125B47f2a22a7012a35E',\n },\n hubChainId: 10004, // Base Sepolia\n },\n mainnet: {\n name: 'Monad',\n chainId: 143,\n wormholeChainId: 0, // TBD\n rpcUrl: 'https://rpc.monad.xyz',\n explorerUrl: 'https://monadscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x194B123c5E96B9b2E49763619985790Dc241CAC0',\n tokenBridge: '0x0B2719cdA2F10595369e6673ceA3Ee2EDFa13BA7',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // SEI\n // ────────────────────────────────────────────────────────────────────────\n sei: {\n displayName: 'Sei',\n type: 'evm',\n canBeHub: false,\n testnet: {\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',\n },\n },\n mainnet: {\n name: 'Sei',\n chainId: 1329,\n wormholeChainId: 32,\n rpcUrl: 'https://evm-rpc.sei-apis.com',\n explorerUrl: 'https://seitrace.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x0000000000000000000000000000000000000000',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // SOLANA\n // ────────────────────────────────────────────────────────────────────────\n solana: {\n displayName: 'Solana',\n type: 'solana',\n canBeHub: false,\n testnet: {\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 mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // APTOS\n // ────────────────────────────────────────────────────────────────────────\n aptos: {\n displayName: 'Aptos',\n type: 'aptos',\n canBeHub: false,\n testnet: {\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: '0x2935e5d434c383c8f8b8af3b9596aa78b7238c308b5b0fe2bbd19e248b6f018f',\n wormholeCoreBridge: '0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625',\n tokenBridge: '0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // SUI\n // ────────────────────────────────────────────────────────────────────────\n sui: {\n displayName: 'Sui',\n type: 'sui',\n canBeHub: false,\n testnet: {\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: '0x7f6b9a3f9dba7ac6b20d180a9274f525c23a2a9f7e5445218c595c3696c55667',\n wormholeCoreBridge: '0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790',\n },\n },\n mainnet: {\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 // STARKNET\n // ────────────────────────────────────────────────────────────────────────\n starknet: {\n displayName: 'Starknet',\n type: 'starknet',\n canBeHub: false,\n testnet: {\n name: 'Starknet Sepolia',\n chainId: 0,\n wormholeChainId: 50001, // Custom bridge (non-Wormhole)\n rpcUrl: 'https://starknet-sepolia-rpc.publicnode.com',\n explorerUrl: 'https://sepolia.starkscan.co',\n isEvm: false,\n contracts: {\n hub: '0x46139177b8a1d7187cf35fbcddca637882a1d6f50d91f048c59d1322eee9ede',\n wormholeCoreBridge: '0x700488242f8f03248b2311edddc394f0408a18c36181446eabd265067809c83',\n },\n hubChainId: 10004, // Base Sepolia\n },\n mainnet: {\n name: 'Starknet',\n chainId: 0,\n wormholeChainId: 50001,\n rpcUrl: 'https://starknet-mainnet.public.blastapi.io/rpc/v0_7',\n explorerUrl: 'https://starkscan.co',\n isEvm: false,\n contracts: {\n // TODO: Deploy mainnet contracts\n wormholeCoreBridge: '',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // STACKS\n // ────────────────────────────────────────────────────────────────────────\n stacks: {\n displayName: 'Stacks',\n type: 'stacks',\n canBeHub: false,\n testnet: {\n name: 'Stacks Testnet',\n chainId: 2147483648, // CAIP-2: stacks:2147483648\n wormholeChainId: 60, // Official Wormhole chain ID for Stacks\n rpcUrl: 'https://api.testnet.hiro.so',\n explorerUrl: 'https://explorer.hiro.so/?chain=testnet',\n isEvm: false,\n contracts: {\n // Spoke contract: identity + session management\n hub: 'ST398EE8PHNSACV2M9F5MYVVBSDS4ZZ0S44WCJ6KR.veridex-spoke',\n // Vault contract: STX/sBTC custody\n vaultFactory: 'ST398EE8PHNSACV2M9F5MYVVBSDS4ZZ0S44WCJ6KR.veridex-vault',\n wormholeCoreBridge: '',\n // Phase 2: Wormhole integration contracts\n wormholeVerifier: 'ST398EE8PHNSACV2M9F5MYVVBSDS4ZZ0S44WCJ6KR.veridex-wormhole-verifier',\n vaultVaa: 'ST398EE8PHNSACV2M9F5MYVVBSDS4ZZ0S44WCJ6KR.veridex-vault-vaa',\n },\n hubChainId: 10004, // Base Sepolia\n },\n mainnet: {\n name: 'Stacks',\n chainId: 1, // CAIP-2: stacks:1\n wormholeChainId: 60,\n rpcUrl: 'https://api.hiro.so',\n explorerUrl: 'https://explorer.hiro.so',\n isEvm: false,\n contracts: {\n // TODO: Deploy mainnet contracts\n wormholeCoreBridge: '',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // NEAR\n // ────────────────────────────────────────────────────────────────────────\n near: {\n displayName: 'Near',\n type: 'near',\n canBeHub: false,\n testnet: {\n name: 'Near Testnet',\n chainId: 0,\n wormholeChainId: 15,\n rpcUrl: 'https://rpc.testnet.near.org',\n explorerUrl: 'https://explorer.testnet.near.org',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: 'wormhole.wormhole.testnet',\n tokenBridge: 'token.wormhole.testnet',\n },\n },\n mainnet: {\n name: 'Near',\n chainId: 0,\n wormholeChainId: 15,\n rpcUrl: 'https://rpc.mainnet.near.org',\n explorerUrl: 'https://explorer.near.org',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: 'contract.wormhole_crypto.near',\n tokenBridge: 'contract.portalbridge.near',\n },\n },\n },\n};\n\n// ============================================================================\n// Custom RPC URL Overrides\n// ============================================================================\n\n/**\n * Global RPC URL overrides. Set once at app startup to avoid passing\n * custom URLs to every SDK / client constructor.\n *\n * @example\n * ```typescript\n * import { configureDefaultRpcUrls } from '@veridex/sdk';\n *\n * configureDefaultRpcUrls({\n * starknet: { testnet: 'https://my-starknet-rpc.example.com' },\n * base: { mainnet: 'https://my-base-mainnet.example.com' },\n * });\n * ```\n */\nconst _rpcOverrides: Partial<Record<ChainName, Partial<Record<NetworkType, string>>>> = {};\n\n/**\n * Configure global default RPC URL overrides.\n * These take precedence over the built-in public endpoints but are\n * themselves overridden by per-SDK `rpcUrl` / `rpcUrls` options.\n *\n * Call with an empty object to clear all overrides.\n */\nexport function configureDefaultRpcUrls(\n overrides: Partial<Record<ChainName, Partial<Record<NetworkType, string>>>>\n): void {\n // Clear existing overrides\n for (const key of Object.keys(_rpcOverrides) as ChainName[]) {\n delete _rpcOverrides[key];\n }\n // Apply new overrides\n Object.assign(_rpcOverrides, overrides);\n}\n\n/**\n * Get the current global RPC URL override for a chain + network, if any.\n */\nexport function getRpcUrlOverride(\n chain: ChainName,\n network: NetworkType\n): string | undefined {\n return _rpcOverrides[chain]?.[network];\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get chain configuration by name and network.\n *\n * Returns a copy of the built-in config with any global RPC override applied.\n * Per-SDK overrides (`rpcUrl`, `rpcUrls`) still take priority in the factory.\n */\nexport function getChainConfig(\n chain: ChainName,\n network: NetworkType = 'testnet'\n): ChainConfig {\n const preset = CHAIN_PRESETS[chain];\n if (!preset) {\n throw new Error(\n `Unknown chain: \"${chain}\". Supported chains: ${Object.keys(CHAIN_PRESETS).join(', ')}`\n );\n }\n const config = preset[network];\n const rpcOverride = getRpcUrlOverride(chain, network);\n if (rpcOverride) {\n return { ...config, rpcUrl: rpcOverride };\n }\n return config;\n}\n\n/**\n * Get chain preset by name\n */\nexport function getChainPreset(chain: ChainName): ChainPreset {\n const preset = CHAIN_PRESETS[chain];\n if (!preset) {\n throw new Error(\n `Unknown chain: \"${chain}\". Supported chains: ${Object.keys(CHAIN_PRESETS).join(', ')}`\n );\n }\n return preset;\n}\n\n/**\n * Get all supported chain names\n */\nexport function getSupportedChains(): ChainName[] {\n return Object.keys(CHAIN_PRESETS) as ChainName[];\n}\n\n/**\n * Get hub-capable chains.\n * \n * When multi-hub feature flag is disabled, returns only the primary hub chain ('base').\n * When enabled, returns all chains with canBeHub: true.\n */\nexport function getHubChains(): ChainName[] {\n if (!isMultiHubEnabled()) {\n const primary = getEffectivePrimaryHub();\n return [primary];\n }\n return Object.entries(CHAIN_PRESETS)\n .filter(([_, preset]) => preset.canBeHub)\n .map(([name]) => name as ChainName);\n}\n\n/**\n * Check if chain is supported\n */\nexport function isChainSupported(chain: string): chain is ChainName {\n return chain in CHAIN_PRESETS;\n}\n\n/**\n * Check if a specific chain is currently acting as a hub.\n * \n * When multi-hub is disabled, only the primary hub ('base') returns true.\n * When enabled, any chain with canBeHub: true returns true.\n */\nexport function isHubChain(chain: ChainName): boolean {\n if (!isMultiHubEnabled()) {\n return chain === getEffectivePrimaryHub();\n }\n const preset = CHAIN_PRESETS[chain];\n return preset?.canBeHub ?? false;\n}\n\n/**\n * Get default hub chain.\n * \n * Returns the effective primary hub's config. When multi-hub is disabled,\n * this always returns Base. When enabled, it returns the configured primary hub.\n */\nexport function getDefaultHub(network: NetworkType = 'testnet'): ChainConfig {\n const primary = getEffectivePrimaryHub();\n return CHAIN_PRESETS[primary][network];\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/featureFlags.ts","../src/presets.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Feature Flags\n * \n * Centralized feature flag management for toggling SDK capabilities.\n * These flags allow operators to enable/disable features at runtime,\n * which is critical for:\n * - Hackathon demos (Avalanche Build Games: single hub for simplicity)\n * - Enterprise deployments (controlled rollout of multi-hub)\n * - Compliance (restrict routing to audited chains only)\n * \n * ## Multi-Hub Feature\n * \n * When `multiHub` is **disabled** (default):\n * - Only the primary hub chain (Base) is used for identity and session management\n * - `getHubChains()` returns only `['base']`\n * - `getDefaultHub()` returns Base config\n * - Avalanche operates as a spoke chain (payments only, identity on Base)\n * \n * When `multiHub` is **enabled**:\n * - All chains marked `canBeHub: true` are available as hubs\n * - `getHubChains()` returns all hub-capable chains\n * - `getDefaultHub()` can be overridden to point at any hub chain\n * - Avalanche can operate as a secondary hub with its own identity registry\n * \n * ## Enterprise Risk Alignment\n * \n * Feature flags enable the \"Enterprise Trust Firewall\" narrative:\n * - Single hub = single source of truth = simpler audit trail\n * - Multi-hub = horizontal scaling for enterprise multi-region deployments\n * - Trace logging integration points are hub-aware\n * \n * @example\n * ```typescript\n * import { setFeatureFlags, getFeatureFlags } from '@veridex/sdk';\n * \n * // Disable multi-hub (default for hackathon demos)\n * setFeatureFlags({ multiHub: false });\n * \n * // Enable multi-hub for enterprise deployment\n * setFeatureFlags({ multiHub: true });\n * \n * // Check current flags\n * const flags = getFeatureFlags();\n * console.log(flags.multiHub); // false\n * ```\n */\n\nimport type { ChainName } from './presets.js';\n\n// ============================================================================\n// Feature Flag Types\n// ============================================================================\n\nexport interface FeatureFlags {\n /**\n * Enable multi-hub architecture.\n * \n * When false (default), only 'base' is treated as a hub chain.\n * When true, all chains with `canBeHub: true` in presets are available.\n * \n * @default false\n */\n multiHub: boolean;\n\n /**\n * Primary hub chain override.\n * \n * When multiHub is false, this is ignored (always 'base').\n * When multiHub is true, this sets the preferred hub chain.\n * \n * @default 'base'\n */\n primaryHub: ChainName;\n}\n\n// ============================================================================\n// Default Flags\n// ============================================================================\n\nconst DEFAULT_FLAGS: FeatureFlags = {\n multiHub: false,\n primaryHub: 'base' as ChainName,\n};\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet _flags: FeatureFlags = { ...DEFAULT_FLAGS };\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Get current feature flags (immutable copy).\n */\nexport function getFeatureFlags(): Readonly<FeatureFlags> {\n return { ..._flags };\n}\n\n/**\n * Set feature flags. Merges with current flags.\n * \n * @param flags - Partial flags to merge\n * \n * @example\n * ```typescript\n * // Enable multi-hub\n * setFeatureFlags({ multiHub: true });\n * \n * // Set Avalanche as primary hub\n * setFeatureFlags({ multiHub: true, primaryHub: 'avalanche' });\n * ```\n */\nexport function setFeatureFlags(flags: Partial<FeatureFlags>): void {\n _flags = { ..._flags, ...flags };\n}\n\n/**\n * Reset feature flags to defaults.\n * Useful for testing and cleanup.\n */\nexport function resetFeatureFlags(): void {\n _flags = { ...DEFAULT_FLAGS };\n}\n\n/**\n * Check if multi-hub is enabled.\n * Convenience function used throughout the SDK.\n */\nexport function isMultiHubEnabled(): boolean {\n return _flags.multiHub;\n}\n\n/**\n * Get the effective primary hub chain name.\n * \n * When multiHub is false, always returns 'base'.\n * When multiHub is true, returns the configured primaryHub.\n */\nexport function getEffectivePrimaryHub(): ChainName {\n if (!_flags.multiHub) {\n return 'base' as ChainName;\n }\n return _flags.primaryHub;\n}\n","/**\n * Veridex Protocol SDK - Chain Presets\n * \n * Pre-configured chain settings for easy SDK initialization.\n * Developers only need to specify chain name and network type.\n * \n * @example\n * ```typescript\n * import { createSDK } from '@veridex/sdk';\n * \n * // Simple initialization - testnet by default\n * const sdk = await createSDK('base');\n * \n * // Or specify mainnet\n * const mainnetSdk = await createSDK('base', { network: 'mainnet' });\n * ```\n */\n\nimport type { ChainConfig } from './types.js';\nimport { isMultiHubEnabled, getEffectivePrimaryHub } from './featureFlags.js';\n\n// ============================================================================\n// Supported Chain Names\n// ============================================================================\n\n/**\n * All supported chain names for easy reference\n */\nexport const CHAIN_NAMES = {\n // EVM L2s (Hub-capable)\n BASE: 'base',\n OPTIMISM: 'optimism',\n ARBITRUM: 'arbitrum',\n SCROLL: 'scroll',\n BLAST: 'blast',\n MANTLE: 'mantle',\n \n // EVM L1s\n ETHEREUM: 'ethereum',\n POLYGON: 'polygon',\n BSC: 'bsc',\n AVALANCHE: 'avalanche',\n FANTOM: 'fantom',\n CELO: 'celo',\n MOONBEAM: 'moonbeam',\n \n // EVM L1s (High Performance)\n MONAD: 'monad',\n \n // Non-EVM\n SOLANA: 'solana',\n APTOS: 'aptos',\n SUI: 'sui',\n STARKNET: 'starknet',\n STACKS: 'stacks',\n NEAR: 'near',\n SEI: 'sei',\n} as const;\n\nexport type ChainName = typeof CHAIN_NAMES[keyof typeof CHAIN_NAMES];\nexport type NetworkType = 'mainnet' | 'testnet';\n\n// ============================================================================\n// Chain Preset Interface\n// ============================================================================\n\nexport interface ChainPreset {\n /** Human-readable chain name */\n displayName: string;\n /** Chain type for client selection */\n type: 'evm' | 'solana' | 'aptos' | 'sui' | 'starknet' | 'stacks' | 'near' | 'cosmos';\n /** Whether this chain can be a hub */\n canBeHub: boolean;\n /** Testnet configuration */\n testnet: ChainConfig;\n /** Mainnet configuration */\n mainnet: ChainConfig;\n}\n\n// ============================================================================\n// EVM Chain Presets\n// ============================================================================\n\nexport const CHAIN_PRESETS: Record<ChainName, ChainPreset> = {\n // ────────────────────────────────────────────────────────────────────────\n // BASE - Primary Hub Chain\n // ────────────────────────────────────────────────────────────────────────\n base: {\n displayName: 'Base',\n type: 'evm',\n canBeHub: true,\n testnet: {\n name: 'Base Sepolia',\n chainId: 84532,\n wormholeChainId: 10004,\n rpcUrl: 'https://sepolia.base.org',\n explorerUrl: 'https://sepolia.basescan.org',\n isEvm: true,\n contracts: {\n hub: '0xD5D29b6EaeE6FF4b765e704298a7e48D22607059',\n vaultFactory: '0xb25b73D5FeD5693dcd1Bb78f8e33387B59A022EC',\n vaultImplementation: '0x2CB8397df988c1880d9e5cFfF65bfC22D7D90EE6',\n wormholeCoreBridge: '0x79A1027a6A159502049F10906D333EC57E95F083',\n tokenBridge: '0x86F55A04690fd7815A3D802bD587e83eA888B239',\n },\n },\n mainnet: {\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 // TODO: Deploy mainnet contracts\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x8d2de8d2f73F1F4cAB472AC9A881C9b123C79627',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // OPTIMISM - Secondary Hub / Spoke\n // ────────────────────────────────────────────────────────────────────────\n optimism: {\n displayName: 'Optimism',\n type: 'evm',\n canBeHub: true,\n testnet: {\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: '0x3c5e4aCdC8Cd53ae5ae603B4c511885191fBb868',\n vaultImplementation: '0xA45dBF322c5A3028687fEEB161603d3BCe02e119',\n wormholeCoreBridge: '0x31377888146f3253211EFEf5c676D41ECe7D58Fe',\n tokenBridge: '0x99737Ec4B815d816c49A385943baf0380e75c0Ac',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // ARBITRUM\n // ────────────────────────────────────────────────────────────────────────\n arbitrum: {\n displayName: 'Arbitrum',\n type: 'evm',\n canBeHub: true,\n testnet: {\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: '0xB9C3e6bad3c6f26956be4a4bb5a366376Fd3045D',\n vaultImplementation: '0x8601881b94B68B09b485f407317686103d3CB681',\n wormholeCoreBridge: '0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35',\n tokenBridge: '0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // ETHEREUM\n // ────────────────────────────────────────────────────────────────────────\n ethereum: {\n displayName: 'Ethereum',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Sepolia',\n chainId: 11155111,\n wormholeChainId: 10002,\n rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n explorerUrl: 'https://sepolia.etherscan.io',\n isEvm: true,\n contracts: {\n vaultFactory: '0x265c10763B4d16AD970bC3d7670c645e37f63AF4',\n vaultImplementation: '0x942426C94652ebC48f4f404928016B95ADb1DA25',\n wormholeCoreBridge: '0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78',\n tokenBridge: '0xDB5492265f6038831E89f495670FF909aDe94bd9',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // POLYGON\n // ────────────────────────────────────────────────────────────────────────\n polygon: {\n displayName: 'Polygon',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Polygon Amoy',\n chainId: 80002,\n wormholeChainId: 10007,\n rpcUrl: 'https://rpc-amoy.polygon.technology',\n explorerUrl: 'https://amoy.polygonscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x0CBE91CF822c73C2315FB05100C2F714765d5c20',\n tokenBridge: '0x0290FB167208Af455bB137780163b7B7a9a10C16',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // BSC\n // ────────────────────────────────────────────────────────────────────────\n bsc: {\n displayName: 'BNB Chain',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'BSC Testnet',\n chainId: 97,\n wormholeChainId: 4,\n rpcUrl: 'https://data-seed-prebsc-1-s1.binance.org:8545',\n explorerUrl: 'https://testnet.bscscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x68605AD7b15c732a30b1BbC62BE8F2A509D74b4D',\n tokenBridge: '0x9dcF9D205C9De35334D646BeE44b2D2859712A09',\n },\n },\n mainnet: {\n name: 'BNB Chain',\n chainId: 56,\n wormholeChainId: 4,\n rpcUrl: 'https://bsc-dataseed.binance.org',\n explorerUrl: 'https://bscscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B',\n tokenBridge: '0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // AVALANCHE — ACP-204 Native P-256 + ICM Teleporter + Hub-Capable\n // ────────────────────────────────────────────────────────────────────────\n avalanche: {\n displayName: 'Avalanche',\n type: 'evm',\n canBeHub: true, // ACP-204 provides native P-256 at 0x0100 (6,900 gas)\n testnet: {\n name: 'Avalanche Fuji',\n chainId: 43113,\n wormholeChainId: 6,\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n explorerUrl: 'https://testnet.snowtrace.io',\n isEvm: true,\n contracts: {\n // Veridex Hub (deployed via deploy-avalanche.ts)\n hub: '', // No Hub on Fuji — Hub is on Base Sepolia\n vaultFactory: '0x9e9716442e908A9b61F11432cC38024DD390cd2a',\n vaultImplementation: '0xE0b9919ffDf3415355Db369C8FfA5Dd4e000052c',\n // Wormhole bridges (canonical Fuji addresses)\n wormholeCoreBridge: '0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C',\n tokenBridge: '0x61E44E506Ca5659E6c0bba9b678586fA2d729756',\n // Avalanche-specific: ACP-204 P-256 verifier wrapper\n p256Verifier: '0xB5d29EA1E2e90A24D6506E2a6a269506a12974CC',\n // Avalanche-specific: ICM Spoke for cross-L1 session bridging\n icmSpoke: '0x9fCFC608086539A69839EfA9628884dB75ac07D0',\n // Chainlink price feeds (Fuji testnet)\n chainlinkAvaxUsd: '0x5498BB86BC934c8D34FDA08E81D444153d0D06aD',\n chainlinkUsdcUsd: '0x7898AcCC83587C3C55116c5230C17a6Cd9C71bad',\n chainlinkUsdtUsd: '0x7898AcCC83587C3C55116c5230C17a6Cd9C71bad',\n },\n hubChainId: 10004, // Base Sepolia (primary Hub)\n },\n mainnet: {\n name: 'Avalanche',\n chainId: 43114,\n wormholeChainId: 6,\n rpcUrl: 'https://api.avax.network/ext/bc/C/rpc',\n explorerUrl: 'https://snowtrace.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x54a8e5f9c4CbA08F9943965859F6c34eAF03E26c',\n tokenBridge: '0x0e082F06FF657D94310cB8cE8B0D9a04541d8052',\n // Chainlink price feeds (Avalanche mainnet)\n chainlinkAvaxUsd: '0x0A77230d17318075983913bC2145DB16C7366156',\n chainlinkUsdcUsd: '0xF096872672F44d6EBA71458D74fe67F9a77a23B9',\n chainlinkUsdtUsd: '0xEBE676ee90Fe1112671f19b6B7459bC678B67e8a',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // SCROLL\n // ────────────────────────────────────────────────────────────────────────\n scroll: {\n displayName: 'Scroll',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Scroll Sepolia',\n chainId: 534351,\n wormholeChainId: 34,\n rpcUrl: 'https://sepolia-rpc.scroll.io',\n explorerUrl: 'https://sepolia.scrollscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x055F47F1250012C6B20c436570a76e52c17Af2D5',\n tokenBridge: '0x22427d90B7dA3fA4642F7025A854c7254E4e45BF',\n },\n },\n mainnet: {\n name: 'Scroll',\n chainId: 534352,\n wormholeChainId: 34,\n rpcUrl: 'https://rpc.scroll.io',\n explorerUrl: 'https://scrollscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // BLAST\n // ────────────────────────────────────────────────────────────────────────\n blast: {\n displayName: 'Blast',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Blast Sepolia',\n chainId: 168587773,\n wormholeChainId: 36,\n rpcUrl: 'https://sepolia.blast.io',\n explorerUrl: 'https://sepolia.blastscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x473e002D7add6fB67a4964F13bFd61280Ca46886',\n tokenBridge: '0x430855B4D43b8AEB9D2B9869B74d58dda79C0dB2',\n },\n },\n mainnet: {\n name: 'Blast',\n chainId: 81457,\n wormholeChainId: 36,\n rpcUrl: 'https://rpc.blast.io',\n explorerUrl: 'https://blastscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // MANTLE\n // ────────────────────────────────────────────────────────────────────────\n mantle: {\n displayName: 'Mantle',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Mantle Sepolia',\n chainId: 5003,\n wormholeChainId: 35,\n rpcUrl: 'https://rpc.sepolia.mantle.xyz',\n explorerUrl: 'https://sepolia.mantlescan.xyz',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x376428e7f26D5867e69201b275553C45B09EE090',\n tokenBridge: '0x75Bfa155a9D7A3714b0861c8a8aF0C4633c45b5D',\n },\n },\n mainnet: {\n name: 'Mantle',\n chainId: 5000,\n wormholeChainId: 35,\n rpcUrl: 'https://rpc.mantle.xyz',\n explorerUrl: 'https://mantlescan.xyz',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6',\n tokenBridge: '0x24850c6f61C438823F01B7A3BF2B89B72174Fa9d',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // FANTOM\n // ────────────────────────────────────────────────────────────────────────\n fantom: {\n displayName: 'Fantom',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Fantom Testnet',\n chainId: 4002,\n wormholeChainId: 10,\n rpcUrl: 'https://rpc.testnet.fantom.network',\n explorerUrl: 'https://testnet.ftmscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x1BB3B4119b7BA9dfad76B0545fb3F531383c3bB7',\n tokenBridge: '0x599CEa2204B4FaECd584Ab1F2b6aCA137a0afbE8',\n },\n },\n mainnet: {\n name: 'Fantom',\n chainId: 250,\n wormholeChainId: 10,\n rpcUrl: 'https://rpcapi.fantom.network',\n explorerUrl: 'https://ftmscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x126783A6Cb203a3E35344528B26ca3a0489a1485',\n tokenBridge: '0x7C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // CELO\n // ────────────────────────────────────────────────────────────────────────\n celo: {\n displayName: 'Celo',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Celo Alfajores',\n chainId: 44787,\n wormholeChainId: 14,\n rpcUrl: 'https://alfajores-forno.celo-testnet.org',\n explorerUrl: 'https://alfajores.celoscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x88505117CA88e7dd2eC6EA1E13f0948db2D50D56',\n tokenBridge: '0x05ca6037eC51F8b712eD2E6Fa72219FEaE74E153',\n },\n },\n mainnet: {\n name: 'Celo',\n chainId: 42220,\n wormholeChainId: 14,\n rpcUrl: 'https://forno.celo.org',\n explorerUrl: 'https://celoscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xa321448d90d4e5b0A732867c18eA198e75CAC48E',\n tokenBridge: '0x796Dff6D74F3E27060B71255Fe517BFb23C93eed',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // MOONBEAM\n // ────────────────────────────────────────────────────────────────────────\n moonbeam: {\n displayName: 'Moonbeam',\n type: 'evm',\n canBeHub: false,\n testnet: {\n name: 'Moonbase Alpha',\n chainId: 1287,\n wormholeChainId: 16,\n rpcUrl: 'https://rpc.api.moonbase.moonbeam.network',\n explorerUrl: 'https://moonbase.moonscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xa5B7D85a8f27dd7907dc8FdC21FA5657D5E2F901',\n tokenBridge: '0xbc976D4b9D57E57c3cA52e1Fd136C45FF7955A96',\n },\n },\n mainnet: {\n name: 'Moonbeam',\n chainId: 1284,\n wormholeChainId: 16,\n rpcUrl: 'https://rpc.api.moonbeam.network',\n explorerUrl: 'https://moonscan.io',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0xC8e2b0cD52Cf01b0Ce87d389Daa3d414d4cE29f3',\n tokenBridge: '0xb1731c586ca89a23809861c6103F0b96B3F57D92',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // MONAD - High-Performance L1 with EIP-7951 P256 + Agent Gateway\n // ────────────────────────────────────────────────────────────────────────\n monad: {\n displayName: 'Monad',\n type: 'evm',\n canBeHub: true, // Has native P-256 precompile (EIP-7951)\n testnet: {\n name: 'Monad Testnet',\n chainId: 10143,\n wormholeChainId: 10048,\n rpcUrl: 'https://testnet-rpc.monad.xyz',\n explorerUrl: 'https://testnet.monadvision.com',\n isEvm: true,\n contracts: {\n vaultFactory: '0x50F2c37584823A6cc293bd0d7647D558d05CA4C1',\n vaultImplementation: '0x53d4D3943d0E524836f0B1955AbB216449F538fF',\n wormholeCoreBridge: '0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd',\n // Agent Gateway contracts\n serviceDirectory: '0x2d20f29E1f5B24294B3F125B47f2a22a7012a35E',\n },\n hubChainId: 10004, // Base Sepolia\n },\n mainnet: {\n name: 'Monad',\n chainId: 143,\n wormholeChainId: 0, // TBD\n rpcUrl: 'https://rpc.monad.xyz',\n explorerUrl: 'https://monadscan.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x194B123c5E96B9b2E49763619985790Dc241CAC0',\n tokenBridge: '0x0B2719cdA2F10595369e6673ceA3Ee2EDFa13BA7',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // SEI\n // ────────────────────────────────────────────────────────────────────────\n sei: {\n displayName: 'Sei',\n type: 'evm',\n canBeHub: false,\n testnet: {\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',\n },\n },\n mainnet: {\n name: 'Sei',\n chainId: 1329,\n wormholeChainId: 32,\n rpcUrl: 'https://evm-rpc.sei-apis.com',\n explorerUrl: 'https://seitrace.com',\n isEvm: true,\n contracts: {\n wormholeCoreBridge: '0x0000000000000000000000000000000000000000',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // SOLANA\n // ────────────────────────────────────────────────────────────────────────\n solana: {\n displayName: 'Solana',\n type: 'solana',\n canBeHub: false,\n testnet: {\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: '64ZZBdmGd1YT6Fok7PELvAdfoXyR4PHxHnRqHNqZHJ13',\n wormholeCoreBridge: '3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5',\n tokenBridge: 'DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // APTOS\n // ────────────────────────────────────────────────────────────────────────\n aptos: {\n displayName: 'Aptos',\n type: 'aptos',\n canBeHub: false,\n testnet: {\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: '0x9e8641143245ab8b93af1417a1fbc698d40fd351a25f6c17e4210e59bf82c9c7',\n wormholeCoreBridge: '0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625',\n tokenBridge: '0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f',\n },\n },\n mainnet: {\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 },\n\n // ────────────────────────────────────────────────────────────────────────\n // SUI\n // ────────────────────────────────────────────────────────────────────────\n sui: {\n displayName: 'Sui',\n type: 'sui',\n canBeHub: false,\n testnet: {\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: '0xaf36d8bc349883b23e78b00a342a656c799319508600583eaee9121ffaa7f5f7',\n wormholeCoreBridge: '0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790',\n },\n },\n mainnet: {\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 // STARKNET\n // ────────────────────────────────────────────────────────────────────────\n starknet: {\n displayName: 'Starknet',\n type: 'starknet',\n canBeHub: false,\n testnet: {\n name: 'Starknet Sepolia',\n chainId: 0,\n wormholeChainId: 50001, // Custom bridge (non-Wormhole)\n rpcUrl: 'https://starknet-sepolia-rpc.publicnode.com',\n explorerUrl: 'https://sepolia.starkscan.co',\n isEvm: false,\n contracts: {\n hub: '0x7bb7cbe7d82e910b296611b582035a207343431f98bdd7b692bddfdd6f28737',\n wormholeCoreBridge: '0x30d2e7f26dc75819cfddcd7caa26a76b681d5918f219c99060c42ce1e3f69e4',\n },\n hubChainId: 10004, // Base Sepolia\n },\n mainnet: {\n name: 'Starknet',\n chainId: 0,\n wormholeChainId: 50001,\n rpcUrl: 'https://starknet-mainnet.public.blastapi.io/rpc/v0_7',\n explorerUrl: 'https://starkscan.co',\n isEvm: false,\n contracts: {\n // TODO: Deploy mainnet contracts\n wormholeCoreBridge: '',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // STACKS\n // ────────────────────────────────────────────────────────────────────────\n stacks: {\n displayName: 'Stacks',\n type: 'stacks',\n canBeHub: false,\n testnet: {\n name: 'Stacks Testnet',\n chainId: 2147483648, // CAIP-2: stacks:2147483648\n wormholeChainId: 60, // Official Wormhole chain ID for Stacks\n rpcUrl: 'https://api.testnet.hiro.so',\n explorerUrl: 'https://explorer.hiro.so/?chain=testnet',\n isEvm: false,\n contracts: {\n // Spoke contract: identity + session management\n hub: 'STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-spoke',\n // Vault contract: STX/sBTC custody\n vaultFactory: 'STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-vault',\n wormholeCoreBridge: '',\n // Phase 2: Wormhole integration contracts\n wormholeVerifier: 'STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-wormhole-verifier',\n vaultVaa: 'STWJ9E8J5NPKB4MT1378G6XWNFGAKRY1E6D6PYSM.veridex-vault-vaa',\n },\n hubChainId: 10004, // Base Sepolia\n },\n mainnet: {\n name: 'Stacks',\n chainId: 1, // CAIP-2: stacks:1\n wormholeChainId: 60,\n rpcUrl: 'https://api.hiro.so',\n explorerUrl: 'https://explorer.hiro.so',\n isEvm: false,\n contracts: {\n // TODO: Deploy mainnet contracts\n wormholeCoreBridge: '',\n },\n },\n },\n\n // ────────────────────────────────────────────────────────────────────────\n // NEAR\n // ────────────────────────────────────────────────────────────────────────\n near: {\n displayName: 'Near',\n type: 'near',\n canBeHub: false,\n testnet: {\n name: 'Near Testnet',\n chainId: 0,\n wormholeChainId: 15,\n rpcUrl: 'https://rpc.testnet.near.org',\n explorerUrl: 'https://explorer.testnet.near.org',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: 'wormhole.wormhole.testnet',\n tokenBridge: 'token.wormhole.testnet',\n },\n },\n mainnet: {\n name: 'Near',\n chainId: 0,\n wormholeChainId: 15,\n rpcUrl: 'https://rpc.mainnet.near.org',\n explorerUrl: 'https://explorer.near.org',\n isEvm: false,\n contracts: {\n wormholeCoreBridge: 'contract.wormhole_crypto.near',\n tokenBridge: 'contract.portalbridge.near',\n },\n },\n },\n};\n\n// ============================================================================\n// Custom RPC URL Overrides\n// ============================================================================\n\n/**\n * Global RPC URL overrides. Set once at app startup to avoid passing\n * custom URLs to every SDK / client constructor.\n *\n * @example\n * ```typescript\n * import { configureDefaultRpcUrls } from '@veridex/sdk';\n *\n * configureDefaultRpcUrls({\n * starknet: { testnet: 'https://my-starknet-rpc.example.com' },\n * base: { mainnet: 'https://my-base-mainnet.example.com' },\n * });\n * ```\n */\nconst _rpcOverrides: Partial<Record<ChainName, Partial<Record<NetworkType, string>>>> = {};\n\n/**\n * Configure global default RPC URL overrides.\n * These take precedence over the built-in public endpoints but are\n * themselves overridden by per-SDK `rpcUrl` / `rpcUrls` options.\n *\n * Call with an empty object to clear all overrides.\n */\nexport function configureDefaultRpcUrls(\n overrides: Partial<Record<ChainName, Partial<Record<NetworkType, string>>>>\n): void {\n // Clear existing overrides\n for (const key of Object.keys(_rpcOverrides) as ChainName[]) {\n delete _rpcOverrides[key];\n }\n // Apply new overrides\n Object.assign(_rpcOverrides, overrides);\n}\n\n/**\n * Get the current global RPC URL override for a chain + network, if any.\n */\nexport function getRpcUrlOverride(\n chain: ChainName,\n network: NetworkType\n): string | undefined {\n return _rpcOverrides[chain]?.[network];\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get chain configuration by name and network.\n *\n * Returns a copy of the built-in config with any global RPC override applied.\n * Per-SDK overrides (`rpcUrl`, `rpcUrls`) still take priority in the factory.\n */\nexport function getChainConfig(\n chain: ChainName,\n network: NetworkType = 'testnet'\n): ChainConfig {\n const preset = CHAIN_PRESETS[chain];\n if (!preset) {\n throw new Error(\n `Unknown chain: \"${chain}\". Supported chains: ${Object.keys(CHAIN_PRESETS).join(', ')}`\n );\n }\n const config = preset[network];\n const rpcOverride = getRpcUrlOverride(chain, network);\n if (rpcOverride) {\n return { ...config, rpcUrl: rpcOverride };\n }\n return config;\n}\n\n/**\n * Get chain preset by name\n */\nexport function getChainPreset(chain: ChainName): ChainPreset {\n const preset = CHAIN_PRESETS[chain];\n if (!preset) {\n throw new Error(\n `Unknown chain: \"${chain}\". Supported chains: ${Object.keys(CHAIN_PRESETS).join(', ')}`\n );\n }\n return preset;\n}\n\n/**\n * Get all supported chain names\n */\nexport function getSupportedChains(): ChainName[] {\n return Object.keys(CHAIN_PRESETS) as ChainName[];\n}\n\n/**\n * Get hub-capable chains.\n * \n * When multi-hub feature flag is disabled, returns only the primary hub chain ('base').\n * When enabled, returns all chains with canBeHub: true.\n */\nexport function getHubChains(): ChainName[] {\n if (!isMultiHubEnabled()) {\n const primary = getEffectivePrimaryHub();\n return [primary];\n }\n return Object.entries(CHAIN_PRESETS)\n .filter(([_, preset]) => preset.canBeHub)\n .map(([name]) => name as ChainName);\n}\n\n/**\n * Check if chain is supported\n */\nexport function isChainSupported(chain: string): chain is ChainName {\n return chain in CHAIN_PRESETS;\n}\n\n/**\n * Check if a specific chain is currently acting as a hub.\n * \n * When multi-hub is disabled, only the primary hub ('base') returns true.\n * When enabled, any chain with canBeHub: true returns true.\n */\nexport function isHubChain(chain: ChainName): boolean {\n if (!isMultiHubEnabled()) {\n return chain === getEffectivePrimaryHub();\n }\n const preset = CHAIN_PRESETS[chain];\n return preset?.canBeHub ?? false;\n}\n\n/**\n * Get default hub chain.\n * \n * Returns the effective primary hub's config. When multi-hub is disabled,\n * this always returns Base. When enabled, it returns the configured primary hub.\n */\nexport function getDefaultHub(network: NetworkType = 'testnet'): ChainConfig {\n const primary = getEffectivePrimaryHub();\n return CHAIN_PRESETS[primary][network];\n}\n"],"mappings":";AA+EA,IAAM,gBAA8B;AAAA,EAClC,UAAU;AAAA,EACV,YAAY;AACd;AAMA,IAAI,SAAuB,EAAE,GAAG,cAAc;AASvC,SAAS,kBAA0C;AACxD,SAAO,EAAE,GAAG,OAAO;AACrB;AAgBO,SAAS,gBAAgB,OAAoC;AAClE,WAAS,EAAE,GAAG,QAAQ,GAAG,MAAM;AACjC;AAMO,SAAS,oBAA0B;AACxC,WAAS,EAAE,GAAG,cAAc;AAC9B;AAMO,SAAS,oBAA6B;AAC3C,SAAO,OAAO;AAChB;AAQO,SAAS,yBAAoC;AAClD,MAAI,CAAC,OAAO,UAAU;AACpB,WAAO;AAAA,EACT;AACA,SAAO,OAAO;AAChB;;;ACtHO,IAAM,cAAc;AAAA;AAAA,EAEzB,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA;AAAA,EAGR,UAAU;AAAA,EACV,SAAS;AAAA,EACT,KAAK;AAAA,EACL,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AAAA;AAAA,EAGV,OAAO;AAAA;AAAA,EAGP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AACP;AA0BO,IAAM,gBAAgD;AAAA;AAAA;AAAA;AAAA,EAI3D,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,KAAK;AAAA,QACL,cAAc;AAAA,QACd,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA;AAAA,QAET,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,cAAc;AAAA,QACd,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,cAAc;AAAA,QACd,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,cAAc;AAAA,QACd,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AAAA,IACP,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK;AAAA,IACH,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW;AAAA,IACT,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA;AAAA,QAET,KAAK;AAAA;AAAA,QACL,cAAc;AAAA,QACd,qBAAqB;AAAA;AAAA,QAErB,oBAAoB;AAAA,QACpB,aAAa;AAAA;AAAA,QAEb,cAAc;AAAA;AAAA,QAEd,UAAU;AAAA;AAAA,QAEV,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,MACpB;AAAA,MACA,YAAY;AAAA;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA;AAAA,QAEb,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,QAClB,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO;AAAA,IACL,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO;AAAA,IACL,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,cAAc;AAAA,QACd,qBAAqB;AAAA,QACrB,oBAAoB;AAAA;AAAA,QAEpB,kBAAkB;AAAA,MACpB;AAAA,MACA,YAAY;AAAA;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK;AAAA,IACH,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,cAAc;AAAA,QACd,qBAAqB;AAAA,QACrB,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,KAAK;AAAA,QACL,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO;AAAA,IACL,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,KAAK;AAAA,QACL,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK;AAAA,IACH,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,KAAK;AAAA,QACL,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AAAA,IACR,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,KAAK;AAAA,QACL,oBAAoB;AAAA,MACtB;AAAA,MACA,YAAY;AAAA;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA;AAAA,QAET,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,MACT,iBAAiB;AAAA;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA;AAAA,QAET,KAAK;AAAA;AAAA,QAEL,cAAc;AAAA,QACd,oBAAoB;AAAA;AAAA,QAEpB,kBAAkB;AAAA,QAClB,UAAU;AAAA,MACZ;AAAA,MACA,YAAY;AAAA;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA;AAAA,QAET,oBAAoB;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM;AAAA,IACJ,aAAa;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,oBAAoB;AAAA,QACpB,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAoBA,IAAM,gBAAkF,CAAC;AASlF,SAAS,wBACd,WACM;AAEN,aAAW,OAAO,OAAO,KAAK,aAAa,GAAkB;AAC3D,WAAO,cAAc,GAAG;AAAA,EAC1B;AAEA,SAAO,OAAO,eAAe,SAAS;AACxC;AAKO,SAAS,kBACd,OACA,SACoB;AACpB,SAAO,cAAc,KAAK,IAAI,OAAO;AACvC;AAYO,SAAS,eACd,OACA,UAAuB,WACV;AACb,QAAM,SAAS,cAAc,KAAK;AAClC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR,mBAAmB,KAAK,wBAAwB,OAAO,KAAK,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,IACvF;AAAA,EACF;AACA,QAAM,SAAS,OAAO,OAAO;AAC7B,QAAM,cAAc,kBAAkB,OAAO,OAAO;AACpD,MAAI,aAAa;AACf,WAAO,EAAE,GAAG,QAAQ,QAAQ,YAAY;AAAA,EAC1C;AACA,SAAO;AACT;AAKO,SAAS,eAAe,OAA+B;AAC5D,QAAM,SAAS,cAAc,KAAK;AAClC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR,mBAAmB,KAAK,wBAAwB,OAAO,KAAK,aAAa,EAAE,KAAK,IAAI,CAAC;AAAA,IACvF;AAAA,EACF;AACA,SAAO;AACT;AAKO,SAAS,qBAAkC;AAChD,SAAO,OAAO,KAAK,aAAa;AAClC;AAQO,SAAS,eAA4B;AAC1C,MAAI,CAAC,kBAAkB,GAAG;AACxB,UAAM,UAAU,uBAAuB;AACvC,WAAO,CAAC,OAAO;AAAA,EACjB;AACA,SAAO,OAAO,QAAQ,aAAa,EAChC,OAAO,CAAC,CAAC,GAAG,MAAM,MAAM,OAAO,QAAQ,EACvC,IAAI,CAAC,CAAC,IAAI,MAAM,IAAiB;AACtC;AAKO,SAAS,iBAAiB,OAAmC;AAClE,SAAO,SAAS;AAClB;AAQO,SAAS,WAAW,OAA2B;AACpD,MAAI,CAAC,kBAAkB,GAAG;AACxB,WAAO,UAAU,uBAAuB;AAAA,EAC1C;AACA,QAAM,SAAS,cAAc,KAAK;AAClC,SAAO,QAAQ,YAAY;AAC7B;AAQO,SAAS,cAAc,UAAuB,WAAwB;AAC3E,QAAM,UAAU,uBAAuB;AACvC,SAAO,cAAc,OAAO,EAAE,OAAO;AACvC;","names":[]}
|
package/dist/constants.js
CHANGED
|
@@ -248,8 +248,8 @@ var TESTNET_CHAINS = {
|
|
|
248
248
|
explorerUrl: "https://testnet.snowtrace.io",
|
|
249
249
|
isEvm: true,
|
|
250
250
|
contracts: {
|
|
251
|
-
vaultFactory: "
|
|
252
|
-
vaultImplementation: "
|
|
251
|
+
vaultFactory: "0x9e9716442e908A9b61F11432cC38024DD390cd2a",
|
|
252
|
+
vaultImplementation: "0xE0b9919ffDf3415355Db369C8FfA5Dd4e000052c",
|
|
253
253
|
wormholeCoreBridge: "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C",
|
|
254
254
|
tokenBridge: "0x61E44E506Ca5659E6c0bba9b678586fA2d729756"
|
|
255
255
|
}
|
|
@@ -276,7 +276,7 @@ var TESTNET_CHAINS = {
|
|
|
276
276
|
explorerUrl: "https://explorer.solana.com",
|
|
277
277
|
isEvm: false,
|
|
278
278
|
contracts: {
|
|
279
|
-
hub: "
|
|
279
|
+
hub: "64ZZBdmGd1YT6Fok7PELvAdfoXyR4PHxHnRqHNqZHJ13",
|
|
280
280
|
wormholeCoreBridge: "3u8hJUVTA4jH1wYAyUur7FFZVQ8H635K3tSHHF4ssjQ5",
|
|
281
281
|
tokenBridge: "DZnkkTmCiFWfYTfT41X3Rd1kDgozqzxWaHqsw6W4x2oe"
|
|
282
282
|
}
|
|
@@ -289,7 +289,7 @@ var TESTNET_CHAINS = {
|
|
|
289
289
|
explorerUrl: "https://explorer.aptoslabs.com",
|
|
290
290
|
isEvm: false,
|
|
291
291
|
contracts: {
|
|
292
|
-
hub: "
|
|
292
|
+
hub: "0x9e8641143245ab8b93af1417a1fbc698d40fd351a25f6c17e4210e59bf82c9c7",
|
|
293
293
|
wormholeCoreBridge: "0x5bc11445584a763c1fa7ed39081f1b920954da14e04b32440cba863d03e19625",
|
|
294
294
|
tokenBridge: "0x576410486a2da45eee6c949c995670112ddf2fbeedab20350d506328eefc9d4f"
|
|
295
295
|
}
|
|
@@ -302,7 +302,7 @@ var TESTNET_CHAINS = {
|
|
|
302
302
|
explorerUrl: "https://suiscan.xyz/testnet",
|
|
303
303
|
isEvm: false,
|
|
304
304
|
contracts: {
|
|
305
|
-
hub: "
|
|
305
|
+
hub: "0xaf36d8bc349883b23e78b00a342a656c799319508600583eaee9121ffaa7f5f7",
|
|
306
306
|
wormholeCoreBridge: "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
|
|
307
307
|
}
|
|
308
308
|
},
|
|
@@ -314,8 +314,8 @@ var TESTNET_CHAINS = {
|
|
|
314
314
|
explorerUrl: "https://sepolia.starkscan.co",
|
|
315
315
|
isEvm: false,
|
|
316
316
|
contracts: {
|
|
317
|
-
hub: "
|
|
318
|
-
wormholeCoreBridge: "
|
|
317
|
+
hub: "0x7bb7cbe7d82e910b296611b582035a207343431f98bdd7b692bddfdd6f28737",
|
|
318
|
+
wormholeCoreBridge: "0x30d2e7f26dc75819cfddcd7caa26a76b681d5918f219c99060c42ce1e3f69e4"
|
|
319
319
|
},
|
|
320
320
|
hubChainId: 10004
|
|
321
321
|
}
|