@baerae/zkap-zkp-react-native 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +24 -1
  2. package/ZkapReactNative.podspec +42 -0
  3. package/android/CMakeLists.txt +81 -0
  4. package/android/build.gradle +111 -14
  5. package/android/cpp-adapter.cpp +43 -0
  6. package/android/libs/arm64-v8a/libzkap_uniffi_bindings.so +0 -0
  7. package/android/libs/x86_64/libzkap_uniffi_bindings.so +0 -0
  8. package/android/proguard-rules.pro +2 -0
  9. package/android/src/main/AndroidManifest.xml +5 -0
  10. package/android/src/main/java/com/baerae/zkapreactnative/ZkapReactNativeModule.kt +51 -0
  11. package/android/src/main/java/com/baerae/zkapreactnative/ZkapReactNativePackage.kt +34 -0
  12. package/cpp/baerae-zkap-react-native.cpp +17 -0
  13. package/cpp/baerae-zkap-react-native.h +15 -0
  14. package/cpp/generated/zkap_uniffi_bindings.cpp +2154 -0
  15. package/cpp/generated/zkap_uniffi_bindings.hpp +66 -0
  16. package/ios/ZkapReactNative.h +16 -0
  17. package/ios/ZkapReactNative.mm +412 -0
  18. package/ios/ZkapZkp.xcframework/Info.plist +5 -5
  19. package/ios/ZkapZkp.xcframework/ios-arm64/libzkap_uniffi_bindings.a +0 -0
  20. package/ios/ZkapZkp.xcframework/ios-arm64_x86_64-simulator/libzkap_uniffi_bindings.a +0 -0
  21. package/package.json +37 -14
  22. package/src/NativeZkapReactNative.ts +11 -0
  23. package/src/generated/zkap_uniffi_bindings-ffi.ts +150 -0
  24. package/src/generated/zkap_uniffi_bindings.ts +1015 -0
  25. package/src/index.ts +250 -46
  26. package/ubrn.config.yaml +13 -0
  27. package/android/libs/armeabi-v7a/libzkap_uniffi_bindings.so +0 -0
  28. package/android/src/main/java/expo/modules/zkap/ZkapSdkModule.kt +0 -153
  29. package/android/src/main/java/uniffi/zkap_uniffi_bindings/zkap_uniffi_bindings.kt +0 -1566
  30. package/expo-module.config.json +0 -9
  31. package/ios/ZkapSdkModule.podspec +0 -35
  32. package/ios/ZkapSdkModule.swift +0 -147
  33. package/ios/uniffi/zkap_uniffi_bindings.swift +0 -1174
  34. package/ios/uniffi/zkap_uniffi_bindingsFFI.h +0 -567
  35. package/ios/uniffi/zkap_uniffi_bindingsFFI.modulemap +0 -7
package/src/index.ts CHANGED
@@ -1,6 +1,19 @@
1
- import { requireNativeModule } from 'expo-modules-core';
2
-
3
- const ZkapSdk = requireNativeModule('ZkapSdk');
1
+ import NativeZkapReactNative from './NativeZkapReactNative';
2
+ import { Platform } from 'react-native';
3
+ import generatedBindings, {
4
+ generateAnchor as nativeGenerateAnchor,
5
+ generateAudHash as nativeGenerateAudHash,
6
+ generateHash as nativeGenerateHash,
7
+ generateLeafHash as nativeGenerateLeafHash,
8
+ prepareWitnessInputs as nativePrepareWitnessInputs,
9
+ prove as nativeProve,
10
+ proveFromWitnessBundleFile as nativeProveFromWitnessBundleFile,
11
+ type ZkapCircuitConfig,
12
+ type ZkapPreparedWitnessInputs,
13
+ type ZkapProofRequest,
14
+ type ZkapProveCredential,
15
+ type ZkapWitnessBundleFile,
16
+ } from './generated/zkap_uniffi_bindings';
4
17
 
5
18
  // ──────────────────────────────────────────────────────────────────
6
19
  // Input / Output types
@@ -28,34 +41,212 @@ export interface Secret {
28
41
  aud: string;
29
42
  }
30
43
 
