@permissionless-technologies/upp-sdk 0.5.5 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/{chunk-Q6BLTPWV.js → chunk-2NKFTLPD.js} +3 -3
  2. package/dist/{chunk-Q6BLTPWV.js.map → chunk-2NKFTLPD.js.map} +1 -1
  3. package/dist/{chunk-EHGH6TAW.js → chunk-37RFFZU2.js} +3 -3
  4. package/dist/{chunk-EHGH6TAW.js.map → chunk-37RFFZU2.js.map} +1 -1
  5. package/dist/{chunk-UQIM2KT3.js → chunk-4E23V3AT.js} +29 -4
  6. package/dist/chunk-4E23V3AT.js.map +1 -0
  7. package/dist/{chunk-53JACDGZ.js → chunk-A6IYQ7UF.js} +3 -3
  8. package/dist/chunk-A6IYQ7UF.js.map +1 -0
  9. package/dist/{chunk-7T4CUE6E.js → chunk-AVSR443A.js} +3 -3
  10. package/dist/{chunk-7T4CUE6E.js.map → chunk-AVSR443A.js.map} +1 -1
  11. package/dist/{chunk-UFEDJJSH.cjs → chunk-BCSMUH4L.cjs} +30 -3
  12. package/dist/chunk-BCSMUH4L.cjs.map +1 -0
  13. package/dist/{chunk-IYRCJAME.cjs → chunk-C3HXJ5A6.cjs} +9 -9
  14. package/dist/{chunk-IYRCJAME.cjs.map → chunk-C3HXJ5A6.cjs.map} +1 -1
  15. package/dist/{chunk-MEFCUBQC.js → chunk-CRUJLZV7.js} +5 -4
  16. package/dist/chunk-CRUJLZV7.js.map +1 -0
  17. package/dist/{chunk-DTEAFJG7.js → chunk-FTEXUSHR.js} +4 -4
  18. package/dist/{chunk-DTEAFJG7.js.map → chunk-FTEXUSHR.js.map} +1 -1
  19. package/dist/chunk-FW2U6TKQ.js +498 -0
  20. package/dist/chunk-FW2U6TKQ.js.map +1 -0
  21. package/dist/{chunk-6TFDBBAQ.js → chunk-H4NDMIPF.js} +3 -3
  22. package/dist/{chunk-6TFDBBAQ.js.map → chunk-H4NDMIPF.js.map} +1 -1
  23. package/dist/{chunk-DD2RTRPE.cjs → chunk-HVSP62AH.cjs} +22 -36
  24. package/dist/chunk-HVSP62AH.cjs.map +1 -0
  25. package/dist/{chunk-7BNJV2ZS.cjs → chunk-LKXC3OQT.cjs} +14 -14
  26. package/dist/{chunk-7BNJV2ZS.cjs.map → chunk-LKXC3OQT.cjs.map} +1 -1
  27. package/dist/{chunk-HB43C26P.cjs → chunk-NGXEIUQ6.cjs} +4 -4
  28. package/dist/chunk-NGXEIUQ6.cjs.map +1 -0
  29. package/dist/{chunk-KV2QFPSJ.cjs → chunk-P6E3LE7T.cjs} +5 -4
  30. package/dist/chunk-P6E3LE7T.cjs.map +1 -0
  31. package/dist/chunk-PGIV2GDM.cjs +511 -0
  32. package/dist/chunk-PGIV2GDM.cjs.map +1 -0
  33. package/dist/{chunk-M6O7HMN7.js → chunk-UHMHZQZV.js} +6 -20
  34. package/dist/chunk-UHMHZQZV.js.map +1 -0
  35. package/dist/{chunk-I5EKGD4P.cjs → chunk-XNSMPNY6.cjs} +4 -4
  36. package/dist/{chunk-I5EKGD4P.cjs.map → chunk-XNSMPNY6.cjs.map} +1 -1
  37. package/dist/{chunk-U3YFYMWF.cjs → chunk-XSJ5VVH4.cjs} +5 -5
  38. package/dist/{chunk-U3YFYMWF.cjs.map → chunk-XSJ5VVH4.cjs.map} +1 -1
  39. package/dist/{chunk-SWTNJPK5.cjs → chunk-Y6WCXYOC.cjs} +11 -11
  40. package/dist/{chunk-SWTNJPK5.cjs.map → chunk-Y6WCXYOC.cjs.map} +1 -1
  41. package/dist/core/index.cjs +63 -67
  42. package/dist/core/index.d.cts +2 -5
  43. package/dist/core/index.d.ts +2 -5
  44. package/dist/core/index.js +7 -7
  45. package/dist/crypto-FWREDAVI.js +8 -0
  46. package/dist/crypto-FWREDAVI.js.map +1 -0
  47. package/dist/crypto-IZKHHFDU.cjs +42 -0
  48. package/dist/crypto-IZKHHFDU.cjs.map +1 -0
  49. package/dist/{index-BRgBwiBM.d.ts → index-DLvLv3mg.d.ts} +11 -23
  50. package/dist/{index-D6YhhbRP.d.cts → index-DOiHUft6.d.cts} +3 -4
  51. package/dist/{index-DHW5lKcd.d.ts → index-DY0XAmFw.d.ts} +3 -4
  52. package/dist/{index-brLSTa0y.d.cts → index-KTJgQUxb.d.cts} +11 -23
  53. package/dist/index.cjs +240 -240
  54. package/dist/index.d.cts +4 -7
  55. package/dist/index.d.ts +4 -7
  56. package/dist/index.js +10 -10
  57. package/dist/indexer/index.cjs +62 -11
  58. package/dist/indexer/index.d.cts +196 -12
  59. package/dist/indexer/index.d.ts +196 -12
  60. package/dist/indexer/index.js +4 -1
  61. package/dist/keys/index.cjs +17 -17
  62. package/dist/keys/index.js +3 -3
  63. package/dist/react/index.cjs +214 -693
  64. package/dist/react/index.cjs.map +1 -1
  65. package/dist/react/index.d.cts +138 -6
  66. package/dist/react/index.d.ts +138 -6
  67. package/dist/react/index.js +193 -672
  68. package/dist/react/index.js.map +1 -1
  69. package/dist/{transfer-BVZAMEJH.js → transfer-2UYFZMIK.js} +4 -4
  70. package/dist/{transfer-BVZAMEJH.js.map → transfer-2UYFZMIK.js.map} +1 -1
  71. package/dist/{transfer-ZD76R7XF.cjs → transfer-6OW3XKVC.cjs} +10 -10
  72. package/dist/{transfer-ZD76R7XF.cjs.map → transfer-6OW3XKVC.cjs.map} +1 -1
  73. package/dist/{transfer-p-NXHdGY.d.cts → transfer-C1XU_z-6.d.cts} +46 -156
  74. package/dist/{transfer-BxiDgCvx.d.ts → transfer-DgjxZlR7.d.ts} +46 -156
  75. package/dist/utils/index.cjs +44 -44
  76. package/dist/utils/index.d.cts +186 -5
  77. package/dist/utils/index.d.ts +186 -5
  78. package/dist/utils/index.js +4 -4
  79. package/package.json +1 -1
  80. package/src/deployments/31337.json +2 -1
  81. package/dist/chunk-53JACDGZ.js.map +0 -1
  82. package/dist/chunk-DD2RTRPE.cjs.map +0 -1
  83. package/dist/chunk-HB43C26P.cjs.map +0 -1
  84. package/dist/chunk-KV2QFPSJ.cjs.map +0 -1
  85. package/dist/chunk-M6O7HMN7.js.map +0 -1
  86. package/dist/chunk-MEFCUBQC.js.map +0 -1
  87. package/dist/chunk-UFEDJJSH.cjs.map +0 -1
  88. package/dist/chunk-UQIM2KT3.js.map +0 -1
  89. package/dist/stark-BcTD1OaJ.d.cts +0 -185
  90. package/dist/stark-BcTD1OaJ.d.ts +0 -185
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/indexer/storage/localStorage.ts","../src/indexer/storage/memory.ts","../src/indexer/storage/index.ts","../src/indexer/decryption.ts","../src/indexer/rpc.ts"],"names":["toHex","eventsProcessed","eventsSkipped","tryDecryptNote","keccak256"],"mappings":"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","file":"chunk-UHMHZQZV.js","sourcesContent":["/**\n * localStorage Storage Adapter\n *\n * Provides persistent storage using localStorage for browser environments.\n * This is a fallback adapter when IndexedDB is not available or for simpler use cases.\n *\n * Limitations:\n * - 5MB storage limit per origin\n * - Synchronous API (blocks main thread on large operations)\n * - Data must be JSON serializable\n */\n\nimport type { StorageAdapter } from '../types.js'\n\n/**\n * localStorage storage adapter\n */\nclass LocalStorageAdapter implements StorageAdapter {\n private prefix: string\n\n constructor(prefix: string = '') {\n this.prefix = prefix\n }\n\n /**\n * Check if localStorage is available\n */\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false\n try {\n const test = '__storage_test__'\n window.localStorage.setItem(test, test)\n window.localStorage.removeItem(test)\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Get the full key with prefix\n */\n private getKey(key: string): string {\n return this.prefix ? `upp:${this.prefix}:${key}` : `upp:${key}`\n }\n\n /**\n * Get a value by key\n */\n async get<T>(key: string): Promise<T | null> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const fullKey = this.getKey(key)\n const value = localStorage.getItem(fullKey)\n\n if (value === null) {\n return null\n }\n\n try {\n return JSON.parse(value) as T\n } catch {\n // If JSON parse fails, return null\n console.warn(`Failed to parse localStorage value for key \"${fullKey}\"`)\n return null\n }\n }\n\n /**\n * Set a value\n */\n async set<T>(key: string, value: T): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const fullKey = this.getKey(key)\n\n try {\n const serialized = JSON.stringify(value)\n localStorage.setItem(fullKey, serialized)\n } catch (e) {\n if (e instanceof Error && e.name === 'QuotaExceededError') {\n throw new Error('localStorage quota exceeded. Consider using IndexedDB instead.')\n }\n throw e\n }\n }\n\n /**\n * Delete a value\n */\n async delete(key: string): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const fullKey = this.getKey(key)\n localStorage.removeItem(fullKey)\n }\n\n /**\n * Clear all data with this prefix\n */\n async clear(): Promise<void> {\n if (!this.isAvailable()) {\n throw new Error('localStorage is not available')\n }\n\n const prefix = this.prefix ? `upp:${this.prefix}:` : 'upp:'\n const keysToRemove: string[] = []\n\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i)\n if (key && key.startsWith(prefix)) {\n keysToRemove.push(key)\n }\n }\n\n for (const key of keysToRemove) {\n localStorage.removeItem(key)\n }\n }\n}\n\n/**\n * Create a localStorage storage adapter\n *\n * @param prefix - Optional prefix for keys (useful for multi-account)\n * @returns StorageAdapter instance\n *\n * @example\n * ```ts\n * const storage = createLocalStorageAdapter('account_0x123')\n * await storage.set('notes', myNotes)\n * const notes = await storage.get('notes')\n * ```\n */\nexport function createLocalStorageAdapter(prefix: string = ''): StorageAdapter {\n return new LocalStorageAdapter(prefix)\n}\n\n/**\n * Default localStorage adapter instance (no prefix)\n */\nexport const localStorageAdapter = createLocalStorageAdapter()\n","/**\n * In-Memory Storage Adapter\n *\n * Provides non-persistent storage for testing and development.\n * Data is lost when the process ends or the adapter is cleared.\n *\n * Use cases:\n * - Unit tests\n * - Server-side rendering (where IndexedDB/localStorage aren't available)\n * - Development without persistence\n */\n\nimport type { StorageAdapter } from '../types.js'\n\n/**\n * In-memory storage adapter\n */\nclass MemoryAdapter implements StorageAdapter {\n private store: Map<string, unknown>\n private prefix: string\n\n constructor(prefix: string = '') {\n this.store = new Map()\n this.prefix = prefix\n }\n\n /**\n * Always available\n */\n isAvailable(): boolean {\n return true\n }\n\n /**\n * Get the full key with prefix\n */\n private getKey(key: string): string {\n return this.prefix ? `${this.prefix}:${key}` : key\n }\n\n /**\n * Get a value by key\n */\n async get<T>(key: string): Promise<T | null> {\n const fullKey = this.getKey(key)\n const value = this.store.get(fullKey)\n return (value as T) ?? null\n }\n\n /**\n * Set a value\n */\n async set<T>(key: string, value: T): Promise<void> {\n const fullKey = this.getKey(key)\n // Deep clone to prevent external mutations\n this.store.set(fullKey, structuredClone(value))\n }\n\n /**\n * Delete a value\n */\n async delete(key: string): Promise<void> {\n const fullKey = this.getKey(key)\n this.store.delete(fullKey)\n }\n\n /**\n * Clear all data with this prefix\n */\n async clear(): Promise<void> {\n if (!this.prefix) {\n this.store.clear()\n } else {\n const keysToDelete: string[] = []\n for (const key of this.store.keys()) {\n if (key.startsWith(`${this.prefix}:`)) {\n keysToDelete.push(key)\n }\n }\n for (const key of keysToDelete) {\n this.store.delete(key)\n }\n }\n }\n\n /**\n * Get the number of stored items (for testing)\n */\n size(): number {\n if (!this.prefix) {\n return this.store.size\n }\n let count = 0\n for (const key of this.store.keys()) {\n if (key.startsWith(`${this.prefix}:`)) {\n count++\n }\n }\n return count\n }\n\n /**\n * Get all keys (for testing)\n */\n keys(): string[] {\n const result: string[] = []\n const prefixToRemove = this.prefix ? `${this.prefix}:` : ''\n for (const key of this.store.keys()) {\n if (!this.prefix || key.startsWith(prefixToRemove)) {\n result.push(this.prefix ? key.slice(prefixToRemove.length) : key)\n }\n }\n return result\n }\n}\n\n/**\n * Create an in-memory storage adapter\n *\n * @param prefix - Optional prefix for keys\n * @returns StorageAdapter instance\n *\n * @example\n * ```ts\n * const storage = createMemoryAdapter()\n * await storage.set('notes', myNotes)\n * const notes = await storage.get('notes')\n * ```\n */\nexport function createMemoryAdapter(prefix: string = ''): StorageAdapter & {\n size(): number\n keys(): string[]\n} {\n return new MemoryAdapter(prefix)\n}\n\n/**\n * Default in-memory adapter instance (no prefix)\n */\nexport const memoryAdapter = createMemoryAdapter()\n","/**\n * Storage Adapters\n *\n * Pluggable storage backends for the indexer.\n */\n\n// Types\nexport type { StorageAdapter, IndexerState, SyncState, SerializedNote } from './types.js'\n\n// IndexedDB adapter (default, recommended)\nexport { createIndexedDBAdapter, indexedDBAdapter } from './indexedDB.js'\n\n// localStorage adapter (fallback)\nexport { createLocalStorageAdapter, localStorageAdapter } from './localStorage.js'\n\n// In-memory adapter (testing)\nexport { createMemoryAdapter, memoryAdapter } from './memory.js'\n\n// Static imports for createAutoAdapter (avoid require() which breaks ESM)\nimport { createIndexedDBAdapter } from './indexedDB.js'\nimport { createLocalStorageAdapter } from './localStorage.js'\nimport { createMemoryAdapter } from './memory.js'\nimport type { StorageAdapter } from './types.js'\n\n/**\n * Create the best available storage adapter\n *\n * Tries IndexedDB first, falls back to localStorage, then memory.\n *\n * @param prefix - Optional prefix for keys\n * @returns The best available StorageAdapter\n */\nexport function createAutoAdapter(prefix: string = ''): StorageAdapter {\n if (typeof window !== 'undefined' && 'indexedDB' in window) {\n return createIndexedDBAdapter(prefix)\n }\n\n if (typeof window !== 'undefined' && typeof localStorage !== 'undefined') {\n try {\n const test = '__storage_test__'\n localStorage.setItem(test, test)\n localStorage.removeItem(test)\n return createLocalStorageAdapter(prefix)\n } catch {\n // localStorage not available\n }\n }\n\n return createMemoryAdapter(prefix)\n}\n","/**\n * Decryption utilities for UPP note discovery\n *\n * This module contains the trial decryption logic used by indexers (RPC, Subsquid, etc.)\n * to find notes belonging to a particular account.\n *\n * Key concepts:\n * - Search tag: Lower 64 bits of Poseidon(viewingSharedSecret.x, 0), used to quickly filter events\n * - Dual ECDH: Viewing key for decryption, spending key for commitment verification\n * - UPP note format: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n */\n\nimport { keccak256, toHex, type Hex } from 'viem' // keccak256 still used for AES key derivation\nimport type { Point } from '../utils/babyjubjub.js'\nimport { hexToBytes, bytesToBigint } from '../utils/crypto.js'\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface DecryptedNote {\n amount: bigint\n blinding: bigint\n oneTimeSecret: bigint\n oneTimePubkey: Point\n origin: bigint\n token: bigint\n}\n\nexport interface UnpackedNoteData {\n searchTag: bigint\n ephemeralPubkeyX: bigint\n ephemeralPubkeyY: bigint\n encryptedNote: Hex\n}\n\nexport interface DecryptionKeys {\n spendingSecret: bigint\n spendingPubkey: Point\n masterViewingSecret: bigint\n masterViewingPubKey: Point\n}\n\n// SDK type (loaded dynamically to avoid circular deps)\ntype SDK = typeof import('../index.js')\n\n// ============================================================================\n// Search Tag Filtering\n// ============================================================================\n\n/**\n * Compute the expected search tag for a given ephemeral public key\n *\n * The search tag is computed as: Poseidon(viewingSharedSecret.x, 0) & ((1n << 64n) - 1n)\n * This must match how search tags are computed during note creation in createUPPNote().\n *\n * - DVK is the derived viewing key (derived from master viewing key using R.x as nonce)\n * - R is the ephemeral public key\n * - viewingSharedSecret = DVK * R\n *\n * This allows quick filtering of events before expensive trial decryption.\n */\nexport async function computeSearchTag(\n sdk: SDK,\n masterViewingSecret: bigint,\n masterViewingPubKey: Point,\n ephemeralPubkey: Point,\n debug: boolean = false\n): Promise<bigint> {\n // Derive DVK using R.x as nonce (same as in decryption)\n const dvk = await sdk.deriveDecryptionViewingKey(\n masterViewingSecret,\n masterViewingPubKey,\n ephemeralPubkey.x\n )\n\n // Compute shared secret\n const viewingSharedSecret = await sdk.computeSharedSecret(dvk, ephemeralPubkey)\n\n // Search tag = lower 64 bits of Poseidon(sharedSecret.x, 0)\n // This must match the computation in createUPPNote()\n const searchTagHash = await sdk.poseidon([viewingSharedSecret.x, 0n])\n const searchTag = searchTagHash & ((1n << 64n) - 1n)\n\n if (debug) {\n console.log(`[computeSearchTag] viewingSharedSecret.x: ${viewingSharedSecret.x}`)\n console.log(`[computeSearchTag] searchTagHash: ${searchTagHash}`)\n console.log(`[computeSearchTag] searchTag (lower 64 bits): ${searchTag}`)\n }\n\n return searchTag\n}\n\n/**\n * Check if a search tag from an event matches our viewing key\n *\n * This is a fast check that can filter out 99%+ of events before\n * attempting expensive trial decryption.\n *\n * @param eventSearchTag - The search tag from the event (8 bytes as bigint)\n * @param sdk - The loaded SDK module\n * @param masterViewingSecret - Our master viewing secret\n * @param masterViewingPubKey - Our master viewing public key\n * @param ephemeralPubkey - The ephemeral public key from the event\n * @param debug - Enable debug logging\n * @returns true if the search tag matches (event might be ours)\n */\nexport async function matchesSearchTag(\n eventSearchTag: bigint,\n sdk: SDK,\n masterViewingSecret: bigint,\n masterViewingPubKey: Point,\n ephemeralPubkey: Point,\n debug: boolean = false\n): Promise<boolean> {\n const expectedTag = await computeSearchTag(\n sdk,\n masterViewingSecret,\n masterViewingPubKey,\n ephemeralPubkey,\n debug\n )\n\n if (debug) {\n console.log(`[matchesSearchTag] eventSearchTag: ${eventSearchTag}, expectedTag: ${expectedTag}, match: ${eventSearchTag === expectedTag}`)\n }\n\n return eventSearchTag === expectedTag\n}\n\n// ============================================================================\n// Note Decryption\n// ============================================================================\n\n/**\n * Try to decrypt a note using dual ECDH (UPP format with origin and token)\n *\n * 1. Viewing ECDH: DVK * R → AES decryption key (viewing shared secret)\n * 2. Spending ECDH: spendingSecret * R → one-time key for commitment verification\n *\n * DVK is derived using R.x (ephemeral public key x-coordinate) as the nonce.\n *\n * UPP encrypted payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n * UPP commitment: Poseidon(amount, pubkeyX, pubkeyY, blinding, origin, token)\n *\n * @param sdk - The loaded SDK module\n * @param keys - Decryption keys (spending and viewing)\n * @param ephemeralPubkey - The ephemeral public key from the event\n * @param encryptedNote - The encrypted note data\n * @param expectedCommitment - The commitment to verify against\n * @param debug - Enable debug logging\n * @returns Decrypted note data or null if decryption/verification failed\n */\nexport async function tryDecryptNote(\n sdk: SDK,\n keys: DecryptionKeys,\n ephemeralPubkey: Point,\n encryptedNote: Hex,\n expectedCommitment: bigint,\n debug: boolean = false\n): Promise<DecryptedNote | null> {\n try {\n // --- ECDH #2: Viewing key (note decryption) ---\n // Derive DVK using R.x as nonce\n const dvk = await sdk.deriveDecryptionViewingKey(\n keys.masterViewingSecret,\n keys.masterViewingPubKey,\n ephemeralPubkey.x\n )\n const viewingSharedSecret = await sdk.computeSharedSecret(dvk, ephemeralPubkey)\n\n // Derive AES key from viewing shared secret\n const keyMaterial = keccak256(toHex(viewingSharedSecret.x, { size: 32 }))\n const keyBytes = hexToBytes(keyMaterial)\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength) as ArrayBuffer,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n )\n\n // Parse encrypted note\n const encryptedBytes = hexToBytes(encryptedNote)\n const nonce = encryptedBytes.slice(0, 12)\n const ciphertext = encryptedBytes.slice(12)\n\n // Decrypt\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, cryptoKey, ciphertext)\n\n const plaintextBytes = new Uint8Array(plaintext)\n if (debug) {\n console.log(`[tryDecryptNote] Decrypted plaintext length: ${plaintextBytes.length} bytes`)\n }\n\n // UPP payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n const amount = bytesToBigint(plaintextBytes.slice(0, 32))\n const blinding = bytesToBigint(plaintextBytes.slice(32, 64))\n const origin = bytesToBigint(plaintextBytes.slice(64, 84))\n const token = bytesToBigint(plaintextBytes.slice(84, 104))\n\n // --- Hash-based ownership verification (BLS12-381) ---\n // ownerHash = Poseidon(spendingSecret)\n // commitment = Poseidon(amount, ownerHash, blinding, origin, token)\n const ownerHash = await sdk.poseidon([keys.spendingSecret])\n const oneTimeSecret = keys.spendingSecret\n\n const computedCommitment = await sdk.poseidon([\n amount,\n ownerHash,\n blinding,\n origin,\n token,\n ])\n\n if (debug) {\n console.log(`[tryDecryptNote] Decrypted values:`)\n console.log(` amount: ${amount}`)\n console.log(` blinding: ${blinding}`)\n console.log(` origin: 0x${origin.toString(16).padStart(40, '0')}`)\n console.log(` token: 0x${token.toString(16).padStart(40, '0')}`)\n console.log(` ownerHash: ${ownerHash}`)\n console.log(` computedCommitment: ${computedCommitment}`)\n console.log(` expectedCommitment: ${expectedCommitment}`)\n console.log(` match: ${computedCommitment === expectedCommitment}`)\n }\n\n if (computedCommitment !== expectedCommitment) {\n if (debug) {\n console.log(`[tryDecryptNote] Commitment mismatch - not our note`)\n }\n return null\n }\n\n return { amount, blinding, oneTimeSecret, oneTimePubkey: { x: ownerHash, y: 0n }, origin, token }\n } catch (e) {\n if (debug) {\n console.log(`[tryDecryptNote] Decryption exception:`, e instanceof Error ? e.message : e)\n console.log(`[tryDecryptNote] encryptedNote hex length: ${encryptedNote.length} chars = ${(encryptedNote.length - 2) / 2} bytes`)\n }\n return null\n }\n}\n\n// ============================================================================\n// Note Unpacking\n// ============================================================================\n\n/**\n * Unpack note data from packed on-chain format\n *\n * Format: searchTag (8 bytes) + ephemeralPubkeyX (32 bytes) + ephemeralPubkeyY (32 bytes) + encryptedNote (variable)\n *\n * @param packed - The packed note data from the event\n * @param debug - Enable debug logging\n * @returns Unpacked note data or null if format is invalid\n */\nexport function unpackNoteData(packed: Hex, debug: boolean = false): UnpackedNoteData | null {\n try {\n const bytes = hexToBytes(packed)\n // Minimum length: 8 + 32 + 32 + 12 (nonce) + 16 (tag) = 100 bytes minimum\n if (bytes.length < 100) {\n if (debug) {\n console.log(`[unpackNoteData] Packed data too short: ${bytes.length} bytes`)\n }\n return null\n }\n\n const searchTag = bytesToBigint(bytes.slice(0, 8))\n const ephemeralPubkeyX = bytesToBigint(bytes.slice(8, 40))\n const ephemeralPubkeyY = bytesToBigint(bytes.slice(40, 72))\n const encryptedNote = ('0x' + Array.from(bytes.slice(72)).map(b => b.toString(16).padStart(2, '0')).join('')) as Hex\n\n if (debug) {\n console.log(`[unpackNoteData] Total packed bytes: ${bytes.length}, header: 72, encryptedNote: ${bytes.length - 72}`)\n console.log(`[unpackNoteData] searchTag=${searchTag}, ephemeralPubkeyX=${ephemeralPubkeyX}`)\n }\n\n return { searchTag, ephemeralPubkeyX, ephemeralPubkeyY, encryptedNote }\n } catch (e) {\n if (debug) {\n console.log(`[unpackNoteData] Failed to unpack:`, e)\n }\n return null\n }\n}\n\n// ============================================================================\n// Re-exported Helper Functions (canonical implementations in utils/crypto.ts)\n// ============================================================================\n\nexport { hexToBytes, bytesToBigint }\n","/**\n * RPC Indexer\n *\n * Direct blockchain scanning using RPC getLogs() with adaptive batching.\n * This is the default indexer that works with any RPC provider.\n *\n * Features:\n * - Adaptive batch sizing (shrinks on rate limits, grows on success)\n * - Incremental sync from last processed block\n * - Trial decryption to find notes belonging to the account\n * - Persistent state in pluggable storage\n * - Live sync with configurable interval\n */\n\nimport { keccak256, toHex, type Address, type Hex } from 'viem'\nimport type { Point } from '../utils/babyjubjub.js'\nimport type {\n Indexer,\n IndexedNote,\n RpcIndexerConfig,\n SyncResult,\n NoteFilters,\n LiveSyncConfig,\n IndexerState,\n SyncState,\n SerializedNote,\n SyncConfig,\n} from './types.js'\nimport { createAutoAdapter } from './storage/index.js'\nimport {\n unpackNoteData,\n matchesSearchTag,\n hexToBytes,\n bytesToBigint,\n} from './decryption.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_BATCH_SIZE = 200\nconst MIN_BATCH_SIZE = 50\nconst MAX_BATCH_SIZE = 2000\nconst BATCH_DELAY_MS = 100\nconst DEFAULT_LIVE_SYNC_INTERVAL_MS = 30000\n\n// Rate limiting defaults (tuned for dedicated/high-bandwidth nodes)\nconst DEFAULT_REQUESTS_PER_SECOND = 20 // Higher limit for dedicated nodes\nconst DEFAULT_MAX_CONCURRENT = 10 // Max parallel requests\n\n// Storage keys\nconst STORAGE_KEY_SYNC = 'sync'\nconst STORAGE_KEY_NOTES = 'notes'\nconst STORAGE_KEY_NULLIFIERS = 'nullifiers'\n\n// Event signatures (for getLogs)\nconst COMMITMENT_INSERTED_EVENT = {\n type: 'event' as const,\n name: 'CommitmentInserted',\n inputs: [\n { indexed: true, name: 'commitment', type: 'bytes32' },\n { indexed: false, name: 'leafIndex', type: 'uint256' },\n { indexed: false, name: 'timestamp', type: 'uint256' },\n ],\n}\n\nconst STEALTH_TRANSACT_EVENT = {\n type: 'event' as const,\n name: 'StealthTransact',\n inputs: [\n { indexed: true, name: 'commitment', type: 'bytes32' },\n { indexed: true, name: 'searchTag', type: 'uint64' },\n { indexed: false, name: 'ephemeralPubkeyX', type: 'uint256' },\n { indexed: false, name: 'ephemeralPubkeyY', type: 'uint256' },\n { indexed: false, name: 'encryptedNote', type: 'bytes' },\n ],\n}\n\nconst SHIELDED_EVENT = {\n type: 'event' as const,\n name: 'Shielded',\n inputs: [\n { indexed: true, name: 'token', type: 'address' },\n { indexed: true, name: 'depositor', type: 'address' },\n { indexed: true, name: 'commitment', type: 'bytes32' },\n { indexed: false, name: 'leafIndex', type: 'uint256' },\n { indexed: false, name: 'encryptedNote', type: 'bytes' },\n ],\n}\n\nconst TRANSFERRED_EVENT = {\n type: 'event' as const,\n name: 'Transferred',\n inputs: [\n { indexed: true, name: 'nullifier', type: 'bytes32' },\n { indexed: true, name: 'outputCommitment1', type: 'bytes32' },\n { indexed: true, name: 'outputCommitment2', type: 'bytes32' },\n { indexed: false, name: 'encryptedNote1', type: 'bytes' },\n { indexed: false, name: 'encryptedNote2', type: 'bytes' },\n ],\n}\n\nconst NULLIFIED_EVENT = {\n type: 'event' as const,\n name: 'Nullified',\n inputs: [{ indexed: true, name: 'nullifier', type: 'bytes32' }],\n}\n\nconst WITHDRAWN_EVENT = {\n type: 'event' as const,\n name: 'Withdrawn',\n inputs: [\n { indexed: true, name: 'token', type: 'address' },\n { indexed: true, name: 'recipient', type: 'address' },\n { indexed: true, name: 'nullifier', type: 'bytes32' },\n { indexed: false, name: 'amount', type: 'uint256' },\n { indexed: false, name: 'isRagequit', type: 'bool' },\n ],\n}\n\n// ============================================================================\n// Rate Limiter (Token Bucket)\n// ============================================================================\n\n/**\n * Simple token bucket rate limiter for RPC requests\n *\n * Prevents hitting 429 errors by proactively limiting request rate.\n */\nclass RateLimiter {\n private tokens: number\n private maxTokens: number\n private refillRate: number // tokens per ms\n private lastRefill: number\n private activeRequests: number\n private maxConcurrent: number\n private queue: Array<() => void> = []\n\n constructor(requestsPerSecond: number, maxConcurrent: number) {\n this.maxTokens = requestsPerSecond\n this.tokens = requestsPerSecond\n this.refillRate = requestsPerSecond / 1000 // per ms\n this.lastRefill = Date.now()\n this.activeRequests = 0\n this.maxConcurrent = maxConcurrent\n }\n\n /**\n * Refill tokens based on time elapsed\n */\n private refill(): void {\n const now = Date.now()\n const elapsed = now - this.lastRefill\n this.tokens = Math.min(this.maxTokens, this.tokens + elapsed * this.refillRate)\n this.lastRefill = now\n }\n\n /**\n * Try to process queued requests\n */\n private processQueue(): void {\n while (this.queue.length > 0 && this.activeRequests < this.maxConcurrent) {\n this.refill()\n if (this.tokens >= 1) {\n this.tokens -= 1\n this.activeRequests++\n const resolve = this.queue.shift()\n resolve?.()\n } else {\n break\n }\n }\n }\n\n /**\n * Acquire a token (wait if necessary)\n */\n async acquire(): Promise<void> {\n return new Promise((resolve) => {\n this.refill()\n\n // Can proceed immediately?\n if (this.tokens >= 1 && this.activeRequests < this.maxConcurrent) {\n this.tokens -= 1\n this.activeRequests++\n resolve()\n return\n }\n\n // Queue the request\n this.queue.push(resolve)\n\n // Schedule a check for when tokens should be available\n const waitTime = this.tokens < 1 ? Math.ceil((1 - this.tokens) / this.refillRate) : 10\n setTimeout(() => this.processQueue(), waitTime)\n })\n }\n\n /**\n * Release a token (call after request completes)\n */\n release(): void {\n this.activeRequests = Math.max(0, this.activeRequests - 1)\n this.processQueue()\n }\n\n /**\n * Execute a function with rate limiting\n */\n async execute<T>(fn: () => Promise<T>): Promise<T> {\n await this.acquire()\n try {\n return await fn()\n } finally {\n this.release()\n }\n }\n}\n\n// ============================================================================\n// SDK Loader (lazy load to avoid circular deps)\n// ============================================================================\n\nlet sdkPromise: Promise<typeof import('../index.js')> | null = null\n\nasync function loadSDK() {\n if (!sdkPromise) {\n sdkPromise = import('../index.js')\n }\n return sdkPromise\n}\n\n// ============================================================================\n// RPC Indexer Implementation\n// ============================================================================\n\nclass RpcIndexer implements Indexer {\n private client: RpcIndexerConfig['client']\n private contractAddress: Address\n private chainId: number\n private storage: import('./types.js').StorageAdapter\n private spendingSecret: bigint\n private spendingPubkey: Point\n private masterViewingSecret: bigint\n private masterViewingPubKey: Point\n\n // Adaptive batching state\n private batchSize: number\n private minBatchSize: number\n private batchDelayMs: number\n\n // In-memory cache\n private notes: IndexedNote[] = []\n private nullifiers: Set<string> = new Set()\n private lastBlock: number = 0\n private initialized: boolean = false\n\n // Initial starting block (fallback if no saved state)\n private initialFromBlock: number\n\n // Live sync state\n private liveSyncInterval: ReturnType<typeof setInterval> | null = null\n private liveSyncConfig: LiveSyncConfig | null = null\n\n // Rate limiter for RPC requests\n private rateLimiter: RateLimiter\n\n constructor(config: RpcIndexerConfig) {\n this.client = config.client\n this.contractAddress = config.contractAddress\n this.chainId = config.chainId\n this.spendingSecret = config.spendingSecret\n this.spendingPubkey = config.spendingPubkey\n this.masterViewingSecret = config.masterViewingSecret\n this.masterViewingPubKey = config.masterViewingPubKey\n\n // Batching config\n this.batchSize = config.batchSize ?? DEFAULT_BATCH_SIZE\n this.minBatchSize = config.minBatchSize ?? MIN_BATCH_SIZE\n this.batchDelayMs = config.batchDelayMs ?? BATCH_DELAY_MS\n\n // Initial starting block (0 = scan from beginning)\n this.initialFromBlock = config.fromBlock ?? 0\n\n // Storage (auto-detect if not provided)\n const accountPrefix = `${config.chainId}_${config.contractAddress.slice(2, 10)}_${toHex(config.spendingPubkey.x).slice(2, 12)}`\n this.storage = config.storage ?? createAutoAdapter(accountPrefix)\n\n // Rate limiter for RPC requests (prevents 429 errors)\n this.rateLimiter = new RateLimiter(DEFAULT_REQUESTS_PER_SECOND, DEFAULT_MAX_CONCURRENT)\n }\n\n /**\n * Initialize from storage\n */\n private async init(): Promise<void> {\n if (this.initialized) return\n\n // Load sync state\n const syncState = await this.storage.get<SyncState>(STORAGE_KEY_SYNC)\n if (syncState && syncState.chainId === this.chainId && syncState.contractAddress === this.contractAddress) {\n this.lastBlock = syncState.lastBlock\n } else {\n // No saved state - use initial fromBlock (e.g., account creation block)\n this.lastBlock = this.initialFromBlock\n }\n\n // Load notes\n const serializedNotes = await this.storage.get<SerializedNote[]>(STORAGE_KEY_NOTES)\n if (serializedNotes) {\n this.notes = serializedNotes.map(deserializeNote)\n }\n\n // Load nullifiers\n const nullifiers = await this.storage.get<Hex[]>(STORAGE_KEY_NULLIFIERS)\n if (nullifiers) {\n this.nullifiers = new Set(nullifiers.map((n) => n.toLowerCase()))\n }\n\n this.initialized = true\n\n // Check loaded notes against loaded nullifiers\n // This ensures notes spent in previous sessions are correctly marked\n if (this.notes.length > 0 && this.nullifiers.size > 0) {\n await this.checkNotesAgainstNullifiers()\n }\n }\n\n /**\n * Check all notes against known nullifiers and mark spent ones\n */\n private async checkNotesAgainstNullifiers(): Promise<number> {\n const sdk = await loadSDK()\n let spentCount = 0\n\n console.log(`[Indexer] checkNotesAgainstNullifiers: ${this.notes.length} notes, ${this.nullifiers.size} nullifiers in set`)\n if (this.nullifiers.size > 0) {\n console.log(`[Indexer] Known nullifiers:`)\n for (const n of this.nullifiers) {\n console.log(` ${n}`)\n }\n }\n\n for (const note of this.notes) {\n if (note.status === 'spent') continue\n\n try {\n const nullifier = await sdk.poseidon([\n BigInt(note.oneTimeSecret),\n BigInt(note.leafIndex),\n BigInt(note.commitment),\n ])\n const nullifierHex = toHex(nullifier, { size: 32 }).toLowerCase()\n\n const isSpent = this.nullifiers.has(nullifierHex)\n console.log(`[Indexer] Note ${note.commitment.slice(0, 18)}... leafIndex=${note.leafIndex} → nullifier=${nullifierHex.slice(0, 18)}... → ${isSpent ? 'SPENT' : 'unspent'}`)\n\n if (isSpent) {\n note.status = 'spent'\n spentCount++\n }\n } catch (e) {\n console.error(`[Indexer] Error computing nullifier for note:`, e)\n }\n }\n\n if (spentCount > 0) {\n console.log(`[Indexer] Marked ${spentCount} notes as spent based on nullifiers`)\n await this.persist()\n }\n\n return spentCount\n }\n\n /**\n * Persist current state to storage\n */\n private async persist(): Promise<void> {\n const syncState: SyncState = {\n lastBlock: this.lastBlock,\n chainId: this.chainId,\n contractAddress: this.contractAddress,\n lastSyncTimestamp: Date.now(),\n }\n\n await Promise.all([\n this.storage.set(STORAGE_KEY_SYNC, syncState),\n this.storage.set(STORAGE_KEY_NOTES, this.notes.map(serializeNote)),\n this.storage.set(STORAGE_KEY_NULLIFIERS, Array.from(this.nullifiers) as Hex[]),\n ])\n }\n\n /**\n * Sync notes from blockchain\n *\n * @param config - Optional sync configuration\n */\n async sync(config?: SyncConfig): Promise<SyncResult> {\n const startTime = Date.now()\n await this.init()\n\n const errors: string[] = []\n let newNotesCount = 0\n let spentNotesCount = 0\n const debug = config?.debug ?? false\n // TEMPORARILY DISABLED: Search tag filtering has a bug with transferred notes\n // Set to false to debug - notes from transfers don't match search tags correctly\n const useSearchTagFiltering = config?.useSearchTagFiltering ?? false\n\n try {\n const currentBlock = Number(await this.client.getBlockNumber())\n const fromBlock = this.lastBlock > 0 ? this.lastBlock + 1 : this.initialFromBlock\n\n if (fromBlock > currentBlock) {\n // Already up to date\n return {\n newNotesCount: 0,\n spentNotesCount: 0,\n lastBlock: this.lastBlock,\n durationMs: Date.now() - startTime,\n }\n }\n\n // Report initial progress\n const reportProgress = (currentBlock_: number, eventsProcessed: number, notesFound: number, eventsSkipped: number) => {\n if (config?.onProgress) {\n const totalBlocks = currentBlock - fromBlock + 1\n const processedBlocks = currentBlock_ - fromBlock + 1\n config.onProgress({\n currentBlock: currentBlock_,\n targetBlock: currentBlock,\n eventsProcessed,\n notesFound,\n percent: Math.round((processedBlocks / totalBlocks) * 100),\n eventsSkipped,\n })\n }\n }\n\n // Fetch events in batches\n const commitmentMap = new Map<string, { leafIndex: number; timestamp: number; blockNumber: number }>()\n const stealthEvents: Array<{\n commitment: Hex\n ephemeralPubkeyX: bigint\n ephemeralPubkeyY: bigint\n encryptedNote: Hex\n txHash: Hex\n blockNumber: number\n searchTag?: bigint // For filtering before trial decryption\n }> = []\n const newNullifiers: Hex[] = []\n\n let currentBatchSize = this.batchSize\n let batchStart = fromBlock\n\n while (batchStart <= currentBlock) {\n const batchEnd = Math.min(batchStart + currentBatchSize - 1, currentBlock)\n\n try {\n // Fetch all event types with rate limiting\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const [commitmentLogs, stealthLogs, shieldedLogs, transferredLogs, nullifiedLogs, withdrawnLogs] = await Promise.all([\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: COMMITMENT_INSERTED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: STEALTH_TRANSACT_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: SHIELDED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: TRANSFERRED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: NULLIFIED_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n this.rateLimiter.execute(() =>\n this.client.getLogs({\n address: this.contractAddress,\n event: WITHDRAWN_EVENT,\n fromBlock: BigInt(batchStart),\n toBlock: BigInt(batchEnd),\n })\n ),\n ]) as [any[], any[], any[], any[], any[], any[]]\n\n // Process commitment events\n for (const log of commitmentLogs) {\n const commitment = (log.args as { commitment: Hex }).commitment.toLowerCase()\n commitmentMap.set(commitment, {\n leafIndex: Number((log.args as { leafIndex: number }).leafIndex),\n timestamp: Number((log.args as { timestamp: bigint }).timestamp),\n blockNumber: Number(log.blockNumber),\n })\n }\n\n // Process stealth events\n for (const log of stealthLogs) {\n const args = log.args as {\n commitment: Hex\n searchTag: bigint\n ephemeralPubkeyX: bigint\n ephemeralPubkeyY: bigint\n encryptedNote: Hex\n }\n stealthEvents.push({\n commitment: args.commitment.toLowerCase() as Hex,\n ephemeralPubkeyX: args.ephemeralPubkeyX,\n ephemeralPubkeyY: args.ephemeralPubkeyY,\n encryptedNote: args.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: args.searchTag,\n })\n }\n\n // Process shielded events (packed note format)\n for (const log of shieldedLogs) {\n const args = log.args as {\n commitment: Hex\n leafIndex: bigint\n encryptedNote: Hex\n }\n // Unpack note data: searchTag (8) + ephemeralPubkeyX (32) + ephemeralPubkeyY (32) + encryptedNote\n const unpacked = unpackNoteData(args.encryptedNote)\n if (unpacked) {\n stealthEvents.push({\n commitment: args.commitment.toLowerCase() as Hex,\n ephemeralPubkeyX: unpacked.ephemeralPubkeyX,\n ephemeralPubkeyY: unpacked.ephemeralPubkeyY,\n encryptedNote: unpacked.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: unpacked.searchTag,\n })\n // Also track in commitmentMap\n commitmentMap.set(args.commitment.toLowerCase(), {\n leafIndex: Number(args.leafIndex),\n timestamp: Math.floor(Date.now() / 1000),\n blockNumber: Number(log.blockNumber),\n })\n }\n }\n\n // Process transferred events (2 packed notes)\n for (const log of transferredLogs) {\n const args = log.args as {\n outputCommitment1: Hex\n outputCommitment2: Hex\n encryptedNote1: Hex\n encryptedNote2: Hex\n }\n // Process first output\n const unpacked1 = unpackNoteData(args.encryptedNote1)\n if (unpacked1) {\n stealthEvents.push({\n commitment: args.outputCommitment1.toLowerCase() as Hex,\n ephemeralPubkeyX: unpacked1.ephemeralPubkeyX,\n ephemeralPubkeyY: unpacked1.ephemeralPubkeyY,\n encryptedNote: unpacked1.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: unpacked1.searchTag,\n })\n }\n // Process second output (change note)\n const unpacked2 = unpackNoteData(args.encryptedNote2)\n if (unpacked2) {\n stealthEvents.push({\n commitment: args.outputCommitment2.toLowerCase() as Hex,\n ephemeralPubkeyX: unpacked2.ephemeralPubkeyX,\n ephemeralPubkeyY: unpacked2.ephemeralPubkeyY,\n encryptedNote: unpacked2.encryptedNote,\n txHash: log.transactionHash,\n blockNumber: Number(log.blockNumber),\n searchTag: unpacked2.searchTag,\n })\n }\n }\n\n // Process nullifier events (explicit Nullified events)\n for (const log of nullifiedLogs) {\n const nullifier = (log.args as { nullifier: Hex }).nullifier.toLowerCase() as Hex\n newNullifiers.push(nullifier)\n }\n\n // Also extract nullifiers from Transferred events (the input that was spent)\n for (const log of transferredLogs) {\n const args = log.args as { nullifier: Hex }\n if (args.nullifier) {\n newNullifiers.push(args.nullifier.toLowerCase() as Hex)\n }\n }\n\n // Extract nullifiers from Withdrawn events (notes spent via withdrawal)\n if (withdrawnLogs.length > 0) {\n console.log(`[Indexer] Found ${withdrawnLogs.length} Withdrawn events in batch`)\n }\n for (const log of withdrawnLogs) {\n const args = log.args as { nullifier: Hex }\n if (args.nullifier) {\n const nullifierLower = args.nullifier.toLowerCase() as Hex\n console.log(`[Indexer] Withdrawn event nullifier: ${nullifierLower}`)\n newNullifiers.push(nullifierLower)\n }\n }\n\n // Success - try to increase batch size\n if (currentBatchSize < MAX_BATCH_SIZE) {\n currentBatchSize = Math.min(currentBatchSize * 2, MAX_BATCH_SIZE)\n }\n\n // Report progress after each batch\n reportProgress(batchEnd, stealthEvents.length, 0, 0)\n\n batchStart = batchEnd + 1\n\n // Small delay between batches to avoid overwhelming RPC\n if (batchStart <= currentBlock) {\n await sleep(this.batchDelayMs)\n }\n } catch (e) {\n // Check if rate limit error\n if (isRateLimitError(e)) {\n // Shrink batch size\n currentBatchSize = Math.max(Math.floor(currentBatchSize / 2), this.minBatchSize)\n errors.push(`Rate limited at block ${batchStart}, reducing batch size to ${currentBatchSize}`)\n await sleep(1000) // Wait a second before retrying\n continue // Retry same batch with smaller size\n }\n throw e\n }\n }\n\n // Update adaptive batch size for next sync\n this.batchSize = currentBatchSize\n\n // Process nullifiers - add to set\n console.log(`[Indexer] Processing ${newNullifiers.length} new nullifiers`)\n for (const nullifier of newNullifiers) {\n if (!this.nullifiers.has(nullifier.toLowerCase())) {\n this.nullifiers.add(nullifier.toLowerCase())\n }\n }\n console.log(`[Indexer] Total nullifiers in set: ${this.nullifiers.size}`)\n\n // NOTE: checkNotesAgainstNullifiers is called AFTER trial decryption\n // so that newly discovered notes can also be checked against nullifiers\n\n // Trial decryption for stealth events\n const sdk = await loadSDK()\n const existingCommitmentsMap = new Map(this.notes.map((n) => [n.commitment.toLowerCase(), n]))\n\n // Always log sync summary (useful for debugging)\n console.log(`[Indexer] Sync: blocks ${fromBlock} to ${currentBlock} (${currentBlock - fromBlock + 1} blocks)`)\n console.log(`[Indexer] Found: ${stealthEvents.length} stealth events, ${commitmentMap.size} commitment events`)\n console.log(`[Indexer] Search tag filtering: ${useSearchTagFiltering ? 'ENABLED' : 'DISABLED'}`)\n\n if (debug) {\n console.log(`[Indexer] Existing notes in memory: ${this.notes.length}`)\n console.log(`[Indexer] masterViewingPubKey: x=${this.masterViewingPubKey.x}, y=${this.masterViewingPubKey.y}`)\n }\n\n // Search tag filtering: skip events that don't match our viewing key\n let eventsSkipped = 0\n let eventsProcessed = 0\n\n for (const event of stealthEvents) {\n const commitmentLower = event.commitment.toLowerCase()\n const existingNote = existingCommitmentsMap.get(commitmentLower)\n\n // If we already have this note as confirmed, skip it\n if (existingNote && existingNote.status === 'confirmed') {\n continue\n }\n\n // If we have a pending note with this commitment, update it to confirmed\n if (existingNote && existingNote.status === 'pending') {\n const info = commitmentMap.get(commitmentLower)\n existingNote.status = 'confirmed'\n existingNote.leafIndex = info?.leafIndex ?? existingNote.leafIndex\n existingNote.blockNumber = info?.blockNumber ?? event.blockNumber\n existingNote.timestamp = info?.timestamp ?? existingNote.timestamp\n newNotesCount++ // Count as \"new\" since it's newly confirmed\n continue\n }\n\n // Search tag filtering: check if this event might be ours before expensive decryption\n if (useSearchTagFiltering && event.searchTag !== undefined) {\n const ephemeralPubkey = { x: event.ephemeralPubkeyX, y: event.ephemeralPubkeyY }\n\n // Log first few events for debugging (limit to avoid spam)\n const shouldLogDetails = debug && eventsSkipped + eventsProcessed < 3\n if (shouldLogDetails) {\n console.log(`[Indexer] Checking event searchTag=${event.searchTag}`)\n console.log(`[Indexer] ephemeralPubkey: x=${ephemeralPubkey.x}, y=${ephemeralPubkey.y}`)\n }\n\n const matches = await matchesSearchTag(\n event.searchTag,\n sdk,\n this.masterViewingSecret,\n this.masterViewingPubKey,\n ephemeralPubkey,\n shouldLogDetails // Pass debug flag\n )\n if (!matches) {\n eventsSkipped++\n continue // Not our note, skip expensive trial decryption\n }\n if (debug) {\n console.log(`[Indexer] ✓ Search tag MATCHED for commitment ${event.commitment.slice(0, 18)}...`)\n }\n }\n\n eventsProcessed++\n try {\n if (debug) {\n console.log(`[Indexer] Trying to decrypt event commitment: ${event.commitment}`)\n console.log(`[Indexer] Encrypted note length: ${(event.encryptedNote.length - 2) / 2} bytes`)\n }\n\n const decrypted = await tryDecryptNote(\n sdk,\n this.spendingSecret,\n this.spendingPubkey,\n this.masterViewingSecret,\n this.masterViewingPubKey,\n { x: event.ephemeralPubkeyX, y: event.ephemeralPubkeyY },\n event.encryptedNote,\n BigInt(event.commitment)\n )\n\n if (decrypted) {\n if (debug) {\n console.log(`[Indexer] ✓ Decryption SUCCESS for commitment ${event.commitment.slice(0, 18)}...`)\n console.log(`[Indexer] Amount: ${decrypted.amount}, Origin: 0x${decrypted.origin.toString(16)}, Token: 0x${decrypted.token.toString(16)}`)\n }\n const info = commitmentMap.get(event.commitment.toLowerCase())\n const note: IndexedNote = {\n amount: decrypted.amount,\n blinding: decrypted.blinding,\n commitment: event.commitment.toLowerCase() as Hex,\n oneTimeSecret: toHex(decrypted.oneTimeSecret, { size: 32 }),\n oneTimePubkeyX: toHex(decrypted.oneTimePubkey.x, { size: 32 }),\n oneTimePubkeyY: toHex(decrypted.oneTimePubkey.y, { size: 32 }),\n leafIndex: info?.leafIndex ?? 0,\n txHash: event.txHash,\n status: 'confirmed',\n blockNumber: info?.blockNumber ?? event.blockNumber,\n timestamp: info?.timestamp ?? Math.floor(Date.now() / 1000),\n origin: ('0x' + decrypted.origin.toString(16).padStart(40, '0')) as Address,\n token: ('0x' + decrypted.token.toString(16).padStart(40, '0')) as Address,\n ephemeralX: toHex(event.ephemeralPubkeyX, { size: 32 }),\n ephemeralY: toHex(event.ephemeralPubkeyY, { size: 32 }),\n }\n\n this.notes.push(note)\n existingCommitmentsMap.set(note.commitment.toLowerCase(), note)\n newNotesCount++\n }\n } catch (decryptErr) {\n // Decryption failed - not our note, continue\n if (debug) {\n console.log(`[Indexer] ✗ Decryption FAILED for commitment ${event.commitment.slice(0, 18)}...`, decryptErr)\n }\n }\n }\n\n // Always log search tag filtering stats (useful for debugging)\n if (stealthEvents.length > 0) {\n console.log(`[Indexer] Result: ${eventsSkipped} skipped by search tag, ${eventsProcessed} processed, ${newNotesCount} notes found`)\n }\n\n // Report final progress\n reportProgress(currentBlock, eventsProcessed, newNotesCount, eventsSkipped)\n\n // Mark notes as spent by computing their nullifiers and checking against on-chain nullifiers\n // This MUST happen AFTER trial decryption so newly discovered notes are checked too\n spentNotesCount = await this.checkNotesAgainstNullifiers()\n\n this.lastBlock = currentBlock\n await this.persist()\n\n // Notify live sync callbacks\n if (newNotesCount > 0 && this.liveSyncConfig?.onNewNotes) {\n const newNotes = this.notes.slice(-newNotesCount)\n this.liveSyncConfig.onNewNotes(newNotes)\n }\n\n return {\n newNotesCount,\n spentNotesCount,\n lastBlock: this.lastBlock,\n durationMs: Date.now() - startTime,\n errors: errors.length > 0 ? errors : undefined,\n }\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e))\n if (this.liveSyncConfig?.onError) {\n this.liveSyncConfig.onError(error)\n }\n throw error\n }\n }\n\n /**\n * Get total balance of unspent notes\n */\n getBalance(token?: Address): bigint {\n const unspent = this.getUnspentNotes()\n const filtered = token ? unspent.filter((n) => n.token === token) : unspent\n return filtered.reduce((sum, n) => sum + n.amount, 0n)\n }\n\n /**\n * Get all notes matching filters\n */\n getNotes(filters?: NoteFilters): IndexedNote[] {\n let result = [...this.notes]\n\n if (filters?.status) {\n const statuses = Array.isArray(filters.status) ? filters.status : [filters.status]\n result = result.filter((n) => statuses.includes(n.status))\n }\n\n if (filters?.token) {\n result = result.filter((n) => n.token === filters.token)\n }\n\n if (filters?.minAmount !== undefined) {\n result = result.filter((n) => n.amount >= filters.minAmount!)\n }\n\n if (filters?.maxAmount !== undefined) {\n result = result.filter((n) => n.amount <= filters.maxAmount!)\n }\n\n return result\n }\n\n /**\n * Get unspent notes\n */\n getUnspentNotes(): IndexedNote[] {\n return this.notes.filter((n) => n.status !== 'spent')\n }\n\n /**\n * Get the last synced block number\n */\n getLastBlock(): number {\n return this.lastBlock\n }\n\n /**\n * Mark a note as spent\n */\n markSpent(commitment: Hex): void {\n const note = this.notes.find((n) => n.commitment.toLowerCase() === commitment.toLowerCase())\n if (note) {\n note.status = 'spent'\n // Persist async (don't block)\n this.persist().catch(console.error)\n }\n }\n\n /**\n * Add a note directly\n */\n addNote(note: IndexedNote): void {\n // Check for duplicate\n if (this.notes.some((n) => n.commitment.toLowerCase() === note.commitment.toLowerCase())) {\n return\n }\n this.notes.push(note)\n // Persist async (don't block)\n this.persist().catch(console.error)\n }\n\n /**\n * Start live sync\n */\n startLiveSync(config?: LiveSyncConfig): void {\n if (this.liveSyncInterval) {\n this.stopLiveSync()\n }\n\n this.liveSyncConfig = config ?? {}\n const intervalMs = config?.intervalMs ?? DEFAULT_LIVE_SYNC_INTERVAL_MS\n\n this.liveSyncInterval = setInterval(() => {\n this.sync().catch((e) => {\n if (config?.onError) {\n config.onError(e instanceof Error ? e : new Error(String(e)))\n }\n })\n }, intervalMs)\n\n // Also sync immediately\n this.sync().catch((e) => {\n if (config?.onError) {\n config.onError(e instanceof Error ? e : new Error(String(e)))\n }\n })\n }\n\n /**\n * Stop live sync\n */\n stopLiveSync(): void {\n if (this.liveSyncInterval) {\n clearInterval(this.liveSyncInterval)\n this.liveSyncInterval = null\n }\n this.liveSyncConfig = null\n }\n\n /**\n * Check if live sync is running\n */\n isLiveSyncing(): boolean {\n return this.liveSyncInterval !== null\n }\n\n /**\n * Clear all indexed data\n */\n async clear(): Promise<void> {\n this.notes = []\n this.nullifiers.clear()\n this.lastBlock = 0\n await this.storage.clear()\n }\n\n /**\n * Export current state\n */\n async exportState(): Promise<IndexerState> {\n await this.init()\n return {\n sync: {\n lastBlock: this.lastBlock,\n chainId: this.chainId,\n contractAddress: this.contractAddress,\n lastSyncTimestamp: Date.now(),\n },\n notes: this.notes.map(serializeNote),\n nullifiers: Array.from(this.nullifiers) as Hex[],\n }\n }\n\n /**\n * Import state\n */\n async importState(state: IndexerState): Promise<void> {\n // Validate chain/contract match\n if (state.sync.chainId !== this.chainId || state.sync.contractAddress !== this.contractAddress) {\n throw new Error('State does not match indexer configuration')\n }\n\n this.lastBlock = state.sync.lastBlock\n this.notes = state.notes.map(deserializeNote)\n this.nullifiers = new Set(state.nullifiers.map((n) => n.toLowerCase()))\n this.initialized = true\n\n await this.persist()\n }\n}\n\n// ============================================================================\n// Factory Function\n// ============================================================================\n\n/**\n * Create an RPC indexer\n *\n * @param config - Indexer configuration\n * @returns Indexer instance\n *\n * @example\n * ```ts\n * import { makeRpcIndexer } from '@upp/sdk/indexer'\n * import { createPublicClient, http } from 'viem'\n *\n * const client = createPublicClient({ transport: http() })\n *\n * const indexer = makeRpcIndexer({\n * client,\n * contractAddress: '0x...',\n * chainId: 1,\n * spendingSecret: mySpendingSecret,\n * spendingPubkey: mySpendingPubkey,\n * })\n *\n * // Initial sync\n * const result = await indexer.sync()\n * console.log(`Found ${result.newNotesCount} new notes`)\n *\n * // Get balance\n * const balance = indexer.getBalance()\n *\n * // Start live sync\n * indexer.startLiveSync({\n * intervalMs: 30000,\n * onNewNotes: (notes) => console.log('New notes:', notes),\n * })\n * ```\n */\nexport function makeRpcIndexer(config: RpcIndexerConfig): Indexer {\n return new RpcIndexer(config)\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Try to decrypt a note using dual ECDH (UPP format with origin and token)\n *\n * 1. Viewing ECDH: DVK * R → AES decryption key (viewing shared secret)\n * 2. Spending ECDH: spendingSecret * R → one-time key for commitment verification\n *\n * DVK is derived using R.x (ephemeral public key x-coordinate) as the nonce.\n *\n * UPP encrypted payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n * UPP commitment: Poseidon(amount, pubkeyX, pubkeyY, blinding, origin, token)\n */\nasync function tryDecryptNote(\n sdk: typeof import('../index.js'),\n spendingSecret: bigint,\n _spendingPubkey: Point,\n _masterViewingSecret: bigint,\n _masterViewingPubKey: Point,\n _ephemeralPubkey: Point,\n encryptedNote: Hex,\n expectedCommitment: bigint\n): Promise<{\n amount: bigint\n blinding: bigint\n oneTimeSecret: bigint\n oneTimePubkey: Point\n origin: bigint\n token: bigint\n} | null> {\n try {\n // --- Viewing key decryption (hash-based, BLS12-381) ---\n // For self-shielded notes, the AES key is derived from the viewing secret directly.\n // For stealth notes (future), ECDH will be re-implemented with a non-BabyJubJub curve.\n const dvk = await sdk.deriveDecryptionViewingKey(_masterViewingSecret, _masterViewingPubKey, _ephemeralPubkey.x)\n const viewingSharedSecret = await sdk.computeSharedSecret(dvk, _ephemeralPubkey)\n\n // Derive AES key from viewing shared secret\n const keyMaterial = keccak256(toHex(viewingSharedSecret.x, { size: 32 }))\n const keyBytes = hexToBytes(keyMaterial)\n\n const cryptoKey = await crypto.subtle.importKey(\n 'raw',\n keyBytes.buffer.slice(keyBytes.byteOffset, keyBytes.byteOffset + keyBytes.byteLength) as ArrayBuffer,\n { name: 'AES-GCM', length: 256 },\n false,\n ['decrypt']\n )\n\n // Parse encrypted note\n const encryptedBytes = hexToBytes(encryptedNote)\n const nonce = encryptedBytes.slice(0, 12)\n const ciphertext = encryptedBytes.slice(12)\n\n // Decrypt\n const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, cryptoKey, ciphertext)\n\n const plaintextBytes = new Uint8Array(plaintext)\n console.log(`[tryDecryptNote] Decrypted plaintext length: ${plaintextBytes.length} bytes`)\n\n // UPP payload: amount (32) + blinding (32) + origin (20) + token (20) = 104 bytes\n const amount = bytesToBigint(plaintextBytes.slice(0, 32))\n const blinding = bytesToBigint(plaintextBytes.slice(32, 64))\n const origin = bytesToBigint(plaintextBytes.slice(64, 84))\n const token = bytesToBigint(plaintextBytes.slice(84, 104))\n\n // --- Hash-based ownership verification (BLS12-381) ---\n const ownerHash = await sdk.poseidon([spendingSecret])\n const oneTimeSecret = spendingSecret\n const oneTimePubkey = { x: ownerHash, y: 0n }\n\n // Verify UPP commitment (5 elements: amount, ownerHash, blinding, origin, token)\n const computedCommitment = await sdk.poseidon([\n amount,\n ownerHash,\n blinding,\n origin,\n token,\n ])\n\n console.log(`[tryDecryptNote] Decrypted values:`)\n console.log(` amount: ${amount}`)\n console.log(` blinding: ${blinding}`)\n console.log(` origin: 0x${origin.toString(16).padStart(40, '0')}`)\n console.log(` token: 0x${token.toString(16).padStart(40, '0')}`)\n console.log(` oneTimePubkey.x: ${oneTimePubkey.x}`)\n console.log(` oneTimePubkey.y: ${oneTimePubkey.y}`)\n console.log(` computedCommitment: ${computedCommitment}`)\n console.log(` expectedCommitment: ${expectedCommitment}`)\n console.log(` match: ${computedCommitment === expectedCommitment}`)\n\n if (computedCommitment !== expectedCommitment) {\n console.log(`[tryDecryptNote] Commitment mismatch - not our note`)\n return null\n }\n\n return { amount, blinding, oneTimeSecret, oneTimePubkey, origin, token }\n } catch (e) {\n console.log(`[tryDecryptNote] Decryption exception:`, e instanceof Error ? e.message : e)\n console.log(`[tryDecryptNote] encryptedNote hex length: ${encryptedNote.length} chars = ${(encryptedNote.length - 2) / 2} bytes`)\n return null\n }\n}\n\n/**\n * Serialize a note for storage\n */\nfunction serializeNote(note: IndexedNote): SerializedNote {\n return {\n amount: note.amount.toString(),\n blinding: note.blinding.toString(),\n commitment: note.commitment,\n oneTimeSecret: note.oneTimeSecret,\n oneTimePubkeyX: note.oneTimePubkeyX,\n oneTimePubkeyY: note.oneTimePubkeyY,\n leafIndex: note.leafIndex,\n txHash: note.txHash,\n status: note.status,\n blockNumber: note.blockNumber,\n timestamp: note.timestamp,\n origin: note.origin,\n token: note.token,\n ephemeralX: note.ephemeralX,\n ephemeralY: note.ephemeralY,\n }\n}\n\n/**\n * Deserialize a note from storage\n */\nfunction deserializeNote(note: SerializedNote): IndexedNote {\n return {\n amount: BigInt(note.amount),\n blinding: BigInt(note.blinding),\n commitment: note.commitment as Hex,\n oneTimeSecret: note.oneTimeSecret as Hex,\n oneTimePubkeyX: note.oneTimePubkeyX as Hex,\n oneTimePubkeyY: note.oneTimePubkeyY as Hex,\n leafIndex: note.leafIndex,\n txHash: note.txHash as Hex | undefined,\n status: note.status,\n blockNumber: note.blockNumber,\n timestamp: note.timestamp,\n origin: note.origin as Address | undefined,\n token: note.token as Address | undefined,\n ephemeralX: note.ephemeralX as Hex | undefined,\n ephemeralY: note.ephemeralY as Hex | undefined,\n }\n}\n\n/**\n * Check if an error is a rate limit error\n */\nfunction isRateLimitError(e: unknown): boolean {\n if (e instanceof Error) {\n const message = e.message.toLowerCase()\n return (\n message.includes('rate limit') ||\n message.includes('too many requests') ||\n message.includes('429') ||\n message.includes('exceeded')\n )\n }\n return false\n}\n\n/**\n * Sleep for a given number of milliseconds\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n// hexToBytes, bytesToBigint, unpackNoteData are now imported from ./decryption.js\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkUFEDJJSH_cjs = require('./chunk-UFEDJJSH.cjs');
3
+ var chunkBCSMUH4L_cjs = require('./chunk-BCSMUH4L.cjs');
4
4
  var chunkHEHXSV47_cjs = require('./chunk-HEHXSV47.cjs');
5
5
 
6
6
  // src/utils/index.ts
@@ -95,7 +95,7 @@ async function deriveDecryptionViewingKey(masterViewingPrivKey, masterViewingPub
95
95
  }
96
96
 
97
97
  // src/utils/index.ts
98
- chunkUFEDJJSH_cjs.init_crypto();
98
+ chunkBCSMUH4L_cjs.init_crypto();
99
99
 
100
100
  exports.addPoints = addPoints;
101
101
  exports.computeSharedSecret = computeSharedSecret;
@@ -109,5 +109,5 @@ exports.packPoint = packPoint;
109
109
  exports.pointToTuple = pointToTuple;
110
110
  exports.privateToPublic = privateToPublic;
111
111
  exports.tupleToPoint = tupleToPoint;
112
- //# sourceMappingURL=chunk-I5EKGD4P.cjs.map
113
- //# sourceMappingURL=chunk-I5EKGD4P.cjs.map
112
+ //# sourceMappingURL=chunk-XNSMPNY6.cjs.map
113
+ //# sourceMappingURL=chunk-XNSMPNY6.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/index.ts","../src/utils/babyjubjub.ts"],"names":["init_poseidon","poseidonScalar","BABYJUBJUB_SUBORDER","init_crypto"],"mappings":";;;;;;AAKAA,+BAAA,EAAA;;;ACKAA,+BAAA,EAAA;AA+BA,IAAI,eAAA,GAAqC,IAAA;AAKzC,eAAe,WAAA,GAAmC;AAChD,EAAA,IAAI,oBAAoB,IAAA,EAAM;AAC5B,IAAA,MAAM,EAAE,YAAA,EAAa,GAAI,MAAM,OAAO,aAAa,CAAA;AACnD,IAAA,eAAA,GAAkB,MAAM,YAAA,EAAa;AAAA,EACvC;AACA,EAAA,OAAO,eAAA;AACT;AAKA,eAAsB,WAAA,GAA+B;AACnD,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAClC,EAAA,OAAO,OAAA,CAAQ,QAAA;AACjB;AAKA,eAAsB,YAAA,GAA+B;AACnD,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAClC,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,CAAA,CAAE,SAAS,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACtC,GAAG,OAAA,CAAQ,CAAA,CAAE,SAAS,OAAA,CAAQ,KAAA,CAAM,CAAC,CAAC;AAAA,GACxC;AACF;AAKA,eAAsB,UAAU,KAAA,EAAgC;AAC9D,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAClC,EAAA,MAAM,QAAA,GAAW,CAAC,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AAC5D,EAAA,OAAO,OAAA,CAAQ,QAAQ,QAAQ,CAAA;AACjC;AASA,eAAsB,cAAA,CAAe,OAAc,MAAA,EAAgC;AACjF,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAGlC,EAAA,MAAM,QAAA,GAAW,CAAC,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA;AAG5D,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,eAAA,CAAgB,QAAA,EAAU,MAAM,CAAA;AAEvD,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC/B,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC;AAAA,GACjC;AACF;AAKA,eAAsB,SAAA,CAAU,IAAW,EAAA,EAA2B;AACpE,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAGlC,EAAA,MAAM,SAAA,GAAY,CAAC,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,EAAA,CAAG,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,EAAA,CAAG,CAAC,CAAC,CAAA;AACvD,EAAA,MAAM,SAAA,GAAY,CAAC,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,EAAA,CAAG,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,EAAA,CAAG,CAAC,CAAC,CAAA;AAGvD,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,QAAA,CAAS,SAAA,EAAW,SAAS,CAAA;AAEpD,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC/B,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC;AAAA,GACjC;AACF;AASA,eAAsB,gBAAgB,UAAA,EAAoC;AACxE,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAGlC,EAAA,MAAM,MAAA,GAAS,aAAa,OAAA,CAAQ,QAAA;AAGpC,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,eAAA,CAAgB,OAAA,CAAQ,OAAO,MAAM,CAAA;AAE5D,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC/B,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC;AAAA,GACjC;AACF;AAUA,eAAsB,mBAAA,CACpB,cACA,cAAA,EACgB;AAChB,EAAA,OAAO,cAAA,CAAe,gBAAgB,YAAY,CAAA;AACpD;AAMO,SAAS,UAAU,KAAA,EAAsB;AAE9C,EAAA,MAAM,KAAA,GAAQ,MAAM,CAAA,GAAI,EAAA;AACxB,EAAA,OAAO,KAAA,CAAM,IAAK,KAAA,IAAS,IAAA;AAC7B;AAKO,SAAS,aAAa,KAAA,EAAgC;AAC3D,EAAA,OAAO,CAAC,KAAA,CAAM,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA;AAC1B;AAKO,SAAS,aAAa,KAAA,EAAgC;AAC3D,EAAA,OAAO,EAAE,GAAG,KAAA,CAAM,CAAC,GAAG,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAE;AACpC;AA2LA,eAAsB,0BAAA,CACpB,qBACA,KAAA,EACgB;AAEhB,EAAA,MAAM,EAAE,cAAA,EAAAC,eAAAA,EAAe,GAAI,MAAM,OAAO,yBAAe,CAAA;AAEvD,EAAA,MAAM,OAAA,GAAU,MAAM,WAAA,EAAY;AAGlC,EAAA,MAAM,MAAA,GAAS,MAAMA,eAAAA,CAAe,CAAC,oBAAoB,CAAA,EAAG,mBAAA,CAAoB,CAAA,EAAG,KAAK,CAAC,CAAA;AAGzF,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,eAAA,CAAgB,OAAA,CAAQ,OAAO,MAAM,CAAA;AAG5D,EAAA,MAAM,WAAA,GAAc;AAAA,IAClB,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,mBAAA,CAAoB,CAAC,CAAA;AAAA,IACjC,OAAA,CAAQ,CAAA,CAAE,CAAA,CAAE,mBAAA,CAAoB,CAAC;AAAA,GACnC;AAGA,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,QAAA,CAAS,WAAA,EAAa,MAAM,CAAA;AAEnD,EAAA,OAAO;AAAA,IACL,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC/B,GAAG,OAAA,CAAQ,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,CAAC,CAAC;AAAA,GACjC;AACF;AAeA,eAAsB,0BAAA,CACpB,oBAAA,EACA,mBAAA,EACA,KAAA,EACiB;AAEjB,EAAA,MAAM,EAAE,cAAA,EAAAA,eAAAA,EAAe,GAAI,MAAM,OAAO,yBAAe,CAAA;AAGvD,EAAA,MAAM,MAAA,GAAS,MAAMA,eAAAA,CAAe,CAAC,oBAAoB,CAAA,EAAG,mBAAA,CAAoB,CAAA,EAAG,KAAK,CAAC,CAAA;AAGzF,EAAA,OAAA,CAAQ,uBAAuB,MAAA,IAAUC,qCAAA;AAC3C;;;AD5XAC,6BAAA,EAAA","file":"chunk-I5EKGD4P.cjs","sourcesContent":["/**\n * Utility functions for UPP SDK\n */\n\n// Poseidon hash\nexport {\n poseidon,\n poseidonHash,\n poseidonScalar,\n FIELD_PRIME,\n BABYJUBJUB_SUBORDER,\n addressToField,\n fieldToAddress,\n isValidFieldElement,\n toFieldElement,\n} from './poseidon.js'\n\n// BabyJubJub curve operations\nexport {\n type Point,\n getSubOrder,\n getBasePoint,\n isOnCurve,\n mulPointScalar,\n addPoints,\n privateToPublic,\n computeSharedSecret,\n packPoint,\n pointToTuple,\n tupleToPoint,\n deriveEncryptionViewingKey,\n deriveDecryptionViewingKey,\n} from './babyjubjub.js'\n\n// Merkle tree\nexport {\n MerkleTree,\n buildMerkleTree,\n getMerkleProof,\n verifyMerkleProof,\n type MerkleProof,\n MAX_TREE_DEPTH,\n} from './merkle.js'\n\n// Crypto utilities\nexport {\n randomBytes,\n randomFieldElement,\n bytesToHex,\n hexToBytes,\n bigintToBytes,\n bytesToBigint,\n} from './crypto.js'\n\n// STARK utilities (amount scaling, witness building, Fiat-Shamir)\nexport {\n STARK_AMOUNT_SCALE,\n STARK_STATE_TREE_DEPTH,\n STARK_ASP_TREE_DEPTH,\n isStarkAligned,\n scaleAmountForStark,\n truncateToM31,\n addressToM31,\n splitSecretToM31Limbs,\n packM31Digest,\n computeWithdrawPublicInputsSeed,\n computeTransferPublicInputsSeed,\n buildStarkWithdrawWitness,\n buildStarkTransferWitness,\n type StarkWithdrawWitness,\n type StarkTransferWitness,\n} from './stark.js'\n\n// Keccak-M31 hashing (STARK)\nexport {\n keccakM31,\n keccakHashTwo,\n computeStarkOwnerHash,\n computeStarkCommitment,\n computeStarkNullifier,\n splitToM31Limbs,\n M31_P,\n DIGEST_SIZE,\n SECRET_LIMBS,\n type M31Digest,\n type M31Secret,\n} from './keccak-m31.js'\n","/**\n * BabyJubJub Elliptic Curve Utilities\n *\n * Wrapper around circomlibjs BabyJubJub implementation.\n * Used for stealth addresses, key derivation, and ECDH.\n *\n * BabyJubJub is a twisted Edwards curve embedded in BN254's scalar field,\n * making it efficient for use in zk-SNARKs.\n */\n\nimport { BABYJUBJUB_SUBORDER } from './poseidon.js'\n\n/**\n * A point on the BabyJubJub curve\n */\nexport interface Point {\n x: bigint\n y: bigint\n}\n\n/**\n * Internal BabyJubJub field type from circomlibjs\n */\ntype BabyJubJubField = {\n e: (val: bigint) => unknown\n toObject: (val: unknown) => bigint\n}\n\n/**\n * BabyJubJub instance type from circomlibjs\n */\ntype BabyJubJub = {\n F: BabyJubJubField\n Base8: [unknown, unknown]\n subOrder: bigint\n mulPointEscalar: (p: [unknown, unknown], scalar: bigint) => [unknown, unknown]\n addPoint: (p1: [unknown, unknown], p2: [unknown, unknown]) => [unknown, unknown]\n inCurve: (p: [unknown, unknown]) => boolean\n}\n\n// Lazily initialized BabyJubJub instance\nlet babyjubInstance: BabyJubJub | null = null\n\n/**\n * Initialize BabyJubJub curve (lazy loading)\n */\nasync function initBabyJub(): Promise<BabyJubJub> {\n if (babyjubInstance === null) {\n const { buildBabyjub } = await import('circomlibjs')\n babyjubInstance = await buildBabyjub() as BabyJubJub\n }\n return babyjubInstance as BabyJubJub\n}\n\n/**\n * Get the BabyJubJub subgroup order\n */\nexport async function getSubOrder(): Promise<bigint> {\n const babyjub = await initBabyJub()\n return babyjub.subOrder\n}\n\n/**\n * Get the generator point (Base8)\n */\nexport async function getBasePoint(): Promise<Point> {\n const babyjub = await initBabyJub()\n return {\n x: babyjub.F.toObject(babyjub.Base8[0]),\n y: babyjub.F.toObject(babyjub.Base8[1]),\n }\n}\n\n/**\n * Check if a point is on the curve\n */\nexport async function isOnCurve(point: Point): Promise<boolean> {\n const babyjub = await initBabyJub()\n const internal = [babyjub.F.e(point.x), babyjub.F.e(point.y)] as [unknown, unknown]\n return babyjub.inCurve(internal)\n}\n\n/**\n * Scalar multiplication: point * scalar\n *\n * @param point - Point on the curve\n * @param scalar - Scalar value (mod subOrder)\n * @returns Resulting point\n */\nexport async function mulPointScalar(point: Point, scalar: bigint): Promise<Point> {\n const babyjub = await initBabyJub()\n\n // Convert to internal format\n const internal = [babyjub.F.e(point.x), babyjub.F.e(point.y)] as [unknown, unknown]\n\n // Perform scalar multiplication\n const result = babyjub.mulPointEscalar(internal, scalar)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Point addition: p1 + p2\n */\nexport async function addPoints(p1: Point, p2: Point): Promise<Point> {\n const babyjub = await initBabyJub()\n\n // Convert to internal format\n const internal1 = [babyjub.F.e(p1.x), babyjub.F.e(p1.y)] as [unknown, unknown]\n const internal2 = [babyjub.F.e(p2.x), babyjub.F.e(p2.y)] as [unknown, unknown]\n\n // Add points\n const result = babyjub.addPoint(internal1, internal2)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Generate public key from private key\n * pubKey = privateKey * Base8\n *\n * @param privateKey - Private key scalar (must be < subOrder)\n * @returns Public key point\n */\nexport async function privateToPublic(privateKey: bigint): Promise<Point> {\n const babyjub = await initBabyJub()\n\n // Ensure private key is in valid range\n const scalar = privateKey % babyjub.subOrder\n\n // pubKey = scalar * Base8\n const result = babyjub.mulPointEscalar(babyjub.Base8, scalar)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Compute ECDH shared secret\n * sharedSecret = myPrivateKey * theirPublicKey\n *\n * @param myPrivateKey - Your private key\n * @param theirPublicKey - Their public key\n * @returns Shared secret point\n */\nexport async function computeSharedSecret(\n myPrivateKey: bigint,\n theirPublicKey: Point\n): Promise<Point> {\n return mulPointScalar(theirPublicKey, myPrivateKey)\n}\n\n/**\n * Pack a point into a single bigint (compressed form)\n * Uses the x-coordinate and a sign bit for y\n */\nexport function packPoint(point: Point): bigint {\n // Use x-coordinate with y sign bit in high position\n const ySign = point.y % 2n\n return point.x | (ySign << 254n)\n}\n\n/**\n * Convert a point to tuple format [x, y] for use with snarkjs\n */\nexport function pointToTuple(point: Point): [bigint, bigint] {\n return [point.x, point.y]\n}\n\n/**\n * Convert a tuple [x, y] to Point format\n */\nexport function tupleToPoint(tuple: [bigint, bigint]): Point {\n return { x: tuple[0], y: tuple[1] }\n}\n\n// BabyJubJub curve parameters\n// Curve: a*x² + y² = 1 + d*x²*y²\nconst BABYJUBJUB_A = 168700n\nconst BABYJUBJUB_D = 168696n\n// Field prime (BN254 scalar field)\nconst BABYJUBJUB_P = 21888242871839275222246405745257275088548364400416034343698204186575808495617n\n\n/**\n * Modular exponentiation: base^exp mod p\n */\nfunction modPow(base: bigint, exp: bigint, p: bigint): bigint {\n let result = 1n\n base = ((base % p) + p) % p\n while (exp > 0n) {\n if (exp % 2n === 1n) {\n result = (result * base) % p\n }\n exp = exp / 2n\n base = (base * base) % p\n }\n return result\n}\n\n/**\n * Modular inverse using Fermat's little theorem: a^(-1) = a^(p-2) mod p\n */\nfunction modInverse(a: bigint, p: bigint): bigint {\n return modPow(a, p - 2n, p)\n}\n\n/**\n * Tonelli-Shanks algorithm for modular square root\n * Returns sqrt(n) mod p, or null if no square root exists\n */\nfunction modSqrt(n: bigint, p: bigint): bigint | null {\n n = ((n % p) + p) % p\n if (n === 0n) return 0n\n\n // Check if n is a quadratic residue (Euler's criterion)\n if (modPow(n, (p - 1n) / 2n, p) !== 1n) {\n return null // No square root exists\n }\n\n // For p ≡ 3 (mod 4), sqrt(n) = n^((p+1)/4) mod p\n // BN254 scalar field: p ≡ 1 (mod 4), so we need Tonelli-Shanks\n\n // Factor out powers of 2 from p - 1\n let q = p - 1n\n let s = 0n\n while (q % 2n === 0n) {\n q = q / 2n\n s++\n }\n\n // Find a quadratic non-residue\n let z = 2n\n while (modPow(z, (p - 1n) / 2n, p) !== p - 1n) {\n z++\n }\n\n let m = s\n let c = modPow(z, q, p)\n let t = modPow(n, q, p)\n let r = modPow(n, (q + 1n) / 2n, p)\n\n while (true) {\n if (t === 1n) return r\n\n // Find the least i such that t^(2^i) = 1\n let i = 1n\n let temp = (t * t) % p\n while (temp !== 1n) {\n temp = (temp * temp) % p\n i++\n }\n\n // Update values\n const b = modPow(c, modPow(2n, m - i - 1n, p - 1n), p)\n m = i\n c = (b * b) % p\n t = (t * c) % p\n r = (r * b) % p\n }\n}\n\n/**\n * Reconstruct a BabyJubJub point from its x-coordinate\n *\n * BabyJubJub curve equation: a*x² + y² = 1 + d*x²*y²\n * Solving for y²: y² = (1 - a*x²) / (1 - d*x²)\n *\n * Returns the point with the smaller y value (canonical form),\n * or null if x is not on the curve.\n *\n * @param x - The x-coordinate\n * @returns Point with the given x, or null if invalid\n */\nexport async function reconstructPointFromX(x: bigint): Promise<Point | null> {\n const p = BABYJUBJUB_P\n x = ((x % p) + p) % p\n\n // Compute x²\n const x2 = (x * x) % p\n\n // Compute numerator: 1 - a*x²\n const numerator = ((1n - BABYJUBJUB_A * x2) % p + p) % p\n\n // Compute denominator: 1 - d*x²\n const denominator = ((1n - BABYJUBJUB_D * x2) % p + p) % p\n\n if (denominator === 0n) {\n return null // Division by zero\n }\n\n // Compute y² = numerator / denominator\n const y2 = (numerator * modInverse(denominator, p)) % p\n\n // Compute y = sqrt(y²)\n const y = modSqrt(y2, p)\n if (y === null) {\n return null // x is not on the curve\n }\n\n // Return the point with smaller y (canonical form)\n const yAlt = p - y\n const yCanonical = y < yAlt ? y : yAlt\n\n const point = { x, y: yCanonical }\n\n // Verify the point is actually on the curve\n if (!(await isOnCurve(point))) {\n // Try the other y\n const pointAlt = { x, y: y < yAlt ? yAlt : y }\n if (!(await isOnCurve(pointAlt))) {\n return null\n }\n return pointAlt\n }\n\n return point\n}\n\n/**\n * Reconstruct a BabyJubJub point from x-coordinate and y parity bit\n *\n * @param x - The x-coordinate\n * @param yParity - 0 for even y, 1 for odd y\n * @returns Point with matching parity, or null if invalid\n */\nexport async function reconstructPointFromXWithParity(\n x: bigint,\n yParity: 0 | 1\n): Promise<Point | null> {\n const p = BABYJUBJUB_P\n x = ((x % p) + p) % p\n\n const x2 = (x * x) % p\n const numerator = ((1n - BABYJUBJUB_A * x2) % p + p) % p\n const denominator = ((1n - BABYJUBJUB_D * x2) % p + p) % p\n\n if (denominator === 0n) return null\n\n const y2 = (numerator * modInverse(denominator, p)) % p\n const y = modSqrt(y2, p)\n if (y === null) return null\n\n // Select y based on parity\n const actualParity = Number(y % 2n)\n const finalY = actualParity === yParity ? y : p - y\n\n return { x, y: finalY }\n}\n\n/**\n * Derive a per-transaction viewing public key (EVK)\n *\n * EVK = MVK_pub + Poseidon(MVK_pub.x, MVK_pub.y, nonce) * Base8\n *\n * This allows the sender to derive a unique encryption key for each transaction\n * without knowing the recipient's private key.\n *\n * @param masterViewingPubKey - Recipient's master viewing public key\n * @param nonce - Unique per-note nonce (R.x — ephemeral public key x-coordinate)\n * @returns Per-transaction encryption viewing key\n */\nexport async function deriveEncryptionViewingKey(\n masterViewingPubKey: Point,\n nonce: bigint\n): Promise<Point> {\n // Import poseidonScalar to avoid circular dependency\n const { poseidonScalar } = await import('./poseidon.js')\n\n const babyjub = await initBabyJub()\n\n // Compute scalar: Poseidon(MVK_pub.x, MVK_pub.y, nonce) mod subOrder\n const scalar = await poseidonScalar([masterViewingPubKey.x, masterViewingPubKey.y, nonce])\n\n // Compute offset: scalar * Base8\n const offset = babyjub.mulPointEscalar(babyjub.Base8, scalar)\n\n // Convert MVK_pub to internal format\n const mvkInternal = [\n babyjub.F.e(masterViewingPubKey.x),\n babyjub.F.e(masterViewingPubKey.y),\n ] as [unknown, unknown]\n\n // EVK = MVK_pub + offset\n const result = babyjub.addPoint(mvkInternal, offset)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Derive a per-transaction viewing private key (DVK)\n *\n * DVK = MVK_priv + Poseidon(MVK_pub.x, MVK_pub.y, nonce)\n *\n * Only the owner with MVK_priv can compute this.\n * DVK can be shared with auditors to decrypt specific transactions.\n *\n * @param masterViewingPrivKey - Owner's master viewing private key\n * @param masterViewingPubKey - Owner's master viewing public key\n * @param nonce - Unique per-note nonce (R.x — ephemeral public key x-coordinate)\n * @returns Per-transaction decryption viewing key\n */\nexport async function deriveDecryptionViewingKey(\n masterViewingPrivKey: bigint,\n masterViewingPubKey: Point,\n nonce: bigint\n): Promise<bigint> {\n // Import poseidonScalar to avoid circular dependency\n const { poseidonScalar } = await import('./poseidon.js')\n\n // Compute scalar: Poseidon(MVK_pub.x, MVK_pub.y, nonce) mod subOrder\n const scalar = await poseidonScalar([masterViewingPubKey.x, masterViewingPubKey.y, nonce])\n\n // DVK = MVK_priv + scalar (mod subOrder)\n return (masterViewingPrivKey + scalar) % BABYJUBJUB_SUBORDER\n}\n\n"]}
1
+ {"version":3,"sources":["../src/utils/index.ts","../src/utils/babyjubjub.ts"],"names":["init_poseidon","poseidonScalar","BABYJUBJUB_SUBORDER","init_crypto"],"mappings":"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","file":"chunk-XNSMPNY6.cjs","sourcesContent":["/**\n * Utility functions for UPP SDK\n */\n\n// Poseidon hash\nexport {\n poseidon,\n poseidonHash,\n poseidonScalar,\n FIELD_PRIME,\n BABYJUBJUB_SUBORDER,\n addressToField,\n fieldToAddress,\n isValidFieldElement,\n toFieldElement,\n} from './poseidon.js'\n\n// BabyJubJub curve operations\nexport {\n type Point,\n getSubOrder,\n getBasePoint,\n isOnCurve,\n mulPointScalar,\n addPoints,\n privateToPublic,\n computeSharedSecret,\n packPoint,\n pointToTuple,\n tupleToPoint,\n deriveEncryptionViewingKey,\n deriveDecryptionViewingKey,\n} from './babyjubjub.js'\n\n// Merkle tree\nexport {\n MerkleTree,\n buildMerkleTree,\n getMerkleProof,\n verifyMerkleProof,\n type MerkleProof,\n MAX_TREE_DEPTH,\n} from './merkle.js'\n\n// Crypto utilities\nexport {\n randomBytes,\n randomFieldElement,\n bytesToHex,\n hexToBytes,\n bigintToBytes,\n bytesToBigint,\n} from './crypto.js'\n\n// STARK utilities (amount scaling, witness building, Fiat-Shamir)\nexport {\n STARK_AMOUNT_SCALE,\n STARK_STATE_TREE_DEPTH,\n STARK_ASP_TREE_DEPTH,\n isStarkAligned,\n scaleAmountForStark,\n truncateToM31,\n addressToM31,\n splitSecretToM31Limbs,\n packM31Digest,\n computeWithdrawPublicInputsSeed,\n computeTransferPublicInputsSeed,\n buildStarkWithdrawWitness,\n buildStarkTransferWitness,\n type StarkWithdrawWitness,\n type StarkTransferWitness,\n} from './stark.js'\n\n// Keccak-M31 hashing (STARK)\nexport {\n keccakM31,\n keccakHashTwo,\n computeStarkOwnerHash,\n computeStarkCommitment,\n computeStarkNullifier,\n splitToM31Limbs,\n M31_P,\n DIGEST_SIZE,\n SECRET_LIMBS,\n type M31Digest,\n type M31Secret,\n} from './keccak-m31.js'\n","/**\n * BabyJubJub Elliptic Curve Utilities\n *\n * Wrapper around circomlibjs BabyJubJub implementation.\n * Used for stealth addresses, key derivation, and ECDH.\n *\n * BabyJubJub is a twisted Edwards curve embedded in BN254's scalar field,\n * making it efficient for use in zk-SNARKs.\n */\n\nimport { BABYJUBJUB_SUBORDER } from './poseidon.js'\n\n/**\n * A point on the BabyJubJub curve\n */\nexport interface Point {\n x: bigint\n y: bigint\n}\n\n/**\n * Internal BabyJubJub field type from circomlibjs\n */\ntype BabyJubJubField = {\n e: (val: bigint) => unknown\n toObject: (val: unknown) => bigint\n}\n\n/**\n * BabyJubJub instance type from circomlibjs\n */\ntype BabyJubJub = {\n F: BabyJubJubField\n Base8: [unknown, unknown]\n subOrder: bigint\n mulPointEscalar: (p: [unknown, unknown], scalar: bigint) => [unknown, unknown]\n addPoint: (p1: [unknown, unknown], p2: [unknown, unknown]) => [unknown, unknown]\n inCurve: (p: [unknown, unknown]) => boolean\n}\n\n// Lazily initialized BabyJubJub instance\nlet babyjubInstance: BabyJubJub | null = null\n\n/**\n * Initialize BabyJubJub curve (lazy loading)\n */\nasync function initBabyJub(): Promise<BabyJubJub> {\n if (babyjubInstance === null) {\n const { buildBabyjub } = await import('circomlibjs')\n babyjubInstance = await buildBabyjub() as BabyJubJub\n }\n return babyjubInstance as BabyJubJub\n}\n\n/**\n * Get the BabyJubJub subgroup order\n */\nexport async function getSubOrder(): Promise<bigint> {\n const babyjub = await initBabyJub()\n return babyjub.subOrder\n}\n\n/**\n * Get the generator point (Base8)\n */\nexport async function getBasePoint(): Promise<Point> {\n const babyjub = await initBabyJub()\n return {\n x: babyjub.F.toObject(babyjub.Base8[0]),\n y: babyjub.F.toObject(babyjub.Base8[1]),\n }\n}\n\n/**\n * Check if a point is on the curve\n */\nexport async function isOnCurve(point: Point): Promise<boolean> {\n const babyjub = await initBabyJub()\n const internal = [babyjub.F.e(point.x), babyjub.F.e(point.y)] as [unknown, unknown]\n return babyjub.inCurve(internal)\n}\n\n/**\n * Scalar multiplication: point * scalar\n *\n * @param point - Point on the curve\n * @param scalar - Scalar value (mod subOrder)\n * @returns Resulting point\n */\nexport async function mulPointScalar(point: Point, scalar: bigint): Promise<Point> {\n const babyjub = await initBabyJub()\n\n // Convert to internal format\n const internal = [babyjub.F.e(point.x), babyjub.F.e(point.y)] as [unknown, unknown]\n\n // Perform scalar multiplication\n const result = babyjub.mulPointEscalar(internal, scalar)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Point addition: p1 + p2\n */\nexport async function addPoints(p1: Point, p2: Point): Promise<Point> {\n const babyjub = await initBabyJub()\n\n // Convert to internal format\n const internal1 = [babyjub.F.e(p1.x), babyjub.F.e(p1.y)] as [unknown, unknown]\n const internal2 = [babyjub.F.e(p2.x), babyjub.F.e(p2.y)] as [unknown, unknown]\n\n // Add points\n const result = babyjub.addPoint(internal1, internal2)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Generate public key from private key\n * pubKey = privateKey * Base8\n *\n * @param privateKey - Private key scalar (must be < subOrder)\n * @returns Public key point\n */\nexport async function privateToPublic(privateKey: bigint): Promise<Point> {\n const babyjub = await initBabyJub()\n\n // Ensure private key is in valid range\n const scalar = privateKey % babyjub.subOrder\n\n // pubKey = scalar * Base8\n const result = babyjub.mulPointEscalar(babyjub.Base8, scalar)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Compute ECDH shared secret\n * sharedSecret = myPrivateKey * theirPublicKey\n *\n * @param myPrivateKey - Your private key\n * @param theirPublicKey - Their public key\n * @returns Shared secret point\n */\nexport async function computeSharedSecret(\n myPrivateKey: bigint,\n theirPublicKey: Point\n): Promise<Point> {\n return mulPointScalar(theirPublicKey, myPrivateKey)\n}\n\n/**\n * Pack a point into a single bigint (compressed form)\n * Uses the x-coordinate and a sign bit for y\n */\nexport function packPoint(point: Point): bigint {\n // Use x-coordinate with y sign bit in high position\n const ySign = point.y % 2n\n return point.x | (ySign << 254n)\n}\n\n/**\n * Convert a point to tuple format [x, y] for use with snarkjs\n */\nexport function pointToTuple(point: Point): [bigint, bigint] {\n return [point.x, point.y]\n}\n\n/**\n * Convert a tuple [x, y] to Point format\n */\nexport function tupleToPoint(tuple: [bigint, bigint]): Point {\n return { x: tuple[0], y: tuple[1] }\n}\n\n// BabyJubJub curve parameters\n// Curve: a*x² + y² = 1 + d*x²*y²\nconst BABYJUBJUB_A = 168700n\nconst BABYJUBJUB_D = 168696n\n// Field prime (BN254 scalar field)\nconst BABYJUBJUB_P = 21888242871839275222246405745257275088548364400416034343698204186575808495617n\n\n/**\n * Modular exponentiation: base^exp mod p\n */\nfunction modPow(base: bigint, exp: bigint, p: bigint): bigint {\n let result = 1n\n base = ((base % p) + p) % p\n while (exp > 0n) {\n if (exp % 2n === 1n) {\n result = (result * base) % p\n }\n exp = exp / 2n\n base = (base * base) % p\n }\n return result\n}\n\n/**\n * Modular inverse using Fermat's little theorem: a^(-1) = a^(p-2) mod p\n */\nfunction modInverse(a: bigint, p: bigint): bigint {\n return modPow(a, p - 2n, p)\n}\n\n/**\n * Tonelli-Shanks algorithm for modular square root\n * Returns sqrt(n) mod p, or null if no square root exists\n */\nfunction modSqrt(n: bigint, p: bigint): bigint | null {\n n = ((n % p) + p) % p\n if (n === 0n) return 0n\n\n // Check if n is a quadratic residue (Euler's criterion)\n if (modPow(n, (p - 1n) / 2n, p) !== 1n) {\n return null // No square root exists\n }\n\n // For p ≡ 3 (mod 4), sqrt(n) = n^((p+1)/4) mod p\n // BN254 scalar field: p ≡ 1 (mod 4), so we need Tonelli-Shanks\n\n // Factor out powers of 2 from p - 1\n let q = p - 1n\n let s = 0n\n while (q % 2n === 0n) {\n q = q / 2n\n s++\n }\n\n // Find a quadratic non-residue\n let z = 2n\n while (modPow(z, (p - 1n) / 2n, p) !== p - 1n) {\n z++\n }\n\n let m = s\n let c = modPow(z, q, p)\n let t = modPow(n, q, p)\n let r = modPow(n, (q + 1n) / 2n, p)\n\n while (true) {\n if (t === 1n) return r\n\n // Find the least i such that t^(2^i) = 1\n let i = 1n\n let temp = (t * t) % p\n while (temp !== 1n) {\n temp = (temp * temp) % p\n i++\n }\n\n // Update values\n const b = modPow(c, modPow(2n, m - i - 1n, p - 1n), p)\n m = i\n c = (b * b) % p\n t = (t * c) % p\n r = (r * b) % p\n }\n}\n\n/**\n * Reconstruct a BabyJubJub point from its x-coordinate\n *\n * BabyJubJub curve equation: a*x² + y² = 1 + d*x²*y²\n * Solving for y²: y² = (1 - a*x²) / (1 - d*x²)\n *\n * Returns the point with the smaller y value (canonical form),\n * or null if x is not on the curve.\n *\n * @param x - The x-coordinate\n * @returns Point with the given x, or null if invalid\n */\nexport async function reconstructPointFromX(x: bigint): Promise<Point | null> {\n const p = BABYJUBJUB_P\n x = ((x % p) + p) % p\n\n // Compute x²\n const x2 = (x * x) % p\n\n // Compute numerator: 1 - a*x²\n const numerator = ((1n - BABYJUBJUB_A * x2) % p + p) % p\n\n // Compute denominator: 1 - d*x²\n const denominator = ((1n - BABYJUBJUB_D * x2) % p + p) % p\n\n if (denominator === 0n) {\n return null // Division by zero\n }\n\n // Compute y² = numerator / denominator\n const y2 = (numerator * modInverse(denominator, p)) % p\n\n // Compute y = sqrt(y²)\n const y = modSqrt(y2, p)\n if (y === null) {\n return null // x is not on the curve\n }\n\n // Return the point with smaller y (canonical form)\n const yAlt = p - y\n const yCanonical = y < yAlt ? y : yAlt\n\n const point = { x, y: yCanonical }\n\n // Verify the point is actually on the curve\n if (!(await isOnCurve(point))) {\n // Try the other y\n const pointAlt = { x, y: y < yAlt ? yAlt : y }\n if (!(await isOnCurve(pointAlt))) {\n return null\n }\n return pointAlt\n }\n\n return point\n}\n\n/**\n * Reconstruct a BabyJubJub point from x-coordinate and y parity bit\n *\n * @param x - The x-coordinate\n * @param yParity - 0 for even y, 1 for odd y\n * @returns Point with matching parity, or null if invalid\n */\nexport async function reconstructPointFromXWithParity(\n x: bigint,\n yParity: 0 | 1\n): Promise<Point | null> {\n const p = BABYJUBJUB_P\n x = ((x % p) + p) % p\n\n const x2 = (x * x) % p\n const numerator = ((1n - BABYJUBJUB_A * x2) % p + p) % p\n const denominator = ((1n - BABYJUBJUB_D * x2) % p + p) % p\n\n if (denominator === 0n) return null\n\n const y2 = (numerator * modInverse(denominator, p)) % p\n const y = modSqrt(y2, p)\n if (y === null) return null\n\n // Select y based on parity\n const actualParity = Number(y % 2n)\n const finalY = actualParity === yParity ? y : p - y\n\n return { x, y: finalY }\n}\n\n/**\n * Derive a per-transaction viewing public key (EVK)\n *\n * EVK = MVK_pub + Poseidon(MVK_pub.x, MVK_pub.y, nonce) * Base8\n *\n * This allows the sender to derive a unique encryption key for each transaction\n * without knowing the recipient's private key.\n *\n * @param masterViewingPubKey - Recipient's master viewing public key\n * @param nonce - Unique per-note nonce (R.x — ephemeral public key x-coordinate)\n * @returns Per-transaction encryption viewing key\n */\nexport async function deriveEncryptionViewingKey(\n masterViewingPubKey: Point,\n nonce: bigint\n): Promise<Point> {\n // Import poseidonScalar to avoid circular dependency\n const { poseidonScalar } = await import('./poseidon.js')\n\n const babyjub = await initBabyJub()\n\n // Compute scalar: Poseidon(MVK_pub.x, MVK_pub.y, nonce) mod subOrder\n const scalar = await poseidonScalar([masterViewingPubKey.x, masterViewingPubKey.y, nonce])\n\n // Compute offset: scalar * Base8\n const offset = babyjub.mulPointEscalar(babyjub.Base8, scalar)\n\n // Convert MVK_pub to internal format\n const mvkInternal = [\n babyjub.F.e(masterViewingPubKey.x),\n babyjub.F.e(masterViewingPubKey.y),\n ] as [unknown, unknown]\n\n // EVK = MVK_pub + offset\n const result = babyjub.addPoint(mvkInternal, offset)\n\n return {\n x: babyjub.F.toObject(result[0]),\n y: babyjub.F.toObject(result[1]),\n }\n}\n\n/**\n * Derive a per-transaction viewing private key (DVK)\n *\n * DVK = MVK_priv + Poseidon(MVK_pub.x, MVK_pub.y, nonce)\n *\n * Only the owner with MVK_priv can compute this.\n * DVK can be shared with auditors to decrypt specific transactions.\n *\n * @param masterViewingPrivKey - Owner's master viewing private key\n * @param masterViewingPubKey - Owner's master viewing public key\n * @param nonce - Unique per-note nonce (R.x — ephemeral public key x-coordinate)\n * @returns Per-transaction decryption viewing key\n */\nexport async function deriveDecryptionViewingKey(\n masterViewingPrivKey: bigint,\n masterViewingPubKey: Point,\n nonce: bigint\n): Promise<bigint> {\n // Import poseidonScalar to avoid circular dependency\n const { poseidonScalar } = await import('./poseidon.js')\n\n // Compute scalar: Poseidon(MVK_pub.x, MVK_pub.y, nonce) mod subOrder\n const scalar = await poseidonScalar([masterViewingPubKey.x, masterViewingPubKey.y, nonce])\n\n // DVK = MVK_priv + scalar (mod subOrder)\n return (masterViewingPrivKey + scalar) % BABYJUBJUB_SUBORDER\n}\n\n"]}
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var chunkUFEDJJSH_cjs = require('./chunk-UFEDJJSH.cjs');
3
+ var chunkBCSMUH4L_cjs = require('./chunk-BCSMUH4L.cjs');
4
4
  var viem = require('viem');
5
5
 
6
6
  // src/utils/keccak-m31.ts
7
- chunkUFEDJJSH_cjs.init_crypto();
7
+ chunkBCSMUH4L_cjs.init_crypto();
8
8
  var M31_P = 2147483647n;
9
9
  var DIGEST_SIZE = 4;
10
10
  var SECRET_LIMBS = 8;
@@ -18,7 +18,7 @@ function keccakM31(inputs) {
18
18
  bytes[offset + 2] = val >> 16 & 255;
19
19
  bytes[offset + 3] = val >> 24 & 255;
20
20
  }
21
- const hashHex = viem.keccak256(chunkUFEDJJSH_cjs.bytesToHex(bytes));
21
+ const hashHex = viem.keccak256(chunkBCSMUH4L_cjs.bytesToHex(bytes));
22
22
  return bytesToM31Digest(hashHex);
23
23
  }
24
24
  function keccakHashTwo(left, right) {
@@ -87,5 +87,5 @@ exports.computeStarkOwnerHash = computeStarkOwnerHash;
87
87
  exports.keccakHashTwo = keccakHashTwo;
88
88
  exports.keccakM31 = keccakM31;
89
89
  exports.splitToM31Limbs = splitToM31Limbs;
90
- //# sourceMappingURL=chunk-U3YFYMWF.cjs.map
91
- //# sourceMappingURL=chunk-U3YFYMWF.cjs.map
90
+ //# sourceMappingURL=chunk-XSJ5VVH4.cjs.map
91
+ //# sourceMappingURL=chunk-XSJ5VVH4.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/keccak-m31.ts"],"names":["init_crypto","keccak256","bytesToHex"],"mappings":"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","file":"chunk-U3YFYMWF.cjs","sourcesContent":["/**\n * Keccak-256 hashing over M31 field elements.\n *\n * This module implements the same hashing algorithm as the Rust Stwo prover\n * (stwo-prover/src/hash.rs), producing identical outputs for identical inputs.\n *\n * Algorithm:\n * 1. Each M31 element is encoded as 4 little-endian bytes\n * 2. All encoded bytes are concatenated and fed to Keccak-256\n * 3. The 32-byte output is split into 4 chunks of 8 bytes\n * 4. Each chunk is read as a little-endian uint64 and reduced mod M31_P\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n */\n\nimport { keccak256 } from 'viem'\nimport { bytesToHex } from './crypto.js'\n\n/** The M31 prime: 2^31 - 1 */\nexport const M31_P = 2147483647n\n\n/** Number of M31 elements in a digest */\nexport const DIGEST_SIZE = 4\n\n/** Number of M31 limbs for owner secrets (248 bits of entropy) */\nexport const SECRET_LIMBS = 8\n\n/** M31 digest type: tuple of 4 M31 values */\nexport type M31Digest = readonly [bigint, bigint, bigint, bigint]\n\n/** M31 secret type: tuple of 8 M31 values */\nexport type M31Secret = readonly [bigint, bigint, bigint, bigint, bigint, bigint, bigint, bigint]\n\n/**\n * Hash arbitrary M31 elements using Keccak-256.\n *\n * Matches Rust: `hash_m31(inputs: &[M31]) -> [M31; 4]`\n *\n * Each M31 is encoded as 4 little-endian bytes. The keccak output\n * is split into 4 × 8-byte LE chunks, each reduced mod M31_P.\n */\nexport function keccakM31(inputs: readonly bigint[]): M31Digest {\n // Encode each M31 as 4 little-endian bytes\n const bytes = new Uint8Array(inputs.length * 4)\n for (let i = 0; i < inputs.length; i++) {\n const val = Number(inputs[i]! & 0xFFFFFFFFn)\n const offset = i * 4\n bytes[offset] = val & 0xFF\n bytes[offset + 1] = (val >> 8) & 0xFF\n bytes[offset + 2] = (val >> 16) & 0xFF\n bytes[offset + 3] = (val >> 24) & 0xFF\n }\n\n // Keccak-256\n const hashHex = keccak256(bytesToHex(bytes))\n\n // Parse 32-byte output into 4 × uint64 LE, reduce mod M31_P\n return bytesToM31Digest(hashHex)\n}\n\n/**\n * Hash two M31 elements (Merkle tree node hash).\n *\n * Matches Rust: `hash_two(left: M31, right: M31) -> [M31; 4]`\n */\nexport function keccakHashTwo(left: bigint, right: bigint): M31Digest {\n return keccakM31([left, right])\n}\n\n/**\n * Compute owner hash from an 8-limb secret.\n *\n * Matches Rust: `compute_owner_hash(owner_secret: &[M31; 8]) -> [M31; 4]`\n */\nexport function computeStarkOwnerHash(ownerSecret: M31Secret): M31Digest {\n return keccakM31(ownerSecret)\n}\n\n/**\n * Compute a STARK note commitment.\n *\n * Matches Rust: `compute_commitment(amount, owner_hash, blinding, origin, token)`\n *\n * Input order: [amount, ownerHash[0], ownerHash[1], ownerHash[2], ownerHash[3], blinding, origin, token]\n */\nexport function computeStarkCommitment(\n amount: bigint,\n ownerHash: M31Digest,\n blinding: bigint,\n origin: bigint,\n token: bigint,\n): M31Digest {\n return keccakM31([\n amount,\n ownerHash[0],\n ownerHash[1],\n ownerHash[2],\n ownerHash[3],\n blinding,\n origin,\n token,\n ])\n}\n\n/**\n * Compute a STARK nullifier.\n *\n * Matches Rust: `compute_nullifier(owner_secret, leaf_index, commitment)`\n *\n * Input order: [ownerSecret[0..8], leafIndex, commitment[0..4]]\n */\nexport function computeStarkNullifier(\n ownerSecret: M31Secret,\n leafIndex: bigint,\n commitment: M31Digest,\n): M31Digest {\n return keccakM31([\n ...ownerSecret,\n leafIndex,\n ...commitment,\n ])\n}\n\n/**\n * Split a 32-byte keccak hash into 8 M31 limbs.\n *\n * Used for deriving STARK spending/viewing secrets from a seed.\n * Each limb is 4 bytes of the hash, read as LE uint32, reduced mod M31_P.\n */\nexport function splitToM31Limbs(hashHex: `0x${string}`): M31Secret {\n const bytes = hexToUint8Array(hashHex)\n const limbs: bigint[] = []\n for (let i = 0; i < SECRET_LIMBS; i++) {\n const offset = i * 4\n const val = (bytes[offset]!)\n | ((bytes[offset + 1]!) << 8)\n | ((bytes[offset + 2]!) << 16)\n | ((bytes[offset + 3]!) << 24)\n limbs.push(BigInt(val >>> 0) % M31_P)\n }\n return limbs as unknown as M31Secret\n}\n\n/**\n * Convert a hex hash output to an M31 digest (4 elements).\n *\n * Splits 32 bytes into 4 × 8-byte LE chunks, reduces each mod M31_P.\n */\nfunction bytesToM31Digest(hashHex: `0x${string}`): M31Digest {\n const bytes = hexToUint8Array(hashHex)\n const digest: bigint[] = []\n\n for (let i = 0; i < DIGEST_SIZE; i++) {\n const offset = i * 8\n // Read 8 bytes as little-endian uint64\n let val = 0n\n for (let j = 0; j < 8; j++) {\n val |= BigInt(bytes[offset + j]!) << BigInt(j * 8)\n }\n digest.push(val % M31_P)\n }\n\n return digest as unknown as M31Digest\n}\n\n/**\n * Convert hex string to Uint8Array\n */\nfunction hexToUint8Array(hex: `0x${string}`): Uint8Array {\n const str = hex.slice(2)\n const bytes = new Uint8Array(str.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/keccak-m31.ts"],"names":["init_crypto","keccak256","bytesToHex"],"mappings":"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","file":"chunk-XSJ5VVH4.cjs","sourcesContent":["/**\n * Keccak-256 hashing over M31 field elements.\n *\n * This module implements the same hashing algorithm as the Rust Stwo prover\n * (stwo-prover/src/hash.rs), producing identical outputs for identical inputs.\n *\n * Algorithm:\n * 1. Each M31 element is encoded as 4 little-endian bytes\n * 2. All encoded bytes are concatenated and fed to Keccak-256\n * 3. The 32-byte output is split into 4 chunks of 8 bytes\n * 4. Each chunk is read as a little-endian uint64 and reduced mod M31_P\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n */\n\nimport { keccak256 } from 'viem'\nimport { bytesToHex } from './crypto.js'\n\n/** The M31 prime: 2^31 - 1 */\nexport const M31_P = 2147483647n\n\n/** Number of M31 elements in a digest */\nexport const DIGEST_SIZE = 4\n\n/** Number of M31 limbs for owner secrets (248 bits of entropy) */\nexport const SECRET_LIMBS = 8\n\n/** M31 digest type: tuple of 4 M31 values */\nexport type M31Digest = readonly [bigint, bigint, bigint, bigint]\n\n/** M31 secret type: tuple of 8 M31 values */\nexport type M31Secret = readonly [bigint, bigint, bigint, bigint, bigint, bigint, bigint, bigint]\n\n/**\n * Hash arbitrary M31 elements using Keccak-256.\n *\n * Matches Rust: `hash_m31(inputs: &[M31]) -> [M31; 4]`\n *\n * Each M31 is encoded as 4 little-endian bytes. The keccak output\n * is split into 4 × 8-byte LE chunks, each reduced mod M31_P.\n */\nexport function keccakM31(inputs: readonly bigint[]): M31Digest {\n // Encode each M31 as 4 little-endian bytes\n const bytes = new Uint8Array(inputs.length * 4)\n for (let i = 0; i < inputs.length; i++) {\n const val = Number(inputs[i]! & 0xFFFFFFFFn)\n const offset = i * 4\n bytes[offset] = val & 0xFF\n bytes[offset + 1] = (val >> 8) & 0xFF\n bytes[offset + 2] = (val >> 16) & 0xFF\n bytes[offset + 3] = (val >> 24) & 0xFF\n }\n\n // Keccak-256\n const hashHex = keccak256(bytesToHex(bytes))\n\n // Parse 32-byte output into 4 × uint64 LE, reduce mod M31_P\n return bytesToM31Digest(hashHex)\n}\n\n/**\n * Hash two M31 elements (Merkle tree node hash).\n *\n * Matches Rust: `hash_two(left: M31, right: M31) -> [M31; 4]`\n */\nexport function keccakHashTwo(left: bigint, right: bigint): M31Digest {\n return keccakM31([left, right])\n}\n\n/**\n * Compute owner hash from an 8-limb secret.\n *\n * Matches Rust: `compute_owner_hash(owner_secret: &[M31; 8]) -> [M31; 4]`\n */\nexport function computeStarkOwnerHash(ownerSecret: M31Secret): M31Digest {\n return keccakM31(ownerSecret)\n}\n\n/**\n * Compute a STARK note commitment.\n *\n * Matches Rust: `compute_commitment(amount, owner_hash, blinding, origin, token)`\n *\n * Input order: [amount, ownerHash[0], ownerHash[1], ownerHash[2], ownerHash[3], blinding, origin, token]\n */\nexport function computeStarkCommitment(\n amount: bigint,\n ownerHash: M31Digest,\n blinding: bigint,\n origin: bigint,\n token: bigint,\n): M31Digest {\n return keccakM31([\n amount,\n ownerHash[0],\n ownerHash[1],\n ownerHash[2],\n ownerHash[3],\n blinding,\n origin,\n token,\n ])\n}\n\n/**\n * Compute a STARK nullifier.\n *\n * Matches Rust: `compute_nullifier(owner_secret, leaf_index, commitment)`\n *\n * Input order: [ownerSecret[0..8], leafIndex, commitment[0..4]]\n */\nexport function computeStarkNullifier(\n ownerSecret: M31Secret,\n leafIndex: bigint,\n commitment: M31Digest,\n): M31Digest {\n return keccakM31([\n ...ownerSecret,\n leafIndex,\n ...commitment,\n ])\n}\n\n/**\n * Split a 32-byte keccak hash into 8 M31 limbs.\n *\n * Used for deriving STARK spending/viewing secrets from a seed.\n * Each limb is 4 bytes of the hash, read as LE uint32, reduced mod M31_P.\n */\nexport function splitToM31Limbs(hashHex: `0x${string}`): M31Secret {\n const bytes = hexToUint8Array(hashHex)\n const limbs: bigint[] = []\n for (let i = 0; i < SECRET_LIMBS; i++) {\n const offset = i * 4\n const val = (bytes[offset]!)\n | ((bytes[offset + 1]!) << 8)\n | ((bytes[offset + 2]!) << 16)\n | ((bytes[offset + 3]!) << 24)\n limbs.push(BigInt(val >>> 0) % M31_P)\n }\n return limbs as unknown as M31Secret\n}\n\n/**\n * Convert a hex hash output to an M31 digest (4 elements).\n *\n * Splits 32 bytes into 4 × 8-byte LE chunks, reduces each mod M31_P.\n */\nfunction bytesToM31Digest(hashHex: `0x${string}`): M31Digest {\n const bytes = hexToUint8Array(hashHex)\n const digest: bigint[] = []\n\n for (let i = 0; i < DIGEST_SIZE; i++) {\n const offset = i * 8\n // Read 8 bytes as little-endian uint64\n let val = 0n\n for (let j = 0; j < 8; j++) {\n val |= BigInt(bytes[offset + j]!) << BigInt(j * 8)\n }\n digest.push(val % M31_P)\n }\n\n return digest as unknown as M31Digest\n}\n\n/**\n * Convert hex string to Uint8Array\n */\nfunction hexToUint8Array(hex: `0x${string}`): Uint8Array {\n const str = hex.slice(2)\n const bytes = new Uint8Array(str.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(str.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkU3YFYMWF_cjs = require('./chunk-U3YFYMWF.cjs');
3
+ var chunkXSJ5VVH4_cjs = require('./chunk-XSJ5VVH4.cjs');
4
4
  var viem = require('viem');
5
5
 
6
6
  var STARK_AMOUNT_SCALE = 10n ** 15n;
@@ -9,30 +9,30 @@ var STARK_ASP_TREE_DEPTH = 20;
9
9
  function isStarkAligned(amount) {
10
10
  if (amount <= 0n) return false;
11
11
  const scaled = amount / STARK_AMOUNT_SCALE;
12
- return scaled * STARK_AMOUNT_SCALE === amount && scaled < chunkU3YFYMWF_cjs.M31_P;
12
+ return scaled * STARK_AMOUNT_SCALE === amount && scaled < chunkXSJ5VVH4_cjs.M31_P;
13
13
  }
14
14
  function scaleAmountForStark(weiAmount) {
15
15
  const scaled = weiAmount / STARK_AMOUNT_SCALE;
16
16
  if (scaled * STARK_AMOUNT_SCALE !== weiAmount) {
17
17
  throw new Error(`Amount ${weiAmount} not aligned to STARK scale (${STARK_AMOUNT_SCALE})`);
18
18
  }
19
- if (scaled >= chunkU3YFYMWF_cjs.M31_P) {
20
- throw new Error(`Scaled amount ${scaled} exceeds M31 max (${chunkU3YFYMWF_cjs.M31_P})`);
19
+ if (scaled >= chunkXSJ5VVH4_cjs.M31_P) {
20
+ throw new Error(`Scaled amount ${scaled} exceeds M31 max (${chunkXSJ5VVH4_cjs.M31_P})`);
21
21
  }
22
22
  return Number(scaled);
23
23
  }
24
24
  function truncateToM31(value) {
25
- return Number(value % chunkU3YFYMWF_cjs.M31_P);
25
+ return Number(value % chunkXSJ5VVH4_cjs.M31_P);
26
26
  }
27
27
  function addressToM31(addr) {
28
- return Number(BigInt(addr) % chunkU3YFYMWF_cjs.M31_P);
28
+ return Number(BigInt(addr) % chunkXSJ5VVH4_cjs.M31_P);
29
29
  }
30
30
  function splitSecretToM31Limbs(secret) {
31
31
  const limbs = [];
32
32
  let remaining = secret;
33
- for (let i = 0; i < chunkU3YFYMWF_cjs.SECRET_LIMBS; i++) {
34
- limbs.push(Number(remaining % chunkU3YFYMWF_cjs.M31_P));
35
- remaining = remaining / chunkU3YFYMWF_cjs.M31_P;
33
+ for (let i = 0; i < chunkXSJ5VVH4_cjs.SECRET_LIMBS; i++) {
34
+ limbs.push(Number(remaining % chunkXSJ5VVH4_cjs.M31_P));
35
+ remaining = remaining / chunkXSJ5VVH4_cjs.M31_P;
36
36
  }
37
37
  return limbs;
38
38
  }
@@ -150,5 +150,5 @@ exports.packM31Digest = packM31Digest;
150
150
  exports.scaleAmountForStark = scaleAmountForStark;
151
151
  exports.splitSecretToM31Limbs = splitSecretToM31Limbs;
152
152
  exports.truncateToM31 = truncateToM31;
153
- //# sourceMappingURL=chunk-SWTNJPK5.cjs.map
154
- //# sourceMappingURL=chunk-SWTNJPK5.cjs.map
153
+ //# sourceMappingURL=chunk-Y6WCXYOC.cjs.map
154
+ //# sourceMappingURL=chunk-Y6WCXYOC.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/stark.ts"],"names":["M31_P","SECRET_LIMBS","keccak256","encodePacked","pad","numberToHex"],"mappings":"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","file":"chunk-SWTNJPK5.cjs","sourcesContent":["/**\n * STARK Utilities — Amount scaling, witness building, Fiat-Shamir\n *\n * These functions must produce identical outputs to the Rust Stwo prover\n * (stwo-prover/src/) and the Solidity verifier.\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n * Amount precision: 0.001 tokens (1e15 wei scale factor)\n */\n\nimport type { Address, Hex } from 'viem'\nimport { keccak256, encodePacked, pad, numberToHex } from 'viem'\nimport { M31_P, SECRET_LIMBS } from './keccak-m31.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Matches Solidity STARK_AMOUNT_SCALE = 1e15 */\nexport const STARK_AMOUNT_SCALE = 10n ** 15n\n\n/** State tree depth (Merkle tree for commitments) */\nexport const STARK_STATE_TREE_DEPTH = 32\n\n/** ASP tree depth */\nexport const STARK_ASP_TREE_DEPTH = 20\n\n// ============================================================================\n// Amount Scaling\n// ============================================================================\n\n/** Check if a wei amount is STARK-scale aligned and fits in M31. */\nexport function isStarkAligned(amount: bigint): boolean {\n if (amount <= 0n) return false\n const scaled = amount / STARK_AMOUNT_SCALE\n return scaled * STARK_AMOUNT_SCALE === amount && scaled < M31_P\n}\n\n/**\n * Scale a wei amount down for the STARK circuit.\n * Precision: 0.001 tokens (1e15 wei). Max: ~2.1M tokens.\n *\n * @returns The scaled amount as a number (fits in M31)\n * @throws If not aligned to STARK_AMOUNT_SCALE or exceeds M31\n */\nexport function scaleAmountForStark(weiAmount: bigint): number {\n const scaled = weiAmount / STARK_AMOUNT_SCALE\n if (scaled * STARK_AMOUNT_SCALE !== weiAmount) {\n throw new Error(`Amount ${weiAmount} not aligned to STARK scale (${STARK_AMOUNT_SCALE})`)\n }\n if (scaled >= M31_P) {\n throw new Error(`Scaled amount ${scaled} exceeds M31 max (${M31_P})`)\n }\n return Number(scaled)\n}\n\n/** Truncate a bigint to fit in M31 (modular reduction). */\nexport function truncateToM31(value: bigint): number {\n return Number(value % M31_P)\n}\n\n// ============================================================================\n// Field Conversions\n// ============================================================================\n\n/** Convert an Ethereum address to an M31 field element (truncated). */\nexport function addressToM31(addr: Address): number {\n return Number(BigInt(addr) % M31_P)\n}\n\n/**\n * Split a 254-bit spending secret into 8 M31 limbs (248 bits of entropy).\n *\n * Each limb holds 31 bits (reduced mod M31_P). The secret is split\n * little-endian: limb[0] = lowest 31 bits, limb[7] = highest bits.\n *\n * This matches the Rust prover's expectation of `[M31; 8]` for owner_secret.\n */\nexport function splitSecretToM31Limbs(secret: bigint): number[] {\n const limbs: number[] = []\n let remaining = secret\n for (let i = 0; i < SECRET_LIMBS; i++) {\n limbs.push(Number(remaining % M31_P))\n remaining = remaining / M31_P\n }\n return limbs\n}\n\n/**\n * Pack an M31 digest (4 M31 elements) into a uint128 for Solidity.\n * Each element occupies 32 bits (little-endian packing).\n */\nexport function packM31Digest(digest: [number, number, number, number]): bigint {\n return BigInt(digest[0])\n | (BigInt(digest[1]) << 32n)\n | (BigInt(digest[2]) << 64n)\n | (BigInt(digest[3]) << 96n)\n}\n\n// ============================================================================\n// Fiat-Shamir Public Input Seeds\n// ============================================================================\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK withdrawal.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeWithdrawPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n aspId: bigint\n token: Address\n amount: bigint\n recipient: Address\n isRagequit: boolean\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'uint256', 'address', 'uint256', 'address', 'bool'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.aspId,\n params.token,\n params.amount,\n params.recipient,\n params.isRagequit,\n ],\n ),\n )\n}\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK transfer.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeTransferPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n token: Address\n outputCommitment1: Hex\n outputCommitment2: Hex\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'address', 'bytes32', 'bytes32'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.token,\n params.outputCommitment1,\n params.outputCommitment2,\n ],\n ),\n )\n}\n\n// ============================================================================\n// Witness Types\n// ============================================================================\n\n/**\n * Witness inputs for the STARK withdrawal prover.\n * All numeric values are u32 (must fit in M31 field, i.e. < 2^31 - 1).\n * Hex string fields are for Fiat-Shamir seed binding.\n */\nexport interface StarkWithdrawWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n withdraw_amount: number\n change_amount: number\n change_blinding: number\n recipient: number\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n asp_id_hex: string\n token_address_hex: string\n amount_hex: string\n recipient_address_hex: string\n is_ragequit_bool: boolean\n}\n\n/**\n * Witness inputs for the STARK transfer prover (1-in-2-out).\n * All numeric values are u32 (must fit in M31 field).\n */\nexport interface StarkTransferWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n // Output 1\n output1_amount: number\n output1_owner_hash: [number, number, number, number]\n output1_blinding: number\n output1_origin: number\n // Output 2\n output2_amount: number\n output2_owner_hash: [number, number, number, number]\n output2_blinding: number\n output2_origin: number\n // Ragequit flag\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n token_address_hex: string\n output_commitment_1_hex: string\n output_commitment_2_hex: string\n}\n\n// ============================================================================\n// Witness Builders\n// ============================================================================\n\nfunction toBytes32Hex(value: bigint | Hex): string {\n if (typeof value === 'bigint') {\n return pad(numberToHex(value), { size: 32 })\n }\n return value as string\n}\n\nfunction toAddress20Hex(addr: Address): string {\n return addr.toLowerCase()\n}\n\n/**\n * Build a complete STARK withdrawal witness from note data.\n */\nexport function buildStarkWithdrawWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n withdrawAmount: number\n changeAmount: number\n changeBlinding: number\n recipient: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n aspIdBigInt: bigint\n tokenAddress: Address\n amountWei: bigint\n recipientAddress: Address\n isRagequitBool: boolean\n}): StarkWithdrawWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n withdraw_amount: params.withdrawAmount,\n change_amount: params.changeAmount,\n change_blinding: params.changeBlinding,\n recipient: params.recipient,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n asp_id_hex: toBytes32Hex(params.aspIdBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n amount_hex: toBytes32Hex(params.amountWei),\n recipient_address_hex: toAddress20Hex(params.recipientAddress),\n is_ragequit_bool: params.isRagequitBool,\n }\n}\n\n/**\n * Build a complete STARK transfer witness (1-in-2-out).\n */\nexport function buildStarkTransferWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n output1Amount: number\n output1OwnerHash: [number, number, number, number]\n output1Blinding: number\n output1Origin: number\n output2Amount: number\n output2OwnerHash: [number, number, number, number]\n output2Blinding: number\n output2Origin: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n tokenAddress: Address\n outputCommitment1Hex: Hex\n outputCommitment2Hex: Hex\n}): StarkTransferWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n output1_amount: params.output1Amount,\n output1_owner_hash: params.output1OwnerHash,\n output1_blinding: params.output1Blinding,\n output1_origin: params.output1Origin,\n output2_amount: params.output2Amount,\n output2_owner_hash: params.output2OwnerHash,\n output2_blinding: params.output2Blinding,\n output2_origin: params.output2Origin,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n output_commitment_1_hex: params.outputCommitment1Hex,\n output_commitment_2_hex: params.outputCommitment2Hex,\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/stark.ts"],"names":["M31_P","SECRET_LIMBS","keccak256","encodePacked","pad","numberToHex"],"mappings":"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","file":"chunk-Y6WCXYOC.cjs","sourcesContent":["/**\n * STARK Utilities — Amount scaling, witness building, Fiat-Shamir\n *\n * These functions must produce identical outputs to the Rust Stwo prover\n * (stwo-prover/src/) and the Solidity verifier.\n *\n * M31 field: p = 2^31 - 1 = 2,147,483,647\n * Amount precision: 0.001 tokens (1e15 wei scale factor)\n */\n\nimport type { Address, Hex } from 'viem'\nimport { keccak256, encodePacked, pad, numberToHex } from 'viem'\nimport { M31_P, SECRET_LIMBS } from './keccak-m31.js'\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Matches Solidity STARK_AMOUNT_SCALE = 1e15 */\nexport const STARK_AMOUNT_SCALE = 10n ** 15n\n\n/** State tree depth (Merkle tree for commitments) */\nexport const STARK_STATE_TREE_DEPTH = 32\n\n/** ASP tree depth */\nexport const STARK_ASP_TREE_DEPTH = 20\n\n// ============================================================================\n// Amount Scaling\n// ============================================================================\n\n/** Check if a wei amount is STARK-scale aligned and fits in M31. */\nexport function isStarkAligned(amount: bigint): boolean {\n if (amount <= 0n) return false\n const scaled = amount / STARK_AMOUNT_SCALE\n return scaled * STARK_AMOUNT_SCALE === amount && scaled < M31_P\n}\n\n/**\n * Scale a wei amount down for the STARK circuit.\n * Precision: 0.001 tokens (1e15 wei). Max: ~2.1M tokens.\n *\n * @returns The scaled amount as a number (fits in M31)\n * @throws If not aligned to STARK_AMOUNT_SCALE or exceeds M31\n */\nexport function scaleAmountForStark(weiAmount: bigint): number {\n const scaled = weiAmount / STARK_AMOUNT_SCALE\n if (scaled * STARK_AMOUNT_SCALE !== weiAmount) {\n throw new Error(`Amount ${weiAmount} not aligned to STARK scale (${STARK_AMOUNT_SCALE})`)\n }\n if (scaled >= M31_P) {\n throw new Error(`Scaled amount ${scaled} exceeds M31 max (${M31_P})`)\n }\n return Number(scaled)\n}\n\n/** Truncate a bigint to fit in M31 (modular reduction). */\nexport function truncateToM31(value: bigint): number {\n return Number(value % M31_P)\n}\n\n// ============================================================================\n// Field Conversions\n// ============================================================================\n\n/** Convert an Ethereum address to an M31 field element (truncated). */\nexport function addressToM31(addr: Address): number {\n return Number(BigInt(addr) % M31_P)\n}\n\n/**\n * Split a 254-bit spending secret into 8 M31 limbs (248 bits of entropy).\n *\n * Each limb holds 31 bits (reduced mod M31_P). The secret is split\n * little-endian: limb[0] = lowest 31 bits, limb[7] = highest bits.\n *\n * This matches the Rust prover's expectation of `[M31; 8]` for owner_secret.\n */\nexport function splitSecretToM31Limbs(secret: bigint): number[] {\n const limbs: number[] = []\n let remaining = secret\n for (let i = 0; i < SECRET_LIMBS; i++) {\n limbs.push(Number(remaining % M31_P))\n remaining = remaining / M31_P\n }\n return limbs\n}\n\n/**\n * Pack an M31 digest (4 M31 elements) into a uint128 for Solidity.\n * Each element occupies 32 bits (little-endian packing).\n */\nexport function packM31Digest(digest: [number, number, number, number]): bigint {\n return BigInt(digest[0])\n | (BigInt(digest[1]) << 32n)\n | (BigInt(digest[2]) << 64n)\n | (BigInt(digest[3]) << 96n)\n}\n\n// ============================================================================\n// Fiat-Shamir Public Input Seeds\n// ============================================================================\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK withdrawal.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeWithdrawPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n aspId: bigint\n token: Address\n amount: bigint\n recipient: Address\n isRagequit: boolean\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'uint256', 'address', 'uint256', 'address', 'bool'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.aspId,\n params.token,\n params.amount,\n params.recipient,\n params.isRagequit,\n ],\n ),\n )\n}\n\n/**\n * Compute the Fiat-Shamir public inputs seed for a STARK transfer.\n * Must produce the same hash as Solidity and Rust.\n */\nexport function computeTransferPublicInputsSeed(params: {\n nullifier: Hex\n stateRoot: bigint\n aspRoot: bigint\n token: Address\n outputCommitment1: Hex\n outputCommitment2: Hex\n}): Hex {\n return keccak256(\n encodePacked(\n ['bytes32', 'uint256', 'uint256', 'address', 'bytes32', 'bytes32'],\n [\n params.nullifier,\n params.stateRoot,\n params.aspRoot,\n params.token,\n params.outputCommitment1,\n params.outputCommitment2,\n ],\n ),\n )\n}\n\n// ============================================================================\n// Witness Types\n// ============================================================================\n\n/**\n * Witness inputs for the STARK withdrawal prover.\n * All numeric values are u32 (must fit in M31 field, i.e. < 2^31 - 1).\n * Hex string fields are for Fiat-Shamir seed binding.\n */\nexport interface StarkWithdrawWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n withdraw_amount: number\n change_amount: number\n change_blinding: number\n recipient: number\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n asp_id_hex: string\n token_address_hex: string\n amount_hex: string\n recipient_address_hex: string\n is_ragequit_bool: boolean\n}\n\n/**\n * Witness inputs for the STARK transfer prover (1-in-2-out).\n * All numeric values are u32 (must fit in M31 field).\n */\nexport interface StarkTransferWitness {\n owner_secret: number[]\n input_amount: number\n input_blinding: number\n input_origin: number\n token: number\n leaf_index: number\n state_path_elements: number[]\n state_path_indices: number[]\n asp_path_elements: number[]\n asp_path_indices: number[]\n // Output 1\n output1_amount: number\n output1_owner_hash: [number, number, number, number]\n output1_blinding: number\n output1_origin: number\n // Output 2\n output2_amount: number\n output2_owner_hash: [number, number, number, number]\n output2_blinding: number\n output2_origin: number\n // Ragequit flag\n is_ragequit: number\n // Ethereum-native hex values for Fiat-Shamir seed binding\n nullifier_hex: string\n state_root_hex: string\n asp_root_hex: string\n token_address_hex: string\n output_commitment_1_hex: string\n output_commitment_2_hex: string\n}\n\n// ============================================================================\n// Witness Builders\n// ============================================================================\n\nfunction toBytes32Hex(value: bigint | Hex): string {\n if (typeof value === 'bigint') {\n return pad(numberToHex(value), { size: 32 })\n }\n return value as string\n}\n\nfunction toAddress20Hex(addr: Address): string {\n return addr.toLowerCase()\n}\n\n/**\n * Build a complete STARK withdrawal witness from note data.\n */\nexport function buildStarkWithdrawWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n withdrawAmount: number\n changeAmount: number\n changeBlinding: number\n recipient: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n aspIdBigInt: bigint\n tokenAddress: Address\n amountWei: bigint\n recipientAddress: Address\n isRagequitBool: boolean\n}): StarkWithdrawWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n withdraw_amount: params.withdrawAmount,\n change_amount: params.changeAmount,\n change_blinding: params.changeBlinding,\n recipient: params.recipient,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n asp_id_hex: toBytes32Hex(params.aspIdBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n amount_hex: toBytes32Hex(params.amountWei),\n recipient_address_hex: toAddress20Hex(params.recipientAddress),\n is_ragequit_bool: params.isRagequitBool,\n }\n}\n\n/**\n * Build a complete STARK transfer witness (1-in-2-out).\n */\nexport function buildStarkTransferWitness(params: {\n ownerSecret: number[]\n inputAmount: number\n inputBlinding: number\n inputOrigin: number\n token: number\n leafIndex: number\n output1Amount: number\n output1OwnerHash: [number, number, number, number]\n output1Blinding: number\n output1Origin: number\n output2Amount: number\n output2OwnerHash: [number, number, number, number]\n output2Blinding: number\n output2Origin: number\n isRagequit: number\n // Full Ethereum values for seed binding\n nullifierHex: Hex\n stateRootBigInt: bigint\n aspRootBigInt: bigint\n tokenAddress: Address\n outputCommitment1Hex: Hex\n outputCommitment2Hex: Hex\n}): StarkTransferWitness {\n return {\n owner_secret: params.ownerSecret,\n input_amount: params.inputAmount,\n input_blinding: params.inputBlinding,\n input_origin: params.inputOrigin,\n token: params.token,\n leaf_index: params.leafIndex,\n state_path_elements: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n state_path_indices: new Array(STARK_STATE_TREE_DEPTH).fill(0),\n asp_path_elements: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n asp_path_indices: new Array(STARK_ASP_TREE_DEPTH).fill(0),\n output1_amount: params.output1Amount,\n output1_owner_hash: params.output1OwnerHash,\n output1_blinding: params.output1Blinding,\n output1_origin: params.output1Origin,\n output2_amount: params.output2Amount,\n output2_owner_hash: params.output2OwnerHash,\n output2_blinding: params.output2Blinding,\n output2_origin: params.output2Origin,\n is_ragequit: params.isRagequit,\n nullifier_hex: params.nullifierHex,\n state_root_hex: toBytes32Hex(params.stateRootBigInt),\n asp_root_hex: toBytes32Hex(params.aspRootBigInt),\n token_address_hex: toAddress20Hex(params.tokenAddress),\n output_commitment_1_hex: params.outputCommitment1Hex,\n output_commitment_2_hex: params.outputCommitment2Hex,\n }\n}\n"]}