@veridex/sdk 1.1.0 → 1.1.1

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.
Files changed (83) hide show
  1. package/dist/auth/prepareAuth.js +107 -32
  2. package/dist/auth/prepareAuth.js.map +1 -1
  3. package/dist/auth/prepareAuth.mjs +6 -6
  4. package/dist/chains/aptos/index.js.map +1 -1
  5. package/dist/chains/aptos/index.mjs +3 -3
  6. package/dist/chains/avalanche/index.js.map +1 -1
  7. package/dist/chains/avalanche/index.mjs +4 -4
  8. package/dist/chains/evm/index.d.mts +2 -2
  9. package/dist/chains/evm/index.js.map +1 -1
  10. package/dist/chains/evm/index.mjs +3 -3
  11. package/dist/chains/solana/index.js.map +1 -1
  12. package/dist/chains/solana/index.mjs +3 -3
  13. package/dist/chains/stacks/index.d.mts +1 -1
  14. package/dist/chains/stacks/index.js.map +1 -1
  15. package/dist/chains/stacks/index.mjs +3 -3
  16. package/dist/chains/starknet/index.d.mts +1 -1
  17. package/dist/chains/starknet/index.js.map +1 -1
  18. package/dist/chains/starknet/index.mjs +3 -3
  19. package/dist/chains/sui/index.d.mts +1 -1
  20. package/dist/chains/sui/index.js.map +1 -1
  21. package/dist/chains/sui/index.mjs +3 -3
  22. package/dist/{chunk-Q5O3M5LP.mjs → chunk-2TS375ET.mjs} +2 -2
  23. package/dist/{chunk-QT4ZZ4GM.mjs → chunk-5FDOTI5G.mjs} +2 -2
  24. package/dist/{chunk-5T6KPH7A.mjs → chunk-CSU4IV2F.mjs} +2 -2
  25. package/dist/{chunk-YCUJZ6Z7.mjs → chunk-CTYDGO6E.mjs} +63 -6
  26. package/dist/chunk-CTYDGO6E.mjs.map +1 -0
  27. package/dist/{chunk-SXXGTQIR.mjs → chunk-E3SU36C2.mjs} +2 -2
  28. package/dist/{chunk-NUWSMJFJ.mjs → chunk-EFIXFA6V.mjs} +2 -2
  29. package/dist/{chunk-MLXQHIH2.mjs → chunk-GM5DKEHD.mjs} +2 -2
  30. package/dist/{chunk-GWJRKDSA.mjs → chunk-GOWXQPTW.mjs} +3 -3
  31. package/dist/{chunk-OVMMTL6H.mjs → chunk-ICGB3AHI.mjs} +2 -2
  32. package/dist/{chunk-QDO6NQ7P.mjs → chunk-M3GUNREX.mjs} +20 -3
  33. package/dist/{chunk-QDO6NQ7P.mjs.map → chunk-M3GUNREX.mjs.map} +1 -1
  34. package/dist/{chunk-N4A2RMUN.mjs → chunk-PEGOXMBU.mjs} +2 -2
  35. package/dist/{chunk-X7BZMSPQ.mjs → chunk-RD6ZYUVG.mjs} +52 -30
  36. package/dist/chunk-RD6ZYUVG.mjs.map +1 -0
  37. package/dist/{chunk-F3YAGZSW.mjs → chunk-TPEP6XUA.mjs} +2 -2
  38. package/dist/{chunk-M3MM4YMF.mjs → chunk-UPO55SBK.mjs} +2 -2
  39. package/dist/{chunk-USDA5JTN.mjs → chunk-YBN2VC6E.mjs} +2 -2
  40. package/dist/{chunk-PDHZ5X5O.mjs → chunk-YYT3V7CI.mjs} +2 -2
  41. package/dist/constants.d.mts +2 -2
  42. package/dist/constants.js +51 -29
  43. package/dist/constants.js.map +1 -1
  44. package/dist/constants.mjs +1 -1
  45. package/dist/{index-DDalBhAm.d.mts → index-CySMITQ9.d.mts} +9 -6
  46. package/dist/index.d.mts +41 -13
  47. package/dist/index.js +445 -147
  48. package/dist/index.js.map +1 -1
  49. package/dist/index.mjs +327 -127
  50. package/dist/index.mjs.map +1 -1
  51. package/dist/passkey.js +57 -4
  52. package/dist/passkey.js.map +1 -1
  53. package/dist/passkey.mjs +3 -3
  54. package/dist/payload.js.map +1 -1
  55. package/dist/payload.mjs +2 -2
  56. package/dist/portfolio-JA4OTF7Y.mjs +13 -0
  57. package/dist/queries/index.js +49 -27
  58. package/dist/queries/index.js.map +1 -1
  59. package/dist/queries/index.mjs +5 -5
  60. package/dist/{types-B7V5VNbO.d.mts → types-DWx-5jmz.d.mts} +12 -3
  61. package/dist/utils.js +49 -27
  62. package/dist/utils.js.map +1 -1
  63. package/dist/utils.mjs +2 -2
  64. package/dist/wormhole.js.map +1 -1
  65. package/dist/wormhole.mjs +2 -2
  66. package/package.json +1 -1
  67. package/dist/chunk-X7BZMSPQ.mjs.map +0 -1
  68. package/dist/chunk-YCUJZ6Z7.mjs.map +0 -1
  69. package/dist/portfolio-V347KZOL.mjs +0 -13
  70. /package/dist/{chunk-Q5O3M5LP.mjs.map → chunk-2TS375ET.mjs.map} +0 -0
  71. /package/dist/{chunk-QT4ZZ4GM.mjs.map → chunk-5FDOTI5G.mjs.map} +0 -0
  72. /package/dist/{chunk-5T6KPH7A.mjs.map → chunk-CSU4IV2F.mjs.map} +0 -0
  73. /package/dist/{chunk-SXXGTQIR.mjs.map → chunk-E3SU36C2.mjs.map} +0 -0
  74. /package/dist/{chunk-NUWSMJFJ.mjs.map → chunk-EFIXFA6V.mjs.map} +0 -0
  75. /package/dist/{chunk-MLXQHIH2.mjs.map → chunk-GM5DKEHD.mjs.map} +0 -0
  76. /package/dist/{chunk-GWJRKDSA.mjs.map → chunk-GOWXQPTW.mjs.map} +0 -0
  77. /package/dist/{chunk-OVMMTL6H.mjs.map → chunk-ICGB3AHI.mjs.map} +0 -0
  78. /package/dist/{chunk-N4A2RMUN.mjs.map → chunk-PEGOXMBU.mjs.map} +0 -0
  79. /package/dist/{chunk-F3YAGZSW.mjs.map → chunk-TPEP6XUA.mjs.map} +0 -0
  80. /package/dist/{chunk-M3MM4YMF.mjs.map → chunk-UPO55SBK.mjs.map} +0 -0
  81. /package/dist/{chunk-USDA5JTN.mjs.map → chunk-YBN2VC6E.mjs.map} +0 -0
  82. /package/dist/{chunk-PDHZ5X5O.mjs.map → chunk-YYT3V7CI.mjs.map} +0 -0
  83. /package/dist/{portfolio-V347KZOL.mjs.map → portfolio-JA4OTF7Y.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/PasskeyManager.ts","../src/core/relayerUrl.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK - Passkey Manager\n * \n * Chain-agnostic WebAuthn/Passkey credential management\n */\n\nimport {\n startRegistration,\n startAuthentication,\n browserSupportsWebAuthn,\n} from '@simplewebauthn/browser';\nimport type {\n PublicKeyCredentialCreationOptionsJSON,\n PublicKeyCredentialRequestOptionsJSON,\n RegistrationResponseJSON,\n AuthenticationResponseJSON,\n} from '@simplewebauthn/types';\nimport { ethers } from 'ethers';\nimport { base64URLEncode, base64URLDecode, parseDERSignature, computeKeyHash } from '../utils.js';\nimport { buildRelayerApiUrl, normalizeRelayerOrigin } from './relayerUrl.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PasskeyCredential {\n credentialId: string;\n publicKeyX: bigint;\n publicKeyY: bigint;\n keyHash: string;\n}\n\nexport interface WebAuthnSignature {\n authenticatorData: string;\n clientDataJSON: string;\n challengeIndex: number;\n typeIndex: number;\n r: bigint;\n s: bigint;\n}\n\nexport interface PasskeyManagerConfig {\n rpName?: string;\n rpId?: string;\n timeout?: number;\n userVerification?: 'required' | 'preferred' | 'discouraged';\n authenticatorAttachment?: 'platform' | 'cross-platform';\n /** Relayer API URL for cross-device credential recovery */\n relayerUrl?: string;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * The canonical Veridex RP ID for cross-domain passkey sharing.\n * All Veridex SDK instances should use this RP ID to enable passkey\n * portability across different applications and domains.\n * \n * This works via W3C Related Origin Requests (ROR) - veridex.network\n * hosts a .well-known/webauthn file that lists allowed origins.\n */\nexport const VERIDEX_RP_ID = 'veridex.network';\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Detects the appropriate RP ID for passkey sharing.\n * \n * For production: Returns VERIDEX_RP_ID ('veridex.network') to enable\n * cross-domain passkey sharing via Related Origin Requests (ROR).\n * \n * For local development:\n * - localhost/127.0.0.1 → returns as-is\n * - IP addresses → returns as-is\n * \n * @param forceLocal - If true, uses local domain detection instead of canonical RP ID\n */\nfunction detectRpId(forceLocal?: boolean): string {\n if (typeof window === 'undefined') return 'localhost';\n\n const hostname = window.location.hostname;\n\n // For local development, always use the actual hostname\n if (hostname === 'localhost' || hostname === '127.0.0.1' || /^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(hostname)) {\n return hostname;\n }\n\n // If forceLocal is true, detect from hostname (legacy behavior)\n if (forceLocal) {\n const parts = hostname.split('.');\n if (parts.length <= 2) {\n return hostname;\n }\n return parts.slice(-2).join('.');\n }\n\n // Default: Use canonical Veridex RP ID for cross-domain passkey sharing\n return VERIDEX_RP_ID;\n}\n\n/**\n * Check if the browser supports Related Origin Requests (ROR).\n * This is a WebAuthn Level 3 feature that allows using passkeys\n * across different domains listed in the RP's .well-known/webauthn file.\n * \n * @returns true if ROR is supported, false otherwise\n */\nexport async function supportsRelatedOrigins(): Promise<boolean> {\n if (typeof window === 'undefined' || !window.PublicKeyCredential) {\n return false;\n }\n\n // Check for getClientCapabilities (WebAuthn L3)\n if ('getClientCapabilities' in PublicKeyCredential) {\n try {\n const getCapabilities = (PublicKeyCredential as unknown as {\n getClientCapabilities: () => Promise<{ relatedOrigins?: boolean }>\n }).getClientCapabilities;\n const capabilities = await getCapabilities();\n return capabilities?.relatedOrigins === true;\n } catch {\n return false;\n }\n }\n\n return false;\n}\n\n/** \n * Export the detectRpId function for external use.\n * Apps can call this to see what RP ID will be used.\n */\nexport { detectRpId };\n\n// ============================================================================\n// PasskeyManager Class\n// ============================================================================\n\n/**\n * Manages WebAuthn passkey credentials for Veridex Protocol\n */\nexport class PasskeyManager {\n private config: Required<PasskeyManagerConfig>;\n private credential: PasskeyCredential | null = null;\n\n constructor(config: PasskeyManagerConfig = {}) {\n this.config = {\n rpName: config.rpName ?? 'Veridex Protocol',\n rpId: config.rpId ?? detectRpId(),\n timeout: config.timeout ?? 60000,\n userVerification: config.userVerification ?? 'required',\n authenticatorAttachment: config.authenticatorAttachment ?? 'platform',\n relayerUrl: normalizeRelayerOrigin(config.relayerUrl ?? ''),\n };\n }\n\n static isSupported(): boolean {\n return browserSupportsWebAuthn();\n }\n\n static async isPlatformAuthenticatorAvailable(): Promise<boolean> {\n if (typeof window === 'undefined' || !window.PublicKeyCredential) {\n return false;\n }\n return await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();\n }\n\n async register(username: string, displayName: string): Promise<PasskeyCredential> {\n if (!PasskeyManager.isSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const challenge = ethers.randomBytes(32);\n const challengeBase64 = base64URLEncode(challenge);\n\n const options: PublicKeyCredentialCreationOptionsJSON = {\n challenge: challengeBase64,\n rp: {\n name: this.config.rpName,\n id: this.config.rpId,\n },\n user: {\n id: base64URLEncode(ethers.toUtf8Bytes(username)),\n name: username,\n displayName: displayName,\n },\n pubKeyCredParams: [\n { alg: -7, type: 'public-key' }, // ES256 (P-256) - WebAuthn default\n { alg: -257, type: 'public-key' }, // RS256 - Widely supported\n { alg: -8, type: 'public-key' }, // EdDSA - Modern, efficient\n { alg: -35, type: 'public-key' }, // ES384 (P-384)\n { alg: -36, type: 'public-key' }, // ES512 (P-521)\n { alg: -37, type: 'public-key' }, // PS256 - RSA PSS\n ],\n authenticatorSelection: {\n authenticatorAttachment: this.config.authenticatorAttachment,\n userVerification: this.config.userVerification,\n residentKey: 'required',\n requireResidentKey: true,\n },\n timeout: this.config.timeout,\n attestation: 'none',\n };\n\n const response = await startRegistration(options);\n const publicKey = this.extractPublicKeyFromAttestation(response);\n const keyHash = computeKeyHash(publicKey.x, publicKey.y);\n\n this.credential = {\n credentialId: response.id,\n publicKeyX: publicKey.x,\n publicKeyY: publicKey.y,\n keyHash,\n };\n\n return this.credential;\n }\n\n async sign(challenge: Uint8Array): Promise<WebAuthnSignature> {\n if (!this.credential) {\n throw new Error('No credential set. Call register() or setCredential() first.');\n }\n\n const challengeBase64 = base64URLEncode(challenge);\n\n const options: PublicKeyCredentialRequestOptionsJSON = {\n challenge: challengeBase64,\n rpId: this.config.rpId,\n allowCredentials: [\n {\n id: this.credential.credentialId,\n type: 'public-key',\n transports: ['internal'],\n },\n ],\n userVerification: this.config.userVerification,\n timeout: this.config.timeout,\n };\n\n const response = await startAuthentication(options);\n return this.parseAuthenticationResponse(response);\n }\n\n\n\n /**\n * Authenticate using a discoverable credential (passkey)\n * This allows sign-in without knowing the credential ID ahead of time.\n * The authenticator will show all available passkeys for this RP.\n * \n * @param challenge - Optional challenge bytes. If not provided, a random challenge is used.\n * @returns The credential that was used to authenticate, along with the signature\n */\n async authenticate(challenge?: Uint8Array): Promise<{\n credential: PasskeyCredential;\n signature: WebAuthnSignature;\n }> {\n if (!PasskeyManager.isSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const actualChallenge = challenge ?? ethers.randomBytes(32);\n const challengeBase64 = base64URLEncode(actualChallenge);\n\n // Allow any registered credential (discoverable or not)\n const options: PublicKeyCredentialRequestOptionsJSON = {\n challenge: challengeBase64,\n rpId: this.config.rpId,\n userVerification: this.config.userVerification,\n timeout: this.config.timeout,\n };\n\n const response = await startAuthentication(options);\n const credentialId = response.id;\n const signature = this.parseAuthenticationResponse(response);\n\n // 1. Try to find the credential in our local cache (could be one of many)\n let storedCredential = this.findCredentialById(credentialId);\n\n if (storedCredential) {\n this.credential = storedCredential;\n return { credential: storedCredential, signature };\n }\n\n // 2. Try to fetch from the Relayer/API if configured\n if (this.config.relayerUrl) {\n storedCredential = await this.loadCredentialFromRelayer(credentialId);\n if (storedCredential) {\n this.credential = storedCredential;\n this.addCredentialToStorage(storedCredential);\n return { credential: storedCredential, signature };\n }\n }\n\n // 3. If we still don't have it, we can't verify signatures or derive the keyHash\n const hasRelayer = !!this.config.relayerUrl;\n throw new Error(\n 'Credential not found. ' +\n 'This passkey was registered on a different device or the data was cleared. ' +\n (hasRelayer\n ? 'The credential was not found. Please register a new passkey.'\n : 'Please register a new passkey or ensure the relayer URL is configured.')\n );\n }\n\n /**\n * Find a credential by ID in the list of stored credentials\n */\n private findCredentialById(credentialId: string): PasskeyCredential | null {\n if (typeof window === 'undefined') return null;\n\n const stored = this.getAllStoredCredentials();\n return stored.find(c => c.credentialId === credentialId) || null;\n }\n\n /**\n * Get all credentials stored in localStorage\n */\n getAllStoredCredentials(key = 'veridex_credentials'): PasskeyCredential[] {\n if (typeof window === 'undefined') return [];\n\n const stored = localStorage.getItem(key);\n if (!stored) {\n // Fallback to legacy single key for backward compatibility\n const legacy = localStorage.getItem('veridex_credential');\n if (legacy) {\n try {\n const data = JSON.parse(legacy);\n // Migrate to new format\n const cred = this.parseStoredCredential(data);\n if (cred) {\n this.saveCredentials([cred], key);\n localStorage.removeItem('veridex_credential');\n return [cred];\n }\n } catch (e) { /* ignore */ }\n }\n return [];\n }\n\n try {\n const data = JSON.parse(stored);\n if (Array.isArray(data)) {\n return data.map(item => this.parseStoredCredential(item)).filter((c): c is PasskeyCredential => c !== null);\n }\n return [];\n } catch (error) {\n console.error('Failed to load credentials:', error);\n return [];\n }\n }\n\n private parseStoredCredential(data: any): PasskeyCredential | null {\n try {\n return {\n credentialId: data.credentialId,\n publicKeyX: BigInt(data.publicKeyX),\n publicKeyY: BigInt(data.publicKeyY),\n keyHash: data.keyHash,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Save a list of credentials to localStorage\n */\n saveCredentials(credentials: PasskeyCredential[], key = 'veridex_credentials'): void {\n if (typeof window === 'undefined') return;\n\n const data = credentials.map(c => ({\n credentialId: c.credentialId,\n publicKeyX: c.publicKeyX.toString(),\n publicKeyY: c.publicKeyY.toString(),\n keyHash: c.keyHash,\n }));\n\n localStorage.setItem(key, JSON.stringify(data));\n }\n\n /**\n * Add a single credential to storage (append or update)\n */\n addCredentialToStorage(credential: PasskeyCredential, key = 'veridex_credentials'): void {\n const stored = this.getAllStoredCredentials(key);\n const existingIndex = stored.findIndex(c => c.credentialId === credential.credentialId);\n\n if (existingIndex >= 0) {\n stored[existingIndex] = credential;\n } else {\n stored.push(credential);\n }\n\n this.saveCredentials(stored, key);\n }\n\n /**\n * Check if there's ANY stored credential for this RP\n */\n hasStoredCredential(): boolean {\n return this.getAllStoredCredentials().length > 0;\n }\n\n getCredential(): PasskeyCredential | null {\n return this.credential;\n }\n\n setCredential(credential: PasskeyCredential): void {\n this.credential = credential;\n }\n\n createCredentialFromPublicKey(\n credentialId: string,\n publicKeyX: bigint,\n publicKeyY: bigint\n ): PasskeyCredential {\n const keyHash = computeKeyHash(publicKeyX, publicKeyY);\n this.credential = {\n credentialId,\n publicKeyX,\n publicKeyY,\n keyHash,\n };\n return this.credential;\n }\n\n clearCredential(): void {\n this.credential = null;\n }\n\n /**\n * Save the current credential to localStorage (appends to list)\n */\n saveToLocalStorage(key = 'veridex_credentials'): void {\n if (!this.credential) {\n throw new Error('No credential to save');\n }\n this.addCredentialToStorage(this.credential, key);\n }\n\n loadFromLocalStorage(key = 'veridex_credentials'): PasskeyCredential | null {\n if (typeof window === 'undefined') {\n return null;\n }\n\n // Return the most recently used credential, or the last one added\n const stored = this.getAllStoredCredentials(key);\n if (stored.length > 0) {\n // Use the last one as default\n this.credential = stored[stored.length - 1];\n return this.credential;\n }\n\n return null;\n }\n\n removeFromLocalStorage(key = 'veridex_credentials'): void {\n if (typeof window !== 'undefined') {\n localStorage.removeItem(key);\n // Also remove legacy key\n localStorage.removeItem('veridex_credential');\n }\n }\n\n // =========================================================================\n // Relayer-based Credential Storage (Cross-Device Recovery)\n // =========================================================================\n\n /**\n * Save the current credential to the relayer for cross-device recovery.\n * This should be called after registration.\n */\n async saveCredentialToRelayer(): Promise<boolean> {\n if (!this.credential) {\n throw new Error('No credential to save');\n }\n if (!this.config.relayerUrl) {\n console.warn('Relayer URL not configured; skipping remote credential storage');\n return false;\n }\n\n try {\n const response = await fetch(buildRelayerApiUrl(this.config.relayerUrl, '/credential'), {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n keyHash: this.credential.keyHash,\n credentialId: this.credential.credentialId,\n publicKeyX: this.credential.publicKeyX.toString(),\n publicKeyY: this.credential.publicKeyY.toString(),\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n console.error('Failed to save credential to relayer:', errorData);\n return false;\n }\n\n console.log('Credential saved to relayer for cross-device recovery');\n return true;\n } catch (error) {\n console.error('Failed to save credential to relayer:', error);\n return false;\n }\n }\n\n /**\n * Load a credential from the relayer by credential ID.\n * Used during discoverable credential authentication when localStorage is empty.\n */\n async loadCredentialFromRelayer(credentialId: string): Promise<PasskeyCredential | null> {\n if (!this.config.relayerUrl) {\n return null;\n }\n\n try {\n const response = await fetch(\n buildRelayerApiUrl(this.config.relayerUrl, `/credential/by-id/${encodeURIComponent(credentialId)}`)\n );\n\n if (!response.ok) {\n return null;\n }\n\n const data = await response.json();\n if (!data.exists) {\n return null;\n }\n\n // Validate required fields before attempting BigInt conversion\n if (!data.credentialId || !data.publicKeyX || !data.publicKeyY || !data.keyHash) {\n console.warn('Relayer returned incomplete credential data:', {\n hasCredentialId: !!data.credentialId,\n hasPublicKeyX: !!data.publicKeyX,\n hasPublicKeyY: !!data.publicKeyY,\n hasKeyHash: !!data.keyHash,\n });\n return null;\n }\n\n return {\n credentialId: data.credentialId,\n publicKeyX: BigInt(data.publicKeyX),\n publicKeyY: BigInt(data.publicKeyY),\n keyHash: data.keyHash,\n };\n } catch (error) {\n console.error('Failed to load credential from relayer:', error);\n return null;\n }\n }\n\n /**\n * Load a credential from the relayer by keyHash.\n * Useful when you know the user's keyHash but not their credential ID.\n */\n async loadCredentialFromRelayerByKeyHash(keyHash: string): Promise<PasskeyCredential | null> {\n if (!this.config.relayerUrl) {\n return null;\n }\n\n try {\n const response = await fetch(\n buildRelayerApiUrl(this.config.relayerUrl, `/credential/${encodeURIComponent(keyHash)}`)\n );\n\n if (!response.ok) {\n return null;\n }\n\n const data = await response.json();\n if (!data.exists) {\n return null;\n }\n\n // Validate required fields before attempting BigInt conversion\n if (!data.credentialId || !data.publicKeyX || !data.publicKeyY || !data.keyHash) {\n console.warn('Relayer returned incomplete credential data for keyHash:', {\n hasCredentialId: !!data.credentialId,\n hasPublicKeyX: !!data.publicKeyX,\n hasPublicKeyY: !!data.publicKeyY,\n hasKeyHash: !!data.keyHash,\n });\n return null;\n }\n\n return {\n credentialId: data.credentialId,\n publicKeyX: BigInt(data.publicKeyX),\n publicKeyY: BigInt(data.publicKeyY),\n keyHash: data.keyHash,\n };\n } catch (error) {\n console.error('Failed to load credential from relayer:', error);\n return null;\n }\n }\n\n // =========================================================================\n // Backup Passkey & Device Migration (Phase 3)\n // =========================================================================\n\n /**\n * Register a backup passkey for the current identity.\n *\n * This creates a new WebAuthn credential on this device/platform that becomes\n * an additional authorized key for the same Veridex identity. The caller\n * must submit the returned credential to VeridexHub.addKey() for on-chain registration.\n *\n * Use cases:\n * - \"Add this device\" flow when signing in on a new machine\n * - Proactive backup creation on a separate authenticator\n * - Cross-ecosystem redundancy (iCloud + Google Password Manager)\n *\n * @param username - Username for the new credential (typically same as primary)\n * @param displayName - Display name for the backup (e.g., \"MacBook Pro Backup\")\n * @param excludeCredentialIds - Credential IDs to exclude (prevents re-registering same authenticator)\n * @returns The newly registered backup credential\n */\n async registerBackupPasskey(\n username: string,\n displayName: string,\n excludeCredentialIds?: string[]\n ): Promise<PasskeyCredential> {\n if (!PasskeyManager.isSupported()) {\n throw new Error('WebAuthn is not supported in this browser');\n }\n\n const challenge = ethers.randomBytes(32);\n const challengeBase64 = base64URLEncode(challenge);\n\n // Build exclude list: prevent re-registering on the same authenticator\n const excludeList = excludeCredentialIds ?? this.getAllStoredCredentials().map(c => c.credentialId);\n\n const options: PublicKeyCredentialCreationOptionsJSON = {\n challenge: challengeBase64,\n rp: {\n name: this.config.rpName,\n id: this.config.rpId,\n },\n user: {\n id: base64URLEncode(ethers.toUtf8Bytes(username)),\n name: username,\n displayName: displayName,\n },\n pubKeyCredParams: [\n { alg: -7, type: 'public-key' }, // ES256 (P-256)\n { alg: -257, type: 'public-key' }, // RS256\n { alg: -8, type: 'public-key' }, // EdDSA\n ],\n excludeCredentials: excludeList.map(id => ({\n id,\n type: 'public-key' as const,\n transports: ['internal' as const, 'hybrid' as const],\n })),\n authenticatorSelection: {\n // Allow cross-platform for backup on security keys\n userVerification: this.config.userVerification,\n residentKey: 'required',\n requireResidentKey: true,\n },\n timeout: this.config.timeout,\n attestation: 'none',\n };\n\n const response = await startRegistration(options);\n const publicKey = this.extractPublicKeyFromAttestation(response);\n const keyHash = computeKeyHash(publicKey.x, publicKey.y);\n\n const backupCredential: PasskeyCredential = {\n credentialId: response.id,\n publicKeyX: publicKey.x,\n publicKeyY: publicKey.y,\n keyHash,\n };\n\n // Store locally alongside existing credentials\n this.addCredentialToStorage(backupCredential);\n\n return backupCredential;\n }\n\n /**\n * Get registration info for backup state from a registration response.\n *\n * This extracts the backup eligibility (BE) and backup state (BS) flags\n * from the authenticator data, which indicate whether the credential\n * is eligible for cloud sync and whether it is currently synced.\n *\n * @param authenticatorData - Hex-encoded authenticator data from registration\n * @returns Backup flags, or null if not determinable\n */\n static parseBackupFlags(authenticatorData: string): {\n backupEligible: boolean;\n backupState: boolean;\n } | null {\n try {\n const data = ethers.getBytes(authenticatorData);\n if (data.length < 37) return null;\n\n // Flags byte is at offset 32 (after the 32-byte rpIdHash)\n const flags = data[32];\n\n // Bit 3 (0x08) = Backup Eligible (BE)\n // Bit 4 (0x10) = Backup State (BS)\n return {\n backupEligible: (flags & 0x08) !== 0,\n backupState: (flags & 0x10) !== 0,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Get the number of credentials stored locally.\n */\n getStoredCredentialCount(): number {\n return this.getAllStoredCredentials().length;\n }\n\n /**\n * Get all credential IDs stored locally (for exclude lists).\n */\n getStoredCredentialIds(): string[] {\n return this.getAllStoredCredentials().map(c => c.credentialId);\n }\n\n private extractPublicKeyFromAttestation(\n response: RegistrationResponseJSON\n ): { x: bigint; y: bigint } {\n const attestationObject = base64URLDecode(response.response.attestationObject);\n\n // Parse CBOR attestation object\n // The attestation object is a CBOR map with keys: fmt, authData, attStmt\n // We need to extract the authData which contains the credential public key\n\n let offset = 0;\n\n // Skip the CBOR map header (usually 0xa3 for 3-item map or 0xa2 for 2-item map)\n if (attestationObject[offset] >= 0xa0 && attestationObject[offset] <= 0xbf) {\n offset++;\n }\n\n // Find the authData field in the CBOR map\n // Look for the text string \"authData\" (0x68 followed by \"authData\")\n while (offset < attestationObject.length - 37) {\n if (attestationObject[offset] === 0x68 && // text string, 8 bytes\n attestationObject[offset + 1] === 0x61 && // 'a'\n attestationObject[offset + 2] === 0x75 && // 'u'\n attestationObject[offset + 3] === 0x74 && // 't'\n attestationObject[offset + 4] === 0x68 && // 'h'\n attestationObject[offset + 5] === 0x44 && // 'D'\n attestationObject[offset + 6] === 0x61 && // 'a'\n attestationObject[offset + 7] === 0x74 && // 't'\n attestationObject[offset + 8] === 0x61) { // 'a'\n offset += 9;\n break;\n }\n offset++;\n }\n\n // Skip the byte string header for authData\n if (attestationObject[offset] === 0x58 || attestationObject[offset] === 0x59) {\n // 0x58 = 1-byte length, 0x59 = 2-byte length\n const lengthBytes = attestationObject[offset] === 0x58 ? 1 : 2;\n offset += 1 + lengthBytes;\n }\n\n // Now we're at the start of authData\n // authData structure:\n // - rpIdHash: 32 bytes\n // - flags: 1 byte\n // - signCount: 4 bytes\n // - attestedCredentialData (if AT flag is set):\n // - aaguid: 16 bytes\n // - credentialIdLength: 2 bytes\n // - credentialId: credentialIdLength bytes\n // - credentialPublicKey: CBOR-encoded COSE_Key\n\n offset += 32; // Skip rpIdHash\n offset += 1; // Skip flags\n offset += 4; // Skip signCount\n offset += 16; // Skip aaguid\n\n // Read credential ID length\n const credIdLen = (attestationObject[offset] << 8) | attestationObject[offset + 1];\n offset += 2;\n offset += credIdLen; // Skip credential ID\n\n // Now we're at the COSE public key\n const coseKey = attestationObject.slice(offset);\n\n console.log('COSE key length:', coseKey.length);\n console.log('COSE key hex:', this.bytesToHex(coseKey.slice(0, Math.min(100, coseKey.length))));\n\n const { x, y } = this.parseCOSEKey(coseKey);\n return { x, y };\n }\n\n private parseCOSEKey(coseKey: Uint8Array): { x: bigint; y: bigint } {\n console.log('COSE key length:', coseKey.length);\n console.log('COSE key hex:', this.bytesToHex(coseKey));\n\n // Try multiple parsing strategies\n const parsed = this.tryParseCOSEKeyStrategies(coseKey);\n if (parsed) {\n return parsed;\n }\n\n // If all strategies fail, try using a CBOR parser approach\n return this.parseCOSEKeyWithCBORStructure(coseKey);\n }\n\n private tryParseCOSEKeyStrategies(coseKey: Uint8Array): { x: bigint; y: bigint } | null {\n // Strategy 1: Look for the specific pattern of EC2 keys\n const keyBytes = new Uint8Array(coseKey);\n\n // Common pattern for EC2 keys with P-256 curve\n for (let i = 0; i < keyBytes.length - 40; i++) {\n // Check for potential x coordinate (32 bytes preceded by key marker)\n if (keyBytes[i] === 0x58 && keyBytes[i + 1] === 0x20) {\n const potentialX = keyBytes.slice(i + 2, i + 34);\n\n // Look for y coordinate after x\n for (let j = i + 34; j < keyBytes.length - 34; j++) {\n if (keyBytes[j] === 0x58 && keyBytes[j + 1] === 0x20) {\n const potentialY = keyBytes.slice(j + 2, j + 34);\n\n // Verify these look like valid coordinates\n if (this.isValidCoordinate(potentialX) && this.isValidCoordinate(potentialY)) {\n console.log('Found coordinates via pattern matching');\n return {\n x: this.bytesToBigInt(potentialX),\n y: this.bytesToBigInt(potentialY)\n };\n }\n }\n }\n }\n }\n\n // Strategy 2: Look for ASN.1 structure\n return this.tryParseASN1Structure(keyBytes);\n }\n\n private parseCOSEKeyWithCBORStructure(coseKey: Uint8Array): { x: bigint; y: bigint } {\n // More flexible parsing that handles different CBOR structures\n const bytes = new Uint8Array(coseKey);\n let xBytes: Uint8Array | null = null;\n let yBytes: Uint8Array | null = null;\n\n // Look for x and y coordinates by scanning for byte strings\n let i = 0;\n while (i < bytes.length) {\n // Check for byte string markers\n if (bytes[i] === 0x58) { // Byte string with length byte\n const length = bytes[i + 1];\n if (length === 0x20) { // 32 bytes - likely a coordinate\n const start = i + 2;\n const end = start + 32;\n\n if (end <= bytes.length) {\n const coordinate = bytes.slice(start, end);\n\n // Assign to x or y based on position or previous assignments\n if (!xBytes) {\n xBytes = coordinate;\n console.log('Found x at offset', i);\n } else if (!yBytes) {\n yBytes = coordinate;\n console.log('Found y at offset', i);\n break; // Found both, exit loop\n }\n }\n i = end;\n } else {\n i += length + 2;\n }\n } else if (bytes[i] === 0x42) { // Byte string with 2-byte length\n if (i + 3 < bytes.length) {\n const length = (bytes[i + 1] << 8) | bytes[i + 2];\n if (length === 32) {\n const start = i + 3;\n const end = start + 32;\n\n if (end <= bytes.length) {\n const coordinate = bytes.slice(start, end);\n\n if (!xBytes) {\n xBytes = coordinate;\n console.log('Found x at offset', i);\n } else if (!yBytes) {\n yBytes = coordinate;\n console.log('Found y at offset', i);\n break;\n }\n }\n i = end;\n } else {\n i += length + 3;\n }\n } else {\n i++;\n }\n } else if (bytes[i] === 0x40) { // Byte string with indefinite length\n // Skip indefinite length marker\n i++;\n // Look for 0x04 marker (uncompressed point) or direct coordinates\n while (i < bytes.length && bytes[i] !== 0xFF) { // 0xFF is break marker\n if (bytes[i] === 0x04 && i + 65 <= bytes.length) {\n // Uncompressed EC point format\n const x = bytes.slice(i + 1, i + 33);\n const y = bytes.slice(i + 33, i + 65);\n\n if (this.isValidCoordinate(x) && this.isValidCoordinate(y)) {\n xBytes = x;\n yBytes = y;\n console.log('Found coordinates in uncompressed point format');\n break;\n }\n }\n i++;\n }\n if (xBytes && yBytes) break;\n } else {\n i++;\n }\n }\n\n if (!xBytes || !yBytes) {\n // Fallback: Try to find any 32-byte sequences\n const potentialCoords = this.find32ByteSequences(bytes);\n if (potentialCoords.length >= 2) {\n xBytes = potentialCoords[0];\n yBytes = potentialCoords[1];\n console.log('Fallback: Using first two 32-byte sequences as coordinates');\n }\n }\n\n if (!xBytes || !yBytes) {\n console.error('Failed to find coordinates in COSE key. Full dump:');\n console.error('Hex:', this.bytesToHex(bytes));\n console.error('Structure analysis:');\n this.analyzeCOSEStructure(bytes);\n throw new Error('Failed to extract public key coordinates from COSE key. Check console for details.');\n }\n\n return {\n x: this.bytesToBigInt(xBytes),\n y: this.bytesToBigInt(yBytes)\n };\n }\n\n private tryParseASN1Structure(bytes: Uint8Array): { x: bigint; y: bigint } | null {\n // ASN.1 SEQUENCE for EC public key\n if (bytes[0] === 0x30) { // SEQUENCE tag\n let offset = 2; // Skip tag and length\n\n // Look for BIT STRING (0x03)\n if (bytes[offset] === 0x03) {\n offset += 2; // Skip BIT STRING tag and unused bits\n\n // Look for another SEQUENCE\n if (bytes[offset] === 0x30) {\n offset += 2;\n\n // Should now have OID for P-256: 1.2.840.10045.3.1.7\n // Skip OID (usually 10 bytes: 06 08 2A 86 48 CE 3D 03 01 07)\n offset += 12;\n\n // BIT STRING containing the raw public key\n if (bytes[offset] === 0x03 && bytes[offset + 2] === 0x04) {\n offset += 3; // Skip to uncompressed point (0x04)\n\n const x = bytes.slice(offset, offset + 32);\n const y = bytes.slice(offset + 32, offset + 64);\n\n if (x.length === 32 && y.length === 32) {\n console.log('Found coordinates via ASN.1 parsing');\n return {\n x: this.bytesToBigInt(x),\n y: this.bytesToBigInt(y)\n };\n }\n }\n }\n }\n }\n return null;\n }\n\n private find32ByteSequences(bytes: Uint8Array): Uint8Array[] {\n const sequences: Uint8Array[] = [];\n\n for (let i = 0; i <= bytes.length - 32; i++) {\n // Check if this 32-byte sequence looks like a valid coordinate\n const sequence = bytes.slice(i, i + 32);\n if (this.isValidCoordinate(sequence)) {\n sequences.push(sequence);\n }\n }\n\n return sequences;\n }\n\n private isValidCoordinate(bytes: Uint8Array): boolean {\n if (bytes.length !== 32) return false;\n\n // Basic validation: not all zeros, not all FF\n let allZeros = true;\n let allOnes = true;\n\n for (const byte of bytes) {\n if (byte !== 0) allZeros = false;\n if (byte !== 0xFF) allOnes = false;\n }\n\n return !allZeros && !allOnes;\n }\n\n private bytesToBigInt(bytes: Uint8Array): bigint {\n return BigInt('0x' + this.bytesToHex(bytes));\n }\n\n private bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n }\n\n private analyzeCOSEStructure(bytes: Uint8Array): void {\n console.log('COSE Structure Analysis:');\n console.log('First 20 bytes:', this.bytesToHex(bytes.slice(0, 20)));\n\n // Check for known COSE key structure markers\n const firstByte = bytes[0];\n console.log('First byte (0x' + firstByte.toString(16) + '):');\n\n if (firstByte >= 0xa0 && firstByte <= 0xbf) {\n console.log('- Definite length map with', (firstByte & 0x1f), 'pairs');\n } else if (firstByte === 0xbf) {\n console.log('- Indefinite length map');\n } else if (firstByte === 0x04) {\n console.log('- Byte string');\n } else if (firstByte === 0x02) {\n console.log('- Negative integer');\n }\n\n // Count occurrences of 32-byte sequences\n let count32 = 0;\n for (let i = 0; i <= bytes.length - 32; i++) {\n const chunk = bytes.slice(i, i + 32);\n if (this.isValidCoordinate(chunk)) {\n console.log(`Found valid 32-byte sequence at offset ${i}:`,\n this.bytesToHex(chunk.slice(0, 8)) + '...');\n count32++;\n }\n }\n console.log(`Total valid 32-byte sequences: ${count32}`);\n\n // Look for specific markers\n console.log('Looking for known markers:');\n const markers = [\n { byte: 0x04, name: 'Uncompressed point marker' },\n { byte: 0x03, name: 'BIT STRING' },\n { byte: 0x30, name: 'SEQUENCE' },\n { byte: 0x02, name: 'INTEGER' },\n { byte: 0x06, name: 'OBJECT IDENTIFIER' },\n { byte: 0x58, name: 'Byte string with length byte' },\n { byte: 0x42, name: 'Byte string with 2-byte length' },\n { byte: 0x40, name: 'Byte string indefinite length' },\n { byte: 0xA0, name: 'Map start' },\n { byte: 0xBF, name: 'Indefinite map start' },\n ];\n\n for (const marker of markers) {\n const indices = [];\n for (let i = 0; i < bytes.length; i++) {\n if (bytes[i] === marker.byte) {\n indices.push(i);\n }\n }\n if (indices.length > 0) {\n console.log(` ${marker.name} (0x${marker.byte.toString(16)}) at positions:`, indices.slice(0, 5).join(', '));\n }\n }\n }\n\n private parseAuthenticationResponse(response: AuthenticationResponseJSON): WebAuthnSignature {\n const authenticatorData = base64URLDecode(response.response.authenticatorData);\n const clientDataJSON = response.response.clientDataJSON;\n const signature = base64URLDecode(response.response.signature);\n\n const { r, s } = parseDERSignature(signature);\n\n // Normalize signature to low-S form.\n // The on-chain WebAuthn verifier rejects signatures with s > n/2.\n // WebAuthn authenticators are not guaranteed to produce low-S signatures,\n // so without this normalization, valid signatures can intermittently fail.\n const P256_N = BigInt('0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551');\n const P256_N_DIV_2 = BigInt(\n '0x7FFFFFFF800000007FFFFFFFFFFFFFFFDE737D56D38BCF4279DCE5617E3192A8'\n );\n\n const clientDataStr = new TextDecoder().decode(base64URLDecode(clientDataJSON));\n const challengeIndex = clientDataStr.indexOf('\"challenge\"');\n const typeIndex = clientDataStr.indexOf('\"type\"');\n\n if (challengeIndex === -1 || typeIndex === -1) {\n throw new Error('Invalid clientDataJSON format');\n }\n\n return {\n authenticatorData: ethers.hexlify(authenticatorData),\n clientDataJSON: clientDataStr,\n challengeIndex,\n typeIndex,\n r: this.bytesToBigInt(r),\n s: (() => {\n const sBig = this.bytesToBigInt(s);\n return sBig > P256_N_DIV_2 ? P256_N - sBig : sBig;\n })(),\n };\n }\n}\n","const API_ROOT = '/api/v1';\n\nfunction trimTrailingSlashes(value: string): string {\n return value.trim().replace(/\\/+$/, '');\n}\n\nexport function normalizeRelayerOrigin(value: string): string {\n const trimmed = trimTrailingSlashes(value);\n if (!trimmed) {\n return '';\n }\n\n if (trimmed.startsWith('/')) {\n return trimmed.replace(/\\/api\\/v1$/i, '');\n }\n\n try {\n const url = new URL(trimmed);\n url.pathname = url.pathname.replace(/\\/api\\/v1$/i, '').replace(/\\/+$/, '');\n return url.toString().replace(/\\/+$/, '');\n } catch {\n return trimmed.replace(/\\/api\\/v1$/i, '');\n }\n}\n\nexport function buildRelayerApiUrl(baseUrl: string, path: string): string {\n const normalizedPath = path.startsWith('/') ? path : `/${path}`;\n const trimmed = trimTrailingSlashes(baseUrl);\n\n if (!trimmed) {\n return `${API_ROOT}${normalizedPath}`;\n }\n\n if (trimmed.startsWith('/')) {\n if (/\\/api\\/v1$/i.test(trimmed) || /\\/api\\/auth\\/relay$/i.test(trimmed)) {\n return `${trimmed}${normalizedPath}`;\n }\n\n return `${trimmed}${normalizedPath}`;\n }\n\n try {\n const url = new URL(trimmed);\n\n if (/\\/api\\/v1$/i.test(url.pathname) || /\\/api\\/auth\\/relay$/i.test(url.pathname)) {\n url.pathname = `${url.pathname.replace(/\\/+$/, '')}${normalizedPath}`;\n return url.toString();\n }\n\n if (!url.pathname || url.pathname === '/') {\n url.pathname = `${API_ROOT}${normalizedPath}`;\n return url.toString();\n }\n\n url.pathname = `${url.pathname.replace(/\\/+$/, '')}${normalizedPath}`;\n return url.toString();\n } catch {\n if (/\\/api\\/v1$/i.test(trimmed) || /\\/api\\/auth\\/relay$/i.test(trimmed)) {\n return `${trimmed}${normalizedPath}`;\n }\n\n return `${trimmed}${API_ROOT}${normalizedPath}`;\n }\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@ import {
2
2
  encodeBridgeAction,
3
3
  encodeExecuteAction,
4
4
  encodeTransferAction
5
- } from "./chunk-F3YAGZSW.mjs";
5
+ } from "./chunk-TPEP6XUA.mjs";
6
6
 