44
+ export interface ProveCredential {
45
+ jwt: string;
46
+ rsa_modulus_b64?: string;
47
+ rsaModulusB64?: string;
48
+ merkle_path?: string[];
49
+ merklePath?: string[];
50
+ merkle_leaf_idx?: number;
51
+ merkleLeafIdx?: number;
52
+ }
53
+
31
54
  export interface ProveRequest {
32
- pk_path: string;
33
- jwts: string[];
34
- pk_ops: string[];
35
- merkle_paths: string[][];
36
- leaf_indices: number[];
37
- root: string;
38
- /** Anchor polynomial evaluations (N - K + 1 entries). */
39
- anchor_evals: string[];
40
- /** Anchor chain hash (hanchor). */
41
- hanchor: string;
42
- h_sign_user_op: string;
55
+ manifest_dir?: string;
56
+ manifestDir?: string;
43
57
  random: string;
44
- /** Pre-computed audience hashes (from generateAudHash). */
45
- aud_hash_list: string[];
58
+ h_sign_user_op?: string;
59
+ hSignUserOp?: string;
60
+ anchor: string[];
61
+ merkle_root?: string;
62
+ merkleRoot?: string;
63
+ credentials: ProveCredential[];
46
64
  }
47
65
 
48
66
  export interface ProveResult {
49
67
  /** Solidity-compatible proof per proof: [ax, ay, bx_c1, bx_c0, by_c1, by_c0, cx, cy] */
50
68
  proofs: string[][];
51
- /** Public inputs shared across all JWTs (indices 0,1,2,3,6,7) as decimal strings */
69
+ /** Public inputs shared across all JWTs as decimal strings. */
52
70
  shared_inputs: string[];
53
- /** partial_rhs per JWT (index 5) as decimal string */
71
+ /** partial_rhs per JWT as decimal string. */
54
72
  partial_rhs_list: string[];
55
- /** jwt_exp per JWT (index 4) as decimal string */
73
+ /** jwt_exp per JWT as decimal string. */
56
74
  jwt_exp_list: string[];
57
75
  }
58
76
 
