@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.
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +48874 -18336
- package/dist/browser.mjs +674 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/chunk-YWGJ77A2.mjs +33806 -0
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/index-DXh2IGkz.d.ts +24681 -0
- package/dist/index-DeE1ZzA4.d.mts +24681 -0
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48676 -17318
- package/dist/index.mjs +583 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +54 -21
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +276 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +201 -0
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +402 -0
- package/src/chains/solana/providers/index.ts +85 -0
- package/src/chains/solana/providers/interface.ts +221 -0
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +790 -0
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +170 -73
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +77 -7
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +37 -0
- package/src/compliance/range-sas.ts +956 -0
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +785 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +336 -0
- package/src/privacy-backends/interface.ts +906 -0
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash-types.ts +278 -0
- package/src/privacy-backends/privacycash.ts +456 -0
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +690 -0
- package/src/privacy-backends/router.ts +626 -0
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +256 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +111 -30
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/surveillance/algorithms/address-reuse.ts +143 -0
- package/src/surveillance/algorithms/cluster.ts +247 -0
- package/src/surveillance/algorithms/exchange.ts +295 -0
- package/src/surveillance/algorithms/temporal.ts +337 -0
- package/src/surveillance/analyzer.ts +442 -0
- package/src/surveillance/index.ts +64 -0
- package/src/surveillance/scoring.ts +372 -0
- package/src/surveillance/types.ts +264 -0
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-Q4NAVBTS.mjs +0 -46
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Proof Composer Implementation
|
|
3
|
+
*
|
|
4
|
+
* Provides core functionality for composing proofs from multiple ZK systems.
|
|
5
|
+
* This class orchestrates proof generation, manages provider registration,
|
|
6
|
+
* and handles the composition pipeline.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { randomBytes } from '@noble/hashes/utils'
|
|
12
|
+
import { bytesToHex } from '@noble/hashes/utils'
|
|
13
|
+
|
|
14
|
+
import type {
|
|
15
|
+
ProofSystem,
|
|
16
|
+
ProofAggregationStrategy,
|
|
17
|
+
SingleProof,
|
|
18
|
+
ComposedProof,
|
|
19
|
+
ProofCompositionConfig,
|
|
20
|
+
ProofProviderCapabilities,
|
|
21
|
+
CompositionResult,
|
|
22
|
+
VerificationResult,
|
|
23
|
+
CompositionEvent,
|
|
24
|
+
CompositionEventListener,
|
|
25
|
+
CompositionMetrics,
|
|
26
|
+
IndividualVerificationResult,
|
|
27
|
+
VerificationHints,
|
|
28
|
+
CompositionMetadata,
|
|
29
|
+
} from '@sip-protocol/types'
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
ProofAggregationStrategy as Strategy,
|
|
33
|
+
ComposedProofStatus,
|
|
34
|
+
CompositionErrorCode,
|
|
35
|
+
DEFAULT_COMPOSITION_CONFIG,
|
|
36
|
+
} from '@sip-protocol/types'
|
|
37
|
+
|
|
38
|
+
import type {
|
|
39
|
+
ProofComposer,
|
|
40
|
+
ComposableProofProvider,
|
|
41
|
+
} from './interface'
|
|
42
|
+
|
|
43
|
+
import {
|
|
44
|
+
ProofCompositionError,
|
|
45
|
+
ProviderNotFoundError,
|
|
46
|
+
CompositionTimeoutError,
|
|
47
|
+
} from './interface'
|
|
48
|
+
|
|
49
|
+
import type {
|
|
50
|
+
ProofProviderRegistration,
|
|
51
|
+
RegisterProviderOptions,
|
|
52
|
+
ProofGenerationRequest,
|
|
53
|
+
ProofGenerationResult,
|
|
54
|
+
ComposeProofsOptions,
|
|
55
|
+
VerifyComposedProofOptions,
|
|
56
|
+
AggregateProofsOptions,
|
|
57
|
+
AggregationResult,
|
|
58
|
+
ConvertProofOptions,
|
|
59
|
+
ConversionResult,
|
|
60
|
+
CacheStats,
|
|
61
|
+
WorkerPoolStatus,
|
|
62
|
+
CompatibilityMatrix,
|
|
63
|
+
FallbackConfig,
|
|
64
|
+
TelemetryCollector,
|
|
65
|
+
SystemCompatibility,
|
|
66
|
+
} from './types'
|
|
67
|
+
|
|
68
|
+
// ─── Helper Functions ───────────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Generate a unique ID
|
|
72
|
+
*/
|
|
73
|
+
function generateId(prefix: string): string {
|
|
74
|
+
const bytes = randomBytes(8)
|
|
75
|
+
return `${prefix}-${bytesToHex(bytes)}`
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Create a timeout promise
|
|
80
|
+
*/
|
|
81
|
+
function timeout(ms: number, message: string): Promise<never> {
|
|
82
|
+
return new Promise((_, reject) => {
|
|
83
|
+
setTimeout(() => reject(new CompositionTimeoutError(ms)), ms)
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Compute hash of proof data for integrity checking
|
|
89
|
+
*/
|
|
90
|
+
function computeProofHash(proofs: SingleProof[]): `0x${string}` {
|
|
91
|
+
const data = proofs.map(p => p.proof).join('')
|
|
92
|
+
// Simple hash for demo - in production use proper hashing
|
|
93
|
+
let hash = 0
|
|
94
|
+
for (let i = 0; i < data.length; i++) {
|
|
95
|
+
const char = data.charCodeAt(i)
|
|
96
|
+
hash = ((hash << 5) - hash) + char
|
|
97
|
+
hash = hash & hash
|
|
98
|
+
}
|
|
99
|
+
return `0x${Math.abs(hash).toString(16).padStart(16, '0')}` as `0x${string}`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ─── Base Proof Composer ────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Base implementation of the ProofComposer interface.
|
|
106
|
+
*
|
|
107
|
+
* Provides core functionality for:
|
|
108
|
+
* - Provider registration and management
|
|
109
|
+
* - Proof generation across multiple systems
|
|
110
|
+
* - Proof composition and aggregation
|
|
111
|
+
* - Verification of composed proofs
|
|
112
|
+
* - Event emission for progress tracking
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* const composer = new BaseProofComposer()
|
|
117
|
+
*
|
|
118
|
+
* // Register providers
|
|
119
|
+
* await composer.registerProvider(noirProvider)
|
|
120
|
+
* await composer.registerProvider(halo2Provider)
|
|
121
|
+
*
|
|
122
|
+
* // Initialize
|
|
123
|
+
* await composer.initialize()
|
|
124
|
+
*
|
|
125
|
+
* // Compose proofs
|
|
126
|
+
* const result = await composer.compose({
|
|
127
|
+
* proofs: [proof1, proof2],
|
|
128
|
+
* strategy: ProofAggregationStrategy.PARALLEL,
|
|
129
|
+
* })
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export class BaseProofComposer implements ProofComposer {
|
|
133
|
+
// ─── Private State ──────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
private _config: ProofCompositionConfig
|
|
136
|
+
private _providers: Map<string, ComposableProofProvider> = new Map()
|
|
137
|
+
private _registrations: Map<string, ProofProviderRegistration> = new Map()
|
|
138
|
+
private _systemToProvider: Map<ProofSystem, string> = new Map()
|
|
139
|
+
private _eventListeners: Set<CompositionEventListener> = new Set()
|
|
140
|
+
private _telemetryCollector?: TelemetryCollector
|
|
141
|
+
private _fallbackConfig?: FallbackConfig
|
|
142
|
+
private _initialized: boolean = false
|
|
143
|
+
|
|
144
|
+
// Cache state
|
|
145
|
+
private _cache: Map<string, { proof: SingleProof | ComposedProof; expiresAt: number }> = new Map()
|
|
146
|
+
private _cacheHits: number = 0
|
|
147
|
+
private _cacheMisses: number = 0
|
|
148
|
+
|
|
149
|
+
// ─── Constructor ────────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
constructor(config?: Partial<ProofCompositionConfig>) {
|
|
152
|
+
this._config = { ...DEFAULT_COMPOSITION_CONFIG, ...config }
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ─── Configuration ──────────────────────────────────────────────────────
|
|
156
|
+
|
|
157
|
+
get config(): ProofCompositionConfig {
|
|
158
|
+
return { ...this._config }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
updateConfig(config: Partial<ProofCompositionConfig>): void {
|
|
162
|
+
this._config = { ...this._config, ...config }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ─── Provider Management ────────────────────────────────────────────────
|
|
166
|
+
|
|
167
|
+
async registerProvider(
|
|
168
|
+
provider: ComposableProofProvider,
|
|
169
|
+
options: RegisterProviderOptions = {},
|
|
170
|
+
): Promise<ProofProviderRegistration> {
|
|
171
|
+
const { override = false, priority = 0, enabled = true } = options
|
|
172
|
+
const system = provider.system
|
|
173
|
+
const existingId = this._systemToProvider.get(system)
|
|
174
|
+
|
|
175
|
+
// Check if provider for this system already exists
|
|
176
|
+
if (existingId && !override) {
|
|
177
|
+
throw new ProofCompositionError(
|
|
178
|
+
'PROVIDER_EXISTS',
|
|
179
|
+
`Provider for system '${system}' already registered. Use override: true to replace.`,
|
|
180
|
+
{ system },
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Remove existing if overriding
|
|
185
|
+
if (existingId && override) {
|
|
186
|
+
this._providers.delete(existingId)
|
|
187
|
+
this._registrations.delete(existingId)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Generate registration ID
|
|
191
|
+
const id = generateId(`provider-${system}`)
|
|
192
|
+
|
|
193
|
+
// Create registration entry
|
|
194
|
+
const registration: ProofProviderRegistration = {
|
|
195
|
+
id,
|
|
196
|
+
system,
|
|
197
|
+
capabilities: provider.capabilities,
|
|
198
|
+
priority,
|
|
199
|
+
enabled,
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Store provider and registration
|
|
203
|
+
this._providers.set(id, provider)
|
|
204
|
+
this._registrations.set(id, registration)
|
|
205
|
+
this._systemToProvider.set(system, id)
|
|
206
|
+
|
|
207
|
+
return registration
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
unregisterProvider(providerId: string): boolean {
|
|
211
|
+
const registration = this._registrations.get(providerId)
|
|
212
|
+
if (!registration) {
|
|
213
|
+
return false
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this._providers.delete(providerId)
|
|
217
|
+
this._registrations.delete(providerId)
|
|
218
|
+
this._systemToProvider.delete(registration.system)
|
|
219
|
+
|
|
220
|
+
return true
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
getProvider(providerId: string): ComposableProofProvider | undefined {
|
|
224
|
+
return this._providers.get(providerId)
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
getProviderForSystem(system: ProofSystem): ComposableProofProvider | undefined {
|
|
228
|
+
const providerId = this._systemToProvider.get(system)
|
|
229
|
+
if (!providerId) return undefined
|
|
230
|
+
return this._providers.get(providerId)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
getProviders(): ProofProviderRegistration[] {
|
|
234
|
+
return Array.from(this._registrations.values())
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
getAvailableSystems(): ProofSystem[] {
|
|
238
|
+
return Array.from(this._systemToProvider.keys())
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ─── Proof Generation ───────────────────────────────────────────────────
|
|
242
|
+
|
|
243
|
+
async generateProof(request: ProofGenerationRequest): Promise<ProofGenerationResult> {
|
|
244
|
+
const startTime = Date.now()
|
|
245
|
+
|
|
246
|
+
// Determine which provider to use
|
|
247
|
+
let provider: ComposableProofProvider | undefined
|
|
248
|
+
let providerId: string
|
|
249
|
+
|
|
250
|
+
if (request.providerId) {
|
|
251
|
+
provider = this._providers.get(request.providerId)
|
|
252
|
+
providerId = request.providerId
|
|
253
|
+
} else if (request.system) {
|
|
254
|
+
provider = this.getProviderForSystem(request.system)
|
|
255
|
+
providerId = this._systemToProvider.get(request.system) || 'unknown'
|
|
256
|
+
} else {
|
|
257
|
+
// Use first available provider
|
|
258
|
+
const firstEntry = this._providers.entries().next().value
|
|
259
|
+
if (firstEntry) {
|
|
260
|
+
[providerId, provider] = firstEntry
|
|
261
|
+
} else {
|
|
262
|
+
providerId = 'unknown'
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (!provider) {
|
|
267
|
+
return {
|
|
268
|
+
success: false,
|
|
269
|
+
error: `No provider available for request`,
|
|
270
|
+
timeMs: Date.now() - startTime,
|
|
271
|
+
providerId: providerId,
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Ensure provider is ready
|
|
276
|
+
if (!provider.status.isReady) {
|
|
277
|
+
try {
|
|
278
|
+
await provider.waitUntilReady(request.timeoutMs || this._config.timeoutMs)
|
|
279
|
+
} catch {
|
|
280
|
+
return {
|
|
281
|
+
success: false,
|
|
282
|
+
error: 'Provider initialization timeout',
|
|
283
|
+
timeMs: Date.now() - startTime,
|
|
284
|
+
providerId,
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Check if circuit is available
|
|
290
|
+
if (!provider.hasCircuit(request.circuitId)) {
|
|
291
|
+
return {
|
|
292
|
+
success: false,
|
|
293
|
+
error: `Circuit '${request.circuitId}' not found`,
|
|
294
|
+
timeMs: Date.now() - startTime,
|
|
295
|
+
providerId,
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
try {
|
|
300
|
+
const result = await provider.generateProof(request)
|
|
301
|
+
return {
|
|
302
|
+
...result,
|
|
303
|
+
providerId,
|
|
304
|
+
}
|
|
305
|
+
} catch (error) {
|
|
306
|
+
return {
|
|
307
|
+
success: false,
|
|
308
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
309
|
+
timeMs: Date.now() - startTime,
|
|
310
|
+
providerId,
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async generateProofs(requests: ProofGenerationRequest[]): Promise<ProofGenerationResult[]> {
|
|
316
|
+
if (!this._config.enableParallelGeneration) {
|
|
317
|
+
// Sequential generation
|
|
318
|
+
const results: ProofGenerationResult[] = []
|
|
319
|
+
for (const request of requests) {
|
|
320
|
+
results.push(await this.generateProof(request))
|
|
321
|
+
}
|
|
322
|
+
return results
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Parallel generation with worker limit
|
|
326
|
+
const maxWorkers = this._config.maxParallelWorkers
|
|
327
|
+
const results: ProofGenerationResult[] = new Array(requests.length)
|
|
328
|
+
const queue = [...requests.entries()]
|
|
329
|
+
|
|
330
|
+
const worker = async () => {
|
|
331
|
+
while (queue.length > 0) {
|
|
332
|
+
const entry = queue.shift()
|
|
333
|
+
if (!entry) break
|
|
334
|
+
const [index, request] = entry
|
|
335
|
+
results[index] = await this.generateProof(request)
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Start workers
|
|
340
|
+
const workers = Array.from(
|
|
341
|
+
{ length: Math.min(maxWorkers, requests.length) },
|
|
342
|
+
() => worker(),
|
|
343
|
+
)
|
|
344
|
+
await Promise.all(workers)
|
|
345
|
+
|
|
346
|
+
return results
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// ─── Composition ────────────────────────────────────────────────────────
|
|
350
|
+
|
|
351
|
+
async compose(options: ComposeProofsOptions): Promise<CompositionResult> {
|
|
352
|
+
const compositionId = generateId('composition')
|
|
353
|
+
const startTime = Date.now()
|
|
354
|
+
const { proofs, strategy = this._config.strategy, config, onProgress, abortSignal } = options
|
|
355
|
+
|
|
356
|
+
// Emit start event
|
|
357
|
+
this.emitEvent({
|
|
358
|
+
type: 'composition:started',
|
|
359
|
+
timestamp: Date.now(),
|
|
360
|
+
compositionId,
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
// Validate proofs
|
|
364
|
+
if (proofs.length === 0) {
|
|
365
|
+
this.emitEvent({
|
|
366
|
+
type: 'composition:failed',
|
|
367
|
+
timestamp: Date.now(),
|
|
368
|
+
compositionId,
|
|
369
|
+
})
|
|
370
|
+
return this.createFailedResult(
|
|
371
|
+
CompositionErrorCode.INVALID_PROOF,
|
|
372
|
+
'No proofs provided for composition',
|
|
373
|
+
startTime,
|
|
374
|
+
)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (proofs.length > (config?.maxProofs || this._config.maxProofs)) {
|
|
378
|
+
this.emitEvent({
|
|
379
|
+
type: 'composition:failed',
|
|
380
|
+
timestamp: Date.now(),
|
|
381
|
+
compositionId,
|
|
382
|
+
})
|
|
383
|
+
return this.createFailedResult(
|
|
384
|
+
CompositionErrorCode.TOO_MANY_PROOFS,
|
|
385
|
+
`Too many proofs: ${proofs.length} exceeds max ${this._config.maxProofs}`,
|
|
386
|
+
startTime,
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Check for abort
|
|
391
|
+
if (abortSignal?.aborted) {
|
|
392
|
+
this.emitEvent({
|
|
393
|
+
type: 'composition:failed',
|
|
394
|
+
timestamp: Date.now(),
|
|
395
|
+
compositionId,
|
|
396
|
+
})
|
|
397
|
+
return this.createFailedResult(
|
|
398
|
+
CompositionErrorCode.TIMEOUT,
|
|
399
|
+
'Composition aborted',
|
|
400
|
+
startTime,
|
|
401
|
+
)
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
// Compose based on strategy
|
|
406
|
+
const composedProof = await this.composeWithStrategy(
|
|
407
|
+
compositionId,
|
|
408
|
+
proofs,
|
|
409
|
+
strategy,
|
|
410
|
+
onProgress,
|
|
411
|
+
abortSignal,
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
// Emit completed event
|
|
415
|
+
this.emitEvent({
|
|
416
|
+
type: 'composition:completed',
|
|
417
|
+
timestamp: Date.now(),
|
|
418
|
+
compositionId,
|
|
419
|
+
})
|
|
420
|
+
|
|
421
|
+
const totalTime = Date.now() - startTime
|
|
422
|
+
|
|
423
|
+
return {
|
|
424
|
+
success: true,
|
|
425
|
+
composedProof,
|
|
426
|
+
metrics: {
|
|
427
|
+
totalTimeMs: totalTime,
|
|
428
|
+
generationTimeMs: 0, // Proofs already generated
|
|
429
|
+
verificationTimeMs: 0,
|
|
430
|
+
aggregationTimeMs: totalTime,
|
|
431
|
+
peakMemoryBytes: 0, // Would need profiling
|
|
432
|
+
proofsProcessed: proofs.length,
|
|
433
|
+
},
|
|
434
|
+
}
|
|
435
|
+
} catch (error) {
|
|
436
|
+
this.emitEvent({
|
|
437
|
+
type: 'composition:failed',
|
|
438
|
+
timestamp: Date.now(),
|
|
439
|
+
compositionId,
|
|
440
|
+
})
|
|
441
|
+
|
|
442
|
+
if (error instanceof CompositionTimeoutError) {
|
|
443
|
+
return this.createFailedResult(
|
|
444
|
+
CompositionErrorCode.TIMEOUT,
|
|
445
|
+
error.message,
|
|
446
|
+
startTime,
|
|
447
|
+
)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return this.createFailedResult(
|
|
451
|
+
CompositionErrorCode.UNKNOWN,
|
|
452
|
+
error instanceof Error ? error.message : 'Unknown error',
|
|
453
|
+
startTime,
|
|
454
|
+
)
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private async composeWithStrategy(
|
|
459
|
+
compositionId: string,
|
|
460
|
+
proofs: SingleProof[],
|
|
461
|
+
strategy: ProofAggregationStrategy,
|
|
462
|
+
onProgress?: CompositionEventListener,
|
|
463
|
+
abortSignal?: AbortSignal,
|
|
464
|
+
): Promise<ComposedProof> {
|
|
465
|
+
const systems = [...new Set(proofs.map(p => p.metadata.system))]
|
|
466
|
+
const totalSteps = proofs.length + 1 // +1 for aggregation step
|
|
467
|
+
|
|
468
|
+
// Progress helper
|
|
469
|
+
const reportProgress = (_step: number, _operation: string) => {
|
|
470
|
+
const event: CompositionEvent = {
|
|
471
|
+
type: 'composition:progress',
|
|
472
|
+
timestamp: Date.now(),
|
|
473
|
+
compositionId,
|
|
474
|
+
}
|
|
475
|
+
this.emitEvent(event)
|
|
476
|
+
onProgress?.(event)
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Process proofs based on strategy
|
|
480
|
+
switch (strategy) {
|
|
481
|
+
case Strategy.SEQUENTIAL:
|
|
482
|
+
for (let i = 0; i < proofs.length; i++) {
|
|
483
|
+
if (abortSignal?.aborted) throw new CompositionTimeoutError(0)
|
|
484
|
+
reportProgress(i, `Processing proof ${i + 1}/${proofs.length}`)
|
|
485
|
+
// Verify each proof sequentially
|
|
486
|
+
const provider = this.getProviderForSystem(proofs[i].metadata.system)
|
|
487
|
+
if (provider) {
|
|
488
|
+
await provider.verifyProof(proofs[i])
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
break
|
|
492
|
+
|
|
493
|
+
case Strategy.PARALLEL:
|
|
494
|
+
reportProgress(0, 'Verifying proofs in parallel')
|
|
495
|
+
await Promise.all(
|
|
496
|
+
proofs.map(async (proof) => {
|
|
497
|
+
const provider = this.getProviderForSystem(proof.metadata.system)
|
|
498
|
+
if (provider) {
|
|
499
|
+
await provider.verifyProof(proof)
|
|
500
|
+
}
|
|
501
|
+
}),
|
|
502
|
+
)
|
|
503
|
+
break
|
|
504
|
+
|
|
505
|
+
case Strategy.BATCH: {
|
|
506
|
+
// Group by system and batch verify
|
|
507
|
+
reportProgress(0, 'Batch verifying proofs')
|
|
508
|
+
const groupedBySystem = new Map<ProofSystem, SingleProof[]>()
|
|
509
|
+
for (const proof of proofs) {
|
|
510
|
+
const existing = groupedBySystem.get(proof.metadata.system) || []
|
|
511
|
+
existing.push(proof)
|
|
512
|
+
groupedBySystem.set(proof.metadata.system, existing)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
for (const [system, systemProofs] of groupedBySystem) {
|
|
516
|
+
const provider = this.getProviderForSystem(system)
|
|
517
|
+
if (provider?.verifyBatch) {
|
|
518
|
+
await provider.verifyBatch(systemProofs)
|
|
519
|
+
} else if (provider) {
|
|
520
|
+
// Fall back to sequential
|
|
521
|
+
for (const proof of systemProofs) {
|
|
522
|
+
await provider.verifyProof(proof)
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
break
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
case Strategy.RECURSIVE:
|
|
530
|
+
// Recursive aggregation - would need actual recursive SNARK support
|
|
531
|
+
reportProgress(0, 'Recursive aggregation (simulated)')
|
|
532
|
+
// For now, just verify all proofs
|
|
533
|
+
for (const proof of proofs) {
|
|
534
|
+
const provider = this.getProviderForSystem(proof.metadata.system)
|
|
535
|
+
if (provider) {
|
|
536
|
+
await provider.verifyProof(proof)
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
break
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
reportProgress(totalSteps - 1, 'Finalizing composition')
|
|
543
|
+
|
|
544
|
+
// Create composed proof
|
|
545
|
+
const composedProof: ComposedProof = {
|
|
546
|
+
id: compositionId,
|
|
547
|
+
proofs,
|
|
548
|
+
strategy,
|
|
549
|
+
status: ComposedProofStatus.VERIFIED,
|
|
550
|
+
combinedPublicInputs: proofs.flatMap(p => p.publicInputs),
|
|
551
|
+
compositionMetadata: {
|
|
552
|
+
proofCount: proofs.length,
|
|
553
|
+
systems,
|
|
554
|
+
compositionTimeMs: 0, // Will be set by caller
|
|
555
|
+
success: true,
|
|
556
|
+
inputHash: computeProofHash(proofs),
|
|
557
|
+
},
|
|
558
|
+
verificationHints: this.computeVerificationHints(proofs, strategy),
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return composedProof
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
private computeVerificationHints(
|
|
565
|
+
proofs: SingleProof[],
|
|
566
|
+
strategy: ProofAggregationStrategy,
|
|
567
|
+
): VerificationHints {
|
|
568
|
+
const verificationOrder = proofs.map(p => p.id)
|
|
569
|
+
|
|
570
|
+
// Group by system for parallel verification
|
|
571
|
+
const systemGroups = new Map<ProofSystem, string[]>()
|
|
572
|
+
for (const proof of proofs) {
|
|
573
|
+
const existing = systemGroups.get(proof.metadata.system) || []
|
|
574
|
+
existing.push(proof.id)
|
|
575
|
+
systemGroups.set(proof.metadata.system, existing)
|
|
576
|
+
}
|
|
577
|
+
const parallelGroups = Array.from(systemGroups.values())
|
|
578
|
+
|
|
579
|
+
return {
|
|
580
|
+
verificationOrder,
|
|
581
|
+
parallelGroups,
|
|
582
|
+
estimatedTimeMs: proofs.length * 100, // Rough estimate
|
|
583
|
+
estimatedCost: BigInt(proofs.length * 100000), // Rough estimate in gas
|
|
584
|
+
supportsBatchVerification: strategy === Strategy.BATCH,
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
private createFailedResult(
|
|
589
|
+
code: CompositionErrorCode,
|
|
590
|
+
message: string,
|
|
591
|
+
startTime: number,
|
|
592
|
+
): CompositionResult {
|
|
593
|
+
return {
|
|
594
|
+
success: false,
|
|
595
|
+
error: {
|
|
596
|
+
code,
|
|
597
|
+
message,
|
|
598
|
+
},
|
|
599
|
+
metrics: {
|
|
600
|
+
totalTimeMs: Date.now() - startTime,
|
|
601
|
+
generationTimeMs: 0,
|
|
602
|
+
verificationTimeMs: 0,
|
|
603
|
+
aggregationTimeMs: 0,
|
|
604
|
+
peakMemoryBytes: 0,
|
|
605
|
+
proofsProcessed: 0,
|
|
606
|
+
},
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
async aggregate(options: AggregateProofsOptions): Promise<AggregationResult> {
|
|
611
|
+
const { proofs, targetSystem, verifyFirst = true } = options
|
|
612
|
+
const startTime = Date.now()
|
|
613
|
+
|
|
614
|
+
// Verify proofs first if requested
|
|
615
|
+
if (verifyFirst) {
|
|
616
|
+
for (const proof of proofs) {
|
|
617
|
+
const provider = this.getProviderForSystem(proof.metadata.system)
|
|
618
|
+
if (provider) {
|
|
619
|
+
const valid = await provider.verifyProof(proof)
|
|
620
|
+
if (!valid) {
|
|
621
|
+
return {
|
|
622
|
+
success: false,
|
|
623
|
+
error: `Proof ${proof.id} failed verification`,
|
|
624
|
+
metrics: {
|
|
625
|
+
inputProofCount: proofs.length,
|
|
626
|
+
outputProofSize: 0,
|
|
627
|
+
timeMs: Date.now() - startTime,
|
|
628
|
+
recursionDepth: 0,
|
|
629
|
+
},
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Check if target provider supports aggregation
|
|
637
|
+
const targetProvider = this.getProviderForSystem(targetSystem)
|
|
638
|
+
if (!targetProvider) {
|
|
639
|
+
return {
|
|
640
|
+
success: false,
|
|
641
|
+
error: `No provider for target system: ${targetSystem}`,
|
|
642
|
+
metrics: {
|
|
643
|
+
inputProofCount: proofs.length,
|
|
644
|
+
outputProofSize: 0,
|
|
645
|
+
timeMs: Date.now() - startTime,
|
|
646
|
+
recursionDepth: 0,
|
|
647
|
+
},
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// For now, return a simple aggregation result
|
|
652
|
+
// Real implementation would use recursive SNARKs
|
|
653
|
+
const aggregatedData = proofs.map(p => p.proof).join('')
|
|
654
|
+
|
|
655
|
+
return {
|
|
656
|
+
success: true,
|
|
657
|
+
aggregatedProof: `0x${Buffer.from(aggregatedData).toString('hex').slice(0, 128)}`,
|
|
658
|
+
metrics: {
|
|
659
|
+
inputProofCount: proofs.length,
|
|
660
|
+
outputProofSize: 64, // Simulated
|
|
661
|
+
timeMs: Date.now() - startTime,
|
|
662
|
+
recursionDepth: 1,
|
|
663
|
+
},
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// ─── Verification ───────────────────────────────────────────────────────
|
|
668
|
+
|
|
669
|
+
async verify(options: VerifyComposedProofOptions): Promise<VerificationResult> {
|
|
670
|
+
const { composedProof, verifyIndividual = true, useBatchVerification = false } = options
|
|
671
|
+
const startTime = Date.now()
|
|
672
|
+
const results: IndividualVerificationResult[] = []
|
|
673
|
+
|
|
674
|
+
if (verifyIndividual) {
|
|
675
|
+
if (useBatchVerification) {
|
|
676
|
+
// Group by system and batch verify
|
|
677
|
+
const groupedBySystem = new Map<ProofSystem, SingleProof[]>()
|
|
678
|
+
for (const proof of composedProof.proofs) {
|
|
679
|
+
const existing = groupedBySystem.get(proof.metadata.system) || []
|
|
680
|
+
existing.push(proof)
|
|
681
|
+
groupedBySystem.set(proof.metadata.system, existing)
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
for (const [system, systemProofs] of groupedBySystem) {
|
|
685
|
+
const provider = this.getProviderForSystem(system)
|
|
686
|
+
if (provider?.verifyBatch) {
|
|
687
|
+
const batchResults = await provider.verifyBatch(systemProofs)
|
|
688
|
+
for (let i = 0; i < systemProofs.length; i++) {
|
|
689
|
+
results.push({
|
|
690
|
+
proofId: systemProofs[i].id,
|
|
691
|
+
valid: batchResults[i],
|
|
692
|
+
timeMs: 0,
|
|
693
|
+
})
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
} else {
|
|
698
|
+
// Verify each proof individually
|
|
699
|
+
for (const proof of composedProof.proofs) {
|
|
700
|
+
const proofStart = Date.now()
|
|
701
|
+
const provider = this.getProviderForSystem(proof.metadata.system)
|
|
702
|
+
let valid = false
|
|
703
|
+
|
|
704
|
+
if (provider) {
|
|
705
|
+
valid = await provider.verifyProof(proof)
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
results.push({
|
|
709
|
+
proofId: proof.id,
|
|
710
|
+
valid,
|
|
711
|
+
timeMs: Date.now() - proofStart,
|
|
712
|
+
})
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const allValid = results.every(r => r.valid)
|
|
718
|
+
|
|
719
|
+
return {
|
|
720
|
+
valid: allValid,
|
|
721
|
+
results,
|
|
722
|
+
totalTimeMs: Date.now() - startTime,
|
|
723
|
+
method: useBatchVerification ? 'batch' : 'individual',
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
async verifySingle(proof: SingleProof): Promise<boolean> {
|
|
728
|
+
const provider = this.getProviderForSystem(proof.metadata.system)
|
|
729
|
+
if (!provider) {
|
|
730
|
+
throw new ProviderNotFoundError(proof.metadata.system)
|
|
731
|
+
}
|
|
732
|
+
return provider.verifyProof(proof)
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// ─── Format Conversion ──────────────────────────────────────────────────
|
|
736
|
+
|
|
737
|
+
async convert(options: ConvertProofOptions): Promise<ConversionResult> {
|
|
738
|
+
const { proof, targetSystem, preserveMetadata = true } = options
|
|
739
|
+
|
|
740
|
+
// Check if conversion is supported
|
|
741
|
+
if (!this.areSystemsCompatible(proof.metadata.system, targetSystem)) {
|
|
742
|
+
return {
|
|
743
|
+
success: false,
|
|
744
|
+
error: `Conversion from ${proof.metadata.system} to ${targetSystem} not supported`,
|
|
745
|
+
lossless: false,
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// For now, just return the proof with updated metadata
|
|
750
|
+
// Real implementation would perform actual conversion
|
|
751
|
+
const convertedProof: SingleProof = {
|
|
752
|
+
...proof,
|
|
753
|
+
id: generateId('converted'),
|
|
754
|
+
metadata: preserveMetadata
|
|
755
|
+
? {
|
|
756
|
+
...proof.metadata,
|
|
757
|
+
system: targetSystem,
|
|
758
|
+
}
|
|
759
|
+
: {
|
|
760
|
+
system: targetSystem,
|
|
761
|
+
systemVersion: '1.0.0',
|
|
762
|
+
circuitId: proof.metadata.circuitId,
|
|
763
|
+
circuitVersion: proof.metadata.circuitVersion,
|
|
764
|
+
generatedAt: Date.now(),
|
|
765
|
+
proofSizeBytes: proof.metadata.proofSizeBytes,
|
|
766
|
+
},
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return {
|
|
770
|
+
success: true,
|
|
771
|
+
convertedProof,
|
|
772
|
+
lossless: proof.metadata.system === targetSystem,
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
getCompatibilityMatrix(): CompatibilityMatrix {
|
|
777
|
+
const systems: ProofSystem[] = ['noir', 'halo2', 'kimchi', 'groth16', 'plonk']
|
|
778
|
+
const matrix: CompatibilityMatrix = {} as CompatibilityMatrix
|
|
779
|
+
|
|
780
|
+
for (const source of systems) {
|
|
781
|
+
matrix[source] = {} as Record<ProofSystem, SystemCompatibility>
|
|
782
|
+
for (const target of systems) {
|
|
783
|
+
matrix[source][target] = {
|
|
784
|
+
source,
|
|
785
|
+
target,
|
|
786
|
+
conversionSupported: source === target,
|
|
787
|
+
aggregationSupported: source === target,
|
|
788
|
+
notes: source === target ? 'Same system - direct composition' : 'Cross-system not yet implemented',
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
return matrix
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
areSystemsCompatible(source: ProofSystem, target: ProofSystem): boolean {
|
|
797
|
+
// For now, only same-system is compatible
|
|
798
|
+
// Future: add cross-system compatibility
|
|
799
|
+
return source === target
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// ─── Caching ────────────────────────────────────────────────────────────
|
|
803
|
+
|
|
804
|
+
getCacheStats(): CacheStats {
|
|
805
|
+
let totalSize = 0
|
|
806
|
+
for (const entry of this._cache.values()) {
|
|
807
|
+
totalSize += JSON.stringify(entry.proof).length
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
const total = this._cacheHits + this._cacheMisses
|
|
811
|
+
const hitRate = total > 0 ? this._cacheHits / total : 0
|
|
812
|
+
|
|
813
|
+
return {
|
|
814
|
+
entryCount: this._cache.size,
|
|
815
|
+
totalSizeBytes: totalSize,
|
|
816
|
+
hitRate,
|
|
817
|
+
hits: this._cacheHits,
|
|
818
|
+
misses: this._cacheMisses,
|
|
819
|
+
evictions: 0, // Would need tracking
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
clearCache(olderThan?: number): void {
|
|
824
|
+
if (olderThan) {
|
|
825
|
+
for (const [key, entry] of this._cache) {
|
|
826
|
+
if (entry.expiresAt < olderThan) {
|
|
827
|
+
this._cache.delete(key)
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
} else {
|
|
831
|
+
this._cache.clear()
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// ─── Worker Pool ────────────────────────────────────────────────────────
|
|
836
|
+
|
|
837
|
+
getWorkerPoolStatus(): WorkerPoolStatus {
|
|
838
|
+
// Simplified - would need actual worker pool implementation
|
|
839
|
+
return {
|
|
840
|
+
activeWorkers: 0,
|
|
841
|
+
idleWorkers: this._config.maxParallelWorkers,
|
|
842
|
+
queuedTasks: 0,
|
|
843
|
+
processingTasks: 0,
|
|
844
|
+
avgTaskTimeMs: 0,
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
async scaleWorkerPool(targetWorkers: number): Promise<void> {
|
|
849
|
+
this._config.maxParallelWorkers = Math.max(1, targetWorkers)
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// ─── Fallback Configuration ─────────────────────────────────────────────
|
|
853
|
+
|
|
854
|
+
setFallbackConfig(config: FallbackConfig): void {
|
|
855
|
+
this._fallbackConfig = config
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
getFallbackConfig(): FallbackConfig | undefined {
|
|
859
|
+
return this._fallbackConfig
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// ─── Events ─────────────────────────────────────────────────────────────
|
|
863
|
+
|
|
864
|
+
addEventListener(listener: CompositionEventListener): () => void {
|
|
865
|
+
this._eventListeners.add(listener)
|
|
866
|
+
return () => this._eventListeners.delete(listener)
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
removeEventListener(listener: CompositionEventListener): void {
|
|
870
|
+
this._eventListeners.delete(listener)
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
private emitEvent(event: CompositionEvent): void {
|
|
874
|
+
for (const listener of this._eventListeners) {
|
|
875
|
+
try {
|
|
876
|
+
listener(event)
|
|
877
|
+
} catch {
|
|
878
|
+
// Ignore listener errors
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// ─── Telemetry ──────────────────────────────────────────────────────────
|
|
884
|
+
|
|
885
|
+
setTelemetryCollector(collector: TelemetryCollector): void {
|
|
886
|
+
this._telemetryCollector = collector
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
// ─── Lifecycle ──────────────────────────────────────────────────────────
|
|
890
|
+
|
|
891
|
+
async initialize(): Promise<void> {
|
|
892
|
+
if (this._initialized) return
|
|
893
|
+
|
|
894
|
+
// Initialize all registered providers
|
|
895
|
+
const initPromises: Promise<void>[] = []
|
|
896
|
+
for (const provider of this._providers.values()) {
|
|
897
|
+
if (!provider.status.isReady) {
|
|
898
|
+
initPromises.push(provider.initialize())
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
await Promise.all(initPromises)
|
|
903
|
+
this._initialized = true
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
async dispose(): Promise<void> {
|
|
907
|
+
// Dispose all providers
|
|
908
|
+
const disposePromises: Promise<void>[] = []
|
|
909
|
+
for (const provider of this._providers.values()) {
|
|
910
|
+
disposePromises.push(provider.dispose())
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
await Promise.all(disposePromises)
|
|
914
|
+
|
|
915
|
+
// Clear state
|
|
916
|
+
this._providers.clear()
|
|
917
|
+
this._registrations.clear()
|
|
918
|
+
this._systemToProvider.clear()
|
|
919
|
+
this._eventListeners.clear()
|
|
920
|
+
this._cache.clear()
|
|
921
|
+
this._initialized = false
|
|
922
|
+
}
|
|
923
|
+
}
|