7
7
  // src/chains/sui/SuiClient.ts
8
8
  import { SuiClient as MystenSuiClient } from "@mysten/sui/client";
@@ -461,4 +461,4 @@ var SuiClient = class {
461
461
  export {
462
462
  SuiClient
463
463
  };
464
- //# sourceMappingURL=chunk-SXXGTQIR.mjs.map
464
+ //# sourceMappingURL=chunk-E3SU36C2.mjs.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MAINNET_CHAINS,
3
3
  TESTNET_CHAINS
4
- } from "./chunk-X7BZMSPQ.mjs";
4
+ } from "./chunk-RD6ZYUVG.mjs";
5
5
 
6
6
  // src/utils.ts
7
7
  import { ethers } from "ethers";
@@ -176,4 +176,4 @@ export {
176
176
  isValidWormholeChainId,
177
177
  retryWithBackoff
178
178
  };
179
- //# sourceMappingURL=chunk-NUWSMJFJ.mjs.map
179
+ //# sourceMappingURL=chunk-EFIXFA6V.mjs.map
@@ -2,7 +2,7 @@ import {
2
2
  encodeBridgeAction,
3
3
  encodeExecuteAction,
4
4
  encodeTransferAction
5
- } from "./chunk-F3YAGZSW.mjs";
5
+ } from "./chunk-TPEP6XUA.mjs";
6
6
 