77
+ let initialized = false;
78
+ const IOS_WITNESS_CHUNK_SIZE = 4 * 1024 * 1024;
79
+
80
+ function ensureInitialized(): void {
81
+ if (initialized) return;
82
+ NativeZkapReactNative.installRustCrate();
83
+ generatedBindings.initialize();
84
+ initialized = true;
85
+ }
86
+
87
+ type ZkapUniFfiError = Error & {
88
+ tag?: string;
89
+ inner?: {
90
+ message?: string;
91
+ };
92
+ };
93
+
94
+ function withZkapErrorMessage<T>(fn: () => T): T {
95
+ try {
96
+ return fn();
97
+ } catch (error) {
98
+ const zkapError = error as ZkapUniFfiError;
99
+ const message = zkapError?.inner?.message;
100
+ if (typeof message === 'string' && message.length > 0) {
101
+ const wrapped = new Error(message);
102
+ wrapped.name = zkapError.tag
103
+ ? `ZkapError.${zkapError.tag}`
104
+ : zkapError.name || 'ZkapError';
105
+ (wrapped as Error & { cause?: unknown }).cause = error;
106
+ throw wrapped;
107
+ }
108
+ throw error;
109
+ }
110
+ }
111
+
112
+ function toNativeConfig(config: CircuitConfig): ZkapCircuitConfig {
113
+ return {
114
+ maxJwtB64Len: BigInt(config.max_jwt_b64_len),
115
+ maxPayloadB64Len: BigInt(config.max_payload_b64_len),
116
+ maxAudLen: BigInt(config.max_aud_len),
117
+ maxExpLen: BigInt(config.max_exp_len),
118
+ maxIssLen: BigInt(config.max_iss_len),
119
+ maxNonceLen: BigInt(config.max_nonce_len),
120
+ maxSubLen: BigInt(config.max_sub_len),
121
+ n: BigInt(config.n),
122
+ k: BigInt(config.k),
123
+ treeHeight: BigInt(config.tree_height),
124
+ numAudienceLimit: BigInt(config.num_audience_limit),
125
+ claims: config.claims,
126
+ forbiddenString: config.forbidden_string,
127
+ };
128
+ }
129
+
130
+ function requireString(value: string | undefined, field: string): string {
131
+ if (!value) {
132
+ throw new Error(`[zkap/sdk-react-native] missing ${field}`);
133
+ }
134
+ return value;
135
+ }
136
+
137
+ function requireArray<T>(value: T[] | undefined, field: string): T[] {
138
+ if (!value) {
139
+ throw new Error(`[zkap/sdk-react-native] missing ${field}`);
140
+ }
141
+ return value;
142
+ }
143
+
144
+ function requireNumber(value: number | undefined, field: string): number {
145
+ if (value === undefined || value === null) {
146
+ throw new Error(`[zkap/sdk-react-native] missing ${field}`);
147
+ }
148
+ return value;
149
+ }
150
+
151
+ function toNativeCredential(credential: ProveCredential): ZkapProveCredential {
152
+ return {
153
+ jwt: credential.jwt,
154
+ rsaModulusB64: requireString(
155
+ credential.rsa_modulus_b64 ?? credential.rsaModulusB64,
156
+ 'credential.rsa_modulus_b64',
157
+ ),
158
+ merklePath: requireArray(
159
+ credential.merkle_path ?? credential.merklePath,
160
+ 'credential.merkle_path',
161
+ ),
162
+ merkleLeafIdx: BigInt(
163
+ requireNumber(
164
+ credential.merkle_leaf_idx ?? credential.merkleLeafIdx,
165
+ 'credential.merkle_leaf_idx',
166
+ ),
167
+ ),
168
+ };
169
+ }
170
+
171
+ function toNativeRequest(request: ProveRequest): ZkapProofRequest {
172
+ return {
173
+ manifestDir: requireString(
174
+ request.manifest_dir ?? request.manifestDir,
175
+ 'manifest_dir',
176
+ ),
177
+ random: request.random,
178
+ hSignUserOp: requireString(
179
+ request.h_sign_user_op ?? request.hSignUserOp,
180
+ 'h_sign_user_op',
181
+ ),
182
+ anchor: request.anchor,
183
+ merkleRoot: requireString(
184
+ request.merkle_root ?? request.merkleRoot,
185
+ 'merkle_root',
186
+ ),
187
+ credentials: request.credentials.map(toNativeCredential),
188
+ };
189
+ }
190
+
191
+ function toProofResult(result: {
192
+ proofs: string[][];
193
+ sharedInputs: string[];
194
+ partialRhsList: string[];
195
+ jwtExpList: string[];
196
+ }): ProveResult {
197
+ return {
198
+ proofs: result.proofs,
199
+ shared_inputs: result.sharedInputs,
200
+ partial_rhs_list: result.partialRhsList,
201
+ jwt_exp_list: result.jwtExpList,
202
+ };
203
+ }
204
+
205
+ function makeRunId(): string {
206
+ return `zkap-${Date.now().toString(36)}-${Math.random()
207
+ .toString(36)
208
+ .slice(2)}`;
209
+ }
210
+
211
+ type IosWitnessRunnerResult = {
212
+ witnessBundlePath?: unknown;
213
+ sha256?: unknown;
214
+ byteLength?: unknown;
215
+ };
216
+
217
+ async function runIosWitness(
218
+ prepared: ZkapPreparedWitnessInputs,
219
+ ): Promise<ZkapWitnessBundleFile> {
220
+ const inputJson = JSON.stringify({
221
+ run_id: makeRunId(),
222
+ chunk_size: IOS_WITNESS_CHUNK_SIZE,
223
+ wasm_base64: prepared.wasmBase64,
224
+ request_json_base64: prepared.requestJsonBase64,
225
+ config_json_base64: prepared.configJsonBase64,
226
+ witness_gen_sha256: prepared.witnessGenSha256,
227
+ request_json_sha256: prepared.requestJsonSha256,
228
+ config_json_sha256: prepared.configJsonSha256,
229
+ wasm_byte_length: prepared.wasmByteLength.toString(),
230
+ request_json_byte_length: prepared.requestJsonByteLength.toString(),
231
+ config_json_byte_length: prepared.configJsonByteLength.toString(),
232
+ });
233
+
234
+ const resultJson = await NativeZkapReactNative.runWitnessInWkWebView(inputJson);
235
+ const parsed = JSON.parse(resultJson) as IosWitnessRunnerResult;
236
+ if (
237
+ typeof parsed.witnessBundlePath !== 'string' ||
238
+ typeof parsed.sha256 !== 'string' ||
239
+ typeof parsed.byteLength !== 'number'
240
+ ) {
241
+ throw new Error('[zkap/sdk-react-native] invalid WKWebView witness result');
242
+ }
243
+ return {
244
+ witnessBundlePath: parsed.witnessBundlePath,
245
+ sha256: parsed.sha256,
246
+ byteLength: BigInt(parsed.byteLength),
247
+ };
248
+ }
249
+
59
250
  // ──────────────────────────────────────────────────────────────────
