@sip-protocol/sdk 0.7.2 → 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 (262) 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 +48874 -18336
  7. package/dist/browser.mjs +674 -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-YWGJ77A2.mjs +33806 -0
  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-DXh2IGkz.d.ts +24681 -0
  24. package/dist/index-DeE1ZzA4.d.mts +24681 -0
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48676 -17318
  28. package/dist/index.mjs +583 -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 +276 -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 +201 -0
  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 +402 -0
  98. package/src/chains/solana/providers/index.ts +85 -0
  99. package/src/chains/solana/providers/interface.ts +221 -0
  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 +790 -0
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +170 -73
  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 +77 -7
  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 +37 -0
  116. package/src/compliance/range-sas.ts +956 -0
  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 +785 -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 +336 -0
  143. package/src/privacy-backends/interface.ts +906 -0
  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-types.ts +278 -0
  148. package/src/privacy-backends/privacycash.ts +456 -0
  149. package/src/privacy-backends/private-swap.ts +570 -0
  150. package/src/privacy-backends/rate-limiter.ts +683 -0
  151. package/src/privacy-backends/registry.ts +690 -0
  152. package/src/privacy-backends/router.ts +626 -0
  153. package/src/privacy-backends/shadowwire.ts +449 -0
  154. package/src/privacy-backends/sip-native.ts +256 -0
  155. package/src/privacy-logger.ts +191 -0
  156. package/src/production-safety.ts +373 -0
  157. package/src/proofs/aggregator.ts +1029 -0
  158. package/src/proofs/browser-composer.ts +1150 -0
  159. package/src/proofs/browser.ts +113 -25
  160. package/src/proofs/cache/index.ts +127 -0
  161. package/src/proofs/cache/interface.ts +545 -0
  162. package/src/proofs/cache/key-generator.ts +188 -0
  163. package/src/proofs/cache/lru-cache.ts +481 -0
  164. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  165. package/src/proofs/cache/persistent-cache.ts +788 -0
  166. package/src/proofs/compliance-proof.ts +872 -0
  167. package/src/proofs/composer/base.ts +923 -0
  168. package/src/proofs/composer/index.ts +25 -0
  169. package/src/proofs/composer/interface.ts +518 -0
  170. package/src/proofs/composer/types.ts +383 -0
  171. package/src/proofs/converters/halo2.ts +452 -0
  172. package/src/proofs/converters/index.ts +208 -0
  173. package/src/proofs/converters/interface.ts +363 -0
  174. package/src/proofs/converters/kimchi.ts +462 -0
  175. package/src/proofs/converters/noir.ts +451 -0
  176. package/src/proofs/fallback.ts +888 -0
  177. package/src/proofs/halo2.ts +42 -0
  178. package/src/proofs/index.ts +471 -0
  179. package/src/proofs/interface.ts +13 -0
  180. package/src/proofs/kimchi.ts +42 -0
  181. package/src/proofs/lazy.ts +1004 -0
  182. package/src/proofs/mock.ts +25 -1
  183. package/src/proofs/noir.ts +111 -30
  184. package/src/proofs/orchestrator.ts +960 -0
  185. package/src/proofs/parallel/concurrency.ts +297 -0
  186. package/src/proofs/parallel/dependency-graph.ts +602 -0
  187. package/src/proofs/parallel/executor.ts +420 -0
  188. package/src/proofs/parallel/index.ts +131 -0
  189. package/src/proofs/parallel/interface.ts +685 -0
  190. package/src/proofs/parallel/worker-pool.ts +644 -0
  191. package/src/proofs/providers/halo2.ts +560 -0
  192. package/src/proofs/providers/index.ts +34 -0
  193. package/src/proofs/providers/kimchi.ts +641 -0
  194. package/src/proofs/validator.ts +881 -0
  195. package/src/proofs/verifier.ts +867 -0
  196. package/src/quantum/index.ts +112 -0
  197. package/src/quantum/winternitz-vault.ts +639 -0
  198. package/src/quantum/wots.ts +611 -0
  199. package/src/settlement/backends/direct-chain.ts +1 -0
  200. package/src/settlement/index.ts +9 -0
  201. package/src/settlement/router.ts +732 -46
  202. package/src/solana/index.ts +72 -0
  203. package/src/solana/jito-relayer.ts +687 -0
  204. package/src/solana/noir-verifier-types.ts +430 -0
  205. package/src/solana/noir-verifier.ts +816 -0
  206. package/src/stealth/address-derivation.ts +193 -0
  207. package/src/stealth/ed25519.ts +431 -0
  208. package/src/stealth/index.ts +233 -0
  209. package/src/stealth/meta-address.ts +221 -0
  210. package/src/stealth/secp256k1.ts +368 -0
  211. package/src/stealth/utils.ts +194 -0
  212. package/src/stealth.ts +50 -1504
  213. package/src/surveillance/algorithms/address-reuse.ts +143 -0
  214. package/src/surveillance/algorithms/cluster.ts +247 -0
  215. package/src/surveillance/algorithms/exchange.ts +295 -0
  216. package/src/surveillance/algorithms/temporal.ts +337 -0
  217. package/src/surveillance/analyzer.ts +442 -0
  218. package/src/surveillance/index.ts +64 -0
  219. package/src/surveillance/scoring.ts +372 -0
  220. package/src/surveillance/types.ts +264 -0
  221. package/src/sync/index.ts +106 -0
  222. package/src/sync/manager.ts +504 -0
  223. package/src/sync/mock-provider.ts +318 -0
  224. package/src/sync/oblivious.ts +625 -0
  225. package/src/tokens/index.ts +15 -0
  226. package/src/tokens/registry.ts +301 -0
  227. package/src/utils/deprecation.ts +94 -0
  228. package/src/utils/index.ts +9 -0
  229. package/src/wallet/ethereum/index.ts +68 -0
  230. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  231. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  232. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  233. package/src/wallet/ethereum/types.ts +3 -1
  234. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  235. package/src/wallet/hardware/index.ts +10 -0
  236. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  237. package/src/wallet/index.ts +71 -0
  238. package/src/wallet/near/adapter.ts +626 -0
  239. package/src/wallet/near/index.ts +86 -0
  240. package/src/wallet/near/meteor-wallet.ts +1153 -0
  241. package/src/wallet/near/my-near-wallet.ts +790 -0
  242. package/src/wallet/near/wallet-selector.ts +702 -0
  243. package/src/wallet/solana/adapter.ts +6 -4
  244. package/src/wallet/solana/index.ts +13 -0
  245. package/src/wallet/solana/privacy-adapter.ts +567 -0
  246. package/src/wallet/sui/types.ts +6 -4
  247. package/src/zcash/rpc-client.ts +13 -6
  248. package/dist/chunk-3INS3PR5.mjs +0 -884
  249. package/dist/chunk-3OVABDRH.mjs +0 -17096
  250. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  251. package/dist/chunk-E6SZWREQ.mjs +0 -57
  252. package/dist/chunk-G33LB27A.mjs +0 -16166
  253. package/dist/chunk-HGU6HZRC.mjs +0 -231
  254. package/dist/chunk-L2K34JCU.mjs +0 -1496
  255. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  256. package/dist/constants-VOI7BSLK.mjs +0 -27
  257. package/dist/index-BYZbDjal.d.ts +0 -11390
  258. package/dist/index-CHB3KuOB.d.mts +0 -11859
  259. package/dist/index-CzWPI6Le.d.ts +0 -11859
  260. package/dist/index-xbWjohNq.d.mts +0 -11390
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-Q4NAVBTS.mjs +0 -46
@@ -0,0 +1,960 @@
1
+ /**
2
+ * Proof Composition Orchestrator
3
+ *
4
+ * High-level orchestrator that manages the entire proof composition workflow.
5
+ * Coordinates providers, manages state, handles the composition lifecycle,
6
+ * and provides retry logic with exponential backoff.
7
+ *
8
+ * Key features:
9
+ * - Composition planning (determine which proofs needed)
10
+ * - Provider selection and initialization
11
+ * - Composition state machine
12
+ * - Timeout and cancellation handling
13
+ * - Retry logic with exponential backoff
14
+ * - Composition audit logging
15
+ * - Composition templates for common patterns
16
+ * - Dry-run/preview support
17
+ *
18
+ * @packageDocumentation
19
+ */
20
+
21
+ import { randomBytes, bytesToHex } from '@noble/hashes/utils'
22
+
23
+ import type {
24
+ ProofSystem,
25
+ SingleProof,
26
+ ComposedProof,
27
+ ProofAggregationStrategy,
28
+ HexString,
29
+ } from '@sip-protocol/types'
30
+
31
+ import {
32
+ ProofAggregationStrategy as Strategy,
33
+ ComposedProofStatus,
34
+ } from '@sip-protocol/types'
35
+
36
+ import type { ComposableProofProvider } from './composer/interface'
37
+ import type { ProofGenerationRequest } from './composer/types'
38
+ import { CrossSystemValidator } from './validator'
39
+ import type { ValidationReport } from './validator'
40
+
41
+ // ─── Types ───────────────────────────────────────────────────────────────────
42
+
43
+ /**
44
+ * Orchestrator configuration
45
+ */
46
+ export interface OrchestratorConfig {
47
+ /** Maximum retries for failed operations */
48
+ maxRetries: number
49
+ /** Base delay for exponential backoff (ms) */
50
+ baseDelayMs: number
51
+ /** Maximum delay between retries (ms) */
52
+ maxDelayMs: number
53
+ /** Overall composition timeout (ms) */
54
+ timeoutMs: number
55
+ /** Enable audit logging */
56
+ enableAuditLog: boolean
57
+ /** Enable dry-run mode by default */
58
+ dryRunDefault: boolean
59
+ /** Validate proofs before composition */
60
+ validateBeforeCompose: boolean
61
+ /** Strict validation mode */
62
+ strictValidation: boolean
63
+ /** Enable parallel provider initialization */
64
+ parallelInit: boolean
65
+ }
66
+
67
+ /**
68
+ * Composition state
69
+ */
70
+ export type CompositionState =
71
+ | 'idle'
72
+ | 'planning'
73
+ | 'initializing'
74
+ | 'generating'
75
+ | 'composing'
76
+ | 'validating'
77
+ | 'completed'
78
+ | 'failed'
79
+ | 'cancelled'
80
+
81
+ /**
82
+ * Composition plan
83
+ */
84
+ export interface CompositionPlan {
85
+ /** Unique plan ID */
86
+ id: string
87
+ /** Proofs to generate */
88
+ proofRequests: ProofGenerationRequest[]
89
+ /** Providers needed */
90
+ requiredProviders: ProofSystem[]
91
+ /** Aggregation strategy */
92
+ strategy: ProofAggregationStrategy
93
+ /** Estimated total time (ms) */
94
+ estimatedTimeMs: number
95
+ /** Whether plan is valid */
96
+ valid: boolean
97
+ /** Validation errors if any */
98
+ errors: string[]
99
+ /** Recommendations */
100
+ recommendations: string[]
101
+ }
102
+
103
+ /**
104
+ * Composition request
105
+ */
106
+ export interface CompositionRequest {
107
+ /** Proof generation requests */
108
+ proofs: ProofGenerationRequest[]
109
+ /** Aggregation strategy (default: SEQUENTIAL) */
110
+ strategy?: ProofAggregationStrategy
111
+ /** Custom timeout for this request */
112
+ timeoutMs?: number
113
+ /** Abort signal */
114
+ abortSignal?: AbortSignal
115
+ /** Dry-run mode (plan without executing) */
116
+ dryRun?: boolean
117
+ /** Use template */
118
+ template?: string
119
+ /** Template parameters */
120
+ templateParams?: Record<string, unknown>
121
+ /** Custom metadata */
122
+ metadata?: Record<string, unknown>
123
+ }
124
+
125
+ /**
126
+ * Orchestrator execution result
127
+ */
128
+ export interface OrchestratorResult {
129
+ /** Whether composition succeeded */
130
+ success: boolean
131
+ /** Composed proof (if successful) */
132
+ composedProof?: ComposedProof
133
+ /** Error message (if failed) */
134
+ error?: string
135
+ /** Final state */
136
+ state: CompositionState
137
+ /** Time taken (ms) */
138
+ timeMs: number
139
+ /** Number of retries */
140
+ retries: number
141
+ /** Validation report */
142
+ validationReport?: ValidationReport
143
+ /** Audit log entries */
144
+ auditLog: AuditLogEntry[]
145
+ }
146
+
147
+ /**
148
+ * Audit log entry
149
+ */
150
+ export interface AuditLogEntry {
151
+ /** Timestamp */
152
+ timestamp: number
153
+ /** Event type */
154
+ event: string
155
+ /** Event details */
156
+ details: Record<string, unknown>
157
+ /** Duration (ms) if applicable */
158
+ durationMs?: number
159
+ }
160
+
161
+ /**
162
+ * Progress event
163
+ */
164
+ export interface OrchestratorProgressEvent {
165
+ /** Current state */
166
+ state: CompositionState
167
+ /** Progress percentage (0-100) */
168
+ progress: number
169
+ /** Current operation */
170
+ operation: string
171
+ /** Time elapsed (ms) */
172
+ elapsedMs: number
173
+ /** Estimated remaining time (ms) */
174
+ estimatedRemainingMs?: number
175
+ }
176
+
177
+ /**
178
+ * Progress callback
179
+ */
180
+ export type OrchestratorProgressCallback = (event: OrchestratorProgressEvent) => void
181
+
182
+ /**
183
+ * Composition template
184
+ */
185
+ export interface CompositionTemplate {
186
+ /** Template ID */
187
+ id: string
188
+ /** Template name */
189
+ name: string
190
+ /** Description */
191
+ description: string
192
+ /** Required proof types */
193
+ requiredProofs: {
194
+ circuitId: string
195
+ system?: ProofSystem
196
+ required: boolean
197
+ }[]
198
+ /** Default strategy */
199
+ defaultStrategy: ProofAggregationStrategy
200
+ /** Parameter schema */
201
+ parameterSchema?: Record<string, unknown>
202
+ }
203
+
204
+ // ─── Default Configuration ───────────────────────────────────────────────────
205
+
206
+ export const DEFAULT_ORCHESTRATOR_CONFIG: OrchestratorConfig = {
207
+ maxRetries: 3,
208
+ baseDelayMs: 1000,
209
+ maxDelayMs: 30000,
210
+ timeoutMs: 300000, // 5 minutes
211
+ enableAuditLog: true,
212
+ dryRunDefault: false,
213
+ validateBeforeCompose: true,
214
+ strictValidation: false,
215
+ parallelInit: true,
216
+ }
217
+
218
+ // ─── Built-in Templates ──────────────────────────────────────────────────────
219
+
220
+ export const BUILTIN_TEMPLATES: CompositionTemplate[] = [
221
+ {
222
+ id: 'shielded-transfer',
223
+ name: 'Shielded Transfer',
224
+ description: 'Standard shielded transfer with funding and validity proofs',
225
+ requiredProofs: [
226
+ { circuitId: 'funding_proof', required: true },
227
+ { circuitId: 'validity_proof', required: true },
228
+ ],
229
+ defaultStrategy: Strategy.SEQUENTIAL,
230
+ },
231
+ {
232
+ id: 'compliant-transfer',
233
+ name: 'Compliant Transfer',
234
+ description: 'Shielded transfer with compliance proof for regulated transfers',
235
+ requiredProofs: [
236
+ { circuitId: 'funding_proof', required: true },
237
+ { circuitId: 'validity_proof', required: true },
238
+ { circuitId: 'compliance_proof', required: true },
239
+ ],
240
+ defaultStrategy: Strategy.SEQUENTIAL,
241
+ },
242
+ {
243
+ id: 'multi-chain-bridge',
244
+ name: 'Multi-Chain Bridge',
245
+ description: 'Cross-chain proof composition for bridge transfers',
246
+ requiredProofs: [
247
+ { circuitId: 'source_chain_proof', required: true },
248
+ { circuitId: 'bridge_proof', required: true },
249
+ { circuitId: 'destination_chain_proof', required: true },
250
+ ],
251
+ defaultStrategy: Strategy.SEQUENTIAL,
252
+ },
253
+ {
254
+ id: 'batch-verification',
255
+ name: 'Batch Verification',
256
+ description: 'Batch multiple proofs for efficient verification',
257
+ requiredProofs: [],
258
+ defaultStrategy: Strategy.BATCH,
259
+ },
260
+ ]
261
+
262
+ // ─── Helper Functions ────────────────────────────────────────────────────────
263
+
264
+ function generateId(prefix: string): string {
265
+ return `${prefix}-${bytesToHex(randomBytes(8))}`
266
+ }
267
+
268
+ function delay(ms: number): Promise<void> {
269
+ return new Promise(resolve => setTimeout(resolve, ms))
270
+ }
271
+
272
+ function computeBackoffDelay(
273
+ attempt: number,
274
+ baseDelayMs: number,
275
+ maxDelayMs: number,
276
+ ): number {
277
+ const exponentialDelay = baseDelayMs * Math.pow(2, attempt)
278
+ const jitter = Math.random() * 0.3 * exponentialDelay
279
+ return Math.min(exponentialDelay + jitter, maxDelayMs)
280
+ }
281
+
282
+ // ─── Proof Orchestrator ──────────────────────────────────────────────────────
283
+
284
+ /**
285
+ * ProofOrchestrator
286
+ *
287
+ * High-level orchestrator for proof composition workflows.
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * const orchestrator = new ProofOrchestrator()
292
+ *
293
+ * // Register providers
294
+ * orchestrator.registerProvider(noirProvider)
295
+ * orchestrator.registerProvider(halo2Provider)
296
+ *
297
+ * // Plan composition
298
+ * const plan = await orchestrator.plan({
299
+ * proofs: [
300
+ * { circuitId: 'funding_proof', ... },
301
+ * { circuitId: 'validity_proof', ... },
302
+ * ],
303
+ * strategy: ProofAggregationStrategy.SEQUENTIAL,
304
+ * })
305
+ *
306
+ * // Execute composition
307
+ * const result = await orchestrator.execute({
308
+ * proofs: [...],
309
+ * onProgress: (event) => console.log(event),
310
+ * })
311
+ * ```
312
+ */
313
+ export class ProofOrchestrator {
314
+ private _config: OrchestratorConfig
315
+ private _providers: Map<ProofSystem, ComposableProofProvider> = new Map()
316
+ private _templates: Map<string, CompositionTemplate> = new Map()
317
+ private _validator: CrossSystemValidator
318
+ private _state: CompositionState = 'idle'
319
+ private _auditLog: AuditLogEntry[] = []
320
+ private _currentAbortController?: AbortController
321
+
322
+ constructor(config?: Partial<OrchestratorConfig>) {
323
+ this._config = { ...DEFAULT_ORCHESTRATOR_CONFIG, ...config }
324
+ this._validator = new CrossSystemValidator({
325
+ strictMode: this._config.strictValidation,
326
+ })
327
+
328
+ // Register built-in templates
329
+ for (const template of BUILTIN_TEMPLATES) {
330
+ this._templates.set(template.id, template)
331
+ }
332
+ }
333
+
334
+ // ─── Configuration ─────────────────────────────────────────────────────────
335
+
336
+ get config(): OrchestratorConfig {
337
+ return { ...this._config }
338
+ }
339
+
340
+ get state(): CompositionState {
341
+ return this._state
342
+ }
343
+
344
+ updateConfig(config: Partial<OrchestratorConfig>): void {
345
+ this._config = { ...this._config, ...config }
346
+ }
347
+
348
+ // ─── Provider Management ───────────────────────────────────────────────────
349
+
350
+ registerProvider(provider: ComposableProofProvider): void {
351
+ this._providers.set(provider.system, provider)
352
+ this._log('provider_registered', { system: provider.system })
353
+ }
354
+
355
+ unregisterProvider(system: ProofSystem): boolean {
356
+ const removed = this._providers.delete(system)
357
+ if (removed) {
358
+ this._log('provider_unregistered', { system })
359
+ }
360
+ return removed
361
+ }
362
+
363
+ getProvider(system: ProofSystem): ComposableProofProvider | undefined {
364
+ return this._providers.get(system)
365
+ }
366
+
367
+ getAvailableSystems(): ProofSystem[] {
368
+ return Array.from(this._providers.keys())
369
+ }
370
+
371
+ // ─── Template Management ───────────────────────────────────────────────────
372
+
373
+ registerTemplate(template: CompositionTemplate): void {
374
+ this._templates.set(template.id, template)
375
+ this._log('template_registered', { templateId: template.id })
376
+ }
377
+
378
+ getTemplate(id: string): CompositionTemplate | undefined {
379
+ return this._templates.get(id)
380
+ }
381
+
382
+ getTemplates(): CompositionTemplate[] {
383
+ return Array.from(this._templates.values())
384
+ }
385
+
386
+ // ─── Planning ──────────────────────────────────────────────────────────────
387
+
388
+ /**
389
+ * Create a composition plan without executing
390
+ */
391
+ async plan(request: CompositionRequest): Promise<CompositionPlan> {
392
+ const startTime = Date.now()
393
+ this._setState('planning')
394
+
395
+ const planId = generateId('plan')
396
+ const errors: string[] = []
397
+ const recommendations: string[] = []
398
+
399
+ // Apply template if specified
400
+ const proofRequests = [...request.proofs]
401
+ let strategy = request.strategy || Strategy.SEQUENTIAL
402
+
403
+ if (request.template) {
404
+ const template = this._templates.get(request.template)
405
+ if (!template) {
406
+ errors.push(`Template '${request.template}' not found`)
407
+ } else {
408
+ strategy = template.defaultStrategy
409
+ // Merge template requirements with provided proofs
410
+ for (const req of template.requiredProofs) {
411
+ const hasProof = proofRequests.some(p => p.circuitId === req.circuitId)
412
+ if (!hasProof && req.required) {
413
+ errors.push(`Required proof '${req.circuitId}' from template not provided`)
414
+ }
415
+ }
416
+ }
417
+ }
418
+
419
+ // Determine required providers
420
+ const requiredProviders = new Set<ProofSystem>()
421
+ for (const proof of proofRequests) {
422
+ const system = proof.system || this._inferSystem(proof.circuitId)
423
+ if (system) {
424
+ requiredProviders.add(system)
425
+ } else {
426
+ errors.push(`Cannot determine system for circuit '${proof.circuitId}'`)
427
+ }
428
+ }
429
+
430
+ // Check provider availability
431
+ for (const system of requiredProviders) {
432
+ if (!this._providers.has(system)) {
433
+ errors.push(`No provider registered for system '${system}'`)
434
+ }
435
+ }
436
+
437
+ // Estimate time
438
+ let estimatedTimeMs = 0
439
+ for (const system of requiredProviders) {
440
+ const provider = this._providers.get(system)
441
+ if (provider) {
442
+ estimatedTimeMs += provider.capabilities.maxProofSize > 0 ? 5000 : 10000
443
+ }
444
+ }
445
+ estimatedTimeMs *= proofRequests.length
446
+
447
+ // Generate recommendations
448
+ if (proofRequests.length > 3 && strategy === Strategy.SEQUENTIAL) {
449
+ recommendations.push('Consider using PARALLEL or BATCH strategy for better performance')
450
+ }
451
+
452
+ const requiredProvidersArray = Array.from(requiredProviders)
453
+ if (requiredProvidersArray.length > 1) {
454
+ const compatible = this._checkProviderCompatibility(requiredProvidersArray)
455
+ if (!compatible) {
456
+ recommendations.push('Multi-system composition detected - ensure cross-system validation')
457
+ }
458
+ }
459
+
460
+ this._setState('idle')
461
+ this._log('plan_created', {
462
+ planId,
463
+ proofCount: proofRequests.length,
464
+ providers: requiredProvidersArray,
465
+ errors: errors.length,
466
+ timeMs: Date.now() - startTime,
467
+ })
468
+
469
+ return {
470
+ id: planId,
471
+ proofRequests,
472
+ requiredProviders: requiredProvidersArray,
473
+ strategy,
474
+ estimatedTimeMs,
475
+ valid: errors.length === 0,
476
+ errors,
477
+ recommendations,
478
+ }
479
+ }
480
+
481
+ // ─── Execution ─────────────────────────────────────────────────────────────
482
+
483
+ /**
484
+ * Execute a composition request
485
+ */
486
+ async execute(
487
+ request: CompositionRequest,
488
+ onProgress?: OrchestratorProgressCallback,
489
+ ): Promise<OrchestratorResult> {
490
+ const startTime = Date.now()
491
+ const auditLog: AuditLogEntry[] = []
492
+
493
+ // Check for dry-run
494
+ if (request.dryRun ?? this._config.dryRunDefault) {
495
+ const plan = await this.plan(request)
496
+ return {
497
+ success: plan.valid,
498
+ error: plan.errors.length > 0 ? plan.errors.join('; ') : undefined,
499
+ state: 'completed',
500
+ timeMs: Date.now() - startTime,
501
+ retries: 0,
502
+ auditLog,
503
+ }
504
+ }
505
+
506
+ // Setup abort handling
507
+ this._currentAbortController = new AbortController()
508
+ const combinedSignal = request.abortSignal
509
+ ? this._combineAbortSignals(request.abortSignal, this._currentAbortController.signal)
510
+ : this._currentAbortController.signal
511
+
512
+ let retries = 0
513
+ let lastError: string | undefined
514
+
515
+ try {
516
+ while (retries <= this._config.maxRetries) {
517
+ try {
518
+ const result = await this._executeOnce(
519
+ request,
520
+ combinedSignal,
521
+ onProgress,
522
+ startTime,
523
+ auditLog,
524
+ )
525
+
526
+ if (result.success) {
527
+ return result
528
+ }
529
+
530
+ lastError = result.error
531
+ retries++
532
+
533
+ if (retries <= this._config.maxRetries) {
534
+ const backoffDelay = computeBackoffDelay(
535
+ retries - 1,
536
+ this._config.baseDelayMs,
537
+ this._config.maxDelayMs,
538
+ )
539
+
540
+ this._log('retry_scheduled', { attempt: retries, delayMs: backoffDelay }, auditLog)
541
+
542
+ await delay(backoffDelay)
543
+
544
+ if (combinedSignal.aborted) {
545
+ return this._createCancelledResult(startTime, auditLog)
546
+ }
547
+ }
548
+ } catch (error) {
549
+ lastError = error instanceof Error ? error.message : 'Unknown error'
550
+ retries++
551
+
552
+ if (retries > this._config.maxRetries) {
553
+ break
554
+ }
555
+
556
+ const backoffDelay = computeBackoffDelay(
557
+ retries - 1,
558
+ this._config.baseDelayMs,
559
+ this._config.maxDelayMs,
560
+ )
561
+
562
+ this._log('error_retry', { error: lastError, attempt: retries, delayMs: backoffDelay }, auditLog)
563
+
564
+ await delay(backoffDelay)
565
+
566
+ if (combinedSignal.aborted) {
567
+ return this._createCancelledResult(startTime, auditLog)
568
+ }
569
+ }
570
+ }
571
+
572
+ // All retries exhausted
573
+ this._setState('failed')
574
+ return {
575
+ success: false,
576
+ error: lastError || 'Max retries exceeded',
577
+ state: 'failed',
578
+ timeMs: Date.now() - startTime,
579
+ retries,
580
+ auditLog,
581
+ }
582
+ } finally {
583
+ this._currentAbortController = undefined
584
+ }
585
+ }
586
+
587
+ /**
588
+ * Cancel current composition
589
+ */
590
+ cancel(): void {
591
+ if (this._currentAbortController) {
592
+ this._currentAbortController.abort()
593
+ this._setState('cancelled')
594
+ this._log('composition_cancelled', {})
595
+ }
596
+ }
597
+
598
+ // ─── Private Methods ───────────────────────────────────────────────────────
599
+
600
+ private async _executeOnce(
601
+ request: CompositionRequest,
602
+ abortSignal: AbortSignal,
603
+ onProgress?: OrchestratorProgressCallback,
604
+ startTime?: number,
605
+ auditLog?: AuditLogEntry[],
606
+ ): Promise<OrchestratorResult> {
607
+ const start = startTime || Date.now()
608
+ const log = auditLog || []
609
+
610
+ // Create timeout
611
+ const timeoutMs = request.timeoutMs || this._config.timeoutMs
612
+ const timeoutPromise = new Promise<never>((_, reject) => {
613
+ setTimeout(() => reject(new Error('Composition timeout')), timeoutMs)
614
+ })
615
+
616
+ try {
617
+ // Planning phase
618
+ this._setState('planning')
619
+ this._reportProgress(onProgress, 'planning', 5, start)
620
+ this._log('execution_started', { proofCount: request.proofs.length }, log)
621
+
622
+ const plan = await this.plan(request)
623
+ if (!plan.valid) {
624
+ return {
625
+ success: false,
626
+ error: plan.errors.join('; '),
627
+ state: 'failed',
628
+ timeMs: Date.now() - start,
629
+ retries: 0,
630
+ auditLog: log,
631
+ }
632
+ }
633
+
634
+ if (abortSignal.aborted) {
635
+ return this._createCancelledResult(start, log)
636
+ }
637
+
638
+ // Initialize providers
639
+ this._setState('initializing')
640
+ this._reportProgress(onProgress, 'initializing', 15, start)
641
+ this._log('providers_initializing', { count: plan.requiredProviders.length }, log)
642
+
643
+ await Promise.race([
644
+ this._initializeProviders(plan.requiredProviders),
645
+ timeoutPromise,
646
+ ])
647
+
648
+ if (abortSignal.aborted) {
649
+ return this._createCancelledResult(start, log)
650
+ }
651
+
652
+ // Generate proofs
653
+ this._setState('generating')
654
+ this._reportProgress(onProgress, 'generating', 30, start)
655
+ this._log('proof_generation_started', { count: plan.proofRequests.length }, log)
656
+
657
+ const proofs = await Promise.race([
658
+ this._generateProofs(plan.proofRequests, onProgress, start),
659
+ timeoutPromise,
660
+ ])
661
+
662
+ if (abortSignal.aborted) {
663
+ return this._createCancelledResult(start, log)
664
+ }
665
+
666
+ // Validate proofs
667
+ let validationReport: ValidationReport | undefined
668
+ if (this._config.validateBeforeCompose) {
669
+ this._setState('validating')
670
+ this._reportProgress(onProgress, 'validating', 70, start)
671
+ this._log('validation_started', {}, log)
672
+
673
+ validationReport = this._validator.validate(proofs)
674
+ this._log('validation_completed', {
675
+ valid: validationReport.valid,
676
+ errors: validationReport.errorCount,
677
+ warnings: validationReport.warningCount,
678
+ }, log)
679
+
680
+ if (!validationReport.valid) {
681
+ return {
682
+ success: false,
683
+ error: 'Proof validation failed',
684
+ state: 'failed',
685
+ timeMs: Date.now() - start,
686
+ retries: 0,
687
+ validationReport,
688
+ auditLog: log,
689
+ }
690
+ }
691
+ }
692
+
693
+ if (abortSignal.aborted) {
694
+ return this._createCancelledResult(start, log)
695
+ }
696
+
697
+ // Compose proofs
698
+ this._setState('composing')
699
+ this._reportProgress(onProgress, 'composing', 85, start)
700
+ this._log('composition_started', { strategy: plan.strategy }, log)
701
+
702
+ const composedProof = await Promise.race([
703
+ this._composeProofs(proofs, plan.strategy),
704
+ timeoutPromise,
705
+ ])
706
+
707
+ // Complete
708
+ this._setState('completed')
709
+ this._reportProgress(onProgress, 'completed', 100, start)
710
+ this._log('composition_completed', {
711
+ composedProofId: composedProof.id,
712
+ timeMs: Date.now() - start,
713
+ }, log)
714
+
715
+ return {
716
+ success: true,
717
+ composedProof,
718
+ state: 'completed',
719
+ timeMs: Date.now() - start,
720
+ retries: 0,
721
+ validationReport,
722
+ auditLog: log,
723
+ }
724
+ } catch (error) {
725
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error'
726
+ this._log('execution_error', { error: errorMessage }, log)
727
+ throw error
728
+ }
729
+ }
730
+
731
+ private async _initializeProviders(systems: ProofSystem[]): Promise<void> {
732
+ const initPromises = systems.map(async (system) => {
733
+ const provider = this._providers.get(system)
734
+ if (provider && !provider.status.isReady) {
735
+ await provider.initialize()
736
+ }
737
+ })
738
+
739
+ if (this._config.parallelInit) {
740
+ await Promise.all(initPromises)
741
+ } else {
742
+ for (const promise of initPromises) {
743
+ await promise
744
+ }
745
+ }
746
+ }
747
+
748
+ private async _generateProofs(
749
+ requests: ProofGenerationRequest[],
750
+ onProgress?: OrchestratorProgressCallback,
751
+ startTime?: number,
752
+ ): Promise<SingleProof[]> {
753
+ const proofs: SingleProof[] = []
754
+ const start = startTime || Date.now()
755
+
756
+ for (let i = 0; i < requests.length; i++) {
757
+ const request = requests[i]
758
+ const system = request.system || this._inferSystem(request.circuitId)
759
+
760
+ if (!system) {
761
+ throw new Error(`Cannot determine system for circuit '${request.circuitId}'`)
762
+ }
763
+
764
+ const provider = this._providers.get(system)
765
+ if (!provider) {
766
+ throw new Error(`No provider for system '${system}'`)
767
+ }
768
+
769
+ const progressPercent = 30 + Math.floor((i / requests.length) * 40)
770
+ this._reportProgress(
771
+ onProgress,
772
+ `generating proof ${i + 1}/${requests.length}`,
773
+ progressPercent,
774
+ start,
775
+ )
776
+
777
+ const result = await provider.generateProof(request)
778
+
779
+ if (!result.success || !result.proof) {
780
+ throw new Error(result.error || 'Proof generation failed')
781
+ }
782
+
783
+ proofs.push(result.proof)
784
+ }
785
+
786
+ return proofs
787
+ }
788
+
789
+ private async _composeProofs(
790
+ proofs: SingleProof[],
791
+ strategy: ProofAggregationStrategy,
792
+ ): Promise<ComposedProof> {
793
+ // Create composed proof structure
794
+ const composedProof: ComposedProof = {
795
+ id: generateId('composed'),
796
+ proofs,
797
+ strategy,
798
+ status: ComposedProofStatus.VERIFIED,
799
+ combinedPublicInputs: proofs.flatMap(p => p.publicInputs),
800
+ compositionMetadata: {
801
+ proofCount: proofs.length,
802
+ systems: [...new Set(proofs.map(p => p.metadata.system))],
803
+ compositionTimeMs: 0,
804
+ success: true,
805
+ inputHash: this._computeInputHash(proofs),
806
+ },
807
+ verificationHints: {
808
+ verificationOrder: proofs.map(p => p.id),
809
+ parallelGroups: strategy === Strategy.PARALLEL ? [proofs.map(p => p.id)] : [],
810
+ estimatedTimeMs: proofs.length * 100,
811
+ estimatedCost: BigInt(proofs.length * 1000),
812
+ supportsBatchVerification: strategy === Strategy.BATCH,
813
+ },
814
+ }
815
+
816
+ return composedProof
817
+ }
818
+
819
+ private _computeInputHash(proofs: SingleProof[]): HexString {
820
+ const data = proofs.map(p => p.proof).join('')
821
+ let hash = 0
822
+ for (let i = 0; i < data.length; i++) {
823
+ hash = ((hash << 5) - hash) + data.charCodeAt(i)
824
+ hash = hash & hash
825
+ }
826
+ return `0x${Math.abs(hash).toString(16).padStart(16, '0')}` as HexString
827
+ }
828
+
829
+ private _inferSystem(circuitId: string): ProofSystem | undefined {
830
+ // Check if any provider has this circuit
831
+ for (const [system, provider] of this._providers) {
832
+ if (provider.hasCircuit(circuitId)) {
833
+ return system
834
+ }
835
+ }
836
+
837
+ // Infer from circuit ID naming convention
838
+ if (circuitId.includes('noir') || circuitId.includes('funding') || circuitId.includes('validity')) {
839
+ return 'noir'
840
+ }
841
+ if (circuitId.includes('halo2') || circuitId.includes('orchard')) {
842
+ return 'halo2'
843
+ }
844
+ if (circuitId.includes('kimchi') || circuitId.includes('mina')) {
845
+ return 'kimchi'
846
+ }
847
+
848
+ return undefined
849
+ }
850
+
851
+ private _checkProviderCompatibility(systems: ProofSystem[]): boolean {
852
+ for (let i = 0; i < systems.length; i++) {
853
+ for (let j = i + 1; j < systems.length; j++) {
854
+ if (!this._validator.areSystemsCompatible(systems[i], systems[j])) {
855
+ return false
856
+ }
857
+ }
858
+ }
859
+ return true
860
+ }
861
+
862
+ private _setState(state: CompositionState): void {
863
+ this._state = state
864
+ }
865
+
866
+ private _reportProgress(
867
+ callback: OrchestratorProgressCallback | undefined,
868
+ operation: string,
869
+ progress: number,
870
+ startTime: number,
871
+ ): void {
872
+ if (callback) {
873
+ const elapsedMs = Date.now() - startTime
874
+ const estimatedRemainingMs = progress > 0
875
+ ? Math.floor((elapsedMs / progress) * (100 - progress))
876
+ : undefined
877
+
878
+ callback({
879
+ state: this._state,
880
+ progress,
881
+ operation,
882
+ elapsedMs,
883
+ estimatedRemainingMs,
884
+ })
885
+ }
886
+ }
887
+
888
+ private _log(
889
+ event: string,
890
+ details: Record<string, unknown>,
891
+ targetLog?: AuditLogEntry[],
892
+ ): void {
893
+ if (!this._config.enableAuditLog) return
894
+
895
+ const entry: AuditLogEntry = {
896
+ timestamp: Date.now(),
897
+ event,
898
+ details,
899
+ }
900
+
901
+ this._auditLog.push(entry)
902
+ if (targetLog) {
903
+ targetLog.push(entry)
904
+ }
905
+ }
906
+
907
+ private _combineAbortSignals(signal1: AbortSignal, signal2: AbortSignal): AbortSignal {
908
+ const controller = new AbortController()
909
+
910
+ const onAbort = () => controller.abort()
911
+
912
+ signal1.addEventListener('abort', onAbort)
913
+ signal2.addEventListener('abort', onAbort)
914
+
915
+ if (signal1.aborted || signal2.aborted) {
916
+ controller.abort()
917
+ }
918
+
919
+ return controller.signal
920
+ }
921
+
922
+ private _createCancelledResult(startTime: number, auditLog: AuditLogEntry[]): OrchestratorResult {
923
+ this._setState('cancelled')
924
+ return {
925
+ success: false,
926
+ error: 'Composition cancelled',
927
+ state: 'cancelled',
928
+ timeMs: Date.now() - startTime,
929
+ retries: 0,
930
+ auditLog,
931
+ }
932
+ }
933
+
934
+ // ─── Audit Log Access ──────────────────────────────────────────────────────
935
+
936
+ /**
937
+ * Get full audit log
938
+ */
939
+ getAuditLog(): AuditLogEntry[] {
940
+ return [...this._auditLog]
941
+ }
942
+
943
+ /**
944
+ * Clear audit log
945
+ */
946
+ clearAuditLog(): void {
947
+ this._auditLog = []
948
+ }
949
+ }
950
+
951
+ // ─── Factory Function ────────────────────────────────────────────────────────
952
+
953
+ /**
954
+ * Create a proof orchestrator with optional configuration
955
+ */
956
+ export function createProofOrchestrator(
957
+ config?: Partial<OrchestratorConfig>,
958
+ ): ProofOrchestrator {
959
+ return new ProofOrchestrator(config)
960
+ }