7
7
  // src/chains/starknet/StarknetClient.ts
8
8
  import { createHash } from "crypto";
@@ -423,4 +423,4 @@ var StarknetClient = class {
423
423
  export {
424
424
  StarknetClient
425
425
  };
426
- //# sourceMappingURL=chunk-MLXQHIH2.mjs.map
426
+ //# sourceMappingURL=chunk-GM5DKEHD.mjs.map
@@ -5,11 +5,11 @@ import {
5
5
  WalletManager,
6
6
  getAllTokens,
7
7
  isNativeToken
8
- } from "./chunk-PDHZ5X5O.mjs";
8
+ } from "./chunk-YYT3V7CI.mjs";
9
9
  import {
10
10
  MAINNET_CHAINS,
11
11
  TESTNET_CHAINS
12
- } from "./chunk-X7BZMSPQ.mjs";
12
+ } from "./chunk-RD6ZYUVG.mjs";
13
13
 
14
14
  // src/queries/portfolio.ts
15
15
  import axios from "axios";
@@ -546,4 +546,4 @@ export {
546
546
  QueryPortfolioError,
547
547
  queryPortfolio
548
548
  };
549
- //# sourceMappingURL=chunk-GWJRKDSA.mjs.map
549
+ //# sourceMappingURL=chunk-GOWXQPTW.mjs.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  MAINNET_CHAINS,
6
6
  TESTNET_CHAINS
