dop-wallet-v6 1.3.40 → 1.3.41
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/dist/services/dop/core/prover.d.ts +7 -0
- package/dist/services/dop/core/prover.js +6 -48
- package/dist/services/dop/core/prover.js.map +1 -1
- package/dist/services/dop/crypto/index.d.ts +1 -1
- package/dist/services/dop/crypto/index.js +23 -17
- package/dist/services/dop/crypto/index.js.map +1 -1
- package/dist/services/dop/crypto/wcd-prover.d.ts +242 -0
- package/dist/services/dop/crypto/wcd-prover.js +499 -0
- package/dist/services/dop/crypto/wcd-prover.js.map +1 -0
- package/package.json +1 -1
- package/dist/services/dop/crypto/custom-prover.d.ts +0 -78
- package/dist/services/dop/crypto/custom-prover.js +0 -78
- package/dist/services/dop/crypto/custom-prover.js.map +0 -1
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { FormattedCircuitInputsDop, SnarkJSGroth16, Proof, Prover } from 'dop-engine-v3';
|
|
2
|
+
/**
|
|
3
|
+
* Get the prover instance from DOP Engine
|
|
4
|
+
*
|
|
5
|
+
* Note: For React Native, use setWCDProver() from crypto/wcd-prover.ts
|
|
6
|
+
* which automatically intercepts the prover to use WCD-based proof generation.
|
|
7
|
+
* This is the recommended approach for mobile.
|
|
8
|
+
*/
|
|
2
9
|
export declare const getProver: () => Prover;
|
|
3
10
|
export { FormattedCircuitInputsDop, Proof, SnarkJSGroth16 };
|
|
@@ -3,61 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getProver = void 0;
|
|
4
4
|
const engine_1 = require("./engine");
|
|
5
5
|
const dop_sharedmodels_v3_1 = require("dop-sharedmodels-v3");
|
|
6
|
-
const custom_prover_1 = require("../crypto/custom-prover");
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* Get the prover instance from DOP Engine
|
|
8
|
+
*
|
|
9
|
+
* Note: For React Native, use setWCDProver() from crypto/wcd-prover.ts
|
|
10
|
+
* which automatically intercepts the prover to use WCD-based proof generation.
|
|
11
|
+
* This is the recommended approach for mobile.
|
|
10
12
|
*/
|
|
11
|
-
function getCircuitIdFromInputs(formattedInputs) {
|
|
12
|
-
// Count nullifiers (non-zero entries)
|
|
13
|
-
const nullifierCount = formattedInputs.nullifiers?.filter((n) => n !== undefined && n !== null && BigInt(n) !== BigInt(0)).length || 0;
|
|
14
|
-
// Count commitments (non-zero entries)
|
|
15
|
-
const commitmentCount = formattedInputs.commitmentsOut?.filter((c) => c !== undefined && c !== null && BigInt(c) !== BigInt(0)).length || 0;
|
|
16
|
-
return `${nullifierCount}x${commitmentCount}`;
|
|
17
|
-
}
|
|
18
|
-
let proverIntercepted = false;
|
|
19
13
|
const getProver = () => {
|
|
20
14
|
const engine = (0, engine_1.getEngine)();
|
|
21
15
|
if (!(0, dop_sharedmodels_v3_1.isDefined)(engine)) {
|
|
22
16
|
throw new Error('DOP Engine not yet init. Please reload your app or try again.');
|
|
23
17
|
}
|
|
24
|
-
|
|
25
|
-
// Intercept groth16.fullProveDop only once
|
|
26
|
-
if (!proverIntercepted && prover.groth16) {
|
|
27
|
-
proverIntercepted = true;
|
|
28
|
-
const originalFullProveDop = prover.groth16.fullProveDop;
|
|
29
|
-
// Wrap fullProveDop to check for custom prover
|
|
30
|
-
prover.groth16.fullProveDop = async (formattedInputs, wasm, zkey, logger, dat, progressCallback) => {
|
|
31
|
-
// Check if custom prover is available
|
|
32
|
-
if ((0, custom_prover_1.hasCustomRapidsnarkProver)()) {
|
|
33
|
-
const customProver = (0, custom_prover_1.getCustomRapidsnarkProver)();
|
|
34
|
-
if (!customProver) {
|
|
35
|
-
throw new Error('Custom prover is null');
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
// Determine circuit ID from inputs
|
|
39
|
-
const circuitId = getCircuitIdFromInputs(formattedInputs);
|
|
40
|
-
logger.debug(`[Custom Prover] Using custom prover for circuit ${circuitId}`);
|
|
41
|
-
// Call custom prover (e.g., backend server)
|
|
42
|
-
const proof = await customProver.generateProof(circuitId, new Uint8Array(zkey), formattedInputs, progressCallback);
|
|
43
|
-
logger.debug(`[Custom Prover] Proof generated successfully via custom prover`);
|
|
44
|
-
// Return in expected format
|
|
45
|
-
return {
|
|
46
|
-
proof,
|
|
47
|
-
publicSignals: proof.publicSignals ?? []
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
52
|
-
logger.debug(`[Custom Prover] Error: ${errorMessage}`);
|
|
53
|
-
throw error;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// No custom prover - use original implementation
|
|
57
|
-
return originalFullProveDop(formattedInputs, wasm, zkey, logger, dat, progressCallback);
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
return prover;
|
|
18
|
+
return engine.prover;
|
|
61
19
|
};
|
|
62
20
|
exports.getProver = getProver;
|
|
63
21
|
//# sourceMappingURL=prover.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prover.js","sourceRoot":"","sources":["../../../../src/services/dop/core/prover.ts"],"names":[],"mappings":";;;AAMA,qCAAqC;AACrC,6DAAgD;
|
|
1
|
+
{"version":3,"file":"prover.js","sourceRoot":"","sources":["../../../../src/services/dop/core/prover.ts"],"names":[],"mappings":";;;AAMA,qCAAqC;AACrC,6DAAgD;AAEhD;;;;;;GAMG;AACI,MAAM,SAAS,GAAG,GAAW,EAAE;IACpC,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;IAC3B,IAAI,CAAC,IAAA,+BAAS,EAAC,MAAM,CAAC,EAAE;QACtB,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;KACH;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC,CAAC;AATW,QAAA,SAAS,aASpB","sourcesContent":["import {\n FormattedCircuitInputsDop,\n SnarkJSGroth16,\n Proof,\n Prover,\n} from 'dop-engine-v3';\nimport { getEngine } from './engine';\nimport { isDefined } from 'dop-sharedmodels-v3';\n\n/**\n * Get the prover instance from DOP Engine\n * \n * Note: For React Native, use setWCDProver() from crypto/wcd-prover.ts\n * which automatically intercepts the prover to use WCD-based proof generation.\n * This is the recommended approach for mobile.\n */\nexport const getProver = (): Prover => {\n const engine = getEngine();\n if (!isDefined(engine)) {\n throw new Error(\n 'DOP Engine not yet init. Please reload your app or try again.',\n );\n }\n \n return engine.prover;\n};\n\nexport { FormattedCircuitInputsDop, Proof, SnarkJSGroth16 };\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './custom-prover';
|
|
2
1
|
export { setRapidSnarkGroth16, type RapidSnarkGroth16Config, type RapidsnarkProofResult, type WitnessCalculator, type FileSystemInterface, type Groth16ProveFunction, createCircomWitnessCalculator, createReactNativeFSInterface, } from './rapidsnark-groth16';
|
|
3
2
|
export { setReactNativeProver, getReactNativeProver, type ReactNativeProverConfig, type RNFileSystem, type RNGroth16ProveFunction, type RNGroth16VerifyFunction, type RNRapidsnarkProofResult, type WitnessResult, type StoredCircuitArtifacts, CircuitArtifactManager, uint8ArrayToBase64, base64ToUint8Array, calculateWitnessFromWASM, createRNFSInterface, createExpoFSInterface, type RNArtifactStore, createRNArtifactStore, getRNArtifactPath, hasRNArtifacts, } from './react-native-prover';
|
|
3
|
+
export { setWCDProver, clearWCDProver, hasWCDProver, getWCDProverConfig, type WCDProverConfig, type WCDFileSystem, type WCDCalculateWitnessFunction, type WCDGroth16ProveFunction, type WCDRapidsnarkProofResult, type WCDArtifacts, WCDArtifactManager, createWCDArtifactManager, storeWCDArtifacts, hasWCDArtifacts, getWCDPath, getZkeyPathForWCD, storeWCDOnly, hasWCDFile, wcdUint8ArrayToBase64, wcdBase64ToUint8Array, } from './wcd-prover';
|
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.hasRNArtifacts = exports.getRNArtifactPath = exports.createRNArtifactStore = exports.createExpoFSInterface = exports.createRNFSInterface = exports.calculateWitnessFromWASM = exports.base64ToUint8Array = exports.uint8ArrayToBase64 = exports.CircuitArtifactManager = exports.getReactNativeProver = exports.setReactNativeProver = exports.createReactNativeFSInterface = exports.createCircomWitnessCalculator = exports.setRapidSnarkGroth16 = void 0;
|
|
18
|
-
__exportStar(require("./custom-prover"), exports);
|
|
3
|
+
exports.wcdBase64ToUint8Array = exports.wcdUint8ArrayToBase64 = exports.hasWCDFile = exports.storeWCDOnly = exports.getZkeyPathForWCD = exports.getWCDPath = exports.hasWCDArtifacts = exports.storeWCDArtifacts = exports.createWCDArtifactManager = exports.WCDArtifactManager = exports.getWCDProverConfig = exports.hasWCDProver = exports.clearWCDProver = exports.setWCDProver = exports.hasRNArtifacts = exports.getRNArtifactPath = exports.createRNArtifactStore = exports.createExpoFSInterface = exports.createRNFSInterface = exports.calculateWitnessFromWASM = exports.base64ToUint8Array = exports.uint8ArrayToBase64 = exports.CircuitArtifactManager = exports.getReactNativeProver = exports.setReactNativeProver = exports.createReactNativeFSInterface = exports.createCircomWitnessCalculator = exports.setRapidSnarkGroth16 = void 0;
|
|
19
4
|
// Export from rapidsnark-groth16 (legacy API, requires WitnessCalculator to be provided)
|
|
20
5
|
var rapidsnark_groth16_1 = require("./rapidsnark-groth16");
|
|
21
6
|
Object.defineProperty(exports, "setRapidSnarkGroth16", { enumerable: true, get: function () { return rapidsnark_groth16_1.setRapidSnarkGroth16; } });
|
|
22
7
|
Object.defineProperty(exports, "createCircomWitnessCalculator", { enumerable: true, get: function () { return rapidsnark_groth16_1.createCircomWitnessCalculator; } });
|
|
23
8
|
Object.defineProperty(exports, "createReactNativeFSInterface", { enumerable: true, get: function () { return rapidsnark_groth16_1.createReactNativeFSInterface; } });
|
|
24
|
-
// Export from react-native-prover (
|
|
9
|
+
// Export from react-native-prover (WASM-based API, handles everything internally)
|
|
25
10
|
var react_native_prover_1 = require("./react-native-prover");
|
|
26
11
|
// Main prover setup
|
|
27
12
|
Object.defineProperty(exports, "setReactNativeProver", { enumerable: true, get: function () { return react_native_prover_1.setReactNativeProver; } });
|
|
@@ -37,4 +22,25 @@ Object.defineProperty(exports, "createExpoFSInterface", { enumerable: true, get:
|
|
|
37
22
|
Object.defineProperty(exports, "createRNArtifactStore", { enumerable: true, get: function () { return react_native_prover_1.createRNArtifactStore; } });
|
|
38
23
|
Object.defineProperty(exports, "getRNArtifactPath", { enumerable: true, get: function () { return react_native_prover_1.getRNArtifactPath; } });
|
|
39
24
|
Object.defineProperty(exports, "hasRNArtifacts", { enumerable: true, get: function () { return react_native_prover_1.hasRNArtifacts; } });
|
|
25
|
+
// Export from wcd-prover (RECOMMENDED for React Native - uses .wcd graph files)
|
|
26
|
+
// This is the fastest approach for mobile witness calculation
|
|
27
|
+
var wcd_prover_1 = require("./wcd-prover");
|
|
28
|
+
// Main prover setup
|
|
29
|
+
Object.defineProperty(exports, "setWCDProver", { enumerable: true, get: function () { return wcd_prover_1.setWCDProver; } });
|
|
30
|
+
Object.defineProperty(exports, "clearWCDProver", { enumerable: true, get: function () { return wcd_prover_1.clearWCDProver; } });
|
|
31
|
+
Object.defineProperty(exports, "hasWCDProver", { enumerable: true, get: function () { return wcd_prover_1.hasWCDProver; } });
|
|
32
|
+
Object.defineProperty(exports, "getWCDProverConfig", { enumerable: true, get: function () { return wcd_prover_1.getWCDProverConfig; } });
|
|
33
|
+
// Artifact management
|
|
34
|
+
Object.defineProperty(exports, "WCDArtifactManager", { enumerable: true, get: function () { return wcd_prover_1.WCDArtifactManager; } });
|
|
35
|
+
Object.defineProperty(exports, "createWCDArtifactManager", { enumerable: true, get: function () { return wcd_prover_1.createWCDArtifactManager; } });
|
|
36
|
+
Object.defineProperty(exports, "storeWCDArtifacts", { enumerable: true, get: function () { return wcd_prover_1.storeWCDArtifacts; } });
|
|
37
|
+
Object.defineProperty(exports, "hasWCDArtifacts", { enumerable: true, get: function () { return wcd_prover_1.hasWCDArtifacts; } });
|
|
38
|
+
Object.defineProperty(exports, "getWCDPath", { enumerable: true, get: function () { return wcd_prover_1.getWCDPath; } });
|
|
39
|
+
Object.defineProperty(exports, "getZkeyPathForWCD", { enumerable: true, get: function () { return wcd_prover_1.getZkeyPathForWCD; } });
|
|
40
|
+
// WCD-only management (SDK handles zkey automatically)
|
|
41
|
+
Object.defineProperty(exports, "storeWCDOnly", { enumerable: true, get: function () { return wcd_prover_1.storeWCDOnly; } });
|
|
42
|
+
Object.defineProperty(exports, "hasWCDFile", { enumerable: true, get: function () { return wcd_prover_1.hasWCDFile; } });
|
|
43
|
+
// Utility functions
|
|
44
|
+
Object.defineProperty(exports, "wcdUint8ArrayToBase64", { enumerable: true, get: function () { return wcd_prover_1.wcdUint8ArrayToBase64; } });
|
|
45
|
+
Object.defineProperty(exports, "wcdBase64ToUint8Array", { enumerable: true, get: function () { return wcd_prover_1.wcdBase64ToUint8Array; } });
|
|
40
46
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/dop/crypto/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/dop/crypto/index.ts"],"names":[],"mappings":";;;AAAA,yFAAyF;AACzF,2DAS8B;AAR5B,0HAAA,oBAAoB,OAAA;AAMpB,mIAAA,6BAA6B,OAAA;AAC7B,kIAAA,4BAA4B,OAAA;AAG9B,kFAAkF;AAClF,6DAwB+B;AAvB7B,oBAAoB;AACpB,2HAAA,oBAAoB,OAAA;AACpB,2HAAA,oBAAoB,OAAA;AAQpB,6HAAA,sBAAsB,OAAA;AACtB,oBAAoB;AACpB,yHAAA,kBAAkB,OAAA;AAClB,yHAAA,kBAAkB,OAAA;AAClB,+HAAA,wBAAwB,OAAA;AACxB,sBAAsB;AACtB,0HAAA,mBAAmB,OAAA;AACnB,4HAAA,qBAAqB,OAAA;AAGrB,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AACjB,qHAAA,cAAc,OAAA;AAGhB,gFAAgF;AAChF,8DAA8D;AAC9D,2CAyBsB;AAxBpB,oBAAoB;AACpB,0GAAA,YAAY,OAAA;AACZ,4GAAA,cAAc,OAAA;AACd,0GAAA,YAAY,OAAA;AACZ,gHAAA,kBAAkB,OAAA;AAOlB,sBAAsB;AACtB,gHAAA,kBAAkB,OAAA;AAClB,sHAAA,wBAAwB,OAAA;AACxB,+GAAA,iBAAiB,OAAA;AACjB,6GAAA,eAAe,OAAA;AACf,wGAAA,UAAU,OAAA;AACV,+GAAA,iBAAiB,OAAA;AACjB,uDAAuD;AACvD,0GAAA,YAAY,OAAA;AACZ,wGAAA,UAAU,OAAA;AACV,oBAAoB;AACpB,mHAAA,qBAAqB,OAAA;AACrB,mHAAA,qBAAqB,OAAA","sourcesContent":["// Export from rapidsnark-groth16 (legacy API, requires WitnessCalculator to be provided)\nexport {\n setRapidSnarkGroth16,\n type RapidSnarkGroth16Config,\n type RapidsnarkProofResult,\n type WitnessCalculator,\n type FileSystemInterface,\n type Groth16ProveFunction,\n createCircomWitnessCalculator,\n createReactNativeFSInterface,\n} from './rapidsnark-groth16';\n\n// Export from react-native-prover (WASM-based API, handles everything internally)\nexport {\n // Main prover setup\n setReactNativeProver,\n getReactNativeProver,\n type ReactNativeProverConfig,\n type RNFileSystem,\n type RNGroth16ProveFunction,\n type RNGroth16VerifyFunction,\n type RNRapidsnarkProofResult,\n type WitnessResult,\n type StoredCircuitArtifacts,\n CircuitArtifactManager,\n // Utility functions\n uint8ArrayToBase64,\n base64ToUint8Array,\n calculateWitnessFromWASM,\n // File system helpers\n createRNFSInterface,\n createExpoFSInterface,\n // Artifact store for SDK integration\n type RNArtifactStore,\n createRNArtifactStore,\n getRNArtifactPath,\n hasRNArtifacts,\n} from './react-native-prover';\n\n// Export from wcd-prover (RECOMMENDED for React Native - uses .wcd graph files)\n// This is the fastest approach for mobile witness calculation\nexport {\n // Main prover setup\n setWCDProver,\n clearWCDProver,\n hasWCDProver,\n getWCDProverConfig,\n type WCDProverConfig,\n type WCDFileSystem,\n type WCDCalculateWitnessFunction,\n type WCDGroth16ProveFunction,\n type WCDRapidsnarkProofResult,\n type WCDArtifacts,\n // Artifact management\n WCDArtifactManager,\n createWCDArtifactManager,\n storeWCDArtifacts,\n hasWCDArtifacts,\n getWCDPath,\n getZkeyPathForWCD,\n // WCD-only management (SDK handles zkey automatically)\n storeWCDOnly,\n hasWCDFile,\n // Utility functions\n wcdUint8ArrayToBase64,\n wcdBase64ToUint8Array,\n} from './wcd-prover';\n"]}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native WCD Prover - Using circom-witnesscalc .wcd files
|
|
3
|
+
*
|
|
4
|
+
* This module provides witness calculation using pre-compiled .wcd graph files
|
|
5
|
+
* from iden3/circom-witnesscalc. This is the recommended approach for React Native
|
|
6
|
+
* as it provides fast, native witness calculation without WASM overhead.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. Load .wcd graph file for the circuit
|
|
10
|
+
* 2. Use @iden3/react-native-circom-witnesscalc to calculate witness
|
|
11
|
+
* 3. Use react-native-rapidsnark to generate proof
|
|
12
|
+
*
|
|
13
|
+
* Benefits over WASM approach:
|
|
14
|
+
* - Faster witness calculation (native code)
|
|
15
|
+
* - No WASM runtime needed
|
|
16
|
+
* - Smaller memory footprint
|
|
17
|
+
* - Better mobile performance
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Result from rapidsnark groth16Prove
|
|
21
|
+
*/
|
|
22
|
+
export interface WCDRapidsnarkProofResult {
|
|
23
|
+
proof: {
|
|
24
|
+
a: string[];
|
|
25
|
+
b: string[][];
|
|
26
|
+
c: string[];
|
|
27
|
+
};
|
|
28
|
+
pub_signals: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Rapidsnark's groth16Prove function signature
|
|
32
|
+
*/
|
|
33
|
+
export type WCDGroth16ProveFunction = (zkeyPath: string, witnessBase64: string) => Promise<WCDRapidsnarkProofResult>;
|
|
34
|
+
/**
|
|
35
|
+
* circom-witnesscalc's calculateWitness function signature
|
|
36
|
+
* From: import { calculateWitness } from '@iden3/react-native-circom-witnesscalc'
|
|
37
|
+
*/
|
|
38
|
+
export type WCDCalculateWitnessFunction = (inputsJson: string, graphBase64: string) => Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* File system interface for React Native
|
|
41
|
+
*/
|
|
42
|
+
export interface WCDFileSystem {
|
|
43
|
+
writeFile(path: string, data: string, encoding: 'base64' | 'utf8'): Promise<void>;
|
|
44
|
+
readFile(path: string, encoding: 'base64' | 'utf8'): Promise<string>;
|
|
45
|
+
exists(path: string): Promise<boolean>;
|
|
46
|
+
unlink(path: string): Promise<void>;
|
|
47
|
+
mkdir(path: string): Promise<void>;
|
|
48
|
+
documentDirectory: string;
|
|
49
|
+
cacheDirectory: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Configuration for WCD-based React Native Prover
|
|
53
|
+
*/
|
|
54
|
+
export interface WCDProverConfig {
|
|
55
|
+
/**
|
|
56
|
+
* circom-witnesscalc's calculateWitness function
|
|
57
|
+
* Import: import { calculateWitness } from '@iden3/react-native-circom-witnesscalc'
|
|
58
|
+
*/
|
|
59
|
+
calculateWitness: WCDCalculateWitnessFunction;
|
|
60
|
+
/**
|
|
61
|
+
* Rapidsnark's groth16Prove function
|
|
62
|
+
* Import: import { groth16Prove } from 'react-native-rapidsnark'
|
|
63
|
+
*/
|
|
64
|
+
groth16Prove: WCDGroth16ProveFunction;
|
|
65
|
+
/**
|
|
66
|
+
* File system interface (react-native-fs or expo-file-system)
|
|
67
|
+
*/
|
|
68
|
+
fs: WCDFileSystem;
|
|
69
|
+
/**
|
|
70
|
+
* Base directory where .wcd files are stored
|
|
71
|
+
* Default: fs.documentDirectory + '/dop-wcd'
|
|
72
|
+
*/
|
|
73
|
+
wcdDirectory?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Base directory where .zkey files are stored
|
|
76
|
+
* Default: fs.documentDirectory + '/dop-zkeys'
|
|
77
|
+
*/
|
|
78
|
+
zkeyDirectory?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Enable debug logging
|
|
81
|
+
*/
|
|
82
|
+
debug?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Stored WCD artifacts info
|
|
86
|
+
*/
|
|
87
|
+
export interface WCDArtifacts {
|
|
88
|
+
wcdPath: string;
|
|
89
|
+
zkeyPath: string;
|
|
90
|
+
vkeyPath?: string;
|
|
91
|
+
circuitId: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Convert Uint8Array to base64 string
|
|
95
|
+
*/
|
|
96
|
+
export declare function wcdUint8ArrayToBase64(data: Uint8Array): string;
|
|
97
|
+
/**
|
|
98
|
+
* Convert base64 string to Uint8Array
|
|
99
|
+
*/
|
|
100
|
+
export declare function wcdBase64ToUint8Array(base64: string): Uint8Array;
|
|
101
|
+
/**
|
|
102
|
+
* Manages WCD artifacts on the device
|
|
103
|
+
*/
|
|
104
|
+
export declare class WCDArtifactManager {
|
|
105
|
+
private fs;
|
|
106
|
+
private wcdDir;
|
|
107
|
+
private zkeyDir;
|
|
108
|
+
private debug;
|
|
109
|
+
constructor(config: WCDProverConfig);
|
|
110
|
+
private log;
|
|
111
|
+
/**
|
|
112
|
+
* Get WCD directory path
|
|
113
|
+
*/
|
|
114
|
+
getWCDDirectory(): string;
|
|
115
|
+
/**
|
|
116
|
+
* Get zkey directory path
|
|
117
|
+
*/
|
|
118
|
+
getZkeyDirectory(): string;
|
|
119
|
+
/**
|
|
120
|
+
* Ensure directory exists
|
|
121
|
+
*/
|
|
122
|
+
ensureDir(dir: string): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Get artifact paths for a circuit
|
|
125
|
+
*/
|
|
126
|
+
getArtifactPaths(circuitId: string): WCDArtifacts;
|
|
127
|
+
/**
|
|
128
|
+
* Check if artifacts exist for a circuit
|
|
129
|
+
*/
|
|
130
|
+
hasArtifacts(circuitId: string): Promise<boolean>;
|
|
131
|
+
/**
|
|
132
|
+
* Store WCD artifact from buffer
|
|
133
|
+
*/
|
|
134
|
+
storeWCD(circuitId: string, wcdBuffer: Uint8Array): Promise<string>;
|
|
135
|
+
/**
|
|
136
|
+
* Store zkey artifact from buffer
|
|
137
|
+
*/
|
|
138
|
+
storeZkey(circuitId: string, zkeyBuffer: Uint8Array): Promise<string>;
|
|
139
|
+
/**
|
|
140
|
+
* Get WCD file as base64
|
|
141
|
+
*/
|
|
142
|
+
getWCDBase64(circuitId: string): Promise<string>;
|
|
143
|
+
/**
|
|
144
|
+
* Get zkey file path
|
|
145
|
+
*/
|
|
146
|
+
getZkeyPath(circuitId: string): string;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if WCD prover is configured
|
|
150
|
+
*/
|
|
151
|
+
export declare function hasWCDProver(): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Get WCD prover configuration
|
|
154
|
+
*/
|
|
155
|
+
export declare function getWCDProverConfig(): WCDProverConfig | null;
|
|
156
|
+
/**
|
|
157
|
+
* Set up WCD-based prover for React Native
|
|
158
|
+
*
|
|
159
|
+
* This configures the SDK to use .wcd graph files with circom-witnesscalc
|
|
160
|
+
* for witness calculation, and rapidsnark for proof generation.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* import { calculateWitness } from '@iden3/react-native-circom-witnesscalc';
|
|
165
|
+
* import { groth16Prove } from 'react-native-rapidsnark';
|
|
166
|
+
* import RNFS from 'react-native-fs';
|
|
167
|
+
*
|
|
168
|
+
* setWCDProver({
|
|
169
|
+
* calculateWitness,
|
|
170
|
+
* groth16Prove,
|
|
171
|
+
* fs: {
|
|
172
|
+
* writeFile: (path, data, encoding) => RNFS.writeFile(path, data, encoding),
|
|
173
|
+
* readFile: (path, encoding) => RNFS.readFile(path, encoding),
|
|
174
|
+
* exists: (path) => RNFS.exists(path),
|
|
175
|
+
* unlink: (path) => RNFS.unlink(path),
|
|
176
|
+
* mkdir: (path) => RNFS.mkdir(path),
|
|
177
|
+
* documentDirectory: RNFS.DocumentDirectoryPath,
|
|
178
|
+
* cacheDirectory: RNFS.CachesDirectoryPath,
|
|
179
|
+
* },
|
|
180
|
+
* debug: true,
|
|
181
|
+
* });
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export declare function setWCDProver(config: WCDProverConfig): void;
|
|
185
|
+
/**
|
|
186
|
+
* Clear WCD prover configuration
|
|
187
|
+
*/
|
|
188
|
+
export declare function clearWCDProver(): void;
|
|
189
|
+
/**
|
|
190
|
+
* Create a WCD artifact store for storing/loading .wcd files
|
|
191
|
+
*/
|
|
192
|
+
export declare function createWCDArtifactManager(config: WCDProverConfig): WCDArtifactManager;
|
|
193
|
+
/**
|
|
194
|
+
* Store WCD artifacts from local buffers (for testing/development)
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* // Load WCD file from assets
|
|
199
|
+
* const wcdBuffer = await loadWCDFromAssets('3x2.wcd');
|
|
200
|
+
* const zkeyBuffer = await loadZkeyFromAssets('3x2.zkey');
|
|
201
|
+
*
|
|
202
|
+
* await storeWCDArtifacts('3x2', wcdBuffer, zkeyBuffer);
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
export declare function storeWCDArtifacts(circuitId: string, wcdBuffer: Uint8Array, zkeyBuffer: Uint8Array): Promise<WCDArtifacts>;
|
|
206
|
+
/**
|
|
207
|
+
* Check if WCD artifacts are available for a circuit
|
|
208
|
+
*/
|
|
209
|
+
export declare function hasWCDArtifacts(circuitId: string): Promise<boolean>;
|
|
210
|
+
/**
|
|
211
|
+
* Get the path where WCD file should be stored
|
|
212
|
+
*/
|
|
213
|
+
export declare function getWCDPath(circuitId: string): string;
|
|
214
|
+
/**
|
|
215
|
+
* Get the path where zkey file should be stored
|
|
216
|
+
*/
|
|
217
|
+
export declare function getZkeyPathForWCD(circuitId: string): string;
|
|
218
|
+
/**
|
|
219
|
+
* Store only WCD file (SDK handles zkey download automatically)
|
|
220
|
+
*
|
|
221
|
+
* Use this when bundling WCD files with your mobile app.
|
|
222
|
+
* The SDK will download zkey files on-demand via ArtifactDownloader.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* // Load WCD from bundled assets
|
|
227
|
+
* const wcdBuffer = await loadWCDFromAssets('3x2.wcd');
|
|
228
|
+
* await storeWCDOnly('3x2', wcdBuffer);
|
|
229
|
+
*
|
|
230
|
+
* // Now SDK can generate proofs for 3x2 circuit
|
|
231
|
+
* // zkey will be downloaded automatically when needed
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
export declare function storeWCDOnly(circuitId: string, wcdBuffer: Uint8Array): Promise<string>;
|
|
235
|
+
/**
|
|
236
|
+
* Check if WCD file exists for a circuit (zkey is handled by SDK)
|
|
237
|
+
*/
|
|
238
|
+
export declare function hasWCDFile(circuitId: string): Promise<boolean>;
|
|
239
|
+
/**
|
|
240
|
+
* Get list of all stored WCD circuit IDs
|
|
241
|
+
*/
|
|
242
|
+
export declare function getStoredWCDCircuits(): Promise<string[]>;
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* React Native WCD Prover - Using circom-witnesscalc .wcd files
|
|
4
|
+
*
|
|
5
|
+
* This module provides witness calculation using pre-compiled .wcd graph files
|
|
6
|
+
* from iden3/circom-witnesscalc. This is the recommended approach for React Native
|
|
7
|
+
* as it provides fast, native witness calculation without WASM overhead.
|
|
8
|
+
*
|
|
9
|
+
* Flow:
|
|
10
|
+
* 1. Load .wcd graph file for the circuit
|
|
11
|
+
* 2. Use @iden3/react-native-circom-witnesscalc to calculate witness
|
|
12
|
+
* 3. Use react-native-rapidsnark to generate proof
|
|
13
|
+
*
|
|
14
|
+
* Benefits over WASM approach:
|
|
15
|
+
* - Faster witness calculation (native code)
|
|
16
|
+
* - No WASM runtime needed
|
|
17
|
+
* - Smaller memory footprint
|
|
18
|
+
* - Better mobile performance
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.getStoredWCDCircuits = exports.hasWCDFile = exports.storeWCDOnly = exports.getZkeyPathForWCD = exports.getWCDPath = exports.hasWCDArtifacts = exports.storeWCDArtifacts = exports.createWCDArtifactManager = exports.clearWCDProver = exports.setWCDProver = exports.getWCDProverConfig = exports.hasWCDProver = exports.WCDArtifactManager = exports.wcdBase64ToUint8Array = exports.wcdUint8ArrayToBase64 = void 0;
|
|
22
|
+
const engine_1 = require("../core/engine");
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Global State
|
|
25
|
+
// ============================================================================
|
|
26
|
+
let wcdProverConfig = null;
|
|
27
|
+
let wcdProverIntercepted = false;
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Utility Functions
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* Convert Uint8Array to base64 string
|
|
33
|
+
*/
|
|
34
|
+
function wcdUint8ArrayToBase64(data) {
|
|
35
|
+
if (typeof Buffer !== 'undefined') {
|
|
36
|
+
return Buffer.from(data).toString('base64');
|
|
37
|
+
}
|
|
38
|
+
let binary = '';
|
|
39
|
+
const len = data.byteLength;
|
|
40
|
+
for (let i = 0; i < len; i += 1) {
|
|
41
|
+
binary += String.fromCharCode(data[i]);
|
|
42
|
+
}
|
|
43
|
+
return btoa(binary);
|
|
44
|
+
}
|
|
45
|
+
exports.wcdUint8ArrayToBase64 = wcdUint8ArrayToBase64;
|
|
46
|
+
/**
|
|
47
|
+
* Convert base64 string to Uint8Array
|
|
48
|
+
*/
|
|
49
|
+
function wcdBase64ToUint8Array(base64) {
|
|
50
|
+
if (typeof Buffer !== 'undefined') {
|
|
51
|
+
return new Uint8Array(Buffer.from(base64, 'base64'));
|
|
52
|
+
}
|
|
53
|
+
const binary = atob(base64);
|
|
54
|
+
const bytes = new Uint8Array(binary.length);
|
|
55
|
+
for (let i = 0; i < binary.length; i += 1) {
|
|
56
|
+
bytes[i] = binary.charCodeAt(i);
|
|
57
|
+
}
|
|
58
|
+
return bytes;
|
|
59
|
+
}
|
|
60
|
+
exports.wcdBase64ToUint8Array = wcdBase64ToUint8Array;
|
|
61
|
+
/**
|
|
62
|
+
* Get circuit ID from formatted inputs
|
|
63
|
+
* DOP circuits are named like "3x2" (3 nullifiers, 2 commitments)
|
|
64
|
+
*/
|
|
65
|
+
function getCircuitIdFromInputs(inputs) {
|
|
66
|
+
const nullifierCount = inputs.nullifiers?.filter((n) => n !== undefined && n !== null && BigInt(n) !== BigInt(0)).length || 0;
|
|
67
|
+
const commitmentCount = inputs.commitmentsOut?.filter((c) => c !== undefined && c !== null && BigInt(c) !== BigInt(0)).length || 0;
|
|
68
|
+
return `${nullifierCount}x${commitmentCount}`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Log message if debug is enabled
|
|
72
|
+
*/
|
|
73
|
+
function debugLog(message) {
|
|
74
|
+
if (wcdProverConfig?.debug === true) {
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.log(`[WCD Prover] ${message}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// WCD Artifact Manager
|
|
81
|
+
// ============================================================================
|
|
82
|
+
/**
|
|
83
|
+
* Manages WCD artifacts on the device
|
|
84
|
+
*/
|
|
85
|
+
class WCDArtifactManager {
|
|
86
|
+
fs;
|
|
87
|
+
wcdDir;
|
|
88
|
+
zkeyDir;
|
|
89
|
+
debug;
|
|
90
|
+
constructor(config) {
|
|
91
|
+
this.fs = config.fs;
|
|
92
|
+
this.wcdDir = config.wcdDirectory ?? `${config.fs.documentDirectory}/dop-wcd`;
|
|
93
|
+
this.zkeyDir = config.zkeyDirectory ?? `${config.fs.documentDirectory}/dop-zkeys`;
|
|
94
|
+
this.debug = config.debug ?? false;
|
|
95
|
+
}
|
|
96
|
+
log(message) {
|
|
97
|
+
if (this.debug) {
|
|
98
|
+
// eslint-disable-next-line no-console
|
|
99
|
+
console.log(`[WCDArtifactManager] ${message}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get WCD directory path
|
|
104
|
+
*/
|
|
105
|
+
getWCDDirectory() {
|
|
106
|
+
return this.wcdDir;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get zkey directory path
|
|
110
|
+
*/
|
|
111
|
+
getZkeyDirectory() {
|
|
112
|
+
return this.zkeyDir;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Ensure directory exists
|
|
116
|
+
*/
|
|
117
|
+
async ensureDir(dir) {
|
|
118
|
+
try {
|
|
119
|
+
if (!(await this.fs.exists(dir))) {
|
|
120
|
+
await this.fs.mkdir(dir);
|
|
121
|
+
this.log(`Created directory: ${dir}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Directory might already exist
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get artifact paths for a circuit
|
|
130
|
+
*/
|
|
131
|
+
getArtifactPaths(circuitId) {
|
|
132
|
+
return {
|
|
133
|
+
wcdPath: `${this.wcdDir}/${circuitId}.wcd`,
|
|
134
|
+
zkeyPath: `${this.zkeyDir}/${circuitId}.zkey`,
|
|
135
|
+
vkeyPath: `${this.zkeyDir}/${circuitId}.vkey.json`,
|
|
136
|
+
circuitId,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check if artifacts exist for a circuit
|
|
141
|
+
*/
|
|
142
|
+
async hasArtifacts(circuitId) {
|
|
143
|
+
const paths = this.getArtifactPaths(circuitId);
|
|
144
|
+
const [hasWcd, hasZkey] = await Promise.all([
|
|
145
|
+
this.fs.exists(paths.wcdPath),
|
|
146
|
+
this.fs.exists(paths.zkeyPath),
|
|
147
|
+
]);
|
|
148
|
+
return hasWcd && hasZkey;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Store WCD artifact from buffer
|
|
152
|
+
*/
|
|
153
|
+
async storeWCD(circuitId, wcdBuffer) {
|
|
154
|
+
await this.ensureDir(this.wcdDir);
|
|
155
|
+
const path = `${this.wcdDir}/${circuitId}.wcd`;
|
|
156
|
+
const base64 = wcdUint8ArrayToBase64(wcdBuffer);
|
|
157
|
+
await this.fs.writeFile(path, base64, 'base64');
|
|
158
|
+
this.log(`Stored WCD: ${path} (${wcdBuffer.length} bytes)`);
|
|
159
|
+
return path;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Store zkey artifact from buffer
|
|
163
|
+
*/
|
|
164
|
+
async storeZkey(circuitId, zkeyBuffer) {
|
|
165
|
+
await this.ensureDir(this.zkeyDir);
|
|
166
|
+
const path = `${this.zkeyDir}/${circuitId}.zkey`;
|
|
167
|
+
const base64 = wcdUint8ArrayToBase64(zkeyBuffer);
|
|
168
|
+
await this.fs.writeFile(path, base64, 'base64');
|
|
169
|
+
this.log(`Stored zkey: ${path} (${zkeyBuffer.length} bytes)`);
|
|
170
|
+
return path;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get WCD file as base64
|
|
174
|
+
*/
|
|
175
|
+
async getWCDBase64(circuitId) {
|
|
176
|
+
const path = `${this.wcdDir}/${circuitId}.wcd`;
|
|
177
|
+
if (!(await this.fs.exists(path))) {
|
|
178
|
+
throw new Error(`WCD file not found: ${path}`);
|
|
179
|
+
}
|
|
180
|
+
return this.fs.readFile(path, 'base64');
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get zkey file path
|
|
184
|
+
*/
|
|
185
|
+
getZkeyPath(circuitId) {
|
|
186
|
+
return `${this.zkeyDir}/${circuitId}.zkey`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
exports.WCDArtifactManager = WCDArtifactManager;
|
|
190
|
+
// ============================================================================
|
|
191
|
+
// Core Prover Functions
|
|
192
|
+
// ============================================================================
|
|
193
|
+
/**
|
|
194
|
+
* Generate proof using WCD-based witness calculation
|
|
195
|
+
*/
|
|
196
|
+
async function generateProofWithWCD(circuitId, formattedInputs, zkeyBuffer, progressCallback) {
|
|
197
|
+
if (wcdProverConfig === null) {
|
|
198
|
+
throw new Error('WCD Prover not configured. Call setWCDProver first.');
|
|
199
|
+
}
|
|
200
|
+
const { calculateWitness, groth16Prove, fs } = wcdProverConfig;
|
|
201
|
+
const artifactManager = new WCDArtifactManager(wcdProverConfig);
|
|
202
|
+
debugLog(`Generating proof for circuit: ${circuitId}`);
|
|
203
|
+
if (progressCallback !== undefined)
|
|
204
|
+
progressCallback(0.1);
|
|
205
|
+
// Step 1: Ensure zkey is stored
|
|
206
|
+
const zkeyPath = artifactManager.getZkeyPath(circuitId);
|
|
207
|
+
if (!(await fs.exists(zkeyPath))) {
|
|
208
|
+
debugLog('Storing zkey file...');
|
|
209
|
+
// Convert ArrayLike to Uint8Array properly
|
|
210
|
+
const zkeyArray = zkeyBuffer instanceof Uint8Array
|
|
211
|
+
? zkeyBuffer
|
|
212
|
+
: new Uint8Array(Array.from(zkeyBuffer));
|
|
213
|
+
await artifactManager.storeZkey(circuitId, zkeyArray);
|
|
214
|
+
}
|
|
215
|
+
if (progressCallback !== undefined)
|
|
216
|
+
progressCallback(0.2);
|
|
217
|
+
// Step 2: Get WCD graph file
|
|
218
|
+
debugLog('Loading WCD graph file...');
|
|
219
|
+
let wcdBase64;
|
|
220
|
+
try {
|
|
221
|
+
wcdBase64 = await artifactManager.getWCDBase64(circuitId);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
throw new Error(`WCD file not found for circuit ${circuitId}. ` +
|
|
225
|
+
`Please ensure the .wcd file is stored at the expected location.`);
|
|
226
|
+
}
|
|
227
|
+
if (progressCallback !== undefined)
|
|
228
|
+
progressCallback(0.3);
|
|
229
|
+
// Step 3: Prepare inputs as JSON string
|
|
230
|
+
const inputsJson = JSON.stringify(formattedInputs, (_, v) => typeof v === 'bigint' ? v.toString() : v);
|
|
231
|
+
debugLog(`Calculating witness with inputs: ${inputsJson.substring(0, 200)}...`);
|
|
232
|
+
// Step 4: Calculate witness using circom-witnesscalc
|
|
233
|
+
debugLog('Calculating witness...');
|
|
234
|
+
const witnessBase64 = await calculateWitness(inputsJson, wcdBase64);
|
|
235
|
+
if (progressCallback !== undefined)
|
|
236
|
+
progressCallback(0.6);
|
|
237
|
+
debugLog(`Witness calculated: ${witnessBase64.length} bytes (base64)`);
|
|
238
|
+
// Step 5: Generate proof using rapidsnark
|
|
239
|
+
debugLog('Generating proof with rapidsnark...');
|
|
240
|
+
const result = await groth16Prove(zkeyPath, witnessBase64);
|
|
241
|
+
if (progressCallback !== undefined)
|
|
242
|
+
progressCallback(0.9);
|
|
243
|
+
// Step 6: Convert proof format
|
|
244
|
+
const proof = {
|
|
245
|
+
pi_a: result.proof.a,
|
|
246
|
+
pi_b: result.proof.b,
|
|
247
|
+
pi_c: result.proof.c,
|
|
248
|
+
};
|
|
249
|
+
if (progressCallback !== undefined)
|
|
250
|
+
progressCallback(1.0);
|
|
251
|
+
debugLog('Proof generated successfully');
|
|
252
|
+
return {
|
|
253
|
+
proof,
|
|
254
|
+
publicSignals: result.pub_signals,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Public API
|
|
259
|
+
// ============================================================================
|
|
260
|
+
/**
|
|
261
|
+
* Check if WCD prover is configured
|
|
262
|
+
*/
|
|
263
|
+
function hasWCDProver() {
|
|
264
|
+
return wcdProverConfig !== null;
|
|
265
|
+
}
|
|
266
|
+
exports.hasWCDProver = hasWCDProver;
|
|
267
|
+
/**
|
|
268
|
+
* Get WCD prover configuration
|
|
269
|
+
*/
|
|
270
|
+
function getWCDProverConfig() {
|
|
271
|
+
return wcdProverConfig;
|
|
272
|
+
}
|
|
273
|
+
exports.getWCDProverConfig = getWCDProverConfig;
|
|
274
|
+
/**
|
|
275
|
+
* Set up WCD-based prover for React Native
|
|
276
|
+
*
|
|
277
|
+
* This configures the SDK to use .wcd graph files with circom-witnesscalc
|
|
278
|
+
* for witness calculation, and rapidsnark for proof generation.
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```typescript
|
|
282
|
+
* import { calculateWitness } from '@iden3/react-native-circom-witnesscalc';
|
|
283
|
+
* import { groth16Prove } from 'react-native-rapidsnark';
|
|
284
|
+
* import RNFS from 'react-native-fs';
|
|
285
|
+
*
|
|
286
|
+
* setWCDProver({
|
|
287
|
+
* calculateWitness,
|
|
288
|
+
* groth16Prove,
|
|
289
|
+
* fs: {
|
|
290
|
+
* writeFile: (path, data, encoding) => RNFS.writeFile(path, data, encoding),
|
|
291
|
+
* readFile: (path, encoding) => RNFS.readFile(path, encoding),
|
|
292
|
+
* exists: (path) => RNFS.exists(path),
|
|
293
|
+
* unlink: (path) => RNFS.unlink(path),
|
|
294
|
+
* mkdir: (path) => RNFS.mkdir(path),
|
|
295
|
+
* documentDirectory: RNFS.DocumentDirectoryPath,
|
|
296
|
+
* cacheDirectory: RNFS.CachesDirectoryPath,
|
|
297
|
+
* },
|
|
298
|
+
* debug: true,
|
|
299
|
+
* });
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
function setWCDProver(config) {
|
|
303
|
+
wcdProverConfig = config;
|
|
304
|
+
// eslint-disable-next-line no-console
|
|
305
|
+
console.log('[WCD Prover] Configuration set');
|
|
306
|
+
if (config.debug === true) {
|
|
307
|
+
// eslint-disable-next-line no-console
|
|
308
|
+
console.log('[WCD Prover] Debug mode enabled');
|
|
309
|
+
// eslint-disable-next-line no-console
|
|
310
|
+
console.log(`[WCD Prover] WCD directory: ${config.wcdDirectory ?? `${config.fs.documentDirectory}/dop-wcd`}`);
|
|
311
|
+
// eslint-disable-next-line no-console
|
|
312
|
+
console.log(`[WCD Prover] Zkey directory: ${config.zkeyDirectory ?? `${config.fs.documentDirectory}/dop-zkeys`}`);
|
|
313
|
+
}
|
|
314
|
+
// Intercept the DOP Engine prover
|
|
315
|
+
interceptEngineProverForWCD();
|
|
316
|
+
}
|
|
317
|
+
exports.setWCDProver = setWCDProver;
|
|
318
|
+
/**
|
|
319
|
+
* Clear WCD prover configuration
|
|
320
|
+
*/
|
|
321
|
+
function clearWCDProver() {
|
|
322
|
+
wcdProverConfig = null;
|
|
323
|
+
wcdProverIntercepted = false;
|
|
324
|
+
// eslint-disable-next-line no-console
|
|
325
|
+
console.log('[WCD Prover] Configuration cleared');
|
|
326
|
+
}
|
|
327
|
+
exports.clearWCDProver = clearWCDProver;
|
|
328
|
+
/**
|
|
329
|
+
* Intercept DOP Engine's prover to use WCD-based proof generation
|
|
330
|
+
*/
|
|
331
|
+
function interceptEngineProverForWCD() {
|
|
332
|
+
if (wcdProverIntercepted) {
|
|
333
|
+
debugLog('Engine prover already intercepted');
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
let engine;
|
|
337
|
+
try {
|
|
338
|
+
engine = (0, engine_1.getEngine)();
|
|
339
|
+
}
|
|
340
|
+
catch {
|
|
341
|
+
// Engine not initialized yet, will intercept later
|
|
342
|
+
// eslint-disable-next-line no-console
|
|
343
|
+
console.log('[WCD Prover] DOP Engine not initialized yet. Prover will be intercepted on first use.');
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (engine === undefined) {
|
|
347
|
+
// eslint-disable-next-line no-console
|
|
348
|
+
console.log('[WCD Prover] DOP Engine not initialized. Will intercept when available.');
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const prover = engine.prover;
|
|
352
|
+
if (prover?.groth16?.fullProveDop === undefined) {
|
|
353
|
+
// eslint-disable-next-line no-console
|
|
354
|
+
console.warn('[WCD Prover] DOP Engine prover not available.');
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
const originalFullProveDop = prover.groth16.fullProveDop;
|
|
358
|
+
prover.groth16.fullProveDop = async (formattedInputs, wasm, zkey, logger, dat, progressCallback) => {
|
|
359
|
+
// If WCD prover is configured, use it
|
|
360
|
+
if (wcdProverConfig !== null) {
|
|
361
|
+
const circuitId = getCircuitIdFromInputs(formattedInputs);
|
|
362
|
+
logger.debug(`[WCD Prover] Using WCD-based prover for circuit ${circuitId}`);
|
|
363
|
+
try {
|
|
364
|
+
const result = await generateProofWithWCD(circuitId, formattedInputs, zkey, progressCallback);
|
|
365
|
+
return {
|
|
366
|
+
proof: result.proof,
|
|
367
|
+
publicSignals: result.publicSignals,
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
logger.debug(`[WCD Prover] Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
372
|
+
throw error;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
// Fallback to original implementation
|
|
376
|
+
return originalFullProveDop(formattedInputs, wasm, zkey, logger, dat, progressCallback);
|
|
377
|
+
};
|
|
378
|
+
wcdProverIntercepted = true;
|
|
379
|
+
debugLog('Engine prover intercepted for WCD-based proof generation');
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Create a WCD artifact store for storing/loading .wcd files
|
|
383
|
+
*/
|
|
384
|
+
function createWCDArtifactManager(config) {
|
|
385
|
+
return new WCDArtifactManager(config);
|
|
386
|
+
}
|
|
387
|
+
exports.createWCDArtifactManager = createWCDArtifactManager;
|
|
388
|
+
/**
|
|
389
|
+
* Store WCD artifacts from local buffers (for testing/development)
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```typescript
|
|
393
|
+
* // Load WCD file from assets
|
|
394
|
+
* const wcdBuffer = await loadWCDFromAssets('3x2.wcd');
|
|
395
|
+
* const zkeyBuffer = await loadZkeyFromAssets('3x2.zkey');
|
|
396
|
+
*
|
|
397
|
+
* await storeWCDArtifacts('3x2', wcdBuffer, zkeyBuffer);
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
async function storeWCDArtifacts(circuitId, wcdBuffer, zkeyBuffer) {
|
|
401
|
+
if (wcdProverConfig === null) {
|
|
402
|
+
throw new Error('WCD Prover not configured. Call setWCDProver first.');
|
|
403
|
+
}
|
|
404
|
+
const manager = new WCDArtifactManager(wcdProverConfig);
|
|
405
|
+
const [wcdPath, zkeyPath] = await Promise.all([
|
|
406
|
+
manager.storeWCD(circuitId, wcdBuffer),
|
|
407
|
+
manager.storeZkey(circuitId, zkeyBuffer),
|
|
408
|
+
]);
|
|
409
|
+
return {
|
|
410
|
+
wcdPath,
|
|
411
|
+
zkeyPath,
|
|
412
|
+
circuitId,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
exports.storeWCDArtifacts = storeWCDArtifacts;
|
|
416
|
+
/**
|
|
417
|
+
* Check if WCD artifacts are available for a circuit
|
|
418
|
+
*/
|
|
419
|
+
async function hasWCDArtifacts(circuitId) {
|
|
420
|
+
if (wcdProverConfig === null) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
const manager = new WCDArtifactManager(wcdProverConfig);
|
|
424
|
+
return manager.hasArtifacts(circuitId);
|
|
425
|
+
}
|
|
426
|
+
exports.hasWCDArtifacts = hasWCDArtifacts;
|
|
427
|
+
/**
|
|
428
|
+
* Get the path where WCD file should be stored
|
|
429
|
+
*/
|
|
430
|
+
function getWCDPath(circuitId) {
|
|
431
|
+
if (wcdProverConfig === null) {
|
|
432
|
+
throw new Error('WCD Prover not configured. Call setWCDProver first.');
|
|
433
|
+
}
|
|
434
|
+
const wcdDir = wcdProverConfig.wcdDirectory ??
|
|
435
|
+
`${wcdProverConfig.fs.documentDirectory}/dop-wcd`;
|
|
436
|
+
return `${wcdDir}/${circuitId}.wcd`;
|
|
437
|
+
}
|
|
438
|
+
exports.getWCDPath = getWCDPath;
|
|
439
|
+
/**
|
|
440
|
+
* Get the path where zkey file should be stored
|
|
441
|
+
*/
|
|
442
|
+
function getZkeyPathForWCD(circuitId) {
|
|
443
|
+
if (wcdProverConfig === null) {
|
|
444
|
+
throw new Error('WCD Prover not configured. Call setWCDProver first.');
|
|
445
|
+
}
|
|
446
|
+
const zkeyDir = wcdProverConfig.zkeyDirectory ??
|
|
447
|
+
`${wcdProverConfig.fs.documentDirectory}/dop-zkeys`;
|
|
448
|
+
return `${zkeyDir}/${circuitId}.zkey`;
|
|
449
|
+
}
|
|
450
|
+
exports.getZkeyPathForWCD = getZkeyPathForWCD;
|
|
451
|
+
/**
|
|
452
|
+
* Store only WCD file (SDK handles zkey download automatically)
|
|
453
|
+
*
|
|
454
|
+
* Use this when bundling WCD files with your mobile app.
|
|
455
|
+
* The SDK will download zkey files on-demand via ArtifactDownloader.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```typescript
|
|
459
|
+
* // Load WCD from bundled assets
|
|
460
|
+
* const wcdBuffer = await loadWCDFromAssets('3x2.wcd');
|
|
461
|
+
* await storeWCDOnly('3x2', wcdBuffer);
|
|
462
|
+
*
|
|
463
|
+
* // Now SDK can generate proofs for 3x2 circuit
|
|
464
|
+
* // zkey will be downloaded automatically when needed
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
async function storeWCDOnly(circuitId, wcdBuffer) {
|
|
468
|
+
if (wcdProverConfig === null) {
|
|
469
|
+
throw new Error('WCD Prover not configured. Call setWCDProver first.');
|
|
470
|
+
}
|
|
471
|
+
const manager = new WCDArtifactManager(wcdProverConfig);
|
|
472
|
+
return manager.storeWCD(circuitId, wcdBuffer);
|
|
473
|
+
}
|
|
474
|
+
exports.storeWCDOnly = storeWCDOnly;
|
|
475
|
+
/**
|
|
476
|
+
* Check if WCD file exists for a circuit (zkey is handled by SDK)
|
|
477
|
+
*/
|
|
478
|
+
async function hasWCDFile(circuitId) {
|
|
479
|
+
if (wcdProverConfig === null) {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
const manager = new WCDArtifactManager(wcdProverConfig);
|
|
483
|
+
const wcdPath = `${manager.getWCDDirectory()}/${circuitId}.wcd`;
|
|
484
|
+
return wcdProverConfig.fs.exists(wcdPath);
|
|
485
|
+
}
|
|
486
|
+
exports.hasWCDFile = hasWCDFile;
|
|
487
|
+
/**
|
|
488
|
+
* Get list of all stored WCD circuit IDs
|
|
489
|
+
*/
|
|
490
|
+
async function getStoredWCDCircuits() {
|
|
491
|
+
if (wcdProverConfig === null) {
|
|
492
|
+
return [];
|
|
493
|
+
}
|
|
494
|
+
// This would require listing directory contents
|
|
495
|
+
// For now, return empty - mobile devs can track this themselves
|
|
496
|
+
return [];
|
|
497
|
+
}
|
|
498
|
+
exports.getStoredWCDCircuits = getStoredWCDCircuits;
|
|
499
|
+
//# sourceMappingURL=wcd-prover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wcd-prover.js","sourceRoot":"","sources":["../../../../src/services/dop/crypto/wcd-prover.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAGH,2CAA2C;AAmG3C,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E,IAAI,eAAe,GAA2B,IAAI,CAAC;AACnD,IAAI,oBAAoB,GAAG,KAAK,CAAC;AAEjC,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;GAEG;AACH,SAAgB,qBAAqB,CAAC,IAAgB;IACpD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;KAC7C;IACD,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE;QAC/B,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;KACxC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAVD,sDAUC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,MAAc;IAClD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;KACtD;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE;QACzC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;KACjC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAVD,sDAUC;AAED;;;GAGG;AACH,SAAS,sBAAsB,CAAC,MAAiC;IAC/D,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAC9C,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CACjF,CAAC,MAAM,IAAI,CAAC,CAAC;IAEd,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CACnD,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CACjF,CAAC,MAAM,IAAI,CAAC,CAAC;IAEd,OAAO,GAAG,cAAc,IAAI,eAAe,EAAE,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,OAAe;IAC/B,IAAI,eAAe,EAAE,KAAK,KAAK,IAAI,EAAE;QACnC,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;KACxC;AACH,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;GAEG;AACH,MAAa,kBAAkB;IACrB,EAAE,CAAgB;IAClB,MAAM,CAAS;IACf,OAAO,CAAS;IAChB,KAAK,CAAU;IAEvB,YAAY,MAAuB;QACjC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,YAAY,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,UAAU,CAAC;QAC9E,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,YAAY,CAAC;QAClF,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;IACrC,CAAC;IAEO,GAAG,CAAC,OAAe;QACzB,IAAI,IAAI,CAAC,KAAK,EAAE;YACd,sCAAsC;YACtC,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;SAChD;IACH,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,IAAI;YACF,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;gBAChC,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;aACvC;SACF;QAAC,MAAM;YACN,gCAAgC;SACjC;IACH,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,SAAiB;QAChC,OAAO;YACL,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,MAAM;YAC1C,QAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO;YAC7C,QAAQ,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,YAAY;YAClD,SAAS;SACV,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,SAAiB;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;SAC/B,CAAC,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,SAAqB;QACrD,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,MAAM,CAAC;QAC/C,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,KAAK,SAAS,CAAC,MAAM,SAAS,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS,CAAC,SAAiB,EAAE,UAAsB;QACvD,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,CAAC;QACjD,MAAM,MAAM,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;QACjD,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,KAAK,UAAU,CAAC,MAAM,SAAS,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,SAAiB;QAClC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,MAAM,CAAC;QAC/C,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;SAChD;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,SAAiB;QAC3B,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,OAAO,CAAC;IAC7C,CAAC;CACF;AAjHD,gDAiHC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;GAEG;AACH,KAAK,UAAU,oBAAoB,CACjC,SAAiB,EACjB,eAA0C,EAC1C,UAA6B,EAC7B,gBAA6C;IAE7C,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;KACxE;IAED,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,EAAE,EAAE,GAAG,eAAe,CAAC;IAC/D,MAAM,eAAe,GAAG,IAAI,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAEhE,QAAQ,CAAC,iCAAiC,SAAS,EAAE,CAAC,CAAC;IAEvD,IAAI,gBAAgB,KAAK,SAAS;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE1D,gCAAgC;IAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACxD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE;QAChC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;QACjC,2CAA2C;QAC3C,MAAM,SAAS,GAAG,UAAU,YAAY,UAAU;YAChD,CAAC,CAAC,UAAU;YACZ,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3C,MAAM,eAAe,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;KACvD;IAED,IAAI,gBAAgB,KAAK,SAAS;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE1D,6BAA6B;IAC7B,QAAQ,CAAC,2BAA2B,CAAC,CAAC;IACtC,IAAI,SAAiB,CAAC;IACtB,IAAI;QACF,SAAS,GAAG,MAAM,eAAe,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;KAC3D;IAAC,MAAM;QACN,MAAM,IAAI,KAAK,CACb,kCAAkC,SAAS,IAAI;YAC/C,iEAAiE,CAClE,CAAC;KACH;IAED,IAAI,gBAAgB,KAAK,SAAS;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE1D,wCAAwC;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC1D,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CACzC,CAAC;IAEF,QAAQ,CAAC,oCAAoC,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAEhF,qDAAqD;IACrD,QAAQ,CAAC,wBAAwB,CAAC,CAAC;IACnC,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAEpE,IAAI,gBAAgB,KAAK,SAAS;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE1D,QAAQ,CAAC,uBAAuB,aAAa,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAEvE,0CAA0C;IAC1C,QAAQ,CAAC,qCAAqC,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAE3D,IAAI,gBAAgB,KAAK,SAAS;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE1D,+BAA+B;IAC/B,MAAM,KAAK,GAAU;QACnB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAqB;QACxC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAyC;QAC5D,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAqB;KACzC,CAAC;IAEF,IAAI,gBAAgB,KAAK,SAAS;QAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE1D,QAAQ,CAAC,8BAA8B,CAAC,CAAC;IAEzC,OAAO;QACL,KAAK;QACL,aAAa,EAAE,MAAM,CAAC,WAAW;KAClC,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;GAEG;AACH,SAAgB,YAAY;IAC1B,OAAO,eAAe,KAAK,IAAI,CAAC;AAClC,CAAC;AAFD,oCAEC;AAED;;GAEG;AACH,SAAgB,kBAAkB;IAChC,OAAO,eAAe,CAAC;AACzB,CAAC;AAFD,gDAEC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,YAAY,CAAC,MAAuB;IAClD,eAAe,GAAG,MAAM,CAAC;IAEzB,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE;QACzB,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,YAAY,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,UAAU,EAAE,CAAC,CAAC;QAC9G,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,CAAC,aAAa,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,YAAY,EAAE,CAAC,CAAC;KACnH;IAED,kCAAkC;IAClC,2BAA2B,EAAE,CAAC;AAChC,CAAC;AAhBD,oCAgBC;AAED;;GAEG;AACH,SAAgB,cAAc;IAC5B,eAAe,GAAG,IAAI,CAAC;IACvB,oBAAoB,GAAG,KAAK,CAAC;IAC7B,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AACpD,CAAC;AALD,wCAKC;AAED;;GAEG;AACH,SAAS,2BAA2B;IAClC,IAAI,oBAAoB,EAAE;QACxB,QAAQ,CAAC,mCAAmC,CAAC,CAAC;QAC9C,OAAO;KACR;IAED,IAAI,MAAM,CAAC;IACX,IAAI;QACF,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;KACtB;IAAC,MAAM;QACN,mDAAmD;QACnD,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;QACrG,OAAO;KACR;IAED,IAAI,MAAM,KAAK,SAAS,EAAE;QACxB,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;QACvF,OAAO;KACR;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,SAAS,EAAE;QAC/C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC9D,OAAO;KACR;IAED,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;IAEzD,MAAM,CAAC,OAAO,CAAC,YAAY,GAAG,KAAK,EACjC,eAA0C,EAC1C,IAAa,EACb,IAAuB,EACvB,MAAwC,EACxC,GAAY,EACZ,gBAA4C,EAC5C,EAAE;QACF,sCAAsC;QACtC,IAAI,eAAe,KAAK,IAAI,EAAE;YAC5B,MAAM,SAAS,GAAG,sBAAsB,CAAC,eAAe,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,CAAC,mDAAmD,SAAS,EAAE,CAAC,CAAC;YAE7E,IAAI;gBACF,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,SAAS,EACT,eAAe,EACf,IAAI,EACJ,gBAAgB,CACjB,CAAC;gBAEF,OAAO;oBACL,KAAK,EAAE,MAAM,CAAC,KAAK;oBACnB,aAAa,EAAE,MAAM,CAAC,aAAa;iBACpC,CAAC;aACH;YAAC,OAAO,KAAK,EAAE;gBACd,MAAM,CAAC,KAAK,CAAC,uBAAuB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC9F,MAAM,KAAK,CAAC;aACb;SACF;QAED,sCAAsC;QACtC,OAAO,oBAAoB,CACzB,eAAe,EACf,IAAqC,EACrC,IAAI,EACJ,MAAM,EACN,GAAoC,EACpC,gBAAgB,CACjB,CAAC;IACJ,CAAC,CAAC;IAEF,oBAAoB,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,0DAA0D,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,SAAgB,wBAAwB,CAAC,MAAuB;IAC9D,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAFD,4DAEC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,SAAqB,EACrB,UAAsB;IAEtB,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;KACxE;IAED,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAExD,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;QACtC,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC;KACzC,CAAC,CAAC;IAEH,OAAO;QACL,OAAO;QACP,QAAQ;QACR,SAAS;KACV,CAAC;AACJ,CAAC;AArBD,8CAqBC;AAED;;GAEG;AACI,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,OAAO,KAAK,CAAC;KACd;IAED,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;AACzC,CAAC;AAPD,0CAOC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,SAAiB;IAC1C,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;KACxE;IAED,MAAM,MAAM,GAAG,eAAe,CAAC,YAAY;QACzC,GAAG,eAAe,CAAC,EAAE,CAAC,iBAAiB,UAAU,CAAC;IACpD,OAAO,GAAG,MAAM,IAAI,SAAS,MAAM,CAAC;AACtC,CAAC;AARD,gCAQC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,SAAiB;IACjD,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;KACxE;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,aAAa;QAC3C,GAAG,eAAe,CAAC,EAAE,CAAC,iBAAiB,YAAY,CAAC;IACtD,OAAO,GAAG,OAAO,IAAI,SAAS,OAAO,CAAC;AACxC,CAAC;AARD,8CAQC;AAED;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,YAAY,CAChC,SAAiB,EACjB,SAAqB;IAErB,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;KACxE;IAED,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAVD,oCAUC;AAED;;GAEG;AACI,KAAK,UAAU,UAAU,CAAC,SAAiB;IAChD,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,OAAO,KAAK,CAAC;KACd;IAED,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC,eAAe,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,eAAe,EAAE,IAAI,SAAS,MAAM,CAAC;IAChE,OAAO,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AARD,gCAQC;AAED;;GAEG;AACI,KAAK,UAAU,oBAAoB;IACxC,IAAI,eAAe,KAAK,IAAI,EAAE;QAC5B,OAAO,EAAE,CAAC;KACX;IAED,gDAAgD;IAChD,gEAAgE;IAChE,OAAO,EAAE,CAAC;AACZ,CAAC;AARD,oDAQC","sourcesContent":["/**\n * React Native WCD Prover - Using circom-witnesscalc .wcd files\n * \n * This module provides witness calculation using pre-compiled .wcd graph files\n * from iden3/circom-witnesscalc. This is the recommended approach for React Native\n * as it provides fast, native witness calculation without WASM overhead.\n * \n * Flow:\n * 1. Load .wcd graph file for the circuit\n * 2. Use @iden3/react-native-circom-witnesscalc to calculate witness\n * 3. Use react-native-rapidsnark to generate proof\n * \n * Benefits over WASM approach:\n * - Faster witness calculation (native code)\n * - No WASM runtime needed\n * - Smaller memory footprint\n * - Better mobile performance\n */\n\nimport { FormattedCircuitInputsDop, Proof } from 'dop-engine-v3';\nimport { getEngine } from '../core/engine';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport { isReactNative } from '../util/runtime';\n\n// ============================================================================\n// Types and Interfaces\n// ============================================================================\n\n/**\n * Result from rapidsnark groth16Prove\n */\nexport interface WCDRapidsnarkProofResult {\n proof: {\n a: string[];\n b: string[][];\n c: string[];\n };\n pub_signals: string[];\n}\n\n/**\n * Rapidsnark's groth16Prove function signature\n */\nexport type WCDGroth16ProveFunction = (\n zkeyPath: string,\n witnessBase64: string\n) => Promise<WCDRapidsnarkProofResult>;\n\n/**\n * circom-witnesscalc's calculateWitness function signature\n * From: import { calculateWitness } from '@iden3/react-native-circom-witnesscalc'\n */\nexport type WCDCalculateWitnessFunction = (\n inputsJson: string,\n graphBase64: string\n) => Promise<string>; // Returns witness as base64\n\n/**\n * File system interface for React Native\n */\nexport interface WCDFileSystem {\n writeFile(path: string, data: string, encoding: 'base64' | 'utf8'): Promise<void>;\n readFile(path: string, encoding: 'base64' | 'utf8'): Promise<string>;\n exists(path: string): Promise<boolean>;\n unlink(path: string): Promise<void>;\n mkdir(path: string): Promise<void>;\n documentDirectory: string;\n cacheDirectory: string;\n}\n\n/**\n * Configuration for WCD-based React Native Prover\n */\nexport interface WCDProverConfig {\n /**\n * circom-witnesscalc's calculateWitness function\n * Import: import { calculateWitness } from '@iden3/react-native-circom-witnesscalc'\n */\n calculateWitness: WCDCalculateWitnessFunction;\n \n /**\n * Rapidsnark's groth16Prove function\n * Import: import { groth16Prove } from 'react-native-rapidsnark'\n */\n groth16Prove: WCDGroth16ProveFunction;\n \n /**\n * File system interface (react-native-fs or expo-file-system)\n */\n fs: WCDFileSystem;\n \n /**\n * Base directory where .wcd files are stored\n * Default: fs.documentDirectory + '/dop-wcd'\n */\n wcdDirectory?: string;\n \n /**\n * Base directory where .zkey files are stored\n * Default: fs.documentDirectory + '/dop-zkeys'\n */\n zkeyDirectory?: string;\n \n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\n/**\n * Stored WCD artifacts info\n */\nexport interface WCDArtifacts {\n wcdPath: string;\n zkeyPath: string;\n vkeyPath?: string;\n circuitId: string;\n}\n\n// ============================================================================\n// Global State\n// ============================================================================\n\nlet wcdProverConfig: WCDProverConfig | null = null;\nlet wcdProverIntercepted = false;\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Convert Uint8Array to base64 string\n */\nexport function wcdUint8ArrayToBase64(data: Uint8Array): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(data).toString('base64');\n }\n let binary = '';\n const len = data.byteLength;\n for (let i = 0; i < len; i += 1) {\n binary += String.fromCharCode(data[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Convert base64 string to Uint8Array\n */\nexport function wcdBase64ToUint8Array(base64: string): Uint8Array {\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(base64, 'base64'));\n }\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i += 1) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Get circuit ID from formatted inputs\n * DOP circuits are named like \"3x2\" (3 nullifiers, 2 commitments)\n */\nfunction getCircuitIdFromInputs(inputs: FormattedCircuitInputsDop): string {\n const nullifierCount = inputs.nullifiers?.filter(\n (n: bigint | string) => n !== undefined && n !== null && BigInt(n) !== BigInt(0)\n ).length || 0;\n \n const commitmentCount = inputs.commitmentsOut?.filter(\n (c: bigint | string) => c !== undefined && c !== null && BigInt(c) !== BigInt(0)\n ).length || 0;\n \n return `${nullifierCount}x${commitmentCount}`;\n}\n\n/**\n * Log message if debug is enabled\n */\nfunction debugLog(message: string): void {\n if (wcdProverConfig?.debug === true) {\n // eslint-disable-next-line no-console\n console.log(`[WCD Prover] ${message}`);\n }\n}\n\n// ============================================================================\n// WCD Artifact Manager\n// ============================================================================\n\n/**\n * Manages WCD artifacts on the device\n */\nexport class WCDArtifactManager {\n private fs: WCDFileSystem;\n private wcdDir: string;\n private zkeyDir: string;\n private debug: boolean;\n \n constructor(config: WCDProverConfig) {\n this.fs = config.fs;\n this.wcdDir = config.wcdDirectory ?? `${config.fs.documentDirectory}/dop-wcd`;\n this.zkeyDir = config.zkeyDirectory ?? `${config.fs.documentDirectory}/dop-zkeys`;\n this.debug = config.debug ?? false;\n }\n \n private log(message: string): void {\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.log(`[WCDArtifactManager] ${message}`);\n }\n }\n \n /**\n * Get WCD directory path\n */\n getWCDDirectory(): string {\n return this.wcdDir;\n }\n \n /**\n * Get zkey directory path\n */\n getZkeyDirectory(): string {\n return this.zkeyDir;\n }\n \n /**\n * Ensure directory exists\n */\n async ensureDir(dir: string): Promise<void> {\n try {\n if (!(await this.fs.exists(dir))) {\n await this.fs.mkdir(dir);\n this.log(`Created directory: ${dir}`);\n }\n } catch {\n // Directory might already exist\n }\n }\n \n /**\n * Get artifact paths for a circuit\n */\n getArtifactPaths(circuitId: string): WCDArtifacts {\n return {\n wcdPath: `${this.wcdDir}/${circuitId}.wcd`,\n zkeyPath: `${this.zkeyDir}/${circuitId}.zkey`,\n vkeyPath: `${this.zkeyDir}/${circuitId}.vkey.json`,\n circuitId,\n };\n }\n \n /**\n * Check if artifacts exist for a circuit\n */\n async hasArtifacts(circuitId: string): Promise<boolean> {\n const paths = this.getArtifactPaths(circuitId);\n const [hasWcd, hasZkey] = await Promise.all([\n this.fs.exists(paths.wcdPath),\n this.fs.exists(paths.zkeyPath),\n ]);\n return hasWcd && hasZkey;\n }\n \n /**\n * Store WCD artifact from buffer\n */\n async storeWCD(circuitId: string, wcdBuffer: Uint8Array): Promise<string> {\n await this.ensureDir(this.wcdDir);\n const path = `${this.wcdDir}/${circuitId}.wcd`;\n const base64 = wcdUint8ArrayToBase64(wcdBuffer);\n await this.fs.writeFile(path, base64, 'base64');\n this.log(`Stored WCD: ${path} (${wcdBuffer.length} bytes)`);\n return path;\n }\n \n /**\n * Store zkey artifact from buffer\n */\n async storeZkey(circuitId: string, zkeyBuffer: Uint8Array): Promise<string> {\n await this.ensureDir(this.zkeyDir);\n const path = `${this.zkeyDir}/${circuitId}.zkey`;\n const base64 = wcdUint8ArrayToBase64(zkeyBuffer);\n await this.fs.writeFile(path, base64, 'base64');\n this.log(`Stored zkey: ${path} (${zkeyBuffer.length} bytes)`);\n return path;\n }\n \n /**\n * Get WCD file as base64\n */\n async getWCDBase64(circuitId: string): Promise<string> {\n const path = `${this.wcdDir}/${circuitId}.wcd`;\n if (!(await this.fs.exists(path))) {\n throw new Error(`WCD file not found: ${path}`);\n }\n return this.fs.readFile(path, 'base64');\n }\n \n /**\n * Get zkey file path\n */\n getZkeyPath(circuitId: string): string {\n return `${this.zkeyDir}/${circuitId}.zkey`;\n }\n}\n\n// ============================================================================\n// Core Prover Functions\n// ============================================================================\n\n/**\n * Generate proof using WCD-based witness calculation\n */\nasync function generateProofWithWCD(\n circuitId: string,\n formattedInputs: FormattedCircuitInputsDop,\n zkeyBuffer: ArrayLike<number>,\n progressCallback?: (progress: number) => void,\n): Promise<{ proof: Proof; publicSignals: string[] }> {\n if (wcdProverConfig === null) {\n throw new Error('WCD Prover not configured. Call setWCDProver first.');\n }\n \n const { calculateWitness, groth16Prove, fs } = wcdProverConfig;\n const artifactManager = new WCDArtifactManager(wcdProverConfig);\n \n debugLog(`Generating proof for circuit: ${circuitId}`);\n \n if (progressCallback !== undefined) progressCallback(0.1);\n \n // Step 1: Ensure zkey is stored\n const zkeyPath = artifactManager.getZkeyPath(circuitId);\n if (!(await fs.exists(zkeyPath))) {\n debugLog('Storing zkey file...');\n // Convert ArrayLike to Uint8Array properly\n const zkeyArray = zkeyBuffer instanceof Uint8Array \n ? zkeyBuffer \n : new Uint8Array(Array.from(zkeyBuffer));\n await artifactManager.storeZkey(circuitId, zkeyArray);\n }\n \n if (progressCallback !== undefined) progressCallback(0.2);\n \n // Step 2: Get WCD graph file\n debugLog('Loading WCD graph file...');\n let wcdBase64: string;\n try {\n wcdBase64 = await artifactManager.getWCDBase64(circuitId);\n } catch {\n throw new Error(\n `WCD file not found for circuit ${circuitId}. ` +\n `Please ensure the .wcd file is stored at the expected location.`\n );\n }\n \n if (progressCallback !== undefined) progressCallback(0.3);\n \n // Step 3: Prepare inputs as JSON string\n const inputsJson = JSON.stringify(formattedInputs, (_, v) =>\n typeof v === 'bigint' ? v.toString() : v\n );\n \n debugLog(`Calculating witness with inputs: ${inputsJson.substring(0, 200)}...`);\n \n // Step 4: Calculate witness using circom-witnesscalc\n debugLog('Calculating witness...');\n const witnessBase64 = await calculateWitness(inputsJson, wcdBase64);\n \n if (progressCallback !== undefined) progressCallback(0.6);\n \n debugLog(`Witness calculated: ${witnessBase64.length} bytes (base64)`);\n \n // Step 5: Generate proof using rapidsnark\n debugLog('Generating proof with rapidsnark...');\n const result = await groth16Prove(zkeyPath, witnessBase64);\n \n if (progressCallback !== undefined) progressCallback(0.9);\n \n // Step 6: Convert proof format\n const proof: Proof = {\n pi_a: result.proof.a as [string, string],\n pi_b: result.proof.b as [[string, string], [string, string]],\n pi_c: result.proof.c as [string, string],\n };\n \n if (progressCallback !== undefined) progressCallback(1.0);\n \n debugLog('Proof generated successfully');\n \n return {\n proof,\n publicSignals: result.pub_signals,\n };\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Check if WCD prover is configured\n */\nexport function hasWCDProver(): boolean {\n return wcdProverConfig !== null;\n}\n\n/**\n * Get WCD prover configuration\n */\nexport function getWCDProverConfig(): WCDProverConfig | null {\n return wcdProverConfig;\n}\n\n/**\n * Set up WCD-based prover for React Native\n * \n * This configures the SDK to use .wcd graph files with circom-witnesscalc\n * for witness calculation, and rapidsnark for proof generation.\n * \n * @example\n * ```typescript\n * import { calculateWitness } from '@iden3/react-native-circom-witnesscalc';\n * import { groth16Prove } from 'react-native-rapidsnark';\n * import RNFS from 'react-native-fs';\n * \n * setWCDProver({\n * calculateWitness,\n * groth16Prove,\n * fs: {\n * writeFile: (path, data, encoding) => RNFS.writeFile(path, data, encoding),\n * readFile: (path, encoding) => RNFS.readFile(path, encoding),\n * exists: (path) => RNFS.exists(path),\n * unlink: (path) => RNFS.unlink(path),\n * mkdir: (path) => RNFS.mkdir(path),\n * documentDirectory: RNFS.DocumentDirectoryPath,\n * cacheDirectory: RNFS.CachesDirectoryPath,\n * },\n * debug: true,\n * });\n * ```\n */\nexport function setWCDProver(config: WCDProverConfig): void {\n wcdProverConfig = config;\n \n // eslint-disable-next-line no-console\n console.log('[WCD Prover] Configuration set');\n if (config.debug === true) {\n // eslint-disable-next-line no-console\n console.log('[WCD Prover] Debug mode enabled');\n // eslint-disable-next-line no-console\n console.log(`[WCD Prover] WCD directory: ${config.wcdDirectory ?? `${config.fs.documentDirectory}/dop-wcd`}`);\n // eslint-disable-next-line no-console\n console.log(`[WCD Prover] Zkey directory: ${config.zkeyDirectory ?? `${config.fs.documentDirectory}/dop-zkeys`}`);\n }\n \n // Intercept the DOP Engine prover\n interceptEngineProverForWCD();\n}\n\n/**\n * Clear WCD prover configuration\n */\nexport function clearWCDProver(): void {\n wcdProverConfig = null;\n wcdProverIntercepted = false;\n // eslint-disable-next-line no-console\n console.log('[WCD Prover] Configuration cleared');\n}\n\n/**\n * Intercept DOP Engine's prover to use WCD-based proof generation\n */\nfunction interceptEngineProverForWCD(): void {\n if (wcdProverIntercepted) {\n debugLog('Engine prover already intercepted');\n return;\n }\n \n let engine;\n try {\n engine = getEngine();\n } catch {\n // Engine not initialized yet, will intercept later\n // eslint-disable-next-line no-console\n console.log('[WCD Prover] DOP Engine not initialized yet. Prover will be intercepted on first use.');\n return;\n }\n \n if (engine === undefined) {\n // eslint-disable-next-line no-console\n console.log('[WCD Prover] DOP Engine not initialized. Will intercept when available.');\n return;\n }\n \n const prover = engine.prover;\n if (prover?.groth16?.fullProveDop === undefined) {\n // eslint-disable-next-line no-console\n console.warn('[WCD Prover] DOP Engine prover not available.');\n return;\n }\n \n const originalFullProveDop = prover.groth16.fullProveDop;\n \n prover.groth16.fullProveDop = async (\n formattedInputs: FormattedCircuitInputsDop,\n wasm: unknown,\n zkey: ArrayLike<number>,\n logger: { debug: (log: string) => void },\n dat: unknown,\n progressCallback: (progress: number) => void\n ) => {\n // If WCD prover is configured, use it\n if (wcdProverConfig !== null) {\n const circuitId = getCircuitIdFromInputs(formattedInputs);\n logger.debug(`[WCD Prover] Using WCD-based prover for circuit ${circuitId}`);\n \n try {\n const result = await generateProofWithWCD(\n circuitId,\n formattedInputs,\n zkey,\n progressCallback\n );\n \n return {\n proof: result.proof,\n publicSignals: result.publicSignals,\n };\n } catch (error) {\n logger.debug(`[WCD Prover] Error: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n }\n \n // Fallback to original implementation\n return originalFullProveDop(\n formattedInputs,\n wasm as ArrayLike<number> | undefined,\n zkey,\n logger,\n dat as ArrayLike<number> | undefined,\n progressCallback\n );\n };\n \n wcdProverIntercepted = true;\n debugLog('Engine prover intercepted for WCD-based proof generation');\n}\n\n/**\n * Create a WCD artifact store for storing/loading .wcd files\n */\nexport function createWCDArtifactManager(config: WCDProverConfig): WCDArtifactManager {\n return new WCDArtifactManager(config);\n}\n\n/**\n * Store WCD artifacts from local buffers (for testing/development)\n * \n * @example\n * ```typescript\n * // Load WCD file from assets\n * const wcdBuffer = await loadWCDFromAssets('3x2.wcd');\n * const zkeyBuffer = await loadZkeyFromAssets('3x2.zkey');\n * \n * await storeWCDArtifacts('3x2', wcdBuffer, zkeyBuffer);\n * ```\n */\nexport async function storeWCDArtifacts(\n circuitId: string,\n wcdBuffer: Uint8Array,\n zkeyBuffer: Uint8Array,\n): Promise<WCDArtifacts> {\n if (wcdProverConfig === null) {\n throw new Error('WCD Prover not configured. Call setWCDProver first.');\n }\n \n const manager = new WCDArtifactManager(wcdProverConfig);\n \n const [wcdPath, zkeyPath] = await Promise.all([\n manager.storeWCD(circuitId, wcdBuffer),\n manager.storeZkey(circuitId, zkeyBuffer),\n ]);\n \n return {\n wcdPath,\n zkeyPath,\n circuitId,\n };\n}\n\n/**\n * Check if WCD artifacts are available for a circuit\n */\nexport async function hasWCDArtifacts(circuitId: string): Promise<boolean> {\n if (wcdProverConfig === null) {\n return false;\n }\n \n const manager = new WCDArtifactManager(wcdProverConfig);\n return manager.hasArtifacts(circuitId);\n}\n\n/**\n * Get the path where WCD file should be stored\n */\nexport function getWCDPath(circuitId: string): string {\n if (wcdProverConfig === null) {\n throw new Error('WCD Prover not configured. Call setWCDProver first.');\n }\n \n const wcdDir = wcdProverConfig.wcdDirectory ?? \n `${wcdProverConfig.fs.documentDirectory}/dop-wcd`;\n return `${wcdDir}/${circuitId}.wcd`;\n}\n\n/**\n * Get the path where zkey file should be stored\n */\nexport function getZkeyPathForWCD(circuitId: string): string {\n if (wcdProverConfig === null) {\n throw new Error('WCD Prover not configured. Call setWCDProver first.');\n }\n \n const zkeyDir = wcdProverConfig.zkeyDirectory ?? \n `${wcdProverConfig.fs.documentDirectory}/dop-zkeys`;\n return `${zkeyDir}/${circuitId}.zkey`;\n}\n\n/**\n * Store only WCD file (SDK handles zkey download automatically)\n * \n * Use this when bundling WCD files with your mobile app.\n * The SDK will download zkey files on-demand via ArtifactDownloader.\n * \n * @example\n * ```typescript\n * // Load WCD from bundled assets\n * const wcdBuffer = await loadWCDFromAssets('3x2.wcd');\n * await storeWCDOnly('3x2', wcdBuffer);\n * \n * // Now SDK can generate proofs for 3x2 circuit\n * // zkey will be downloaded automatically when needed\n * ```\n */\nexport async function storeWCDOnly(\n circuitId: string,\n wcdBuffer: Uint8Array,\n): Promise<string> {\n if (wcdProverConfig === null) {\n throw new Error('WCD Prover not configured. Call setWCDProver first.');\n }\n \n const manager = new WCDArtifactManager(wcdProverConfig);\n return manager.storeWCD(circuitId, wcdBuffer);\n}\n\n/**\n * Check if WCD file exists for a circuit (zkey is handled by SDK)\n */\nexport async function hasWCDFile(circuitId: string): Promise<boolean> {\n if (wcdProverConfig === null) {\n return false;\n }\n \n const manager = new WCDArtifactManager(wcdProverConfig);\n const wcdPath = `${manager.getWCDDirectory()}/${circuitId}.wcd`;\n return wcdProverConfig.fs.exists(wcdPath);\n}\n\n/**\n * Get list of all stored WCD circuit IDs\n */\nexport async function getStoredWCDCircuits(): Promise<string[]> {\n if (wcdProverConfig === null) {\n return [];\n }\n \n // This would require listing directory contents\n // For now, return empty - mobile devs can track this themselves\n return [];\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom Prover Hook
|
|
3
|
-
*
|
|
4
|
-
* Allows applications (especially React Native) to provide their own proof generation
|
|
5
|
-
* implementation, such as a backend server prover instead of local proving.
|
|
6
|
-
*/
|
|
7
|
-
import { FormattedCircuitInputsDop, Proof } from 'dop-engine-v3';
|
|
8
|
-
/**
|
|
9
|
-
* Custom prover interface that applications can implement
|
|
10
|
-
*
|
|
11
|
-
* Example: Backend server prover for React Native that offloads
|
|
12
|
-
* heavy ZK proof computation to a remote server
|
|
13
|
-
*/
|
|
14
|
-
export interface UserRapidsnarkProver {
|
|
15
|
-
/**
|
|
16
|
-
* Generate a ZK proof for the given circuit and inputs
|
|
17
|
-
*
|
|
18
|
-
* @param circuitId - Circuit identifier (e.g., "3x2" for 3 nullifiers, 2 commitments)
|
|
19
|
-
* @param zkeyBuffer - Circuit zkey file content (may not be needed for backend provers)
|
|
20
|
-
* @param jsonInputs - Formatted circuit inputs (auto-generated by DOP Engine)
|
|
21
|
-
* @param progressCallback - Optional callback for progress updates (0-100)
|
|
22
|
-
* @returns Promise resolving to proof object with pi_a, pi_b, pi_c, and publicSignals
|
|
23
|
-
*/
|
|
24
|
-
generateProof(circuitId: string, zkeyBuffer: Uint8Array, jsonInputs: FormattedCircuitInputsDop, progressCallback?: (progress: number) => void): Promise<Proof>;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Set a custom proof generator
|
|
28
|
-
*
|
|
29
|
-
* This allows applications to provide their own proof generation implementation.
|
|
30
|
-
* Common use case: React Native apps using a backend server for proof generation
|
|
31
|
-
* instead of local proving.
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```typescript
|
|
35
|
-
* // Backend prover for React Native
|
|
36
|
-
* const backendProver: UserRapidsnarkProver = {
|
|
37
|
-
* async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {
|
|
38
|
-
* const response = await fetch('https://your-server.com/api/generate-proof', {
|
|
39
|
-
* method: 'POST',
|
|
40
|
-
* headers: {
|
|
41
|
-
* 'Authorization': 'Bearer YOUR_TOKEN',
|
|
42
|
-
* 'Content-Type': 'application/json',
|
|
43
|
-
* },
|
|
44
|
-
* body: JSON.stringify({
|
|
45
|
-
* circuitId,
|
|
46
|
-
* inputs: jsonInputs,
|
|
47
|
-
* }),
|
|
48
|
-
* });
|
|
49
|
-
*
|
|
50
|
-
* const result = await response.json();
|
|
51
|
-
* return {
|
|
52
|
-
* pi_a: result.proof.pi_a,
|
|
53
|
-
* pi_b: result.proof.pi_b,
|
|
54
|
-
* pi_c: result.proof.pi_c,
|
|
55
|
-
* publicSignals: result.publicSignals,
|
|
56
|
-
* };
|
|
57
|
-
* },
|
|
58
|
-
* };
|
|
59
|
-
*
|
|
60
|
-
* // Set it after DOP Engine initialization
|
|
61
|
-
* setCustomRapidsnarkProver(backendProver);
|
|
62
|
-
* ```
|
|
63
|
-
*
|
|
64
|
-
* @param prover - Custom prover implementation or null to clear
|
|
65
|
-
*/
|
|
66
|
-
export declare const setCustomRapidsnarkProver: (prover: UserRapidsnarkProver | null) => void;
|
|
67
|
-
/**
|
|
68
|
-
* Get the currently registered custom prover
|
|
69
|
-
*
|
|
70
|
-
* @returns Custom prover if set, null otherwise
|
|
71
|
-
*/
|
|
72
|
-
export declare const getCustomRapidsnarkProver: () => UserRapidsnarkProver | null;
|
|
73
|
-
/**
|
|
74
|
-
* Check if a custom prover is currently registered
|
|
75
|
-
*
|
|
76
|
-
* @returns True if custom prover is set, false otherwise
|
|
77
|
-
*/
|
|
78
|
-
export declare const hasCustomRapidsnarkProver: () => boolean;
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Custom Prover Hook
|
|
4
|
-
*
|
|
5
|
-
* Allows applications (especially React Native) to provide their own proof generation
|
|
6
|
-
* implementation, such as a backend server prover instead of local proving.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.hasCustomRapidsnarkProver = exports.getCustomRapidsnarkProver = exports.setCustomRapidsnarkProver = void 0;
|
|
10
|
-
/**
|
|
11
|
-
* Global custom prover storage
|
|
12
|
-
* Set this via setCustomRapidsnarkProver()
|
|
13
|
-
*/
|
|
14
|
-
let customProver = null;
|
|
15
|
-
/**
|
|
16
|
-
* Set a custom proof generator
|
|
17
|
-
*
|
|
18
|
-
* This allows applications to provide their own proof generation implementation.
|
|
19
|
-
* Common use case: React Native apps using a backend server for proof generation
|
|
20
|
-
* instead of local proving.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* // Backend prover for React Native
|
|
25
|
-
* const backendProver: UserRapidsnarkProver = {
|
|
26
|
-
* async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {
|
|
27
|
-
* const response = await fetch('https://your-server.com/api/generate-proof', {
|
|
28
|
-
* method: 'POST',
|
|
29
|
-
* headers: {
|
|
30
|
-
* 'Authorization': 'Bearer YOUR_TOKEN',
|
|
31
|
-
* 'Content-Type': 'application/json',
|
|
32
|
-
* },
|
|
33
|
-
* body: JSON.stringify({
|
|
34
|
-
* circuitId,
|
|
35
|
-
* inputs: jsonInputs,
|
|
36
|
-
* }),
|
|
37
|
-
* });
|
|
38
|
-
*
|
|
39
|
-
* const result = await response.json();
|
|
40
|
-
* return {
|
|
41
|
-
* pi_a: result.proof.pi_a,
|
|
42
|
-
* pi_b: result.proof.pi_b,
|
|
43
|
-
* pi_c: result.proof.pi_c,
|
|
44
|
-
* publicSignals: result.publicSignals,
|
|
45
|
-
* };
|
|
46
|
-
* },
|
|
47
|
-
* };
|
|
48
|
-
*
|
|
49
|
-
* // Set it after DOP Engine initialization
|
|
50
|
-
* setCustomRapidsnarkProver(backendProver);
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* @param prover - Custom prover implementation or null to clear
|
|
54
|
-
*/
|
|
55
|
-
const setCustomRapidsnarkProver = (prover) => {
|
|
56
|
-
customProver = prover;
|
|
57
|
-
console.log(prover ? '✅ Custom prover registered' : '🔄 Custom prover cleared');
|
|
58
|
-
};
|
|
59
|
-
exports.setCustomRapidsnarkProver = setCustomRapidsnarkProver;
|
|
60
|
-
/**
|
|
61
|
-
* Get the currently registered custom prover
|
|
62
|
-
*
|
|
63
|
-
* @returns Custom prover if set, null otherwise
|
|
64
|
-
*/
|
|
65
|
-
const getCustomRapidsnarkProver = () => {
|
|
66
|
-
return customProver;
|
|
67
|
-
};
|
|
68
|
-
exports.getCustomRapidsnarkProver = getCustomRapidsnarkProver;
|
|
69
|
-
/**
|
|
70
|
-
* Check if a custom prover is currently registered
|
|
71
|
-
*
|
|
72
|
-
* @returns True if custom prover is set, false otherwise
|
|
73
|
-
*/
|
|
74
|
-
const hasCustomRapidsnarkProver = () => {
|
|
75
|
-
return customProver !== null;
|
|
76
|
-
};
|
|
77
|
-
exports.hasCustomRapidsnarkProver = hasCustomRapidsnarkProver;
|
|
78
|
-
//# sourceMappingURL=custom-prover.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"custom-prover.js","sourceRoot":"","sources":["../../../../src/services/dop/crypto/custom-prover.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA4BH;;;GAGG;AACH,IAAI,YAAY,GAAgC,IAAI,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACI,MAAM,yBAAyB,GAAG,CAAC,MAAmC,EAAQ,EAAE;IACrF,YAAY,GAAG,MAAM,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;AAClF,CAAC,CAAC;AAHW,QAAA,yBAAyB,6BAGpC;AAEF;;;;GAIG;AACI,MAAM,yBAAyB,GAAG,GAAgC,EAAE;IACzE,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAFW,QAAA,yBAAyB,6BAEpC;AAEF;;;;GAIG;AACI,MAAM,yBAAyB,GAAG,GAAY,EAAE;IACrD,OAAO,YAAY,KAAK,IAAI,CAAC;AAC/B,CAAC,CAAC;AAFW,QAAA,yBAAyB,6BAEpC","sourcesContent":["/**\n * Custom Prover Hook\n * \n * Allows applications (especially React Native) to provide their own proof generation\n * implementation, such as a backend server prover instead of local proving.\n */\n\nimport { FormattedCircuitInputsDop, Proof } from 'dop-engine-v3';\n\n/**\n * Custom prover interface that applications can implement\n * \n * Example: Backend server prover for React Native that offloads\n * heavy ZK proof computation to a remote server\n */\nexport interface UserRapidsnarkProver {\n /**\n * Generate a ZK proof for the given circuit and inputs\n * \n * @param circuitId - Circuit identifier (e.g., \"3x2\" for 3 nullifiers, 2 commitments)\n * @param zkeyBuffer - Circuit zkey file content (may not be needed for backend provers)\n * @param jsonInputs - Formatted circuit inputs (auto-generated by DOP Engine)\n * @param progressCallback - Optional callback for progress updates (0-100)\n * @returns Promise resolving to proof object with pi_a, pi_b, pi_c, and publicSignals\n */\n generateProof(\n circuitId: string,\n zkeyBuffer: Uint8Array,\n jsonInputs: FormattedCircuitInputsDop,\n progressCallback?: (progress: number) => void\n ): Promise<Proof>;\n}\n\n/**\n * Global custom prover storage\n * Set this via setCustomRapidsnarkProver()\n */\nlet customProver: UserRapidsnarkProver | null = null;\n\n/**\n * Set a custom proof generator\n * \n * This allows applications to provide their own proof generation implementation.\n * Common use case: React Native apps using a backend server for proof generation\n * instead of local proving.\n * \n * @example\n * ```typescript\n * // Backend prover for React Native\n * const backendProver: UserRapidsnarkProver = {\n * async generateProof(circuitId, zkeyBuffer, jsonInputs, progressCallback) {\n * const response = await fetch('https://your-server.com/api/generate-proof', {\n * method: 'POST',\n * headers: {\n * 'Authorization': 'Bearer YOUR_TOKEN',\n * 'Content-Type': 'application/json',\n * },\n * body: JSON.stringify({\n * circuitId,\n * inputs: jsonInputs,\n * }),\n * });\n * \n * const result = await response.json();\n * return {\n * pi_a: result.proof.pi_a,\n * pi_b: result.proof.pi_b,\n * pi_c: result.proof.pi_c,\n * publicSignals: result.publicSignals,\n * };\n * },\n * };\n * \n * // Set it after DOP Engine initialization\n * setCustomRapidsnarkProver(backendProver);\n * ```\n * \n * @param prover - Custom prover implementation or null to clear\n */\nexport const setCustomRapidsnarkProver = (prover: UserRapidsnarkProver | null): void => {\n customProver = prover;\n console.log(prover ? '✅ Custom prover registered' : '🔄 Custom prover cleared');\n};\n\n/**\n * Get the currently registered custom prover\n * \n * @returns Custom prover if set, null otherwise\n */\nexport const getCustomRapidsnarkProver = (): UserRapidsnarkProver | null => {\n return customProver;\n};\n\n/**\n * Check if a custom prover is currently registered\n * \n * @returns True if custom prover is set, false otherwise\n */\nexport const hasCustomRapidsnarkProver = (): boolean => {\n return customProver !== null;\n};\n"]}
|