@baerae/zkap-zkp-react-native 0.1.0 → 0.1.2

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 (23) hide show
  1. package/android/build.gradle +2 -0
  2. package/android/libs/arm64-v8a/libzkap_uniffi_bindings.so +0 -0
  3. package/android/libs/armeabi-v7a/libzkap_uniffi_bindings.so +0 -0
  4. package/android/libs/x86_64/libzkap_uniffi_bindings.so +0 -0
  5. package/android/src/main/java/expo/modules/zkap/ZkapSdkModule.kt +127 -38
  6. package/android/src/main/java/uniffi/zkap_uniffi_bindings/zkap_uniffi_bindings.kt +1566 -0
  7. package/ios/ZkapSdkModule.swift +103 -63
  8. package/ios/ZkapZkp.xcframework/Info.plist +9 -9
  9. package/ios/ZkapZkp.xcframework/ios-arm64/Headers/zkap_uniffi_bindingsFFI.h +567 -0
  10. package/ios/ZkapZkp.xcframework/ios-arm64/{libzkap_zkp_rn.a → libzkap_uniffi_bindings.a} +0 -0
  11. package/ios/ZkapZkp.xcframework/ios-arm64_x86_64-simulator/Headers/zkap_uniffi_bindingsFFI.h +567 -0
  12. package/ios/ZkapZkp.xcframework/ios-arm64_x86_64-simulator/{libzkap_zkp_rn_sim.a → libzkap_uniffi_bindings_sim.a} +0 -0
  13. package/ios/uniffi/zkap_uniffi_bindings.swift +1174 -0
  14. package/ios/uniffi/zkap_uniffi_bindingsFFI.h +567 -0
  15. package/ios/uniffi/zkap_uniffi_bindingsFFI.modulemap +7 -0
  16. package/package.json +2 -2
  17. package/src/index.ts +18 -10
  18. package/android/libs/arm64-v8a/libzkap_zkp_rn.so +0 -0
  19. package/android/libs/armeabi-v7a/libzkap_zkp_rn.so +0 -0
  20. package/android/libs/x86_64/libzkap_zkp_rn.so +0 -0
  21. package/ios/ZkapZkp.xcframework/ios-arm64/Headers/zkap_zkp_rn.h +0 -15
  22. package/ios/ZkapZkp.xcframework/ios-arm64_x86_64-simulator/Headers/zkap_zkp_rn.h +0 -15
  23. package/ios/include/zkap_zkp_rn.h +0 -15
@@ -24,6 +24,8 @@ repositories {
24
24
 
25
25
  dependencies {
26
26
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0"
27
+ // JNA is required by uniffi-generated Kotlin bindings
28
+ implementation "net.java.dev.jna:jna:5.14.0@aar"
27
29
  // expo-modules-core provides Module, ModuleDefinition, AsyncFunction, etc.
28
30
  // compileOnly: provided by the consumer app at runtime
29
31
  compileOnly project(':expo-modules-core')
@@ -2,63 +2,152 @@ package expo.modules.zkap
2
2
 
3
3
  import expo.modules.kotlin.modules.Module
4
4
  import expo.modules.kotlin.modules.ModuleDefinition
5
+ import org.json.JSONArray
6
+ import org.json.JSONObject
7
+ import uniffi.zkap_uniffi_bindings.*
5
8
 
9
+ @OptIn(kotlin.ExperimentalUnsignedTypes::class)
6
10
  class ZkapSdkModule : Module() {
7
11
 
8
- // Load the native Rust library (built as libzkap_zkp_rn.so)
9
- companion object {
10
- init {
11
- System.loadLibrary("zkap_zkp_rn")
12
- }
13
-
14
- // JNI-compatible native methods (no underscores → no name-mangling issues).
15
- // Corresponding Rust symbol: Java_expo_modules_zkap_ZkapSdkModule_native<X>
16
- // Each JNI wrapper in Rust calls the C-ABI function, copies the result into
17
- // a Java String, and frees the Rust allocation — no memory leak.
18
- @JvmStatic external fun nativeGenerateHash(inputJson: String): String
19
- @JvmStatic external fun nativeGenerateAnchor(inputJson: String): String
20
- @JvmStatic external fun nativeGenerateAudHash(inputJson: String): String
21
- @JvmStatic external fun nativeGenerateLeafHash(inputJson: String): String
22
- @JvmStatic external fun nativeProve(inputJson: String): String
23
- }
24
-
25
12
  override fun definition() = ModuleDefinition {
26
13
  Name("ZkapSdk")
27
14
 
28
15
  AsyncFunction("generateHash") { inputJson: String ->
29
- unwrapResult(nativeGenerateHash(inputJson))
30
- }
31
-
32
- AsyncFunction("generateAnchor") { inputJson: String ->
33
- unwrapResult(nativeGenerateAnchor(inputJson))
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
+ }
34
25
  }
35
26
 
36
27
  AsyncFunction("generateAudHash") { inputJson: String ->
37
- unwrapResult(nativeGenerateAudHash(inputJson))
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
+ }
38
42
  }
39
43
 
40
44
  AsyncFunction("generateLeafHash") { inputJson: String ->
41
- unwrapResult(nativeGenerateLeafHash(inputJson))
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
+ }
42
55
  }
43
56
 
44
- AsyncFunction("prove") { inputJson: String ->
45
- unwrapResult(nativeProve(inputJson))
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
+ }
46
71
  }
47
- }
48
72
 
49
- /** Parse JSON result from Rust FFI. Throws if the result contains an "error" field. */
50
- @Suppress("UNCHECKED_CAST")
51
- private fun unwrapResult(json: String): String {
52
- try {
53
- val obj = org.json.JSONObject(json)
54
- if (obj.has("error")) {
55
- throw ZkapException(obj.getString("error"))
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")
56
129
  }
57
- } catch (e: org.json.JSONException) {
58
- // Not a JSON object — return as-is
59
130
  }
60
- return json
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
+ )
61
150
  }
62
151
  }
63
152
 
64
- class ZkapException(message: String) : Exception("[zkap] $message")
153
+ class ZkapError(message: String) : Exception("[zkap] $message")