7
- } from "./chunk-X7BZMSPQ.mjs";
7
+ } from "./chunk-RD6ZYUVG.mjs";
8
8
 
9
9
  // src/queries/hubState.ts
10
10
  import axios from "axios";
@@ -327,4 +327,4 @@ export {
327
327
  QueryHubStateError,
328
328
  queryHubState
329
329
  };
330
- //# sourceMappingURL=chunk-OVMMTL6H.mjs.map
330
+ //# sourceMappingURL=chunk-ICGB3AHI.mjs.map
@@ -679,7 +679,7 @@ var CHAIN_PRESETS = {
679
679
  chainId: 0,
680
680
  wormholeChainId: 50001,
681
681
  // Custom bridge (non-Wormhole)
682
- rpcUrl: "https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/tsOnfTBZDKMXcUA26OED-",
682
+ rpcUrl: "https://starknet-sepolia-rpc.publicnode.com",
683
683
  explorerUrl: "https://sepolia.starkscan.co",
684
684
  isEvm: false,
685
685
  contracts: {
@@ -778,6 +778,16 @@ var CHAIN_PRESETS = {
778
778
  }
779
779
  }
780
780
  };
781
+ var _rpcOverrides = {};
782
+ function configureDefaultRpcUrls(overrides) {
783
+ for (const key of Object.keys(_rpcOverrides)) {
784
+ delete _rpcOverrides[key];
785
+ }
786
+ Object.assign(_rpcOverrides, overrides);
787
+ }
788
+ function getRpcUrlOverride(chain, network) {
789
+ return _rpcOverrides[chain]?.[network];
790
+ }
781
791
  function getChainConfig(chain, network = "testnet") {
782
792
  const preset = CHAIN_PRESETS[chain];
783
793
  if (!preset) {
@@ -785,7 +795,12 @@ function getChainConfig(chain, network = "testnet") {
785
795
  `Unknown chain: "${chain}". Supported chains: ${Object.keys(CHAIN_PRESETS).join(", ")}`
786
796
  );
787
797
  }
788
- return preset[network];
798
+ const config = preset[network];
799
+ const rpcOverride = getRpcUrlOverride(chain, network);
800
+ if (rpcOverride) {
801
+ return { ...config, rpcUrl: rpcOverride };
802
+ }
803
+ return config;
789
804
  }
