@sip-protocol/sdk 0.7.3 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +267 -0
  3. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  4. package/dist/browser.d.mts +10 -4
  5. package/dist/browser.d.ts +10 -4
  6. package/dist/browser.js +47556 -19603
  7. package/dist/browser.mjs +628 -48
  8. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  9. package/dist/chunk-5D7A3L3W.mjs +717 -0
  10. package/dist/chunk-64AYA5F5.mjs +7834 -0
  11. package/dist/chunk-GMDGB22A.mjs +379 -0
  12. package/dist/chunk-I534WKN7.mjs +328 -0
  13. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  14. package/dist/chunk-PRRZAWJE.mjs +223 -0
  15. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  16. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  17. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  18. package/dist/constants-LHAAUC2T.mjs +51 -0
  19. package/dist/dist-2OGQ7FED.mjs +3957 -0
  20. package/dist/dist-IFHPYLDX.mjs +254 -0
  21. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  22. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  23. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  24. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48396 -19623
  28. package/dist/index.mjs +537 -19
  29. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  30. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  31. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  32. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  33. package/dist/proofs/halo2.d.mts +151 -0
  34. package/dist/proofs/halo2.d.ts +151 -0
  35. package/dist/proofs/halo2.js +350 -0
  36. package/dist/proofs/halo2.mjs +11 -0
  37. package/dist/proofs/kimchi.d.mts +160 -0
  38. package/dist/proofs/kimchi.d.ts +160 -0
  39. package/dist/proofs/kimchi.js +431 -0
  40. package/dist/proofs/kimchi.mjs +13 -0
  41. package/dist/proofs/noir.d.mts +1 -1
  42. package/dist/proofs/noir.d.ts +1 -1
  43. package/dist/proofs/noir.js +74 -18
  44. package/dist/proofs/noir.mjs +84 -24
  45. package/dist/solana-U3MEGU7W.mjs +280 -0
  46. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  47. package/package.json +54 -21
  48. package/src/adapters/index.ts +41 -0
  49. package/src/adapters/jupiter.ts +571 -0
  50. package/src/adapters/near-intents.ts +135 -0
  51. package/src/advisor/advisor.ts +653 -0
  52. package/src/advisor/index.ts +54 -0
  53. package/src/advisor/tools.ts +303 -0
  54. package/src/advisor/types.ts +164 -0
  55. package/src/chains/ethereum/announcement.ts +536 -0
  56. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  57. package/src/chains/ethereum/commitment.ts +522 -0
  58. package/src/chains/ethereum/constants.ts +462 -0
  59. package/src/chains/ethereum/deployment.ts +596 -0
  60. package/src/chains/ethereum/gas-estimation.ts +538 -0
  61. package/src/chains/ethereum/index.ts +268 -0
  62. package/src/chains/ethereum/optimizations.ts +614 -0
  63. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  64. package/src/chains/ethereum/registry.ts +584 -0
  65. package/src/chains/ethereum/rpc.ts +905 -0
  66. package/src/chains/ethereum/stealth.ts +491 -0
  67. package/src/chains/ethereum/token.ts +790 -0
  68. package/src/chains/ethereum/transfer.ts +637 -0
  69. package/src/chains/ethereum/types.ts +456 -0
  70. package/src/chains/ethereum/viewing-key.ts +455 -0
  71. package/src/chains/near/commitment.ts +608 -0
  72. package/src/chains/near/constants.ts +284 -0
  73. package/src/chains/near/function-call.ts +871 -0
  74. package/src/chains/near/history.ts +654 -0
  75. package/src/chains/near/implicit-account.ts +840 -0
  76. package/src/chains/near/index.ts +393 -0
  77. package/src/chains/near/native-transfer.ts +658 -0
  78. package/src/chains/near/nep141.ts +775 -0
  79. package/src/chains/near/privacy-adapter.ts +889 -0
  80. package/src/chains/near/resolver.ts +971 -0
  81. package/src/chains/near/rpc.ts +1016 -0
  82. package/src/chains/near/stealth.ts +419 -0
  83. package/src/chains/near/types.ts +317 -0
  84. package/src/chains/near/viewing-key.ts +876 -0
  85. package/src/chains/solana/anchor-transfer.ts +386 -0
  86. package/src/chains/solana/commitment.ts +577 -0
  87. package/src/chains/solana/constants.ts +126 -12
  88. package/src/chains/solana/ephemeral-keys.ts +543 -0
  89. package/src/chains/solana/index.ts +252 -1
  90. package/src/chains/solana/key-derivation.ts +418 -0
  91. package/src/chains/solana/kit-compat.ts +334 -0
  92. package/src/chains/solana/optimizations.ts +560 -0
  93. package/src/chains/solana/privacy-adapter.ts +605 -0
  94. package/src/chains/solana/providers/generic.ts +47 -6
  95. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  96. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  97. package/src/chains/solana/providers/helius.ts +186 -33
  98. package/src/chains/solana/providers/index.ts +31 -0
  99. package/src/chains/solana/providers/interface.ts +61 -18
  100. package/src/chains/solana/providers/quicknode.ts +409 -0
  101. package/src/chains/solana/providers/triton.ts +426 -0
  102. package/src/chains/solana/providers/webhook.ts +338 -67
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +83 -66
  105. package/src/chains/solana/sol-transfer.ts +732 -0
  106. package/src/chains/solana/spl-transfer.ts +886 -0
  107. package/src/chains/solana/stealth-scanner.ts +703 -0
  108. package/src/chains/solana/sunspot-verifier.ts +453 -0
  109. package/src/chains/solana/transaction-builder.ts +755 -0
  110. package/src/chains/solana/transfer.ts +74 -5
  111. package/src/chains/solana/types.ts +57 -6
  112. package/src/chains/solana/utils.ts +110 -0
  113. package/src/chains/solana/viewing-key.ts +807 -0
  114. package/src/compliance/fireblocks.ts +921 -0
  115. package/src/compliance/index.ts +23 -0
  116. package/src/compliance/range-sas.ts +398 -33
  117. package/src/config/endpoints.ts +100 -0
  118. package/src/crypto.ts +11 -8
  119. package/src/errors.ts +82 -0
  120. package/src/evm/erc4337-relayer.ts +830 -0
  121. package/src/evm/index.ts +47 -0
  122. package/src/fees/calculator.ts +396 -0
  123. package/src/fees/index.ts +87 -0
  124. package/src/fees/near-contract.ts +429 -0
  125. package/src/fees/types.ts +268 -0
  126. package/src/index.ts +686 -1
  127. package/src/intent.ts +6 -3
  128. package/src/logger.ts +324 -0
  129. package/src/network/index.ts +80 -0
  130. package/src/network/proxy.ts +691 -0
  131. package/src/optimizations/index.ts +541 -0
  132. package/src/oracle/types.ts +1 -0
  133. package/src/privacy-backends/arcium-types.ts +727 -0
  134. package/src/privacy-backends/arcium.ts +719 -0
  135. package/src/privacy-backends/combined-privacy.ts +866 -0
  136. package/src/privacy-backends/cspl-token.ts +595 -0
  137. package/src/privacy-backends/cspl-types.ts +512 -0
  138. package/src/privacy-backends/cspl.ts +907 -0
  139. package/src/privacy-backends/health.ts +488 -0
  140. package/src/privacy-backends/inco-types.ts +323 -0
  141. package/src/privacy-backends/inco.ts +616 -0
  142. package/src/privacy-backends/index.ts +254 -4
  143. package/src/privacy-backends/interface.ts +649 -6
  144. package/src/privacy-backends/lru-cache.ts +343 -0
  145. package/src/privacy-backends/magicblock.ts +458 -0
  146. package/src/privacy-backends/mock.ts +258 -0
  147. package/src/privacy-backends/privacycash.ts +13 -17
  148. package/src/privacy-backends/private-swap.ts +570 -0
  149. package/src/privacy-backends/rate-limiter.ts +683 -0
  150. package/src/privacy-backends/registry.ts +414 -2
  151. package/src/privacy-backends/router.ts +283 -3
  152. package/src/privacy-backends/shadowwire.ts +449 -0
  153. package/src/privacy-backends/sip-native.ts +3 -0
  154. package/src/privacy-logger.ts +191 -0
  155. package/src/production-safety.ts +373 -0
  156. package/src/proofs/aggregator.ts +1029 -0
  157. package/src/proofs/browser-composer.ts +1150 -0
  158. package/src/proofs/browser.ts +113 -25
  159. package/src/proofs/cache/index.ts +127 -0
  160. package/src/proofs/cache/interface.ts +545 -0
  161. package/src/proofs/cache/key-generator.ts +188 -0
  162. package/src/proofs/cache/lru-cache.ts +481 -0
  163. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  164. package/src/proofs/cache/persistent-cache.ts +788 -0
  165. package/src/proofs/compliance-proof.ts +872 -0
  166. package/src/proofs/composer/base.ts +923 -0
  167. package/src/proofs/composer/index.ts +25 -0
  168. package/src/proofs/composer/interface.ts +518 -0
  169. package/src/proofs/composer/types.ts +383 -0
  170. package/src/proofs/converters/halo2.ts +452 -0
  171. package/src/proofs/converters/index.ts +208 -0
  172. package/src/proofs/converters/interface.ts +363 -0
  173. package/src/proofs/converters/kimchi.ts +462 -0
  174. package/src/proofs/converters/noir.ts +451 -0
  175. package/src/proofs/fallback.ts +888 -0
  176. package/src/proofs/halo2.ts +42 -0
  177. package/src/proofs/index.ts +471 -0
  178. package/src/proofs/interface.ts +13 -0
  179. package/src/proofs/kimchi.ts +42 -0
  180. package/src/proofs/lazy.ts +1004 -0
  181. package/src/proofs/mock.ts +25 -1
  182. package/src/proofs/noir.ts +110 -29
  183. package/src/proofs/orchestrator.ts +960 -0
  184. package/src/proofs/parallel/concurrency.ts +297 -0
  185. package/src/proofs/parallel/dependency-graph.ts +602 -0
  186. package/src/proofs/parallel/executor.ts +420 -0
  187. package/src/proofs/parallel/index.ts +131 -0
  188. package/src/proofs/parallel/interface.ts +685 -0
  189. package/src/proofs/parallel/worker-pool.ts +644 -0
  190. package/src/proofs/providers/halo2.ts +560 -0
  191. package/src/proofs/providers/index.ts +34 -0
  192. package/src/proofs/providers/kimchi.ts +641 -0
  193. package/src/proofs/validator.ts +881 -0
  194. package/src/proofs/verifier.ts +867 -0
  195. package/src/quantum/index.ts +112 -0
  196. package/src/quantum/winternitz-vault.ts +639 -0
  197. package/src/quantum/wots.ts +611 -0
  198. package/src/settlement/backends/direct-chain.ts +1 -0
  199. package/src/settlement/index.ts +9 -0
  200. package/src/settlement/router.ts +732 -46
  201. package/src/solana/index.ts +72 -0
  202. package/src/solana/jito-relayer.ts +687 -0
  203. package/src/solana/noir-verifier-types.ts +430 -0
  204. package/src/solana/noir-verifier.ts +816 -0
  205. package/src/stealth/address-derivation.ts +193 -0
  206. package/src/stealth/ed25519.ts +431 -0
  207. package/src/stealth/index.ts +233 -0
  208. package/src/stealth/meta-address.ts +221 -0
  209. package/src/stealth/secp256k1.ts +368 -0
  210. package/src/stealth/utils.ts +194 -0
  211. package/src/stealth.ts +50 -1504
  212. package/src/sync/index.ts +106 -0
  213. package/src/sync/manager.ts +504 -0
  214. package/src/sync/mock-provider.ts +318 -0
  215. package/src/sync/oblivious.ts +625 -0
  216. package/src/tokens/index.ts +15 -0
  217. package/src/tokens/registry.ts +301 -0
  218. package/src/utils/deprecation.ts +94 -0
  219. package/src/utils/index.ts +9 -0
  220. package/src/wallet/ethereum/index.ts +68 -0
  221. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  222. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  223. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  224. package/src/wallet/ethereum/types.ts +3 -1
  225. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  226. package/src/wallet/hardware/index.ts +10 -0
  227. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  228. package/src/wallet/index.ts +71 -0
  229. package/src/wallet/near/adapter.ts +626 -0
  230. package/src/wallet/near/index.ts +86 -0
  231. package/src/wallet/near/meteor-wallet.ts +1153 -0
  232. package/src/wallet/near/my-near-wallet.ts +790 -0
  233. package/src/wallet/near/wallet-selector.ts +702 -0
  234. package/src/wallet/solana/adapter.ts +6 -4
  235. package/src/wallet/solana/index.ts +13 -0
  236. package/src/wallet/solana/privacy-adapter.ts +567 -0
  237. package/src/wallet/sui/types.ts +6 -4
  238. package/src/zcash/rpc-client.ts +13 -6
  239. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  240. package/dist/chunk-3INS3PR5.mjs +0 -884
  241. package/dist/chunk-3OVABDRH.mjs +0 -17096
  242. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  243. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  244. package/dist/chunk-E6SZWREQ.mjs +0 -57
  245. package/dist/chunk-F6F73W35.mjs +0 -16166
  246. package/dist/chunk-G33LB27A.mjs +0 -16166
  247. package/dist/chunk-HGU6HZRC.mjs +0 -231
  248. package/dist/chunk-L2K34JCU.mjs +0 -1496
  249. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  250. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  251. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  252. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  253. package/dist/constants-VOI7BSLK.mjs +0 -27
  254. package/dist/index-B71aXVzk.d.ts +0 -13264
  255. package/dist/index-BYZbDjal.d.ts +0 -11390
  256. package/dist/index-CHB3KuOB.d.mts +0 -11859
  257. package/dist/index-CzWPI6Le.d.ts +0 -11859
  258. package/dist/index-pOIIuwfV.d.mts +0 -13264
  259. package/dist/index-xbWjohNq.d.mts +0 -11390
  260. package/dist/solana-4O4K45VU.mjs +0 -46
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-NDABAZ6P.mjs +0 -56
  263. package/dist/solana-Q4NAVBTS.mjs +0 -46
  264. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -0,0 +1,1004 @@