60
251
  // Supported API
61
252
  // ──────────────────────────────────────────────────────────────────
@@ -65,10 +256,8 @@ export interface ProveResult {
65
256
  * Returns the result as a 0x-prefixed hex string.
66
257
  */
67
258
  export async function generateHash(messages: string[]): Promise<string> {
68
- const result: string = await ZkapSdk.generateHash(
69
- JSON.stringify({ messages })
70
- );
71
- return JSON.parse(result).result as string;
259
+ ensureInitialized();
260
+ return withZkapErrorMessage(() => nativeGenerateHash(messages));
72
261
  }
73
262
 
74
263
  /**
@@ -77,12 +266,10 @@ export async function generateHash(messages: string[]): Promise<string> {
77
266
  */
78
267
  export async function generateAnchor(
79
268
  config: CircuitConfig,
80
- secrets: Secret[]
269
+ secrets: Secret[],
81
270
  ): Promise<{ evaluations: string[] }> {
82
- const result: string = await ZkapSdk.generateAnchor(
83
- JSON.stringify({ config, secrets })
84
- );
85
- return JSON.parse(result) as { evaluations: string[] };
271
+ ensureInitialized();
272
+ return withZkapErrorMessage(() => nativeGenerateAnchor(toNativeConfig(config), secrets));
86
273
  }
87
274
 
88
275
  /**
@@ -90,12 +277,16 @@ export async function generateAnchor(
90
277
  */
91
278
  export async function generateAudHash(
92
279
  config: CircuitConfig,
93
- aud_list: string[]
280
+ aud_list: string[],
94
281
  ): Promise<{ aud_hashes: string[]; h_aud_list: string }> {
95
- const result: string = await ZkapSdk.generateAudHash(
96
- JSON.stringify({ config, aud_list })
282
+ ensureInitialized();
283
+ const result = withZkapErrorMessage(() =>
284
+ nativeGenerateAudHash(toNativeConfig(config), aud_list)
97
285
  );
98
- return JSON.parse(result) as { aud_hashes: string[]; h_aud_list: string };
286
+ return {
287
+ aud_hashes: result.audHashes,
288
+ h_aud_list: result.hAudList,
289
+ };
99
290
  }
100
291
 
101
292
  /**
@@ -104,26 +295,40 @@ export async function generateAudHash(
104
295
  export async function generateLeafHash(
105
296
  config: CircuitConfig,
106
297
  iss: string,
107
- pk_b64: string
298
+ pk_b64: string,
108
299
  ): Promise<string> {
109
- const result: string = await ZkapSdk.generateLeafHash(
110
- JSON.stringify({ config, iss, pk_b64 })
111
- );
112
- return JSON.parse(result).result as string;
300
+ ensureInitialized();
301
+ return withZkapErrorMessage(() => nativeGenerateLeafHash(toNativeConfig(config), iss, pk_b64));
113
302
  }
114
303
 
115
304
  /**
116
305
  * Generate Groth16 proofs (on-device proving).
117
- * Requires a proving key file on disk.
306
+ *
307
+ * Requires a manifest-validated CRS directory containing manifest.json,
308
+ * circuit.ar1cs, pk.bin, vk.bin, pvk.bin, config.json, and witness_gen.wasm.
118
309
  */
119
310
  export async function prove(
120
311
  config: CircuitConfig,
121
- request: ProveRequest
312
+ request: ProveRequest,
122
313
  ): Promise<ProveResult> {
123
- const result: string = await ZkapSdk.prove(
124
- JSON.stringify({ config, request })
314
+ ensureInitialized();
315
+ const nativeConfig = toNativeConfig(config);
316
+ const nativeRequest = toNativeRequest(request);
317
+ if (Platform.OS === 'ios') {
318
+ const prepared = withZkapErrorMessage(() =>
319
+ nativePrepareWitnessInputs(nativeConfig, nativeRequest)
320
+ );
321
+ const witness = await runIosWitness(prepared);
322
+ return toProofResult(
323
+ withZkapErrorMessage(() =>
324
+ nativeProveFromWitnessBundleFile(nativeConfig, nativeRequest, witness)
325
+ )
326
+ );
327
+ }
328
+
329
+ return toProofResult(
330
+ withZkapErrorMessage(() => nativeProve(nativeConfig, nativeRequest))
125
331
  );
126
- return JSON.parse(result) as ProveResult;
127
332
  }
128
333
 
129
334
  // ──────────────────────────────────────────────────────────────────
@@ -137,18 +342,17 @@ export async function prove(
137
342
  export function groth16Setup(): never {
138
343
  throw new Error(
139
344
  '[zkap/sdk-react-native] groth16Setup() is not supported on mobile. ' +
140
- 'Note: this function has been removed from all SDK packages as of v0.1.2.'
345
+ 'Note: this function has been removed from all SDK packages as of v0.1.2.',
141
346
  );
142
347
  }
143
348
 
144
349
  /**
145
350
  * NOT supported on React Native.
146
- * verify() has been removed from all SDK packages as of v0.1.2.
351
+ * Verification is currently kept on-chain / server-side for mobile consumers.
147
352
  */
148
353
  export function verify(): never {
149
354
  throw new Error(
150
355
  '[zkap/sdk-react-native] verify() is not supported on mobile. ' +
151
- 'Note: this function has been removed from all SDK packages as of v0.1.2.'
356
+ 'Use the on-chain verifier or the Node SDK verify() helper.',
152
357
  );
153
358
  }
154
-
@@ -0,0 +1,13 @@
1
+ rust:
2
+ directory: ../../crates/uniffi-bindings
3
+ manifestPath: Cargo.toml
4
+ android:
5
+ apiLevel: 28
6
+ targets:
7
+ - arm64-v8a
8
+ - x86_64
9
+ ios:
10
+ targets:
11
+ - aarch64-apple-ios
12
+ - aarch64-apple-ios-sim
13
+ - x86_64-apple-ios
@@ -1,153 +0,0 @@
1
- package expo.modules.zkap
2
-
3
- import expo.modules.kotlin.modules.Module
4
- import expo.modules.kotlin.modules.ModuleDefinition
5
- import org.json.JSONArray
6
- import org.json.JSONObject
7
- import uniffi.zkap_uniffi_bindings.*
8
-
9
- @OptIn(kotlin.ExperimentalUnsignedTypes::class)
10
- class ZkapSdkModule : Module() {
11
-
12
- override fun definition() = ModuleDefinition {
13
- Name("ZkapSdk")
14
-
15
- AsyncFunction("generateHash") { inputJson: String ->
16
- try {
17
- val obj = JSONObject(inputJson)
18
- val messagesArr = obj.getJSONArray("messages")
19
- val messages = List(messagesArr.length()) { messagesArr.getString(it) }
20
- val result = generateHash(messages)
21
- JSONObject().put("result", result).toString()
22
- } catch (e: ZkapException) {
23
- throw ZkapError(e.message ?: "ZkapException")
24
- }
25
- }
26
-
27
- AsyncFunction("generateAudHash") { inputJson: String ->
28
- try {
29
- val obj = JSONObject(inputJson)
30
- val config = parseConfig(obj.getJSONObject("config"))
31
- val audArr = obj.getJSONArray("aud_list")
32
- val audList = List(audArr.length()) { audArr.getString(it) }
33
- val result = generateAudHash(config, audList)
34
- val audHashesArr = JSONArray(result.audHashes)
35
- JSONObject()
36
- .put("aud_hashes", audHashesArr)
37
- .put("h_aud_list", result.hAudList)
38
- .toString()
39
- } catch (e: ZkapException) {
40
- throw ZkapError(e.message ?: "ZkapException")
41
- }
42
- }
43
-
44
- AsyncFunction("generateLeafHash") { inputJson: String ->
45
- try {
46
- val obj = JSONObject(inputJson)
47
- val config = parseConfig(obj.getJSONObject("config"))
48
- val iss = obj.getString("iss")
49
- val pkB64 = obj.getString("pk_b64")
50
- val result = generateLeafHash(config, iss, pkB64)
51
- JSONObject().put("result", result).toString()
52
- } catch (e: ZkapException) {
53
- throw ZkapError(e.message ?: "ZkapException")
54
- }
55
- }
56
-
57
- AsyncFunction("generateAnchor") { inputJson: String ->
58
- try {
59
- val obj = JSONObject(inputJson)
60
- val config = parseConfig(obj.getJSONObject("config"))
61
- val secretsArr = obj.getJSONArray("secrets")
62
- val secrets = List(secretsArr.length()) { i ->
63
- val s = secretsArr.getJSONObject(i)
64
- ZkapSecret(sub = s.getString("sub"), iss = s.getString("iss"), aud = s.getString("aud"))
65
- }
66
- val result = generateAnchor(config, secrets)
67
- JSONObject().put("evaluations", JSONArray(result.evaluations)).toString()
68
- } catch (e: ZkapException) {
69
- throw ZkapError(e.message ?: "ZkapException")
70
- }
71
- }
72
-
73
- AsyncFunction("prove") { inputJson: String ->
74
- try {
75
- val obj = JSONObject(inputJson)
76
- val config = parseConfig(obj.getJSONObject("config"))
77
- val req = obj.getJSONObject("request")
78
-
79
- val jwtsArr = req.getJSONArray("jwts")
80
- val jwts = List(jwtsArr.length()) { jwtsArr.getString(it) }
81
-
82
- val pkOpsArr = req.getJSONArray("pk_ops")
83
- val pkOps = List(pkOpsArr.length()) { pkOpsArr.getString(it) }
84
-
85
- val merklePathsArr = req.getJSONArray("merkle_paths")
86
- val merklePaths = List(merklePathsArr.length()) { i ->
87
- val inner = merklePathsArr.getJSONArray(i)
88
- List(inner.length()) { j -> inner.getString(j) }
89
- }
90
-
91
- val leafIndicesArr = req.getJSONArray("leaf_indices")
92
- val leafIndices = List(leafIndicesArr.length()) { leafIndicesArr.getLong(it).toULong() }
93
-
94
- val anchorEvalsArr = req.getJSONArray("anchor_evals")
95
- val anchorEvals = List(anchorEvalsArr.length()) { anchorEvalsArr.getString(it) }
96
-
97
- val audHashListArr = req.getJSONArray("aud_hash_list")
98
- val audHashList = List(audHashListArr.length()) { audHashListArr.getString(it) }
99
-
100
- val request = ZkapProofRequest(
101
- pkPath = req.getString("pk_path"),
102
- jwts = jwts,
103
- pkOps = pkOps,
104
- merklePaths = merklePaths,
105
- leafIndices = leafIndices,
106
- root = req.getString("root"),
107
- anchorEvals = anchorEvals,
108
- hanchor = req.getString("hanchor"),
109
- hSignUserOp = req.getString("h_sign_user_op"),
110
- random = req.getString("random"),
111
- audHashList = audHashList
112
- )
113
-
114
- val output = prove(config, request)
115
-
116
- val proofsArr = JSONArray()
117
- for (proofList in output.proofs) {
118
- proofsArr.put(JSONArray(proofList))
119
- }
120
-
121
- JSONObject()
122
- .put("proofs", proofsArr)
123
- .put("shared_inputs", JSONArray(output.sharedInputs))
124
- .put("partial_rhs_list", JSONArray(output.partialRhsList))
125
- .put("jwt_exp_list", JSONArray(output.jwtExpList))
126
- .toString()
127
- } catch (e: ZkapException) {
128
- throw ZkapError(e.message ?: "ZkapException")
129
- }
130
- }
131
- }
132
-
133
- private fun parseConfig(obj: JSONObject): ZkapCircuitConfig {
134
- val claimsArr = obj.getJSONArray("claims")
135
- return ZkapCircuitConfig(
136
- maxJwtB64Len = obj.getLong("max_jwt_b64_len").toULong(),
137
- maxPayloadB64Len = obj.getLong("max_payload_b64_len").toULong(),
138
- maxAudLen = obj.getLong("max_aud_len").toULong(),
139
- maxExpLen = obj.getLong("max_exp_len").toULong(),
140
- maxIssLen = obj.getLong("max_iss_len").toULong(),
141
- maxNonceLen = obj.getLong("max_nonce_len").toULong(),
142
- maxSubLen = obj.getLong("max_sub_len").toULong(),
143
- n = obj.getLong("n").toULong(),
144
- k = obj.getLong("k").toULong(),
145
- treeHeight = obj.getLong("tree_height").toULong(),
146
- numAudienceLimit = obj.getLong("num_audience_limit").toULong(),
147
- claims = List(claimsArr.length()) { claimsArr.getString(it) },
148
- forbiddenString = obj.getString("forbidden_string")
149
- )
150
- }
151
- }
152
-
153
- class ZkapError(message: String) : Exception("[zkap] $message")