790
805
  function getChainPreset(chain) {
791
806
  const preset = CHAIN_PRESETS[chain];
@@ -829,6 +844,8 @@ export {
829
844
  getEffectivePrimaryHub,
830
845
  CHAIN_NAMES,
831
846
  CHAIN_PRESETS,
847
+ configureDefaultRpcUrls,
848
+ getRpcUrlOverride,
832
849
  getChainConfig,
833
850
  getChainPreset,
834
851
  getSupportedChains,
@@ -837,4 +854,4 @@ export {
837
854
  isHubChain,
838
855
  getDefaultHub
839
856
  };
840
- //# sourceMappingURL=chunk-QDO6NQ7P.mjs.map
857
+ //# sourceMappingURL=chunk-M3GUNREX.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.g.alchemy.com/starknet/version/rpc/v0_7/tsOnfTBZDKMXcUA26OED-',\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// Helper Functions\n// ============================================================================\n\n/**\n * Get chain configuration by name and network\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 return preset[network];\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;AASO,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,SAAO,OAAO,OAAO;AACvB;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":[]}
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,6 +1,6 @@
1
1
  import {
2
2
  EVMClient
3
- } from "./chunk-USDA5JTN.mjs";
3
+ } from "./chunk-YBN2VC6E.mjs";
4
4
 
5
5
  // src/chains/avalanche/AvalancheClient.ts
6
6
  import { ethers } from "ethers";
@@ -213,4 +213,4 @@ var AvalancheClient = class extends EVMClient {
213
213
  export {
214
214
  AvalancheClient
215
215
  };
216
- //# sourceMappingURL=chunk-N4A2RMUN.mjs.map
216
+ //# sourceMappingURL=chunk-PEGOXMBU.mjs.map