1
+ /**
2
+ * Lazy Proof Generation
3
+ *
4
+ * @module proofs/lazy
5
+ * @description Deferred proof generation with cancellation and priority queue
6
+ *
7
+ * M20-14: Add lazy proof generation support (#319)
8
+ *
9
+ * ## Overview
10
+ *
11
+ * Lazy proofs defer computation until absolutely necessary, improving:
12
+ * - Perceived performance (don't block on proof generation)
13
+ * - Resource usage (only generate proofs that are actually needed)
14
+ * - User experience (can cancel unnecessary proof generation)
15
+ *
16
+ * ## Usage
17
+ *
18
+ * ```typescript
19
+ * import { LazyProof, ProofGenerationQueue } from '@sip-protocol/sdk'
20
+ *
21
+ * // Create a lazy proof
22
+ * const lazy = new LazyProof(async (signal) => {
23
+ * return await provider.generateProof(inputs, signal)
24
+ * })
25
+ *
26
+ * // Proof is NOT generated yet
27
+ * console.log(lazy.status) // 'pending'
28
+ *
29
+ * // Trigger generation when needed
30
+ * const proof = await lazy.resolve()
31
+ *
32
+ * // Or cancel if no longer needed
33
+ * lazy.cancel()
34
+ * ```
35
+ */
36
+
37
+ import type { SingleProof, ProofSystem } from '@sip-protocol/types'
38
+
39
+ // ─── Types ────────────────────────────────────────────────────────────────────
40
+
41
+ /**
42
+ * Status of a lazy proof
43
+ */
44
+ export type LazyProofStatus =
45
+ | 'pending' // Not yet started
46
+ | 'generating' // Currently being generated
47
+ | 'resolved' // Successfully generated
48
+ | 'cancelled' // Generation was cancelled
49
+ | 'failed' // Generation failed
50
+
51
+ /**
52
+ * Trigger for automatic proof generation
53
+ */
54
+ export type ProofTrigger =
55
+ | 'manual' // Only on explicit resolve()
56
+ | 'on-verify' // When verification is requested
57
+ | 'on-serialize' // When serialization is requested
58
+ | 'immediate' // Start immediately (eager)
59
+
60
+ /**
61
+ * Priority level for proof generation
62
+ */
63
+ export type ProofPriority = 'low' | 'normal' | 'high' | 'critical'
64
+
65
+ /**
66
+ * Configuration for lazy proof
67
+ */
68
+ export interface LazyProofConfig {
69
+ /** When to trigger proof generation */
70
+ readonly trigger: ProofTrigger
71
+ /** Priority in the generation queue */
72
+ readonly priority: ProofPriority
73
+ /** Timeout in milliseconds (0 = no timeout) */
74
+ readonly timeoutMs: number
75
+ /** Retry attempts on failure */
76
+ readonly maxRetries: number
77
+ /** Delay between retries in milliseconds */
78
+ readonly retryDelayMs: number
79
+ /** Enable speculative prefetching */
80
+ readonly prefetch: boolean
81
+ }
82
+
83
+ /**
84
+ * Default lazy proof configuration
85
+ */
86
+ export const DEFAULT_LAZY_CONFIG: LazyProofConfig = {
87
+ trigger: 'manual',
88
+ priority: 'normal',
89
+ timeoutMs: 60000, // 1 minute
90
+ maxRetries: 2,
91
+ retryDelayMs: 1000,
92
+ prefetch: false,
93
+ }
94
+
95
+ /**
96
+ * Proof generator function type
97
+ */
98
+ export type ProofGenerator<T = SingleProof> = (
99
+ signal: AbortSignal
100
+ ) => Promise<T>
101
+
102
+ /**
103
+ * Event types for lazy proof
104
+ */
105
+ export type LazyProofEventType =
106
+ | 'start'
107
+ | 'progress'
108
+ | 'complete'
109
+ | 'cancel'
110
+ | 'error'
111
+ | 'retry'
112
+
113
+ /**
114
+ * Lazy proof event
115
+ */
116
+ export interface LazyProofEvent {
117
+ readonly type: LazyProofEventType
118
+ readonly timestamp: number
119
+ readonly data?: {
120
+ readonly progress?: number
121
+ readonly error?: Error
122
+ readonly attempt?: number
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Event listener for lazy proof
128
+ */
129
+ export type LazyProofEventListener = (event: LazyProofEvent) => void
130
+
131
+ /**
132
+ * Serialized lazy proof (for persistence)
133
+ */
134
+ export interface SerializedLazyProof<T = SingleProof> {
135
+ readonly status: LazyProofStatus
136
+ readonly proof?: T
137
+ readonly error?: string
138
+ readonly config: LazyProofConfig
139
+ readonly metadata?: {
140
+ readonly system?: ProofSystem
141
+ readonly circuitId?: string
142
+ readonly createdAt: number
143
+ readonly resolvedAt?: number
144
+ }
145
+ }
146
+
147
+ // ─── LazyProof Class ──────────────────────────────────────────────────────────
148
+
149
+ /**
150
+ * A lazy proof that defers generation until needed
151
+ */
152
+ export class LazyProof<T = SingleProof> {
153
+ private _status: LazyProofStatus = 'pending'
154
+ private _proof: T | null = null
155
+ private _error: Error | null = null
156
+ private _promise: Promise<T> | null = null
157
+ private _abortController: AbortController | null = null
158
+ private _retryCount = 0
159
+ private _createdAt = Date.now()
160
+ private _resolvedAt: number | null = null
161
+ private readonly _listeners = new Set<LazyProofEventListener>()
162
+
163
+ readonly config: LazyProofConfig
164
+
165
+ constructor(
166
+ private readonly generator: ProofGenerator<T>,
167
+ config: Partial<LazyProofConfig> = {},
168
+ private readonly metadata?: {
169
+ system?: ProofSystem
170
+ circuitId?: string
171
+ }
172
+ ) {
173
+ this.config = { ...DEFAULT_LAZY_CONFIG, ...config }
174
+ // Start immediately if configured
175
+ if (this.config.trigger === 'immediate') {
176
+ this.resolve().catch(() => {})
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Get the current status
182
+ */
183
+ get status(): LazyProofStatus {
184
+ return this._status
185
+ }
186
+
187
+ /**
188
+ * Check if the proof is resolved
189
+ */
190
+ get isResolved(): boolean {
191
+ return this._status === 'resolved'
192
+ }
193
+
194
+ /**
195
+ * Check if generation is in progress
196
+ */
197
+ get isGenerating(): boolean {
198
+ return this._status === 'generating'
199
+ }
200
+
201
+ /**
202
+ * Check if cancelled
203
+ */
204
+ get isCancelled(): boolean {
205
+ return this._status === 'cancelled'
206
+ }
207
+
208
+ /**
209
+ * Check if failed
210
+ */
211
+ get isFailed(): boolean {
212
+ return this._status === 'failed'
213
+ }
214
+
215
+ /**
216
+ * Get the proof (throws if not resolved)
217
+ */
218
+ get proof(): T {
219
+ if (!this._proof) {
220
+ throw new LazyProofError(
221
+ 'Proof not yet resolved. Call resolve() first.',
222
+ 'NOT_RESOLVED'
223
+ )
224
+ }
225
+ return this._proof
226
+ }
227
+
228
+ /**
229
+ * Get the proof if available (doesn't throw)
230
+ */
231
+ get proofOrNull(): T | null {
232
+ return this._proof
233
+ }
234
+
235
+ /**
236
+ * Get the error if failed
237
+ */
238
+ get error(): Error | null {
239
+ return this._error
240
+ }
241
+
242
+ /**
243
+ * Resolve (generate) the proof
244
+ */
245
+ async resolve(): Promise<T> {
246
+ // Already resolved
247
+ if (this._status === 'resolved' && this._proof) {
248
+ return this._proof
249
+ }
250
+
251
+ // Already generating - return existing promise
252
+ if (this._status === 'generating' && this._promise) {
253
+ return this._promise
254
+ }
255
+
256
+ // Cannot resolve cancelled proof
257
+ if (this._status === 'cancelled') {
258
+ throw new LazyProofError('Proof generation was cancelled', 'CANCELLED')
259
+ }
260
+
261
+ // Start generation
262
+ this._promise = this._generate()
263
+ return this._promise
264
+ }
265
+
266
+ /**
267
+ * Cancel proof generation
268
+ */
269
+ cancel(): boolean {
270
+ if (this._status === 'resolved' || this._status === 'cancelled') {
271
+ return false
272
+ }
273
+
274
+ this._status = 'cancelled'
275
+ this._abortController?.abort()
276
+ this._emit({ type: 'cancel', timestamp: Date.now() })
277
+ return true
278
+ }
279
+
280
+ /**
281
+ * Reset to pending state (allows re-generation)
282
+ */
283
+ reset(): void {
284
+ if (this._status === 'generating') {
285
+ this.cancel()
286
+ }
287
+
288
+ this._status = 'pending'
289
+ this._proof = null
290
+ this._error = null
291
+ this._promise = null
292
+ this._retryCount = 0
293
+ }
294
+
295
+ /**
296
+ * Add an event listener
297
+ */
298
+ addEventListener(listener: LazyProofEventListener): void {
299
+ this._listeners.add(listener)
300
+ }
301
+
302
+ /**
303
+ * Remove an event listener
304
+ */
305
+ removeEventListener(listener: LazyProofEventListener): void {
306
+ this._listeners.delete(listener)
307
+ }
308
+
309
+ /**
310
+ * Serialize the lazy proof
311
+ */
312
+ serialize(): SerializedLazyProof<T> {
313
+ // Trigger generation if configured
314
+ if (this.config.trigger === 'on-serialize' && this._status === 'pending') {
315
+ this.resolve().catch(() => {})
316
+ }
317
+
318
+ return {
319
+ status: this._status,
320
+ proof: this._proof ?? undefined,
321
+ error: this._error?.message,
322
+ config: this.config,
323
+ metadata: {
324
+ system: this.metadata?.system,
325
+ circuitId: this.metadata?.circuitId,
326
+ createdAt: this._createdAt,
327
+ resolvedAt: this._resolvedAt ?? undefined,
328
+ },
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Create from serialized state
334
+ */
335
+ static deserialize<T = SingleProof>(
336
+ data: SerializedLazyProof<T>,
337
+ generator: ProofGenerator<T>
338
+ ): LazyProof<T> {
339
+ const lazy = new LazyProof<T>(generator, data.config, {
340
+ system: data.metadata?.system,
341
+ circuitId: data.metadata?.circuitId,
342
+ })
343
+
344
+ if (data.status === 'resolved' && data.proof) {
345
+ lazy._status = 'resolved'
346
+ lazy._proof = data.proof
347
+ lazy._resolvedAt = data.metadata?.resolvedAt ?? null
348
+ } else if (data.status === 'failed' && data.error) {
349
+ lazy._status = 'failed'
350
+ lazy._error = new Error(data.error)
351
+ } else if (data.status === 'cancelled') {
352
+ lazy._status = 'cancelled'
353
+ }
354
+
355
+ return lazy
356
+ }
357
+
358
+ // ─── Private Methods ────────────────────────────────────────────────────────
359
+
360
+ private async _generate(): Promise<T> {
361
+ this._status = 'generating'
362
+ this._abortController = new AbortController()
363
+ this._emit({ type: 'start', timestamp: Date.now() })
364
+
365
+ const { timeoutMs, maxRetries, retryDelayMs } = this.config
366
+
367
+ while (this._retryCount <= maxRetries) {
368
+ try {
369
+ // Create timeout if configured
370
+ const timeoutId = timeoutMs > 0
371
+ ? setTimeout(() => this._abortController?.abort(), timeoutMs)
372
+ : null
373
+
374
+ try {
375
+ const proof = await this.generator(this._abortController.signal)
376
+
377
+ // Success!
378
+ this._proof = proof
379
+ this._status = 'resolved'
380
+ this._resolvedAt = Date.now()
381
+ this._emit({ type: 'complete', timestamp: Date.now() })
382
+ return proof
383
+ } finally {
384
+ if (timeoutId) clearTimeout(timeoutId)
385
+ }
386
+ } catch (err) {
387
+ // Check if cancelled (cast needed - cancel() can be called concurrently)
388
+ if (this._abortController.signal.aborted) {
389
+ if ((this._status as LazyProofStatus) === 'cancelled') {
390
+ throw new LazyProofError('Proof generation was cancelled', 'CANCELLED')
391
+ }
392
+ throw new LazyProofError('Proof generation timed out', 'TIMEOUT')
393
+ }
394
+
395
+ // Retry logic
396
+ this._retryCount++
397
+ const error = err instanceof Error ? err : new Error(String(err))
398
+
399
+ if (this._retryCount <= maxRetries) {
400
+ this._emit({
401
+ type: 'retry',
402
+ timestamp: Date.now(),
403
+ data: { attempt: this._retryCount, error },
404
+ })
405
+ await this._delay(retryDelayMs)
406
+ // Create new abort controller for retry
407
+ this._abortController = new AbortController()
408
+ } else {
409
+ // Max retries exceeded
410
+ this._status = 'failed'
411
+ this._error = error
412
+ this._emit({ type: 'error', timestamp: Date.now(), data: { error } })
413
+ throw error
414
+ }
415
+ }
416
+ }
417
+
418
+ // Should never reach here
419
+ throw new LazyProofError('Unexpected error in proof generation', 'INTERNAL')
420
+ }
421
+
422
+ private _emit(event: LazyProofEvent): void {
423
+ for (const listener of this._listeners) {
424
+ try {
425
+ listener(event)
426
+ } catch {
427
+ // Ignore listener errors
428
+ }
429
+ }
430
+ }
431
+
432
+ private _delay(ms: number): Promise<void> {
433
+ return new Promise((resolve) => setTimeout(resolve, ms))
434
+ }
435
+ }
436
+
437
+ // ─── Proof Generation Queue ───────────────────────────────────────────────────
438
+
439
+ /**
440
+ * Queue item for proof generation
441
+ */
442
+ interface QueueItem<T = SingleProof> {
443
+ readonly id: string
444
+ readonly lazy: LazyProof<T>
445
+ readonly priority: ProofPriority
446
+ readonly addedAt: number
447
+ }
448
+
449
+ /**
450
+ * Priority values for sorting
451
+ */
452
+ const PRIORITY_VALUES: Record<ProofPriority, number> = {
453
+ critical: 4,
454
+ high: 3,
455
+ normal: 2,
456
+ low: 1,
457
+ }
458
+
459
+ /**
460
+ * Configuration for proof generation queue
461
+ */
462
+ export interface ProofQueueConfig {
463
+ /** Maximum concurrent proof generations */
464
+ readonly maxConcurrent: number
465
+ /** Maximum queue size (0 = unlimited) */
466
+ readonly maxQueueSize: number
467
+ /** Enable automatic processing */
468
+ readonly autoProcess: boolean
469
+ }
470
+
471
+ /**
472
+ * Default queue configuration
473
+ */
474
+ export const DEFAULT_QUEUE_CONFIG: ProofQueueConfig = {
475
+ maxConcurrent: 2,
476
+ maxQueueSize: 100,
477
+ autoProcess: true,
478
+ }
479
+
480
+ /**
481
+ * Queue statistics
482
+ */
483
+ export interface QueueStats {
484
+ readonly queued: number
485
+ readonly processing: number
486
+ readonly completed: number
487
+ readonly failed: number
488
+ readonly cancelled: number
489
+ }
490
+
491
+ /**
492
+ * Priority queue for proof generation
493
+ */
494
+ export class ProofGenerationQueue<T = SingleProof> {
495
+ private readonly queue: QueueItem<T>[] = []
496
+ private readonly processing = new Map<string, LazyProof<T>>()
497
+ private readonly config: ProofQueueConfig
498
+ private _completed = 0
499
+ private _failed = 0
500
+ private _cancelled = 0
501
+ private _idCounter = 0
502
+ private _isProcessing = false
503
+
504
+ constructor(config: Partial<ProofQueueConfig> = {}) {
505
+ this.config = { ...DEFAULT_QUEUE_CONFIG, ...config }
506
+ }
507
+
508
+ /**
509
+ * Add a lazy proof to the queue
510
+ */
511
+ enqueue(lazy: LazyProof<T>, priority?: ProofPriority): string {
512
+ if (
513
+ this.config.maxQueueSize > 0 &&
514
+ this.queue.length >= this.config.maxQueueSize
515
+ ) {
516
+ throw new LazyProofError('Queue is full', 'QUEUE_FULL')
517
+ }
518
+
519
+ const id = `proof-${++this._idCounter}`
520
+ const item: QueueItem<T> = {
521
+ id,
522
+ lazy,
523
+ priority: priority ?? lazy.config.priority,
524
+ addedAt: Date.now(),
525
+ }
526
+
527
+ // Insert in priority order
528
+ const insertIndex = this.queue.findIndex(
529
+ (q) => PRIORITY_VALUES[q.priority] < PRIORITY_VALUES[item.priority]
530
+ )
531
+
532
+ if (insertIndex === -1) {
533
+ this.queue.push(item)
534
+ } else {
535
+ this.queue.splice(insertIndex, 0, item)
536
+ }
537
+
538
+ // Auto-process if enabled
539
+ if (this.config.autoProcess) {
540
+ this._processNext()
541
+ }
542
+
543
+ return id
544
+ }
545
+
546
+ /**
547
+ * Remove a proof from the queue
548
+ */
549
+ dequeue(id: string): boolean {
550
+ const index = this.queue.findIndex((q) => q.id === id)
551
+ if (index !== -1) {
552
+ const [item] = this.queue.splice(index, 1)
553
+ item.lazy.cancel()
554
+ this._cancelled++
555
+ return true
556
+ }
557
+
558
+ // Check if currently processing
559
+ const processing = this.processing.get(id)
560
+ if (processing) {
561
+ processing.cancel()
562
+ this.processing.delete(id)
563
+ this._cancelled++
564
+ return true
565
+ }
566
+
567
+ return false
568
+ }
569
+
570
+ /**
571
+ * Process the queue manually
572
+ */
573
+ async process(): Promise<void> {
574
+ if (this._isProcessing) return
575
+
576
+ this._isProcessing = true
577
+
578
+ try {
579
+ while (this.queue.length > 0 || this.processing.size > 0) {
580
+ await this._processNext()
581
+ // Small delay to prevent tight loop
582
+ await new Promise((r) => setTimeout(r, 10))
583
+ }
584
+ } finally {
585
+ this._isProcessing = false
586
+ }
587
+ }
588
+
589
+ /**
590
+ * Cancel all pending and processing proofs
591
+ */
592
+ cancelAll(): number {
593
+ let cancelled = 0
594
+
595
+ // Cancel queued
596
+ for (const item of this.queue) {
597
+ item.lazy.cancel()
598
+ cancelled++
599
+ }
600
+ this.queue.length = 0
601
+
602
+ // Cancel processing
603
+ for (const [id, lazy] of this.processing) {
604
+ lazy.cancel()
605
+ this.processing.delete(id)
606
+ cancelled++
607
+ }
608
+
609
+ this._cancelled += cancelled
610
+ return cancelled
611
+ }
612
+
613
+ /**
614
+ * Get queue statistics
615
+ */
616
+ getStats(): QueueStats {
617
+ return {
618
+ queued: this.queue.length,
619
+ processing: this.processing.size,
620
+ completed: this._completed,
621
+ failed: this._failed,
622
+ cancelled: this._cancelled,
623
+ }
624
+ }
625
+
626
+ /**
627
+ * Get the current queue size
628
+ */
629
+ get size(): number {
630
+ return this.queue.length + this.processing.size
631
+ }
632
+
633
+ /**
634
+ * Check if queue is empty
635
+ */
636
+ get isEmpty(): boolean {
637
+ return this.queue.length === 0 && this.processing.size === 0
638
+ }
639
+
640
+ // ─── Private Methods ────────────────────────────────────────────────────────
641
+
642
+ private async _processNext(): Promise<void> {
643
+ // Check if we can process more
644
+ if (this.processing.size >= this.config.maxConcurrent) {
645
+ return
646
+ }
647
+
648
+ // Get next item
649
+ const item = this.queue.shift()
650
+ if (!item) return
651
+
652
+ // Start processing
653
+ this.processing.set(item.id, item.lazy)
654
+
655
+ try {
656
+ await item.lazy.resolve()
657
+ this._completed++
658
+ } catch {
659
+ if (item.lazy.isCancelled) {
660
+ this._cancelled++
661
+ } else {
662
+ this._failed++
663
+ }
664
+ } finally {
665
+ this.processing.delete(item.id)
666
+ }
667
+
668
+ // Process next if auto-process enabled
669
+ if (this.config.autoProcess && this.queue.length > 0) {
670
+ this._processNext()
671
+ }
672
+ }
673
+ }
674
+
675
+ // ─── Lazy Verification Key Loading ────────────────────────────────────────────
676
+
677
+ /**
678
+ * A lazy-loaded verification key
679
+ */
680
+ export class LazyVerificationKey {
681
+ private _vk: string | null = null
682
+ private _promise: Promise<string> | null = null
683
+ private _status: 'pending' | 'loading' | 'loaded' | 'failed' = 'pending'
684
+
685
+ constructor(
686
+ private readonly loader: () => Promise<string>,
687
+ private readonly _system: ProofSystem,
688
+ private readonly _circuitId: string
689
+ ) {}
690
+
691
+ /**
692
+ * Get the proof system this key belongs to
693
+ */
694
+ get system(): ProofSystem {
695
+ return this._system
696
+ }
697
+
698
+ /**
699
+ * Get the circuit ID
700
+ */
701
+ get circuitId(): string {
702
+ return this._circuitId
703
+ }
704
+
705
+ /**
706
+ * Get the verification key (loads if necessary)
707
+ */
708
+ async get(): Promise<string> {
709
+ if (this._vk) return this._vk
710
+
711
+ if (this._promise) return this._promise
712
+
713
+ this._status = 'loading'
714
+ this._promise = this._load()
715
+ return this._promise
716
+ }
717
+
718
+ /**
719
+ * Get the verification key synchronously (null if not loaded)
720
+ */
721
+ getSync(): string | null {
722
+ return this._vk
723
+ }
724
+
725
+ /**
726
+ * Check if loaded
727
+ */
728
+ get isLoaded(): boolean {
729
+ return this._status === 'loaded'
730
+ }
731
+
732
+ /**
733
+ * Preload the verification key
734
+ */
735
+ preload(): void {
736
+ if (this._status === 'pending') {
737
+ this.get().catch(() => {})
738
+ }
739
+ }
740
+
741
+ private async _load(): Promise<string> {
742
+ try {
743
+ this._vk = await this.loader()
744
+ this._status = 'loaded'
745
+ return this._vk
746
+ } catch (err) {
747
+ this._status = 'failed'
748
+ throw err
749
+ }
750
+ }
751
+ }
752
+
753
+ /**
754
+ * Registry for lazy verification keys
755
+ */
756
+ export class VerificationKeyRegistry {
757
+ private readonly keys = new Map<string, LazyVerificationKey>()
758
+
759
+ /**
760
+ * Register a verification key loader
761
+ */
762
+ register(
763
+ system: ProofSystem,
764
+ circuitId: string,
765
+ loader: () => Promise<string>
766
+ ): void {
767
+ const key = this._makeKey(system, circuitId)
768
+ this.keys.set(key, new LazyVerificationKey(loader, system, circuitId))
769
+ }
770
+
771
+ /**
772
+ * Get a verification key
773
+ */
774
+ async get(system: ProofSystem, circuitId: string): Promise<string> {
775
+ const key = this._makeKey(system, circuitId)
776
+ const lazy = this.keys.get(key)
777
+
778
+ if (!lazy) {
779
+ throw new LazyProofError(
780
+ `No verification key registered for ${system}:${circuitId}`,
781
+ 'VK_NOT_FOUND'
782
+ )
783
+ }
784
+
785
+ return lazy.get()
786
+ }
787
+
788
+ /**
789
+ * Preload verification keys for specified circuits
790
+ */
791
+ preload(circuits: Array<{ system: ProofSystem; circuitId: string }>): void {
792
+ for (const { system, circuitId } of circuits) {
793
+ const key = this._makeKey(system, circuitId)
794
+ this.keys.get(key)?.preload()
795
+ }
796
+ }
797
+
798
+ /**
799
+ * Preload all registered verification keys
800
+ */
801
+ preloadAll(): void {
802
+ for (const lazy of this.keys.values()) {
803
+ lazy.preload()
804
+ }
805
+ }
806
+
807
+ private _makeKey(system: ProofSystem, circuitId: string): string {
808
+ return `${system}:${circuitId}`
809
+ }
810
+ }
811
+
812
+ // ─── Speculative Prefetching ──────────────────────────────────────────────────
813
+
814
+ /**
815
+ * Configuration for speculative prefetching
816
+ */
817
+ export interface PrefetchConfig {
818
+ /** Maximum proofs to prefetch */
819
+ readonly maxPrefetch: number
820
+ /** Prefetch when likelihood exceeds this threshold (0-1) */
821
+ readonly likelihoodThreshold: number
822
+ /** Time window for access pattern analysis (ms) */
823
+ readonly analysisWindowMs: number
824
+ }
825
+
826
+ /**
827
+ * Default prefetch configuration
828
+ */
829
+ export const DEFAULT_PREFETCH_CONFIG: PrefetchConfig = {
830
+ maxPrefetch: 5,
831
+ likelihoodThreshold: 0.7,
832
+ analysisWindowMs: 300000, // 5 minutes
833
+ }
834
+
835
+ /**
836
+ * Speculative prefetcher for proofs
837
+ */
838
+ export class SpeculativePrefetcher<T = SingleProof> {
839
+ private readonly config: PrefetchConfig
840
+ private readonly accessHistory: Array<{
841
+ circuitId: string
842
+ timestamp: number
843
+ }> = []
844
+ private readonly prefetched = new Map<string, LazyProof<T>>()
845
+ private readonly generators = new Map<string, ProofGenerator<T>>()
846
+
847
+ constructor(config: Partial<PrefetchConfig> = {}) {
848
+ this.config = { ...DEFAULT_PREFETCH_CONFIG, ...config }
849
+ }
850
+
851
+ /**
852
+ * Register a proof generator for prefetching
853
+ */
854
+ register(circuitId: string, generator: ProofGenerator<T>): void {
855
+ this.generators.set(circuitId, generator)
856
+ }
857
+
858
+ /**
859
+ * Record an access and trigger prefetching
860
+ */
861
+ recordAccess(circuitId: string): void {
862
+ // Record access
863
+ this.accessHistory.push({ circuitId, timestamp: Date.now() })
864
+
865
+ // Trim old history
866
+ const cutoff = Date.now() - this.config.analysisWindowMs
867
+ while (this.accessHistory.length > 0 && this.accessHistory[0].timestamp < cutoff) {
868
+ this.accessHistory.shift()
869
+ }
870
+
871
+ // Analyze and prefetch
872
+ this._prefetchLikely()
873
+ }
874
+
875
+ /**
876
+ * Get a prefetched proof if available
877
+ */
878
+ getPrefetched(circuitId: string): LazyProof<T> | null {
879
+ return this.prefetched.get(circuitId) ?? null
880
+ }
881
+
882
+ /**
883
+ * Clear all prefetched proofs
884
+ */
885
+ clear(): void {
886
+ for (const lazy of this.prefetched.values()) {
887
+ lazy.cancel()
888
+ }
889
+ this.prefetched.clear()
890
+ this.accessHistory.length = 0
891
+ }
892
+
893
+ private _prefetchLikely(): void {
894
+ // Calculate access frequencies
895
+ const frequencies = new Map<string, number>()
896
+ for (const { circuitId } of this.accessHistory) {
897
+ frequencies.set(circuitId, (frequencies.get(circuitId) ?? 0) + 1)
898
+ }
899
+
900
+ // Calculate likelihoods
901
+ const total = this.accessHistory.length
902
+ const likelihoods: Array<{ circuitId: string; likelihood: number }> = []
903
+
904
+ for (const [circuitId, count] of frequencies) {
905
+ const likelihood = count / total
906
+ if (likelihood >= this.config.likelihoodThreshold) {
907
+ likelihoods.push({ circuitId, likelihood })
908
+ }
909
+ }
910
+
911
+ // Sort by likelihood
912
+ likelihoods.sort((a, b) => b.likelihood - a.likelihood)
913
+
914
+ // Prefetch top candidates (respecting maxPrefetch limit including existing)
915
+ for (const { circuitId } of likelihoods) {
916
+ // Check total prefetched count (existing + new)
917
+ if (this.prefetched.size >= this.config.maxPrefetch) break
918
+
919
+ // Skip if already prefetched
920
+ if (this.prefetched.has(circuitId)) continue
921
+
922
+ // Skip if no generator
923
+ const generator = this.generators.get(circuitId)
924
+ if (!generator) continue
925
+
926
+ // Create lazy proof with immediate trigger
927
+ const lazy = new LazyProof(generator, {
928
+ ...DEFAULT_LAZY_CONFIG,
929
+ trigger: 'immediate',
930
+ priority: 'low',
931
+ })
932
+
933
+ this.prefetched.set(circuitId, lazy)
934
+ }
935
+ }
936
+ }
937
+
938
+ // ─── Error Class ──────────────────────────────────────────────────────────────
939
+
940
+ /**
941
+ * Error codes for lazy proof operations
942
+ */
943
+ export type LazyProofErrorCode =
944
+ | 'NOT_RESOLVED'
945
+ | 'CANCELLED'
946
+ | 'TIMEOUT'
947
+ | 'QUEUE_FULL'
948
+ | 'VK_NOT_FOUND'
949
+ | 'INTERNAL'
950
+
951
+ /**
952
+ * Error class for lazy proof operations
953
+ */
954
+ export class LazyProofError extends Error {
955
+ constructor(
956
+ message: string,
957
+ public readonly code: LazyProofErrorCode
958
+ ) {
959
+ super(message)
960
+ this.name = 'LazyProofError'
961
+ }
962
+ }
963
+
964
+ // ─── Factory Functions ────────────────────────────────────────────────────────
965
+
966
+ /**
967
+ * Create a lazy proof with default configuration
968
+ */
969
+ export function createLazyProof<T = SingleProof>(
970
+ generator: ProofGenerator<T>,
971
+ config?: Partial<LazyProofConfig>,
972
+ metadata?: { system?: ProofSystem; circuitId?: string }
973
+ ): LazyProof<T> {
974
+ return new LazyProof<T>(
975
+ generator,
976
+ { ...DEFAULT_LAZY_CONFIG, ...config },
977
+ metadata
978
+ )
979
+ }
980
+
981
+ /**
982
+ * Create a proof generation queue
983
+ */
984
+ export function createProofQueue<T = SingleProof>(
985
+ config?: Partial<ProofQueueConfig>
986
+ ): ProofGenerationQueue<T> {
987
+ return new ProofGenerationQueue<T>(config)
988
+ }
989
+
990
+ /**
991
+ * Create a verification key registry
992
+ */
993
+ export function createVKRegistry(): VerificationKeyRegistry {
994
+ return new VerificationKeyRegistry()
995
+ }
996
+
997
+ /**
998
+ * Create a speculative prefetcher
999
+ */
1000
+ export function createPrefetcher<T = SingleProof>(
1001
+ config?: Partial<PrefetchConfig>
1002
+ ): SpeculativePrefetcher<T> {
1003
+ return new SpeculativePrefetcher<T>(config)
1004
+ }