@veridex/sdk 1.1.5 → 1.1.7

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 (102) hide show
  1. package/dist/{EVMClient-Bmy9czkE.d.mts → EVMClient-DqDiFak8.d.mts} +1 -1
  2. package/dist/auth/prepareAuth.d.mts +5 -4
  3. package/dist/auth/prepareAuth.js +143 -1422
  4. package/dist/auth/prepareAuth.js.map +1 -1
  5. package/dist/auth/prepareAuth.mjs +17 -96
  6. package/dist/auth/prepareAuth.mjs.map +1 -1
  7. package/dist/chains/aptos/index.d.mts +1 -1
  8. package/dist/chains/aptos/index.js +11 -33
  9. package/dist/chains/aptos/index.js.map +1 -1
  10. package/dist/chains/aptos/index.mjs +2 -2
  11. package/dist/chains/avalanche/index.d.mts +2 -2
  12. package/dist/chains/avalanche/index.js +19 -115
  13. package/dist/chains/avalanche/index.js.map +1 -1
  14. package/dist/chains/avalanche/index.mjs +3 -3
  15. package/dist/chains/evm/index.d.mts +5 -4
  16. package/dist/chains/evm/index.js +19 -115
  17. package/dist/chains/evm/index.js.map +1 -1
  18. package/dist/chains/evm/index.mjs +2 -2
  19. package/dist/chains/solana/index.d.mts +1 -1
  20. package/dist/chains/solana/index.js +11 -33
  21. package/dist/chains/solana/index.js.map +1 -1
  22. package/dist/chains/solana/index.mjs +2 -2
  23. package/dist/chains/stacks/index.d.mts +1 -1
  24. package/dist/chains/stacks/index.js +11 -38
  25. package/dist/chains/stacks/index.js.map +1 -1
  26. package/dist/chains/stacks/index.mjs +2 -2
  27. package/dist/chains/starknet/index.d.mts +36 -2
  28. package/dist/chains/starknet/index.js +208 -37
  29. package/dist/chains/starknet/index.js.map +1 -1
  30. package/dist/chains/starknet/index.mjs +9 -4
  31. package/dist/chains/stellar/index.d.mts +2 -1
  32. package/dist/chains/sui/index.d.mts +1 -1
  33. package/dist/chains/sui/index.js +11 -27
  34. package/dist/chains/sui/index.js.map +1 -1
  35. package/dist/chains/sui/index.mjs +2 -2
  36. package/dist/{chunk-ZNIVNPGF.mjs → chunk-3PCAVZUZ.mjs} +173 -37
  37. package/dist/chunk-3PCAVZUZ.mjs.map +1 -0
  38. package/dist/{chunk-DQOW3G7M.mjs → chunk-6BINP4RT.mjs} +48 -9
  39. package/dist/{chunk-DQOW3G7M.mjs.map → chunk-6BINP4RT.mjs.map} +1 -1
  40. package/dist/{chunk-7KN6Y4GX.mjs → chunk-AK5HWYX4.mjs} +12 -40
  41. package/dist/chunk-AK5HWYX4.mjs.map +1 -0
  42. package/dist/{chunk-QVTADARB.mjs → chunk-FPSCAGYS.mjs} +12 -35
  43. package/dist/chunk-FPSCAGYS.mjs.map +1 -0
  44. package/dist/{chunk-USVZH4QC.mjs → chunk-H3WRT6Y4.mjs} +20 -117
  45. package/dist/chunk-H3WRT6Y4.mjs.map +1 -0
  46. package/dist/{chunk-GXJUY2SC.mjs → chunk-MNH22BM2.mjs} +12 -35
  47. package/dist/chunk-MNH22BM2.mjs.map +1 -0
  48. package/dist/chunk-N42LPFPJ.mjs +177 -0
  49. package/dist/chunk-N42LPFPJ.mjs.map +1 -0
  50. package/dist/{chunk-D57UJ4L5.mjs → chunk-NKSRF45N.mjs} +12 -29
  51. package/dist/chunk-NKSRF45N.mjs.map +1 -0
  52. package/dist/{chunk-BJH5HJL5.mjs → chunk-SKZLZFE2.mjs} +91 -65
  53. package/dist/chunk-SKZLZFE2.mjs.map +1 -0
  54. package/dist/{chunk-NVRAQPSF.mjs → chunk-UF5NWMSQ.mjs} +20 -4
  55. package/dist/chunk-UF5NWMSQ.mjs.map +1 -0
  56. package/dist/chunk-WC4X3MAO.mjs +58 -0
  57. package/dist/chunk-WC4X3MAO.mjs.map +1 -0
  58. package/dist/{chunk-5FH67KLG.mjs → chunk-XHDOSV2F.mjs} +2 -2
  59. package/dist/{index-CKKUV4J7.d.mts → index-D1nb2JV9.d.mts} +2 -2
  60. package/dist/index-qyOqd8tx.d.mts +517 -0
  61. package/dist/index.d.mts +30 -366
  62. package/dist/index.js +2412 -2486
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +986 -55
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/passkey-fh8bo2w-.d.mts +241 -0
  67. package/dist/passkey.d.mts +2 -182
  68. package/dist/passkey.js +86 -7
  69. package/dist/passkey.js.map +1 -1
  70. package/dist/passkey.mjs +2 -1
  71. package/dist/payload.d.mts +22 -28
  72. package/dist/payload.js +50 -9
  73. package/dist/payload.js.map +1 -1
  74. package/dist/payload.mjs +7 -3
  75. package/dist/platform/index.d.mts +3 -0
  76. package/dist/platform/index.js +216 -0
  77. package/dist/platform/index.js.map +1 -0
  78. package/dist/platform/index.mjs +21 -0
  79. package/dist/platform/index.mjs.map +1 -0
  80. package/dist/{portfolio-W2FQ2G3O.mjs → portfolio-MLP2JIFK.mjs} +2 -3
  81. package/dist/queries/index.mjs +324 -10
  82. package/dist/queries/index.mjs.map +1 -1
  83. package/dist/{types-DP2CQT8p.d.mts → types-CdlEbixV.d.mts} +12 -1
  84. package/dist/types.d.mts +1 -0
  85. package/dist/types.js.map +1 -1
  86. package/package.json +7 -1
  87. package/dist/chunk-72ZA3OYQ.mjs +0 -20
  88. package/dist/chunk-72ZA3OYQ.mjs.map +0 -1
  89. package/dist/chunk-7KN6Y4GX.mjs.map +0 -1
  90. package/dist/chunk-BJH5HJL5.mjs.map +0 -1
  91. package/dist/chunk-D57UJ4L5.mjs.map +0 -1
  92. package/dist/chunk-GXJUY2SC.mjs.map +0 -1
  93. package/dist/chunk-NVRAQPSF.mjs.map +0 -1
  94. package/dist/chunk-QVTADARB.mjs.map +0 -1
  95. package/dist/chunk-USVZH4QC.mjs.map +0 -1
  96. package/dist/chunk-XDIIFIW6.mjs +0 -330
  97. package/dist/chunk-XDIIFIW6.mjs.map +0 -1
  98. package/dist/chunk-ZNIVNPGF.mjs.map +0 -1
  99. package/dist/chunk-ZXMTPBSP.mjs +0 -857
  100. package/dist/chunk-ZXMTPBSP.mjs.map +0 -1
  101. /package/dist/{chunk-5FH67KLG.mjs.map → chunk-XHDOSV2F.mjs.map} +0 -0
  102. /package/dist/{portfolio-W2FQ2G3O.mjs.map → portfolio-MLP2JIFK.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/PasskeyManager.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\n/**\n * Assurance tier of a credential, derived from the authoritative WebAuthn\n * Backup Eligibility (BE) flag — not from a platform guess.\n *\n * - `device-bound`: BE=0. The private key cannot leave the authenticator\n * (secure element, or a hardware key such as a YubiKey). Not recoverable.\n * - `synced`: BE=1. The credential is eligible for sync/backup by a provider\n * (iCloud Keychain, Google Password Manager, Windows Hello). Recoverable via\n * the user's platform account — which its security therefore depends on.\n * - `unknown`: flags were not determinable from the registration response.\n */\nexport type CredentialAssuranceLevel = 'device-bound' | 'synced' | 'unknown';\n\n/** WebAuthn-derived assurance metadata for a credential. */\nexport interface CredentialAssurance {\n /** BE flag (0x08) — credential may be backed up / synced by a provider. */\n backupEligible: boolean;\n /** BS flag (0x10) — credential is currently backed up / synced. */\n backupState: boolean;\n /** UV flag (0x04) — user was verified (biometric/PIN) at registration. */\n userVerified: boolean;\n /** Tier derived from BE. Consumed by the policy engine to gate authority. */\n level: CredentialAssuranceLevel;\n /** Authenticator model identifier (16-byte AAGUID, hex). Zeroed by many platform authenticators. */\n aaguid?: string;\n}\n\nexport interface PasskeyCredential {\n credentialId: string;\n publicKeyX: bigint;\n publicKeyY: bigint;\n keyHash: string;\n /**\n * Authoritative assurance derived from the WebAuthn authenticator data.\n * Optional for backward compatibility with credentials constructed from\n * stored fields (e.g. env vars) that predate assurance capture.\n */\n assurance?: CredentialAssurance;\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 assurance: PasskeyManager.assuranceFromRegistration(response) ?? undefined,\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 assurance: PasskeyManager.assuranceFromRegistration(response) ?? undefined,\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 assurance = PasskeyManager.deriveAssurance(ethers.getBytes(authenticatorData));\n if (!assurance) return null;\n return {\n backupEligible: assurance.backupEligible,\n backupState: assurance.backupState,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Derive credential assurance from raw WebAuthn authenticator data.\n *\n * authData layout:\n * rpIdHash (32) | flags (1) | signCount (4) | [attestedCredentialData: aaguid (16) | ...]\n *\n * Flags byte: UP 0x01 | UV 0x04 | BE 0x08 | BS 0x10 | AT 0x40 | ED 0x80\n *\n * BE is the authoritative signal for whether a credential is device-bound or\n * syncable. It is set by the authenticator itself — unlike a platform/user-agent\n * guess, it correctly identifies a hardware key used on a syncing platform.\n *\n * @returns Assurance, or `null` if authData is too short to be valid.\n */\n static deriveAssurance(authData: Uint8Array): CredentialAssurance | null {\n if (authData.length < 37) return null;\n\n const flags = authData[32];\n const backupEligible = (flags & 0x08) !== 0;\n const attestedCredentialData = (flags & 0x40) !== 0;\n\n // AAGUID is the first 16 bytes of attestedCredentialData, which begins at\n // offset 37 (after rpIdHash + flags + signCount) and is only present when AT is set.\n let aaguid: string | undefined;\n if (attestedCredentialData && authData.length >= 53) {\n aaguid = ethers.hexlify(authData.slice(37, 53));\n }\n\n return {\n backupEligible,\n backupState: (flags & 0x10) !== 0,\n userVerified: (flags & 0x04) !== 0,\n level: backupEligible ? 'synced' : 'device-bound',\n aaguid,\n };\n }\n\n /**\n * Extract raw authenticator data from a registration response.\n *\n * Prefers the `authenticatorData` field when the authenticator provides it,\n * and otherwise locates the `authData` byte string inside the CBOR\n * attestation object.\n */\n private static extractAuthData(response: RegistrationResponseJSON): Uint8Array | null {\n const direct = response.response.authenticatorData;\n if (direct) {\n try {\n return base64URLDecode(direct);\n } catch {\n // fall through to the attestation object\n }\n }\n\n try {\n const attestationObject = base64URLDecode(response.response.attestationObject);\n let offset = 0;\n\n // Skip the CBOR map header\n if (attestationObject[offset] >= 0xa0 && attestationObject[offset] <= 0xbf) {\n offset++;\n }\n\n // Locate the \"authData\" text key (0x68 = text string of 8 bytes)\n const key = [0x68, 0x61, 0x75, 0x74, 0x68, 0x44, 0x61, 0x74, 0x61];\n let found = false;\n while (offset < attestationObject.length - 37) {\n if (key.every((byte, i) => attestationObject[offset + i] === byte)) {\n offset += key.length;\n found = true;\n break;\n }\n offset++;\n }\n if (!found) return null;\n\n // Skip the byte-string header (0x58 = 1-byte length, 0x59 = 2-byte length)\n if (attestationObject[offset] === 0x58) {\n offset += 2;\n } else if (attestationObject[offset] === 0x59) {\n offset += 3;\n }\n\n return attestationObject.slice(offset);\n } catch {\n return null;\n }\n }\n\n /** Derive assurance directly from a registration response. */\n static assuranceFromRegistration(response: RegistrationResponseJSON): CredentialAssurance | null {\n const authData = PasskeyManager.extractAuthData(response);\n return authData ? PasskeyManager.deriveAssurance(authData) : null;\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"],"mappings":"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","names":[]}
@@ -1,6 +1,3 @@
1
- import {
2
- WORMHOLE_QUERY_PROXY_URLS
3
- } from "./chunk-72ZA3OYQ.mjs";
4
1
  import {
5
2
  WalletManager,
6
3
  getAllTokens,
@@ -27,6 +24,22 @@ import {
27
24
  hexToUint8Array,
28
25
  isValidHexString
29
26
  } from "@wormhole-foundation/wormhole-query-sdk";
27
+
28
+ // src/queries/constants.ts
29
+ var WORMHOLE_QUERY_PROXY_URLS = {
30
+ mainnet: "https://query.wormhole.com/v1/query",
31
+ testnet: "https://testnet.query.wormhole.com/v1/query"
32
+ };
33
+ var WORMHOLE_QUERY_RATE_LIMIT_PER_SECOND = 6;
34
+ var WORMHOLE_QUERY_CHAIN_IDS = {
35
+ ETHEREUM: 2,
36
+ POLYGON: 5,
37
+ ARBITRUM: 23,
38
+ OPTIMISM: 24,
39
+ BASE: 30
40
+ };
41
+
42
+ // src/queries/portfolio.ts
30
43
  var QueryPortfolioError = class extends Error {
31
44
  code;
32
45
  cause;
@@ -543,7 +556,10 @@ async function queryPortfolio(userKeyHash, apiKey, options) {
543
556
  }
544
557
 
545
558
  export {
559
+ WORMHOLE_QUERY_PROXY_URLS,
560
+ WORMHOLE_QUERY_RATE_LIMIT_PER_SECOND,
561
+ WORMHOLE_QUERY_CHAIN_IDS,
546
562
  QueryPortfolioError,
547
563
  queryPortfolio
548
564
  };
549
- //# sourceMappingURL=chunk-NVRAQPSF.mjs.map
565
+ //# sourceMappingURL=chunk-UF5NWMSQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/queries/portfolio.ts","../src/queries/constants.ts"],"sourcesContent":["import axios, { AxiosError } from 'axios';\nimport { Buffer } from 'buffer';\nimport { ethers } from 'ethers';\nimport { PublicKey } from '@solana/web3.js';\nimport {\n EthCallQueryRequest,\n EthCallQueryResponse,\n PerChainQueryRequest,\n QueryRequest,\n QueryResponse,\n SolanaAccountQueryRequest,\n SolanaAccountQueryResponse,\n hexToUint8Array,\n isValidHexString,\n} from '@wormhole-foundation/wormhole-query-sdk';\n\nimport { MAINNET_CHAINS, TESTNET_CHAINS } from '../constants.js';\nimport { WalletManager } from '../core/WalletManager.js';\nimport { getAllTokens, isNativeToken } from '../constants/tokens.js';\nimport { WORMHOLE_QUERY_PROXY_URLS } from './constants.js';\n\nexport type QueryPortfolioNetwork = 'testnet' | 'mainnet';\n\nexport type QueryPortfolioOptions = {\n /** Max response age in seconds (default: 60). */\n maxAge?: number;\n network?: QueryPortfolioNetwork;\n /** Maximum attempts including the first try (default: 4). */\n maxAttempts?: number;\n /** Cache TTL in ms (default: 30_000). */\n cacheTtlMs?: number;\n /** Request timeout in ms (default: 15_000 for testnet, 10_000 for mainnet). */\n timeout?: number;\n /** Override Query Proxy endpoint. */\n endpoint?: string;\n /** Override per-chain RPC URLs used for block tag lookups. */\n rpcUrls?: Record<number, string>;\n /** Override derived vault addresses for specific Wormhole chain IDs. */\n vaultAddresses?: Record<number, string>;\n /** Override token lists (ERC20 only) for specific Wormhole chain IDs. */\n evmTokenAddresses?: Record<number, string[]>;\n /** Additional Solana accounts to include in the Solana account query (base58). */\n solanaAccounts?: string[];\n /** Optional USD prices by symbol/address for aggregation (e.g. { USDC: 1 }). */\n pricesUsd?: Record<string, number>;\n};\n\nexport type PortfolioBalance = {\n assetId: string;\n amount: bigint;\n decimals?: number;\n symbol?: string;\n usdValue?: number;\n};\n\nexport type PortfolioChainErrorCode =\n | 'UNSUPPORTED_CHAIN'\n | 'MISSING_VAULT'\n | 'MISSING_TOKENS'\n | 'ATTESTATION_STALE'\n | 'DECODE_ERROR';\n\nexport type PortfolioChainResult = {\n wormholeChainId: number;\n chainName?: string;\n vaultAddress?: string;\n blockTime?: number;\n balances: PortfolioBalance[];\n error?: {\n code: PortfolioChainErrorCode;\n message: string;\n };\n};\n\nexport type PortfolioResult = {\n proof: Uint8Array;\n totalUsd?: number;\n chains: PortfolioChainResult[];\n};\n\nexport type QueryPortfolioErrorCode =\n | 'INVALID_ARGUMENT'\n | 'NETWORK_ERROR'\n | 'PROXY_HTTP_ERROR'\n | 'PROXY_RESPONSE_INVALID'\n | 'QUERY_RESPONSE_INVALID';\n\nexport class QueryPortfolioError extends Error {\n code: QueryPortfolioErrorCode;\n cause?: unknown;\n\n constructor(code: QueryPortfolioErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'QueryPortfolioError';\n this.code = code;\n this.cause = cause;\n }\n}\n\ntype CacheEntry = { expiresAt: number; value: PortfolioResult };\nconst PORTFOLIO_CACHE = new Map<string, CacheEntry>();\n\nfunction resolveNetwork(options?: QueryPortfolioOptions): QueryPortfolioNetwork {\n if (options?.network) return options.network;\n\n const envCandidates = [\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.VERIDEX_NETWORK,\n (globalThis as any)?.process?.env?.NEXT_PUBLIC_WORMHOLE_NETWORK,\n (globalThis as any)?.process?.env?.WORMHOLE_NETWORK,\n ].filter(Boolean);\n\n const env = (envCandidates[0] as string | undefined)?.toLowerCase();\n if (env === 'mainnet' || env === 'testnet') return env;\n\n return 'testnet';\n}\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((sum, p) => sum + p.length, 0);\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction signaturesToProofBytes(signatures: string[]): Uint8Array {\n const chunks: Uint8Array[] = [];\n\n for (const sig of signatures) {\n if (typeof sig !== 'string' || sig.length !== 132 || !/^[0-9a-fA-F]+$/.test(sig)) {\n throw new QueryPortfolioError(\n 'PROXY_RESPONSE_INVALID',\n `Invalid guardian signature format (expected 132 hex chars): ${String(sig)}`\n );\n }\n // Avoid Node Buffer-backed Uint8Array (can surface as SharedArrayBuffer in DTS types).\n chunks.push(hexToUint8Array(`0x${sig}`));\n }\n\n return concatBytes(chunks);\n}\n\nfunction decodeQueryBytes(bytes: string): Uint8Array {\n if (typeof bytes !== 'string' || bytes.length === 0) {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Missing query response bytes');\n }\n\n if (isValidHexString(bytes)) {\n return hexToUint8Array(bytes);\n }\n\n try {\n if (typeof atob === 'function') {\n const raw = atob(bytes);\n const arr = new Uint8Array(raw.length);\n for (let i = 0; i < raw.length; i++) arr[i] = raw.charCodeAt(i);\n return arr;\n }\n } catch {\n // ignore\n }\n\n try {\n return new Uint8Array(Buffer.from(bytes, 'base64'));\n } catch (cause) {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Unrecognized query response bytes encoding', cause);\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Simple rate limiter for Wormhole Query Proxy (6 requests/second limit).\n * Queues requests and releases them at the allowed rate.\n */\nconst rateLimiter = {\n queue: [] as Array<() => void>,\n lastRequest: 0,\n minInterval: 170, // ~6 req/s with buffer\n \n async acquire(): Promise<void> {\n return new Promise((resolve) => {\n const tryAcquire = () => {\n const now = Date.now();\n const elapsed = now - rateLimiter.lastRequest;\n if (elapsed >= rateLimiter.minInterval) {\n rateLimiter.lastRequest = now;\n resolve();\n } else {\n setTimeout(tryAcquire, rateLimiter.minInterval - elapsed);\n }\n };\n tryAcquire();\n });\n }\n};\n\nasync function withExponentialBackoff<T>(fn: () => Promise<T>, maxAttempts: number): Promise<T> {\n let attempt = 0;\n let lastError: unknown;\n\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts) break;\n\n const baseMs = 250;\n const backoffMs = Math.min(5_000, baseMs * 2 ** (attempt - 1));\n const jitterMs = Math.floor(Math.random() * 100);\n await sleep(backoffMs + jitterMs);\n }\n }\n\n throw lastError;\n}\n\nfunction getChainConfigs(network: QueryPortfolioNetwork) {\n return network === 'testnet' ? TESTNET_CHAINS : MAINNET_CHAINS;\n}\n\nfunction getProxyEndpoint(network: QueryPortfolioNetwork, options?: QueryPortfolioOptions): string {\n if (options?.endpoint) return options.endpoint;\n return network === 'testnet' ? WORMHOLE_QUERY_PROXY_URLS.testnet : WORMHOLE_QUERY_PROXY_URLS.mainnet;\n}\n\nfunction getDefaultPortfolioChains(network: QueryPortfolioNetwork): number[] {\n // Include hub (Base Sepolia 10004) and spoke chains\n return network === 'testnet' ? [10004, 10005, 10003, 1] : [30, 24, 23, 1];\n}\n\nfunction normalizeHex32(hex: string): Uint8Array {\n if (typeof hex !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(hex)) {\n throw new QueryPortfolioError('INVALID_ARGUMENT', `Invalid userKeyHash (expected 0x + 32 bytes hex): ${hex}`);\n }\n return new Uint8Array(Buffer.from(hex.slice(2), 'hex'));\n}\n\nfunction deriveSolanaVaultAddress(programIdBase58: string, userKeyHash: string): string {\n const programId = new PublicKey(programIdBase58);\n const keyHashBytes = normalizeHex32(userKeyHash);\n const [vaultPda] = PublicKey.findProgramAddressSync([Buffer.from('vault'), Buffer.from(keyHashBytes)], programId);\n return vaultPda.toBase58();\n}\n\nfunction makeCacheKey(userKeyHash: string, apiKey: string, options: QueryPortfolioOptions | undefined, chainIds: number[]) {\n // Do not include apiKey in the cache key; it should not affect the data.\n const payload = {\n userKeyHash,\n network: resolveNetwork(options),\n chainIds: [...chainIds].sort((a, b) => a - b),\n vaultAddresses: options?.vaultAddresses ?? null,\n evmTokenAddresses: options?.evmTokenAddresses ?? null,\n solanaAccounts: options?.solanaAccounts ?? null,\n endpoint: options?.endpoint ?? null,\n };\n\n void apiKey;\n return JSON.stringify(payload);\n}\n\nfunction safeNumberFromBigint(b: bigint): number {\n const n = Number(b);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction priceLookup(pricesUsd: Record<string, number> | undefined, symbol?: string, assetId?: string): number | undefined {\n if (!pricesUsd) return undefined;\n if (symbol && pricesUsd[symbol] != null) return pricesUsd[symbol];\n if (assetId && pricesUsd[assetId] != null) return pricesUsd[assetId];\n return undefined;\n}\n\nfunction sumUsd(balances: PortfolioBalance[], pricesUsd?: Record<string, number>): number | undefined {\n let total = 0;\n let any = false;\n\n for (const b of balances) {\n const p = priceLookup(pricesUsd, b.symbol, b.assetId);\n if (p == null) continue;\n if (b.decimals == null) continue;\n\n const denom = 10 ** b.decimals;\n const amount = Number(b.amount) / denom;\n if (!Number.isFinite(amount)) continue;\n total += amount * p;\n any = true;\n }\n\n return any ? total : undefined;\n}\n\nasync function getRecentBlockTag(rpcUrl: string): Promise<number> {\n const provider = new ethers.JsonRpcProvider(rpcUrl);\n const latest = await provider.getBlockNumber();\n return Math.max(0, latest - 2);\n}\n\nfunction encodeErc20BalanceCalls(vaultAddress: string, tokenAddresses: string[]): { to: string; data: string }[] {\n const iface = new ethers.Interface(['function balanceOf(address owner) view returns (uint256)']);\n return tokenAddresses.map((token) => ({\n to: token,\n data: iface.encodeFunctionData('balanceOf', [vaultAddress]),\n }));\n}\n\nfunction decodeErc20Balances(results: string[], tokenAddresses: string[]): bigint[] {\n const iface = new ethers.Interface(['function balanceOf(address owner) view returns (uint256)']);\n const out: bigint[] = [];\n for (let i = 0; i < tokenAddresses.length; i++) {\n const data = results[i];\n if (!data || data === '0x') {\n out.push(0n);\n continue;\n }\n const decoded = iface.decodeFunctionResult('balanceOf', data);\n out.push(decoded[0] as bigint);\n }\n return out;\n}\n\n/**\n * Fetch Guardian-attested vault balances across multiple chains in one Query Proxy request.\n *\n * Notes:\n * - EVM balances are ERC20-only via `eth_call` (native ETH is not queryable via this query type).\n * - Solana balance uses lamports of the Veridex vault PDA (plus optional extra accounts).\n * - Aptos is included only if/when Wormhole Queries adds Aptos query types (currently returned as unsupported).\n */\nexport async function queryPortfolio(\n userKeyHash: string,\n apiKey: string,\n options?: QueryPortfolioOptions\n): Promise<PortfolioResult> {\n const network = resolveNetwork(options);\n const maxAgeSeconds = options?.maxAge ?? 60;\n const maxAttempts = options?.maxAttempts ?? 4;\n const cacheTtlMs = options?.cacheTtlMs ?? 30_000;\n const endpoint = getProxyEndpoint(network, options);\n\n const chainIds = options?.rpcUrls ? Object.keys(options.rpcUrls).map(Number) : undefined;\n void chainIds;\n\n const requestedChains = options?.vaultAddresses\n ? Object.keys(options.vaultAddresses).map(Number)\n : undefined;\n\n const defaultChains = getDefaultPortfolioChains(network);\n const wormholeChainIds = options?.evmTokenAddresses\n ? Array.from(new Set([...defaultChains, ...Object.keys(options.evmTokenAddresses).map(Number)]))\n : defaultChains;\n\n // If the caller provided explicit vault overrides, include those chain IDs even if not in defaults.\n const finalChainIds = requestedChains\n ? Array.from(new Set([...wormholeChainIds, ...requestedChains]))\n : wormholeChainIds;\n\n if (!apiKey || typeof apiKey !== 'string') {\n throw new QueryPortfolioError('INVALID_ARGUMENT', 'Missing Query Proxy apiKey');\n }\n\n const cacheKey = makeCacheKey(userKeyHash, apiKey, options, finalChainIds);\n const cached = PORTFOLIO_CACHE.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.value;\n }\n\n const chains = getChainConfigs(network);\n const walletManager = new WalletManager({ cacheAddresses: true, persistToStorage: false });\n\n const pricesUsd: Record<string, number> | undefined = {\n USDC: 1,\n ...(options?.pricesUsd ?? {}),\n };\n\n const doFetch = async (): Promise<PortfolioResult> => {\n try {\n const perChainRequests: PerChainQueryRequest[] = [];\n const chainMeta: Record<number, { vaultAddress?: string; chainName?: string; kind: 'evm' | 'solana' | 'unsupported' }> = {};\n\n // Precompute any EVM block tags in parallel to keep total latency down.\n const evmChainIds = finalChainIds.filter((id) => {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === id);\n return cfg?.isEvm;\n });\n\n const blockTagsByChainId = new Map<number, number>();\n await Promise.all(\n evmChainIds.map(async (wormholeChainId) => {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n if (!cfg) return;\n const rpcUrl = options?.rpcUrls?.[wormholeChainId] ?? cfg.rpcUrl;\n const blockTag = await getRecentBlockTag(rpcUrl);\n blockTagsByChainId.set(wormholeChainId, blockTag);\n })\n );\n\n for (const wormholeChainId of finalChainIds) {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n\n if (wormholeChainId === 22) {\n chainMeta[wormholeChainId] = { kind: 'unsupported', chainName: cfg?.name };\n continue;\n }\n\n if (!cfg) {\n chainMeta[wormholeChainId] = { kind: 'unsupported' };\n continue;\n }\n\n if (cfg.isEvm) {\n const vaultAddress = options?.vaultAddresses?.[wormholeChainId]\n ?? (cfg.contracts.vaultFactory && cfg.contracts.vaultImplementation\n ? walletManager.computeVaultAddress(userKeyHash, cfg.contracts.vaultFactory, cfg.contracts.vaultImplementation)\n : undefined);\n\n chainMeta[wormholeChainId] = { kind: 'evm', vaultAddress, chainName: cfg.name };\n\n if (!vaultAddress) {\n continue;\n }\n\n const tokenAddresses = options?.evmTokenAddresses?.[wormholeChainId]\n ?? getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address)).map((t) => t.address);\n\n if (!tokenAddresses.length) {\n continue;\n }\n\n const blockTag = blockTagsByChainId.get(wormholeChainId);\n if (blockTag == null) {\n continue;\n }\n\n const calls = encodeErc20BalanceCalls(vaultAddress, tokenAddresses);\n perChainRequests.push(new PerChainQueryRequest(wormholeChainId, new EthCallQueryRequest(blockTag, calls)));\n continue;\n }\n\n // Solana\n if (wormholeChainId === 1) {\n const programId = options?.vaultAddresses?.[wormholeChainId] ?? cfg.contracts.hub;\n chainMeta[wormholeChainId] = { kind: 'solana', chainName: cfg.name };\n\n if (!programId) {\n continue;\n }\n\n const vaultAddress = deriveSolanaVaultAddress(programId, userKeyHash);\n chainMeta[wormholeChainId] = { kind: 'solana', chainName: cfg.name, vaultAddress };\n\n const accounts = [vaultAddress, ...(options?.solanaAccounts ?? [])];\n perChainRequests.push(\n new PerChainQueryRequest(\n wormholeChainId,\n new SolanaAccountQueryRequest('finalized', accounts, undefined, 0n, 0n)\n )\n );\n continue;\n }\n\n chainMeta[wormholeChainId] = { kind: 'unsupported', chainName: cfg.name };\n }\n\n if (perChainRequests.length > 255) {\n throw new QueryPortfolioError(\n 'INVALID_ARGUMENT',\n `Too many per-chain requests (${perChainRequests.length}); max is 255 per Query Proxy request`\n );\n }\n\n // If no per-chain requests were built (e.g., missing vaults or tokens), return early with empty results\n if (perChainRequests.length === 0) {\n const chainsOut: PortfolioChainResult[] = finalChainIds.map((wormholeChainId) => {\n const meta = chainMeta[wormholeChainId] ?? { kind: 'unsupported' as const };\n return {\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { \n code: 'MISSING_VAULT' as const, \n message: 'Unable to build query: missing vault address or no tokens configured' \n },\n };\n });\n return { proof: new Uint8Array(), totalUsd: 0, chains: chainsOut };\n }\n\n const request = new QueryRequest(Date.now() & 0xffffffff, perChainRequests);\n // Wormhole Query Proxy expects raw hex WITHOUT 0x prefix\n const requestHex = Buffer.from(request.serialize()).toString('hex');\n\n // Respect rate limit before making request\n await rateLimiter.acquire();\n\n let response;\n try {\n console.log('[queryPortfolio] Sending request to:', endpoint);\n console.log('[queryPortfolio] Request bytes length:', requestHex.length);\n \n // Use provided timeout, or default to 15s for testnet (slower), 10s for mainnet\n const defaultTimeout = network === 'testnet' ? 15_000 : 10_000;\n const requestTimeout = options?.timeout ?? defaultTimeout;\n \n response = await axios.post(\n endpoint,\n { bytes: requestHex },\n {\n headers: {\n 'X-API-Key': apiKey,\n 'Content-Type': 'application/json',\n },\n timeout: requestTimeout,\n }\n );\n } catch (axiosErr) {\n const err = axiosErr as AxiosError;\n // Network errors (CORS, timeout, no connection) have no response\n if (!err.response) {\n console.error('[queryPortfolio] Network error:', {\n message: err.message,\n code: err.code,\n name: err.name,\n });\n throw new QueryPortfolioError(\n 'NETWORK_ERROR',\n `Network error: ${err.message} (code: ${err.code})`\n );\n }\n const status = err.response.status;\n const errData = err.response.data;\n console.error('[queryPortfolio] Wormhole Query Proxy error:', { status, data: errData });\n throw new QueryPortfolioError(\n 'PROXY_RESPONSE_INVALID',\n `Query Proxy returned ${status}: ${JSON.stringify(errData)}`\n );\n }\n\n const data = response.data as any;\n const signatures = data?.signatures as string[] | undefined;\n const bytes = data?.bytes as string | undefined;\n\n if (!Array.isArray(signatures) || typeof bytes !== 'string') {\n throw new QueryPortfolioError('PROXY_RESPONSE_INVALID', 'Query Proxy response missing signatures/bytes');\n }\n\n const proof = signaturesToProofBytes(signatures);\n const queryBytes = decodeQueryBytes(bytes);\n const parsed = QueryResponse.from(queryBytes);\n\n const nowSeconds = Math.floor(Date.now() / 1000);\n const chainsOut: PortfolioChainResult[] = [];\n\n for (const wormholeChainId of finalChainIds) {\n const meta = chainMeta[wormholeChainId] ?? { kind: 'unsupported' as const };\n\n if (meta.kind === 'unsupported') {\n const msg = wormholeChainId === 22\n ? 'Aptos Queries are not supported by the Wormhole Query SDK yet'\n : 'Chain is not supported by this portfolio query implementation';\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n balances: [],\n error: { code: 'UNSUPPORTED_CHAIN', message: msg },\n });\n continue;\n }\n\n if (!meta.vaultAddress) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n balances: [],\n error: { code: 'MISSING_VAULT', message: 'Unable to derive vault address for chain' },\n });\n continue;\n }\n\n const perChain = parsed.responses.find((r) => r.chainId === wormholeChainId);\n if (!perChain) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'DECODE_ERROR', message: 'Missing per-chain response from Query Proxy' },\n });\n continue;\n }\n\n try {\n if (meta.kind === 'evm') {\n const cfg = Object.values(chains).find((c) => c.wormholeChainId === wormholeChainId);\n const tokenAddresses = options?.evmTokenAddresses?.[wormholeChainId]\n ?? getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address)).map((t) => t.address);\n\n if (!tokenAddresses.length) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'MISSING_TOKENS', message: 'No ERC20 tokens configured for EVM portfolio query' },\n });\n continue;\n }\n\n const chainResp = EthCallQueryResponse.from(perChain.response.serialize());\n const blockTime = Number(chainResp.blockTime);\n const age = nowSeconds - blockTime;\n if (age > maxAgeSeconds) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances: [],\n error: { code: 'ATTESTATION_STALE', message: `Attestation stale by ${age}s (maxAge=${maxAgeSeconds}s)` },\n });\n continue;\n }\n\n const amounts = decodeErc20Balances(chainResp.results, tokenAddresses);\n const tokenInfos = getAllTokens(wormholeChainId).filter((t) => !isNativeToken(t.address));\n\n const balances: PortfolioBalance[] = tokenAddresses.map((addr, i) => {\n const info = tokenInfos.find((t) => t.address.toLowerCase() === addr.toLowerCase());\n const symbol = info?.symbol;\n const decimals = info?.decimals;\n const usdPrice = priceLookup(pricesUsd, symbol, addr);\n const usdValue = usdPrice != null && decimals != null\n ? (Number(amounts[i]) / 10 ** decimals) * usdPrice\n : undefined;\n\n return {\n assetId: addr,\n amount: amounts[i],\n symbol,\n decimals,\n usdValue: Number.isFinite(usdValue ?? NaN) ? usdValue : undefined,\n };\n });\n\n void cfg;\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances,\n });\n continue;\n }\n\n // Solana\n const chainResp = SolanaAccountQueryResponse.from(perChain.response.serialize());\n const blockTime = safeNumberFromBigint(chainResp.blockTime);\n const age = nowSeconds - blockTime;\n if (age > maxAgeSeconds) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances: [],\n error: { code: 'ATTESTATION_STALE', message: `Attestation stale by ${age}s (maxAge=${maxAgeSeconds}s)` },\n });\n continue;\n }\n\n const vaultResult = chainResp.results[0];\n const lamports = vaultResult?.lamports ?? 0n;\n\n const balances: PortfolioBalance[] = [\n {\n assetId: 'SOL',\n amount: lamports,\n decimals: 9,\n symbol: 'SOL',\n usdValue: priceLookup(pricesUsd, 'SOL', 'SOL') != null\n ? (Number(lamports) / 1e9) * (priceLookup(pricesUsd, 'SOL', 'SOL') as number)\n : undefined,\n },\n ];\n\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n blockTime,\n balances,\n });\n } catch (cause) {\n chainsOut.push({\n wormholeChainId,\n chainName: meta.chainName,\n vaultAddress: meta.vaultAddress,\n balances: [],\n error: { code: 'DECODE_ERROR', message: `Failed to decode chain response: ${String((cause as any)?.message ?? cause)}` },\n });\n }\n }\n\n const allBalances = chainsOut.flatMap((c) => c.balances);\n const totalUsd = sumUsd(allBalances, pricesUsd);\n\n const result: PortfolioResult = { proof, totalUsd, chains: chainsOut };\n\n PORTFOLIO_CACHE.set(cacheKey, { expiresAt: Date.now() + cacheTtlMs, value: result });\n return result;\n } catch (err) {\n if (err instanceof QueryPortfolioError) throw err;\n if (axios.isAxiosError(err)) {\n const ax = err as AxiosError;\n const status = ax.response?.status;\n const statusText = ax.response?.statusText;\n const details = typeof ax.response?.data === 'string' ? ax.response?.data : undefined;\n\n throw new QueryPortfolioError(\n 'PROXY_HTTP_ERROR',\n `Query Proxy request failed${status ? ` (${status} ${statusText ?? ''})` : ''}${details ? `: ${details}` : ''}`,\n err\n );\n }\n\n throw new QueryPortfolioError('PROXY_HTTP_ERROR', 'Query Proxy request failed', err);\n }\n };\n\n const result = await withExponentialBackoff(doFetch, maxAttempts);\n PORTFOLIO_CACHE.set(cacheKey, { expiresAt: Date.now() + cacheTtlMs, value: result });\n return result;\n}\n","export const WORMHOLE_QUERY_PROXY_URLS = {\n mainnet: 'https://query.wormhole.com/v1/query',\n testnet: 'https://testnet.query.wormhole.com/v1/query',\n} as const;\n\n/**\n * Wormhole Query Proxy rate limit: 6 queries per second.\n * SDK callers should throttle requests accordingly.\n */\nexport const WORMHOLE_QUERY_RATE_LIMIT_PER_SECOND = 6;\n\n/**\n * Convenience set of Wormhole chain IDs commonly supported by Queries.\n * This is not an exhaustive list of all Wormhole chains.\n */\nexport const WORMHOLE_QUERY_CHAIN_IDS = {\n ETHEREUM: 2,\n POLYGON: 5,\n ARBITRUM: 23,\n OPTIMISM: 24,\n BASE: 30,\n} as const;\n"],"mappings":"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","names":["chainsOut","chainResp","blockTime","age","balances","result"]}
@@ -0,0 +1,58 @@
1
+ // src/core/relayerUrl.ts
2
+ var API_ROOT = "/api/v1";
3
+ function trimTrailingSlashes(value) {
4
+ return value.trim().replace(/\/+$/, "");
5
+ }
6
+ function normalizeRelayerOrigin(value) {
7
+ const trimmed = trimTrailingSlashes(value);
8
+ if (!trimmed) {
9
+ return "";
10
+ }
11
+ if (trimmed.startsWith("/")) {
12
+ return trimmed.replace(/\/api\/v1$/i, "");
13
+ }
14
+ try {
15
+ const url = new URL(trimmed);
16
+ url.pathname = url.pathname.replace(/\/api\/v1$/i, "").replace(/\/+$/, "");
17
+ return url.toString().replace(/\/+$/, "");
18
+ } catch {
19
+ return trimmed.replace(/\/api\/v1$/i, "");
20
+ }
21
+ }
22
+ function buildRelayerApiUrl(baseUrl, path) {
23
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
24
+ const trimmed = trimTrailingSlashes(baseUrl);
25
+ if (!trimmed) {
26
+ return `${API_ROOT}${normalizedPath}`;
27
+ }
28
+ if (trimmed.startsWith("/")) {
29
+ if (/\/api\/v1$/i.test(trimmed) || /\/api\/auth\/relay$/i.test(trimmed)) {
30
+ return `${trimmed}${normalizedPath}`;
31
+ }
32
+ return `${trimmed}${normalizedPath}`;
33
+ }
34
+ try {
35
+ const url = new URL(trimmed);
36
+ if (/\/api\/v1$/i.test(url.pathname) || /\/api\/auth\/relay$/i.test(url.pathname)) {
37
+ url.pathname = `${url.pathname.replace(/\/+$/, "")}${normalizedPath}`;
38
+ return url.toString();
39
+ }
40
+ if (!url.pathname || url.pathname === "/") {
41
+ url.pathname = `${API_ROOT}${normalizedPath}`;
42
+ return url.toString();
43
+ }
44
+ url.pathname = `${url.pathname.replace(/\/+$/, "")}${normalizedPath}`;
45
+ return url.toString();
46
+ } catch {
47
+ if (/\/api\/v1$/i.test(trimmed) || /\/api\/auth\/relay$/i.test(trimmed)) {
48
+ return `${trimmed}${normalizedPath}`;
49
+ }
50
+ return `${trimmed}${API_ROOT}${normalizedPath}`;
51
+ }
52
+ }
53
+
54
+ export {
55
+ normalizeRelayerOrigin,
56
+ buildRelayerApiUrl
57
+ };
58
+ //# sourceMappingURL=chunk-WC4X3MAO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/relayerUrl.ts"],"sourcesContent":["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":";AAAA,IAAM,WAAW;AAEjB,SAAS,oBAAoB,OAAuB;AAChD,SAAO,MAAM,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAC1C;AAEO,SAAS,uBAAuB,OAAuB;AAC1D,QAAM,UAAU,oBAAoB,KAAK;AACzC,MAAI,CAAC,SAAS;AACV,WAAO;AAAA,EACX;AAEA,MAAI,QAAQ,WAAW,GAAG,GAAG;AACzB,WAAO,QAAQ,QAAQ,eAAe,EAAE;AAAA,EAC5C;AAEA,MAAI;AACA,UAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAI,WAAW,IAAI,SAAS,QAAQ,eAAe,EAAE,EAAE,QAAQ,QAAQ,EAAE;AACzE,WAAO,IAAI,SAAS,EAAE,QAAQ,QAAQ,EAAE;AAAA,EAC5C,QAAQ;AACJ,WAAO,QAAQ,QAAQ,eAAe,EAAE;AAAA,EAC5C;AACJ;AAEO,SAAS,mBAAmB,SAAiB,MAAsB;AACtE,QAAM,iBAAiB,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI;AAC7D,QAAM,UAAU,oBAAoB,OAAO;AAE3C,MAAI,CAAC,SAAS;AACV,WAAO,GAAG,QAAQ,GAAG,cAAc;AAAA,EACvC;AAEA,MAAI,QAAQ,WAAW,GAAG,GAAG;AACzB,QAAI,cAAc,KAAK,OAAO,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACrE,aAAO,GAAG,OAAO,GAAG,cAAc;AAAA,IACtC;AAEA,WAAO,GAAG,OAAO,GAAG,cAAc;AAAA,EACtC;AAEA,MAAI;AACA,UAAM,MAAM,IAAI,IAAI,OAAO;AAE3B,QAAI,cAAc,KAAK,IAAI,QAAQ,KAAK,uBAAuB,KAAK,IAAI,QAAQ,GAAG;AAC/E,UAAI,WAAW,GAAG,IAAI,SAAS,QAAQ,QAAQ,EAAE,CAAC,GAAG,cAAc;AACnE,aAAO,IAAI,SAAS;AAAA,IACxB;AAEA,QAAI,CAAC,IAAI,YAAY,IAAI,aAAa,KAAK;AACvC,UAAI,WAAW,GAAG,QAAQ,GAAG,cAAc;AAC3C,aAAO,IAAI,SAAS;AAAA,IACxB;AAEA,QAAI,WAAW,GAAG,IAAI,SAAS,QAAQ,QAAQ,EAAE,CAAC,GAAG,cAAc;AACnE,WAAO,IAAI,SAAS;AAAA,EACxB,QAAQ;AACJ,QAAI,cAAc,KAAK,OAAO,KAAK,uBAAuB,KAAK,OAAO,GAAG;AACrE,aAAO,GAAG,OAAO,GAAG,cAAc;AAAA,IACtC;AAEA,WAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,cAAc;AAAA,EACjD;AACJ;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EVMClient
3
- } from "./chunk-USVZH4QC.mjs";
3
+ } from "./chunk-H3WRT6Y4.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-5FH67KLG.mjs.map
216
+ //# sourceMappingURL=chunk-XHDOSV2F.mjs.map
@@ -1,6 +1,6 @@
1
- import { E as EVMClient } from './EVMClient-Bmy9czkE.mjs';
1
+ import { E as EVMClient } from './EVMClient-DqDiFak8.mjs';
2
2
  import { b as SessionConfig, d as SessionManagerConfig, a as SessionKey, A as ActionParams, c as SessionSignature, g as SessionSignedAction, f as SessionEventCallback } from './types-C564CfsE.mjs';
3
- import { PasskeyCredential } from './passkey.mjs';
3
+ import { a as PasskeyCredential } from './passkey-fh8bo2w-.mjs';
4
4
  import { RegisterSessionParams, RevokeSessionParams } from './types.mjs';
5
5
  import { ethers } from 'ethers';
6
6