@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,717 @@
|
|
|
1
|
+
// src/proofs/providers/halo2.ts
|
|
2
|
+
import { randomBytes, bytesToHex } from "@noble/hashes/utils";
|
|
3
|
+
import {
|
|
4
|
+
ProofAggregationStrategy
|
|
5
|
+
} from "@sip-protocol/types";
|
|
6
|
+
var DEFAULT_HALO2_CONFIG = {
|
|
7
|
+
artifactsPath: "",
|
|
8
|
+
circuits: [],
|
|
9
|
+
verbose: false,
|
|
10
|
+
numThreads: 4,
|
|
11
|
+
enableRecursion: false,
|
|
12
|
+
backend: "wasm"
|
|
13
|
+
};
|
|
14
|
+
var Halo2Provider = class {
|
|
15
|
+
system = "halo2";
|
|
16
|
+
_config;
|
|
17
|
+
_status;
|
|
18
|
+
_capabilities;
|
|
19
|
+
_metrics;
|
|
20
|
+
_circuits = /* @__PURE__ */ new Map();
|
|
21
|
+
_provingKeys = /* @__PURE__ */ new Map();
|
|
22
|
+
_initPromise = null;
|
|
23
|
+
_initError = null;
|
|
24
|
+
constructor(config = {}) {
|
|
25
|
+
this._config = { ...DEFAULT_HALO2_CONFIG, ...config };
|
|
26
|
+
this._metrics = {
|
|
27
|
+
proofsGenerated: 0,
|
|
28
|
+
proofsVerified: 0,
|
|
29
|
+
avgGenerationTimeMs: 0,
|
|
30
|
+
avgVerificationTimeMs: 0,
|
|
31
|
+
successRate: 1,
|
|
32
|
+
memoryUsageBytes: 0
|
|
33
|
+
};
|
|
34
|
+
this._status = {
|
|
35
|
+
isReady: false,
|
|
36
|
+
isBusy: false,
|
|
37
|
+
queueLength: 0,
|
|
38
|
+
metrics: this._metrics
|
|
39
|
+
};
|
|
40
|
+
this._capabilities = {
|
|
41
|
+
system: "halo2",
|
|
42
|
+
supportsRecursion: this._config.enableRecursion,
|
|
43
|
+
supportsBatchVerification: true,
|
|
44
|
+
supportsBrowser: this._config.backend === "wasm",
|
|
45
|
+
supportsNode: true,
|
|
46
|
+
maxProofSize: 10 * 1024 * 1024,
|
|
47
|
+
// 10MB
|
|
48
|
+
supportedStrategies: [
|
|
49
|
+
ProofAggregationStrategy.SEQUENTIAL,
|
|
50
|
+
ProofAggregationStrategy.PARALLEL,
|
|
51
|
+
ProofAggregationStrategy.BATCH,
|
|
52
|
+
...this._config.enableRecursion ? [ProofAggregationStrategy.RECURSIVE] : []
|
|
53
|
+
],
|
|
54
|
+
availableCircuits: []
|
|
55
|
+
};
|
|
56
|
+
for (const circuit of this._config.circuits) {
|
|
57
|
+
this._circuits.set(circuit.id, circuit);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ─── Properties ───────────────────────────────────────────────────────────
|
|
61
|
+
get capabilities() {
|
|
62
|
+
return {
|
|
63
|
+
...this._capabilities,
|
|
64
|
+
availableCircuits: Array.from(this._circuits.keys())
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
get status() {
|
|
68
|
+
return { ...this._status };
|
|
69
|
+
}
|
|
70
|
+
// ─── Lifecycle ────────────────────────────────────────────────────────────
|
|
71
|
+
async initialize() {
|
|
72
|
+
if (this._status.isReady) return;
|
|
73
|
+
if (this._initPromise) {
|
|
74
|
+
return this._initPromise;
|
|
75
|
+
}
|
|
76
|
+
this._initPromise = this.doInitialize();
|
|
77
|
+
return this._initPromise;
|
|
78
|
+
}
|
|
79
|
+
async doInitialize() {
|
|
80
|
+
try {
|
|
81
|
+
if (this._config.verbose) {
|
|
82
|
+
console.log("[Halo2Provider] Initializing...");
|
|
83
|
+
}
|
|
84
|
+
await this.simulateAsyncLoad();
|
|
85
|
+
if (this._config.artifactsPath) {
|
|
86
|
+
await this.loadCircuitArtifacts();
|
|
87
|
+
}
|
|
88
|
+
this._status.isReady = true;
|
|
89
|
+
if (this._config.verbose) {
|
|
90
|
+
console.log("[Halo2Provider] Initialization complete");
|
|
91
|
+
console.log(`[Halo2Provider] Available circuits: ${Array.from(this._circuits.keys()).join(", ")}`);
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
this._initError = error instanceof Error ? error : new Error(String(error));
|
|
95
|
+
this._status.lastError = this._initError.message;
|
|
96
|
+
throw this._initError;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async waitUntilReady(timeoutMs = 3e4) {
|
|
100
|
+
if (this._status.isReady) return;
|
|
101
|
+
if (this._initError) {
|
|
102
|
+
throw this._initError;
|
|
103
|
+
}
|
|
104
|
+
if (!this._initPromise) {
|
|
105
|
+
this._initPromise = this.doInitialize();
|
|
106
|
+
}
|
|
107
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
108
|
+
setTimeout(() => reject(new Error(`Halo2Provider initialization timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
109
|
+
});
|
|
110
|
+
await Promise.race([this._initPromise, timeoutPromise]);
|
|
111
|
+
}
|
|
112
|
+
async dispose() {
|
|
113
|
+
this._provingKeys.clear();
|
|
114
|
+
this._status.isReady = false;
|
|
115
|
+
this._initPromise = null;
|
|
116
|
+
this._initError = null;
|
|
117
|
+
if (this._config.verbose) {
|
|
118
|
+
console.log("[Halo2Provider] Disposed");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ─── Circuit Management ───────────────────────────────────────────────────
|
|
122
|
+
getAvailableCircuits() {
|
|
123
|
+
return Array.from(this._circuits.keys());
|
|
124
|
+
}
|
|
125
|
+
hasCircuit(circuitId) {
|
|
126
|
+
return this._circuits.has(circuitId);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Register a circuit configuration
|
|
130
|
+
*/
|
|
131
|
+
registerCircuit(config) {
|
|
132
|
+
this._circuits.set(config.id, config);
|
|
133
|
+
if (this._config.verbose) {
|
|
134
|
+
console.log(`[Halo2Provider] Registered circuit: ${config.id} (k=${config.k})`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Load proving/verifying keys for a circuit
|
|
139
|
+
*/
|
|
140
|
+
async loadCircuitKeys(circuitId) {
|
|
141
|
+
const circuit = this._circuits.get(circuitId);
|
|
142
|
+
if (!circuit) {
|
|
143
|
+
throw new Error(`Circuit not found: ${circuitId}`);
|
|
144
|
+
}
|
|
145
|
+
const provingKey = {
|
|
146
|
+
circuitId,
|
|
147
|
+
k: circuit.k,
|
|
148
|
+
pkBytes: void 0,
|
|
149
|
+
// Lazy-loaded
|
|
150
|
+
vkBytes: new Uint8Array(64)
|
|
151
|
+
// Placeholder VK
|
|
152
|
+
};
|
|
153
|
+
this._provingKeys.set(circuitId, provingKey);
|
|
154
|
+
if (this._config.verbose) {
|
|
155
|
+
console.log(`[Halo2Provider] Loaded keys for circuit: ${circuitId}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// ─── Proof Generation ─────────────────────────────────────────────────────
|
|
159
|
+
async generateProof(request) {
|
|
160
|
+
const startTime = Date.now();
|
|
161
|
+
if (!this._status.isReady) {
|
|
162
|
+
return {
|
|
163
|
+
success: false,
|
|
164
|
+
error: "Provider not initialized",
|
|
165
|
+
timeMs: Date.now() - startTime,
|
|
166
|
+
providerId: `halo2-${this.generateProviderId()}`
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const circuit = this._circuits.get(request.circuitId);
|
|
170
|
+
if (!circuit) {
|
|
171
|
+
return {
|
|
172
|
+
success: false,
|
|
173
|
+
error: `Circuit not found: ${request.circuitId}`,
|
|
174
|
+
timeMs: Date.now() - startTime,
|
|
175
|
+
providerId: `halo2-${this.generateProviderId()}`
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
this._status.isBusy = true;
|
|
180
|
+
const proof = await this.generateMockProof(request, circuit);
|
|
181
|
+
const timeMs = Date.now() - startTime;
|
|
182
|
+
this._metrics.proofsGenerated++;
|
|
183
|
+
this._metrics.avgGenerationTimeMs = (this._metrics.avgGenerationTimeMs * (this._metrics.proofsGenerated - 1) + timeMs) / this._metrics.proofsGenerated;
|
|
184
|
+
return {
|
|
185
|
+
success: true,
|
|
186
|
+
proof,
|
|
187
|
+
timeMs,
|
|
188
|
+
providerId: `halo2-${this.generateProviderId()}`
|
|
189
|
+
};
|
|
190
|
+
} catch (error) {
|
|
191
|
+
this._metrics.successRate = this._metrics.proofsGenerated > 0 ? (this._metrics.proofsGenerated - 1) / this._metrics.proofsGenerated : 0;
|
|
192
|
+
return {
|
|
193
|
+
success: false,
|
|
194
|
+
error: error instanceof Error ? error.message : "Unknown error during proof generation",
|
|
195
|
+
timeMs: Date.now() - startTime,
|
|
196
|
+
providerId: `halo2-${this.generateProviderId()}`
|
|
197
|
+
};
|
|
198
|
+
} finally {
|
|
199
|
+
this._status.isBusy = false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async generateMockProof(request, circuit) {
|
|
203
|
+
const simulatedTimeMs = Math.min(100 + circuit.k * 10, 2e3);
|
|
204
|
+
await this.delay(simulatedTimeMs);
|
|
205
|
+
const proofBytes = randomBytes(256);
|
|
206
|
+
const proofHex = `0x${bytesToHex(proofBytes)}`;
|
|
207
|
+
const publicInputs = Object.values(request.publicInputs).map((v) => {
|
|
208
|
+
if (typeof v === "string" && v.startsWith("0x")) {
|
|
209
|
+
return v;
|
|
210
|
+
}
|
|
211
|
+
if (typeof v === "bigint" || typeof v === "number") {
|
|
212
|
+
return `0x${v.toString(16).padStart(64, "0")}`;
|
|
213
|
+
}
|
|
214
|
+
return `0x${Buffer.from(String(v)).toString("hex")}`;
|
|
215
|
+
});
|
|
216
|
+
return {
|
|
217
|
+
id: `halo2-proof-${Date.now()}-${randomBytes(4).reduce((a, b) => a + b.toString(16), "")}`,
|
|
218
|
+
proof: proofHex,
|
|
219
|
+
publicInputs,
|
|
220
|
+
metadata: {
|
|
221
|
+
system: "halo2",
|
|
222
|
+
systemVersion: "0.3.0",
|
|
223
|
+
circuitId: circuit.id,
|
|
224
|
+
circuitVersion: "1.0.0",
|
|
225
|
+
generatedAt: Date.now(),
|
|
226
|
+
proofSizeBytes: proofBytes.length,
|
|
227
|
+
verificationCost: BigInt(circuit.k * 1e4)
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// ─── Verification ─────────────────────────────────────────────────────────
|
|
232
|
+
async verifyProof(proof) {
|
|
233
|
+
if (!this._status.isReady) {
|
|
234
|
+
throw new Error("Provider not initialized");
|
|
235
|
+
}
|
|
236
|
+
const startTime = Date.now();
|
|
237
|
+
try {
|
|
238
|
+
const isValid = this.validateProofFormat(proof);
|
|
239
|
+
const timeMs = Date.now() - startTime;
|
|
240
|
+
this._metrics.proofsVerified++;
|
|
241
|
+
this._metrics.avgVerificationTimeMs = (this._metrics.avgVerificationTimeMs * (this._metrics.proofsVerified - 1) + timeMs) / this._metrics.proofsVerified;
|
|
242
|
+
return isValid;
|
|
243
|
+
} catch {
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async verifyBatch(proofs) {
|
|
248
|
+
if (!this._status.isReady) {
|
|
249
|
+
throw new Error("Provider not initialized");
|
|
250
|
+
}
|
|
251
|
+
const results = [];
|
|
252
|
+
for (const proof of proofs) {
|
|
253
|
+
results.push(await this.verifyProof(proof));
|
|
254
|
+
}
|
|
255
|
+
return results;
|
|
256
|
+
}
|
|
257
|
+
validateProofFormat(proof) {
|
|
258
|
+
if (!proof.id || !proof.proof || !proof.metadata) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
if (proof.metadata.system !== "halo2") {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
if (!proof.proof.startsWith("0x")) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
if (proof.metadata.expiresAt && proof.metadata.expiresAt < Date.now()) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
273
|
+
async simulateAsyncLoad() {
|
|
274
|
+
await this.delay(50);
|
|
275
|
+
}
|
|
276
|
+
async loadCircuitArtifacts() {
|
|
277
|
+
if (this._config.verbose) {
|
|
278
|
+
console.log(`[Halo2Provider] Loading artifacts from: ${this._config.artifactsPath}`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
delay(ms) {
|
|
282
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
283
|
+
}
|
|
284
|
+
generateProviderId() {
|
|
285
|
+
return bytesToHex(randomBytes(4));
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
function createHalo2Provider(config) {
|
|
289
|
+
return new Halo2Provider(config);
|
|
290
|
+
}
|
|
291
|
+
function createOrchardProvider() {
|
|
292
|
+
return new Halo2Provider({
|
|
293
|
+
enableRecursion: true,
|
|
294
|
+
circuits: [
|
|
295
|
+
{
|
|
296
|
+
id: "orchard_action",
|
|
297
|
+
name: "Orchard Action Circuit",
|
|
298
|
+
k: 11,
|
|
299
|
+
numColumns: 10,
|
|
300
|
+
numPublicInputs: 5,
|
|
301
|
+
supportsRecursion: true
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
id: "orchard_bundle",
|
|
305
|
+
name: "Orchard Bundle Circuit",
|
|
306
|
+
k: 12,
|
|
307
|
+
numColumns: 12,
|
|
308
|
+
numPublicInputs: 8,
|
|
309
|
+
supportsRecursion: true
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/proofs/providers/kimchi.ts
|
|
316
|
+
import { randomBytes as randomBytes2, bytesToHex as bytesToHex2 } from "@noble/hashes/utils";
|
|
317
|
+
import {
|
|
318
|
+
ProofAggregationStrategy as ProofAggregationStrategy2
|
|
319
|
+
} from "@sip-protocol/types";
|
|
320
|
+
var DEFAULT_KIMCHI_CONFIG = {
|
|
321
|
+
circuits: [],
|
|
322
|
+
verbose: false,
|
|
323
|
+
network: "testnet",
|
|
324
|
+
enablePickles: true,
|
|
325
|
+
cacheDir: "",
|
|
326
|
+
compileWorkers: 2
|
|
327
|
+
};
|
|
328
|
+
var KIMCHI_PROOF_SIZE = 22 * 1024;
|
|
329
|
+
var KIMCHI_VERSION = "1.0.0";
|
|
330
|
+
var KimchiProvider = class {
|
|
331
|
+
system = "kimchi";
|
|
332
|
+
_config;
|
|
333
|
+
_status;
|
|
334
|
+
_capabilities;
|
|
335
|
+
_metrics;
|
|
336
|
+
_circuits = /* @__PURE__ */ new Map();
|
|
337
|
+
_compiledCircuits = /* @__PURE__ */ new Map();
|
|
338
|
+
_initPromise = null;
|
|
339
|
+
_initError = null;
|
|
340
|
+
constructor(config = {}) {
|
|
341
|
+
this._config = { ...DEFAULT_KIMCHI_CONFIG, ...config };
|
|
342
|
+
this._metrics = {
|
|
343
|
+
proofsGenerated: 0,
|
|
344
|
+
proofsVerified: 0,
|
|
345
|
+
avgGenerationTimeMs: 0,
|
|
346
|
+
avgVerificationTimeMs: 0,
|
|
347
|
+
successRate: 1,
|
|
348
|
+
memoryUsageBytes: 0
|
|
349
|
+
};
|
|
350
|
+
this._status = {
|
|
351
|
+
isReady: false,
|
|
352
|
+
isBusy: false,
|
|
353
|
+
queueLength: 0,
|
|
354
|
+
metrics: this._metrics
|
|
355
|
+
};
|
|
356
|
+
this._capabilities = {
|
|
357
|
+
system: "kimchi",
|
|
358
|
+
supportsRecursion: this._config.enablePickles,
|
|
359
|
+
supportsBatchVerification: true,
|
|
360
|
+
supportsBrowser: true,
|
|
361
|
+
supportsNode: true,
|
|
362
|
+
maxProofSize: KIMCHI_PROOF_SIZE * 10,
|
|
363
|
+
// Allow some overhead
|
|
364
|
+
supportedStrategies: [
|
|
365
|
+
ProofAggregationStrategy2.SEQUENTIAL,
|
|
366
|
+
ProofAggregationStrategy2.PARALLEL,
|
|
367
|
+
ProofAggregationStrategy2.BATCH,
|
|
368
|
+
...this._config.enablePickles ? [ProofAggregationStrategy2.RECURSIVE] : []
|
|
369
|
+
],
|
|
370
|
+
availableCircuits: []
|
|
371
|
+
};
|
|
372
|
+
for (const circuit of this._config.circuits) {
|
|
373
|
+
this._circuits.set(circuit.id, circuit);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// ─── Properties ───────────────────────────────────────────────────────────
|
|
377
|
+
get capabilities() {
|
|
378
|
+
return {
|
|
379
|
+
...this._capabilities,
|
|
380
|
+
availableCircuits: Array.from(this._circuits.keys())
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
get status() {
|
|
384
|
+
return { ...this._status };
|
|
385
|
+
}
|
|
386
|
+
// ─── Lifecycle ────────────────────────────────────────────────────────────
|
|
387
|
+
async initialize() {
|
|
388
|
+
if (this._status.isReady) return;
|
|
389
|
+
if (this._initPromise) {
|
|
390
|
+
return this._initPromise;
|
|
391
|
+
}
|
|
392
|
+
this._initPromise = this.doInitialize();
|
|
393
|
+
return this._initPromise;
|
|
394
|
+
}
|
|
395
|
+
async doInitialize() {
|
|
396
|
+
try {
|
|
397
|
+
if (this._config.verbose) {
|
|
398
|
+
console.log("[KimchiProvider] Initializing...");
|
|
399
|
+
console.log(`[KimchiProvider] Network: ${this._config.network}`);
|
|
400
|
+
console.log(`[KimchiProvider] Pickles enabled: ${this._config.enablePickles}`);
|
|
401
|
+
}
|
|
402
|
+
await this.simulateAsyncLoad();
|
|
403
|
+
this._status.isReady = true;
|
|
404
|
+
if (this._config.verbose) {
|
|
405
|
+
console.log("[KimchiProvider] Initialization complete");
|
|
406
|
+
console.log(`[KimchiProvider] Available circuits: ${Array.from(this._circuits.keys()).join(", ") || "none"}`);
|
|
407
|
+
}
|
|
408
|
+
} catch (error) {
|
|
409
|
+
this._initError = error instanceof Error ? error : new Error(String(error));
|
|
410
|
+
this._status.lastError = this._initError.message;
|
|
411
|
+
throw this._initError;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
async waitUntilReady(timeoutMs = 3e4) {
|
|
415
|
+
if (this._status.isReady) return;
|
|
416
|
+
if (this._initError) {
|
|
417
|
+
throw this._initError;
|
|
418
|
+
}
|
|
419
|
+
if (!this._initPromise) {
|
|
420
|
+
this._initPromise = this.doInitialize();
|
|
421
|
+
}
|
|
422
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
423
|
+
setTimeout(() => reject(new Error(`KimchiProvider initialization timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
424
|
+
});
|
|
425
|
+
await Promise.race([this._initPromise, timeoutPromise]);
|
|
426
|
+
}
|
|
427
|
+
async dispose() {
|
|
428
|
+
this._compiledCircuits.clear();
|
|
429
|
+
this._status.isReady = false;
|
|
430
|
+
this._initPromise = null;
|
|
431
|
+
this._initError = null;
|
|
432
|
+
if (this._config.verbose) {
|
|
433
|
+
console.log("[KimchiProvider] Disposed");
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// ─── Circuit Management ───────────────────────────────────────────────────
|
|
437
|
+
getAvailableCircuits() {
|
|
438
|
+
return Array.from(this._circuits.keys());
|
|
439
|
+
}
|
|
440
|
+
hasCircuit(circuitId) {
|
|
441
|
+
return this._circuits.has(circuitId);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Register a circuit configuration
|
|
445
|
+
*/
|
|
446
|
+
registerCircuit(config) {
|
|
447
|
+
this._circuits.set(config.id, config);
|
|
448
|
+
if (this._config.verbose) {
|
|
449
|
+
console.log(`[KimchiProvider] Registered circuit: ${config.id} (${config.gateCount} gates)`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Compile a circuit for proof generation
|
|
454
|
+
*
|
|
455
|
+
* Compiling in Kimchi/o1js creates the verification key and prepares
|
|
456
|
+
* the circuit for proving.
|
|
457
|
+
*/
|
|
458
|
+
async compileCircuit(circuitId) {
|
|
459
|
+
const circuit = this._circuits.get(circuitId);
|
|
460
|
+
if (!circuit) {
|
|
461
|
+
throw new Error(`Circuit not found: ${circuitId}`);
|
|
462
|
+
}
|
|
463
|
+
if (this._config.verbose) {
|
|
464
|
+
console.log(`[KimchiProvider] Compiling circuit: ${circuitId}`);
|
|
465
|
+
}
|
|
466
|
+
await this.delay(100 + circuit.gateCount * 0.1);
|
|
467
|
+
const vkHash = `0x${bytesToHex2(randomBytes2(32))}`;
|
|
468
|
+
this._compiledCircuits.set(circuitId, {
|
|
469
|
+
compiled: true,
|
|
470
|
+
vkHash
|
|
471
|
+
});
|
|
472
|
+
if (this._config.verbose) {
|
|
473
|
+
console.log(`[KimchiProvider] Circuit compiled: ${circuitId}, vkHash: ${vkHash.slice(0, 18)}...`);
|
|
474
|
+
}
|
|
475
|
+
return vkHash;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Check if a circuit is compiled
|
|
479
|
+
*/
|
|
480
|
+
isCircuitCompiled(circuitId) {
|
|
481
|
+
return this._compiledCircuits.get(circuitId)?.compiled === true;
|
|
482
|
+
}
|
|
483
|
+
// ─── Proof Generation ─────────────────────────────────────────────────────
|
|
484
|
+
async generateProof(request) {
|
|
485
|
+
const startTime = Date.now();
|
|
486
|
+
if (!this._status.isReady) {
|
|
487
|
+
return {
|
|
488
|
+
success: false,
|
|
489
|
+
error: "Provider not initialized",
|
|
490
|
+
timeMs: Date.now() - startTime,
|
|
491
|
+
providerId: `kimchi-${this.generateProviderId()}`
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
const circuit = this._circuits.get(request.circuitId);
|
|
495
|
+
if (!circuit) {
|
|
496
|
+
return {
|
|
497
|
+
success: false,
|
|
498
|
+
error: `Circuit not found: ${request.circuitId}`,
|
|
499
|
+
timeMs: Date.now() - startTime,
|
|
500
|
+
providerId: `kimchi-${this.generateProviderId()}`
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
try {
|
|
504
|
+
this._status.isBusy = true;
|
|
505
|
+
if (!this.isCircuitCompiled(request.circuitId)) {
|
|
506
|
+
await this.compileCircuit(request.circuitId);
|
|
507
|
+
}
|
|
508
|
+
const proof = await this.generateMockProof(request, circuit);
|
|
509
|
+
const timeMs = Date.now() - startTime;
|
|
510
|
+
this._metrics.proofsGenerated++;
|
|
511
|
+
this._metrics.avgGenerationTimeMs = (this._metrics.avgGenerationTimeMs * (this._metrics.proofsGenerated - 1) + timeMs) / this._metrics.proofsGenerated;
|
|
512
|
+
return {
|
|
513
|
+
success: true,
|
|
514
|
+
proof,
|
|
515
|
+
timeMs,
|
|
516
|
+
providerId: `kimchi-${this.generateProviderId()}`
|
|
517
|
+
};
|
|
518
|
+
} catch (error) {
|
|
519
|
+
this._metrics.successRate = this._metrics.proofsGenerated > 0 ? (this._metrics.proofsGenerated - 1) / this._metrics.proofsGenerated : 0;
|
|
520
|
+
return {
|
|
521
|
+
success: false,
|
|
522
|
+
error: error instanceof Error ? error.message : "Unknown error during proof generation",
|
|
523
|
+
timeMs: Date.now() - startTime,
|
|
524
|
+
providerId: `kimchi-${this.generateProviderId()}`
|
|
525
|
+
};
|
|
526
|
+
} finally {
|
|
527
|
+
this._status.isBusy = false;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
async generateMockProof(request, circuit) {
|
|
531
|
+
const simulatedTimeMs = Math.min(200 + circuit.gateCount * 0.5, 5e3);
|
|
532
|
+
await this.delay(simulatedTimeMs);
|
|
533
|
+
const proofBytes = randomBytes2(KIMCHI_PROOF_SIZE);
|
|
534
|
+
const proofHex = `0x${bytesToHex2(proofBytes)}`;
|
|
535
|
+
const publicInputs = Object.values(request.publicInputs).map((v) => {
|
|
536
|
+
if (typeof v === "string" && v.startsWith("0x")) {
|
|
537
|
+
return v;
|
|
538
|
+
}
|
|
539
|
+
if (typeof v === "bigint" || typeof v === "number") {
|
|
540
|
+
return `0x${v.toString(16).padStart(64, "0")}`;
|
|
541
|
+
}
|
|
542
|
+
return `0x${Buffer.from(String(v)).toString("hex")}`;
|
|
543
|
+
});
|
|
544
|
+
const vkHash = this._compiledCircuits.get(request.circuitId)?.vkHash;
|
|
545
|
+
return {
|
|
546
|
+
id: `kimchi-proof-${Date.now()}-${randomBytes2(4).reduce((a, b) => a + b.toString(16), "")}`,
|
|
547
|
+
proof: proofHex,
|
|
548
|
+
publicInputs,
|
|
549
|
+
verificationKey: vkHash,
|
|
550
|
+
metadata: {
|
|
551
|
+
system: "kimchi",
|
|
552
|
+
systemVersion: KIMCHI_VERSION,
|
|
553
|
+
circuitId: circuit.id,
|
|
554
|
+
circuitVersion: "1.0.0",
|
|
555
|
+
generatedAt: Date.now(),
|
|
556
|
+
proofSizeBytes: KIMCHI_PROOF_SIZE,
|
|
557
|
+
verificationCost: BigInt(Math.ceil(circuit.gateCount / 10)),
|
|
558
|
+
targetChainId: this._config.network === "mainnet" ? "mina:mainnet" : "mina:testnet"
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
// ─── Verification ─────────────────────────────────────────────────────────
|
|
563
|
+
async verifyProof(proof) {
|
|
564
|
+
if (!this._status.isReady) {
|
|
565
|
+
throw new Error("Provider not initialized");
|
|
566
|
+
}
|
|
567
|
+
const startTime = Date.now();
|
|
568
|
+
try {
|
|
569
|
+
const isValid = this.validateProofFormat(proof);
|
|
570
|
+
const timeMs = Date.now() - startTime;
|
|
571
|
+
this._metrics.proofsVerified++;
|
|
572
|
+
this._metrics.avgVerificationTimeMs = (this._metrics.avgVerificationTimeMs * (this._metrics.proofsVerified - 1) + timeMs) / this._metrics.proofsVerified;
|
|
573
|
+
return isValid;
|
|
574
|
+
} catch {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
async verifyBatch(proofs) {
|
|
579
|
+
if (!this._status.isReady) {
|
|
580
|
+
throw new Error("Provider not initialized");
|
|
581
|
+
}
|
|
582
|
+
const results = [];
|
|
583
|
+
for (const proof of proofs) {
|
|
584
|
+
results.push(await this.verifyProof(proof));
|
|
585
|
+
}
|
|
586
|
+
return results;
|
|
587
|
+
}
|
|
588
|
+
validateProofFormat(proof) {
|
|
589
|
+
if (!proof.id || !proof.proof || !proof.metadata) {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
if (proof.metadata.system !== "kimchi") {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
if (!proof.proof.startsWith("0x")) {
|
|
596
|
+
return false;
|
|
597
|
+
}
|
|
598
|
+
const proofBytes = (proof.proof.length - 2) / 2;
|
|
599
|
+
if (proofBytes < KIMCHI_PROOF_SIZE * 0.5 || proofBytes > KIMCHI_PROOF_SIZE * 2) {
|
|
600
|
+
if (this._config.verbose) {
|
|
601
|
+
console.warn(`[KimchiProvider] Unusual proof size: ${proofBytes} bytes (expected ~${KIMCHI_PROOF_SIZE})`);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
if (proof.metadata.expiresAt && proof.metadata.expiresAt < Date.now()) {
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
// ─── Recursive Proving (Pickles) ──────────────────────────────────────────
|
|
610
|
+
/**
|
|
611
|
+
* Check if Pickles recursive proving is available
|
|
612
|
+
*/
|
|
613
|
+
supportsRecursion() {
|
|
614
|
+
return this._config.enablePickles;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Merge multiple proofs recursively using Pickles
|
|
618
|
+
*
|
|
619
|
+
* This enables constant-size proofs regardless of how many
|
|
620
|
+
* proofs are combined.
|
|
621
|
+
*/
|
|
622
|
+
async mergeProofsRecursively(proofs) {
|
|
623
|
+
if (!this._config.enablePickles) {
|
|
624
|
+
if (this._config.verbose) {
|
|
625
|
+
console.warn("[KimchiProvider] Pickles not enabled for recursive merging");
|
|
626
|
+
}
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
if (proofs.length === 0) {
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
if (proofs.length === 1) {
|
|
633
|
+
return proofs[0];
|
|
634
|
+
}
|
|
635
|
+
if (this._config.verbose) {
|
|
636
|
+
console.log(`[KimchiProvider] Merging ${proofs.length} proofs recursively`);
|
|
637
|
+
}
|
|
638
|
+
await this.delay(proofs.length * 100);
|
|
639
|
+
const mergedProofBytes = randomBytes2(KIMCHI_PROOF_SIZE);
|
|
640
|
+
const combinedInputs = proofs.flatMap((p) => p.publicInputs);
|
|
641
|
+
return {
|
|
642
|
+
id: `kimchi-merged-${Date.now()}`,
|
|
643
|
+
proof: `0x${bytesToHex2(mergedProofBytes)}`,
|
|
644
|
+
publicInputs: combinedInputs.slice(0, 10),
|
|
645
|
+
// Limit public inputs
|
|
646
|
+
metadata: {
|
|
647
|
+
system: "kimchi",
|
|
648
|
+
systemVersion: KIMCHI_VERSION,
|
|
649
|
+
circuitId: "pickles_merge",
|
|
650
|
+
circuitVersion: "1.0.0",
|
|
651
|
+
generatedAt: Date.now(),
|
|
652
|
+
proofSizeBytes: KIMCHI_PROOF_SIZE
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
657
|
+
async simulateAsyncLoad() {
|
|
658
|
+
await this.delay(50);
|
|
659
|
+
}
|
|
660
|
+
delay(ms) {
|
|
661
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
662
|
+
}
|
|
663
|
+
generateProviderId() {
|
|
664
|
+
return bytesToHex2(randomBytes2(4));
|
|
665
|
+
}
|
|
666
|
+
};
|
|
667
|
+
function createKimchiProvider(config) {
|
|
668
|
+
return new KimchiProvider(config);
|
|
669
|
+
}
|
|
670
|
+
function createMinaMainnetProvider() {
|
|
671
|
+
return new KimchiProvider({
|
|
672
|
+
network: "mainnet",
|
|
673
|
+
enablePickles: true,
|
|
674
|
+
circuits: [
|
|
675
|
+
{
|
|
676
|
+
id: "token_transfer",
|
|
677
|
+
name: "Token Transfer Circuit",
|
|
678
|
+
gateCount: 5e3,
|
|
679
|
+
publicInputCount: 4,
|
|
680
|
+
usesRecursion: false
|
|
681
|
+
},
|
|
682
|
+
{
|
|
683
|
+
id: "state_update",
|
|
684
|
+
name: "State Update Circuit",
|
|
685
|
+
gateCount: 8e3,
|
|
686
|
+
publicInputCount: 6,
|
|
687
|
+
usesRecursion: true
|
|
688
|
+
}
|
|
689
|
+
]
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
function createZkAppProvider(network = "testnet") {
|
|
693
|
+
return new KimchiProvider({
|
|
694
|
+
network,
|
|
695
|
+
enablePickles: true,
|
|
696
|
+
verbose: network === "local",
|
|
697
|
+
circuits: [
|
|
698
|
+
{
|
|
699
|
+
id: "zkapp_method",
|
|
700
|
+
name: "zkApp Method Circuit",
|
|
701
|
+
gateCount: 3e3,
|
|
702
|
+
publicInputCount: 3,
|
|
703
|
+
usesRecursion: false
|
|
704
|
+
}
|
|
705
|
+
]
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
export {
|
|
710
|
+
Halo2Provider,
|
|
711
|
+
createHalo2Provider,
|
|
712
|
+
createOrchardProvider,
|
|
713
|
+
KimchiProvider,
|
|
714
|
+
createKimchiProvider,
|
|
715
|
+
createMinaMainnetProvider,
|
|
716
|
+
createZkAppProvider
|
|
717
|
+
};
|