react-native-ufsecp 3.10.0

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.
@@ -0,0 +1,207 @@
1
+ /**
2
+ * UltrafastSecp256k1 — React Native Android Module (ufsecp stable C ABI v1).
3
+ *
4
+ * Bridges NativeModule calls to ufsecp JNI (loads libufsecp_jni.so which links libufsecp.so).
5
+ * All byte-array I/O is hex-encoded.
6
+ */
7
+ package com.ultrafast.ufsecp;
8
+
9
+ import androidx.annotation.NonNull;
10
+
11
+ import com.facebook.react.bridge.Promise;
12
+ import com.facebook.react.bridge.ReactApplicationContext;
13
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
14
+ import com.facebook.react.bridge.ReactMethod;
15
+
16
+ public class UfsecpModule extends ReactContextBaseJavaModule {
17
+
18
+ static {
19
+ System.loadLibrary("ufsecp_jni");
20
+ }
21
+
22
+ private final ReactApplicationContext ctx;
23
+
24
+ public UfsecpModule(ReactApplicationContext reactContext) {
25
+ super(reactContext);
26
+ this.ctx = reactContext;
27
+ }
28
+
29
+ @NonNull
30
+ @Override
31
+ public String getName() {
32
+ return "Ufsecp";
33
+ }
34
+
35
+ /* ── Hex helpers ────────────────────────────────────────────────── */
36
+
37
+ private static byte[] hexToBytes(String hex) {
38
+ int len = hex.length();
39
+ byte[] out = new byte[len / 2];
40
+ for (int i = 0; i < len; i += 2)
41
+ out[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
42
+ + Character.digit(hex.charAt(i + 1), 16));
43
+ return out;
44
+ }
45
+
46
+ private static String bytesToHex(byte[] b) {
47
+ StringBuilder sb = new StringBuilder(b.length * 2);
48
+ for (byte v : b) sb.append(String.format("%02x", v & 0xff));
49
+ return sb.toString();
50
+ }
51
+
52
+ /* ── Native JNI declarations (same as Ufsecp.java) ─────────────── */
53
+
54
+ private static native long nativeCreate();
55
+ private static native void nativeDestroy(long ptr);
56
+ private static native int nativeVersion();
57
+ private static native String nativeVersionString();
58
+ private static native byte[] nativePubkeyCreate(long ctx, byte[] privkey);
59
+ private static native byte[] nativePubkeyCreateUncompressed(long ctx, byte[] privkey);
60
+ private static native boolean nativeSeckeyVerify(long ctx, byte[] privkey);
61
+ private static native byte[] nativeEcdsaSign(long ctx, byte[] msgHash, byte[] privkey);
62
+ private static native boolean nativeEcdsaVerify(long ctx, byte[] msgHash, byte[] sig, byte[] pubkey);
63
+ private static native byte[] nativeSchnorrSign(long ctx, byte[] msg, byte[] privkey, byte[] auxRand);
64
+ private static native boolean nativeSchnorrVerify(long ctx, byte[] msg, byte[] sig, byte[] pubkeyX);
65
+ private static native byte[] nativeEcdh(long ctx, byte[] privkey, byte[] pubkey);
66
+ private static native byte[] nativeSha256(byte[] data);
67
+ private static native byte[] nativeHash160(byte[] data);
68
+ private static native String nativeAddrP2pkh(long ctx, byte[] pubkey, int network);
69
+ private static native String nativeAddrP2wpkh(long ctx, byte[] pubkey, int network);
70
+ private static native String nativeAddrP2tr(long ctx, byte[] xonly, int network);
71
+ private static native String nativeWifEncode(long ctx, byte[] privkey, boolean compressed, int network);
72
+ private static native byte[] nativeBip32Master(long ctx, byte[] seed);
73
+ private static native byte[] nativeBip32Derive(long ctx, byte[] parent, int index);
74
+ private static native byte[] nativeBip32DerivePath(long ctx, byte[] master, String path);
75
+
76
+ /* ── React Native methods ──────────────────────────────────────── */
77
+
78
+ @ReactMethod
79
+ public void create(Promise promise) {
80
+ try { promise.resolve((double) nativeCreate()); }
81
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
82
+ }
83
+
84
+ @ReactMethod
85
+ public void destroy(double handle, Promise promise) {
86
+ try { nativeDestroy((long) handle); promise.resolve(null); }
87
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
88
+ }
89
+
90
+ @ReactMethod
91
+ public void version(Promise promise) { promise.resolve(nativeVersion()); }
92
+
93
+ @ReactMethod
94
+ public void versionString(Promise promise) { promise.resolve(nativeVersionString()); }
95
+
96
+ @ReactMethod
97
+ public void pubkeyCreate(double handle, String privkeyHex, Promise promise) {
98
+ try { promise.resolve(bytesToHex(nativePubkeyCreate((long) handle, hexToBytes(privkeyHex)))); }
99
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
100
+ }
101
+
102
+ @ReactMethod
103
+ public void pubkeyCreateUncompressed(double handle, String privkeyHex, Promise promise) {
104
+ try { promise.resolve(bytesToHex(nativePubkeyCreateUncompressed((long) handle, hexToBytes(privkeyHex)))); }
105
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
106
+ }
107
+
108
+ @ReactMethod
109
+ public void seckeyVerify(double handle, String privkeyHex, Promise promise) {
110
+ try { promise.resolve(nativeSeckeyVerify((long) handle, hexToBytes(privkeyHex))); }
111
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
112
+ }
113
+
114
+ @ReactMethod
115
+ public void ecdsaSign(double handle, String msgHashHex, String privkeyHex, Promise promise) {
116
+ try {
117
+ byte[] sig = nativeEcdsaSign((long) handle, hexToBytes(msgHashHex), hexToBytes(privkeyHex));
118
+ promise.resolve(bytesToHex(sig));
119
+ } catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
120
+ }
121
+
122
+ @ReactMethod
123
+ public void ecdsaVerify(double handle, String msgHashHex, String sigHex, String pubkeyHex, Promise promise) {
124
+ try {
125
+ boolean ok = nativeEcdsaVerify((long) handle, hexToBytes(msgHashHex), hexToBytes(sigHex), hexToBytes(pubkeyHex));
126
+ promise.resolve(ok);
127
+ } catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
128
+ }
129
+
130
+ @ReactMethod
131
+ public void schnorrSign(double handle, String msgHex, String privkeyHex, String auxRandHex, Promise promise) {
132
+ try {
133
+ byte[] sig = nativeSchnorrSign((long) handle, hexToBytes(msgHex), hexToBytes(privkeyHex), hexToBytes(auxRandHex));
134
+ promise.resolve(bytesToHex(sig));
135
+ } catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
136
+ }
137
+
138
+ @ReactMethod
139
+ public void schnorrVerify(double handle, String msgHex, String sigHex, String pubkeyXHex, Promise promise) {
140
+ try {
141
+ boolean ok = nativeSchnorrVerify((long) handle, hexToBytes(msgHex), hexToBytes(sigHex), hexToBytes(pubkeyXHex));
142
+ promise.resolve(ok);
143
+ } catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
144
+ }
145
+
146
+ @ReactMethod
147
+ public void ecdh(double handle, String privkeyHex, String pubkeyHex, Promise promise) {
148
+ try {
149
+ byte[] sec = nativeEcdh((long) handle, hexToBytes(privkeyHex), hexToBytes(pubkeyHex));
150
+ promise.resolve(bytesToHex(sec));
151
+ } catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
152
+ }
153
+
154
+ @ReactMethod
155
+ public void sha256(String dataHex, Promise promise) {
156
+ try { promise.resolve(bytesToHex(nativeSha256(hexToBytes(dataHex)))); }
157
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
158
+ }
159
+
160
+ @ReactMethod
161
+ public void hash160(String dataHex, Promise promise) {
162
+ try { promise.resolve(bytesToHex(nativeHash160(hexToBytes(dataHex)))); }
163
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
164
+ }
165
+
166
+ @ReactMethod
167
+ public void addrP2pkh(double handle, String pubkeyHex, int network, Promise promise) {
168
+ try { promise.resolve(nativeAddrP2pkh((long) handle, hexToBytes(pubkeyHex), network)); }
169
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
170
+ }
171
+
172
+ @ReactMethod
173
+ public void addrP2wpkh(double handle, String pubkeyHex, int network, Promise promise) {
174
+ try { promise.resolve(nativeAddrP2wpkh((long) handle, hexToBytes(pubkeyHex), network)); }
175
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
176
+ }
177
+
178
+ @ReactMethod
179
+ public void addrP2tr(double handle, String xonlyHex, int network, Promise promise) {
180
+ try { promise.resolve(nativeAddrP2tr((long) handle, hexToBytes(xonlyHex), network)); }
181
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
182
+ }
183
+
184
+ @ReactMethod
185
+ public void wifEncode(double handle, String privkeyHex, boolean compressed, int network, Promise promise) {
186
+ try { promise.resolve(nativeWifEncode((long) handle, hexToBytes(privkeyHex), compressed, network)); }
187
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
188
+ }
189
+
190
+ @ReactMethod
191
+ public void bip32Master(double handle, String seedHex, Promise promise) {
192
+ try { promise.resolve(bytesToHex(nativeBip32Master((long) handle, hexToBytes(seedHex)))); }
193
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
194
+ }
195
+
196
+ @ReactMethod
197
+ public void bip32Derive(double handle, String parentHex, int index, Promise promise) {
198
+ try { promise.resolve(bytesToHex(nativeBip32Derive((long) handle, hexToBytes(parentHex), index))); }
199
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
200
+ }
201
+
202
+ @ReactMethod
203
+ public void bip32DerivePath(double handle, String masterHex, String path, Promise promise) {
204
+ try { promise.resolve(bytesToHex(nativeBip32DerivePath((long) handle, hexToBytes(masterHex), path))); }
205
+ catch (Exception e) { promise.reject("UFSECP", e.getMessage()); }
206
+ }
207
+ }
@@ -0,0 +1,385 @@
1
+ package com.ultrafastsecp256k1;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+
6
+ import com.facebook.react.bridge.Arguments;
7
+ import com.facebook.react.bridge.Promise;
8
+ import com.facebook.react.bridge.ReactApplicationContext;
9
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
+ import com.facebook.react.bridge.ReactMethod;
11
+ import com.facebook.react.bridge.WritableMap;
12
+
13
+ /**
14
+ * React Native Android bridge for UltrafastSecp256k1.
15
+ *
16
+ * All byte data is passed as hex strings across the bridge.
17
+ */
18
+ public class UltrafastSecp256k1Module extends ReactContextBaseJavaModule {
19
+
20
+ static {
21
+ System.loadLibrary("ultrafast_secp256k1_jni");
22
+ }
23
+
24
+ public UltrafastSecp256k1Module(ReactApplicationContext reactContext) {
25
+ super(reactContext);
26
+ nativeInit();
27
+ }
28
+
29
+ @NonNull
30
+ @Override
31
+ public String getName() {
32
+ return "UltrafastSecp256k1";
33
+ }
34
+
35
+ // ── Hex helpers ──────────────────────────────────────────────────────
36
+
37
+ private static byte[] hexToBytes(String hex) {
38
+ int len = hex.length();
39
+ byte[] data = new byte[len / 2];
40
+ for (int i = 0; i < len; i += 2) {
41
+ data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
42
+ + Character.digit(hex.charAt(i + 1), 16));
43
+ }
44
+ return data;
45
+ }
46
+
47
+ private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
48
+
49
+ private static String bytesToHex(byte[] bytes) {
50
+ char[] hex = new char[bytes.length * 2];
51
+ for (int i = 0; i < bytes.length; i++) {
52
+ int v = bytes[i] & 0xFF;
53
+ hex[i * 2] = HEX_CHARS[v >>> 4];
54
+ hex[i * 2 + 1] = HEX_CHARS[v & 0x0F];
55
+ }
56
+ return new String(hex);
57
+ }
58
+
59
+ // ── Bridge methods ───────────────────────────────────────────────────
60
+
61
+ @ReactMethod(isBlockingSynchronousMethod = true)
62
+ public String version() {
63
+ return nativeVersion();
64
+ }
65
+
66
+ @ReactMethod
67
+ public void ecPubkeyCreate(String privkeyHex, Promise promise) {
68
+ try {
69
+ byte[] pubkey = nativeEcPubkeyCreate(hexToBytes(privkeyHex));
70
+ promise.resolve(bytesToHex(pubkey));
71
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
72
+ }
73
+
74
+ @ReactMethod
75
+ public void ecPubkeyCreateUncompressed(String privkeyHex, Promise promise) {
76
+ try {
77
+ byte[] pubkey = nativeEcPubkeyCreateUncompressed(hexToBytes(privkeyHex));
78
+ promise.resolve(bytesToHex(pubkey));
79
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
80
+ }
81
+
82
+ @ReactMethod
83
+ public void ecPubkeyParse(String pubkeyHex, Promise promise) {
84
+ try {
85
+ byte[] pubkey = nativeEcPubkeyParse(hexToBytes(pubkeyHex));
86
+ promise.resolve(bytesToHex(pubkey));
87
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
88
+ }
89
+
90
+ @ReactMethod
91
+ public void ecSeckeyVerify(String privkeyHex, Promise promise) {
92
+ try {
93
+ promise.resolve(nativeEcSeckeyVerify(hexToBytes(privkeyHex)));
94
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
95
+ }
96
+
97
+ @ReactMethod
98
+ public void ecPrivkeyNegate(String privkeyHex, Promise promise) {
99
+ try {
100
+ byte[] result = nativeEcPrivkeyNegate(hexToBytes(privkeyHex));
101
+ promise.resolve(bytesToHex(result));
102
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
103
+ }
104
+
105
+ @ReactMethod
106
+ public void ecPrivkeyTweakAdd(String privkeyHex, String tweakHex, Promise promise) {
107
+ try {
108
+ byte[] result = nativeEcPrivkeyTweakAdd(hexToBytes(privkeyHex), hexToBytes(tweakHex));
109
+ promise.resolve(bytesToHex(result));
110
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
111
+ }
112
+
113
+ @ReactMethod
114
+ public void ecPrivkeyTweakMul(String privkeyHex, String tweakHex, Promise promise) {
115
+ try {
116
+ byte[] result = nativeEcPrivkeyTweakMul(hexToBytes(privkeyHex), hexToBytes(tweakHex));
117
+ promise.resolve(bytesToHex(result));
118
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
119
+ }
120
+
121
+ @ReactMethod
122
+ public void ecdsaSign(String msgHashHex, String privkeyHex, Promise promise) {
123
+ try {
124
+ byte[] sig = nativeEcdsaSign(hexToBytes(msgHashHex), hexToBytes(privkeyHex));
125
+ promise.resolve(bytesToHex(sig));
126
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
127
+ }
128
+
129
+ @ReactMethod
130
+ public void ecdsaVerify(String msgHashHex, String sigHex, String pubkeyHex, Promise promise) {
131
+ try {
132
+ promise.resolve(nativeEcdsaVerify(hexToBytes(msgHashHex), hexToBytes(sigHex), hexToBytes(pubkeyHex)));
133
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
134
+ }
135
+
136
+ @ReactMethod
137
+ public void ecdsaSerializeDer(String sigHex, Promise promise) {
138
+ try {
139
+ byte[] der = nativeEcdsaSerializeDer(hexToBytes(sigHex));
140
+ promise.resolve(bytesToHex(der));
141
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
142
+ }
143
+
144
+ @ReactMethod
145
+ public void ecdsaSignRecoverable(String msgHashHex, String privkeyHex, Promise promise) {
146
+ try {
147
+ Object[] result = nativeEcdsaSignRecoverable(hexToBytes(msgHashHex), hexToBytes(privkeyHex));
148
+ WritableMap map = Arguments.createMap();
149
+ map.putString("signature", bytesToHex((byte[]) result[0]));
150
+ map.putInt("recid", (int) result[1]);
151
+ promise.resolve(map);
152
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
153
+ }
154
+
155
+ @ReactMethod
156
+ public void ecdsaRecover(String msgHashHex, String sigHex, int recid, Promise promise) {
157
+ try {
158
+ byte[] pubkey = nativeEcdsaRecover(hexToBytes(msgHashHex), hexToBytes(sigHex), recid);
159
+ promise.resolve(bytesToHex(pubkey));
160
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
161
+ }
162
+
163
+ @ReactMethod
164
+ public void schnorrSign(String msgHex, String privkeyHex, String auxRandHex, Promise promise) {
165
+ try {
166
+ byte[] sig = nativeSchnorrSign(hexToBytes(msgHex), hexToBytes(privkeyHex), hexToBytes(auxRandHex));
167
+ promise.resolve(bytesToHex(sig));
168
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
169
+ }
170
+
171
+ @ReactMethod
172
+ public void schnorrVerify(String msgHex, String sigHex, String pubkeyXHex, Promise promise) {
173
+ try {
174
+ promise.resolve(nativeSchnorrVerify(hexToBytes(msgHex), hexToBytes(sigHex), hexToBytes(pubkeyXHex)));
175
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
176
+ }
177
+
178
+ @ReactMethod
179
+ public void schnorrPubkey(String privkeyHex, Promise promise) {
180
+ try {
181
+ byte[] pubkey = nativeSchnorrPubkey(hexToBytes(privkeyHex));
182
+ promise.resolve(bytesToHex(pubkey));
183
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
184
+ }
185
+
186
+ @ReactMethod
187
+ public void ecdh(String privkeyHex, String pubkeyHex, Promise promise) {
188
+ try {
189
+ byte[] secret = nativeEcdh(hexToBytes(privkeyHex), hexToBytes(pubkeyHex));
190
+ promise.resolve(bytesToHex(secret));
191
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
192
+ }
193
+
194
+ @ReactMethod
195
+ public void ecdhXonly(String privkeyHex, String pubkeyHex, Promise promise) {
196
+ try {
197
+ byte[] secret = nativeEcdhXonly(hexToBytes(privkeyHex), hexToBytes(pubkeyHex));
198
+ promise.resolve(bytesToHex(secret));
199
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
200
+ }
201
+
202
+ @ReactMethod
203
+ public void ecdhRaw(String privkeyHex, String pubkeyHex, Promise promise) {
204
+ try {
205
+ byte[] secret = nativeEcdhRaw(hexToBytes(privkeyHex), hexToBytes(pubkeyHex));
206
+ promise.resolve(bytesToHex(secret));
207
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
208
+ }
209
+
210
+ @ReactMethod
211
+ public void sha256(String dataHex, Promise promise) {
212
+ try {
213
+ byte[] digest = nativeSha256(hexToBytes(dataHex));
214
+ promise.resolve(bytesToHex(digest));
215
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
216
+ }
217
+
218
+ @ReactMethod
219
+ public void hash160(String dataHex, Promise promise) {
220
+ try {
221
+ byte[] digest = nativeHash160(hexToBytes(dataHex));
222
+ promise.resolve(bytesToHex(digest));
223
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
224
+ }
225
+
226
+ @ReactMethod
227
+ public void taggedHash(String tag, String dataHex, Promise promise) {
228
+ try {
229
+ byte[] digest = nativeTaggedHash(tag, hexToBytes(dataHex));
230
+ promise.resolve(bytesToHex(digest));
231
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
232
+ }
233
+
234
+ @ReactMethod
235
+ public void addressP2PKH(String pubkeyHex, int network, Promise promise) {
236
+ try {
237
+ promise.resolve(nativeAddressP2PKH(hexToBytes(pubkeyHex), network));
238
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
239
+ }
240
+
241
+ @ReactMethod
242
+ public void addressP2WPKH(String pubkeyHex, int network, Promise promise) {
243
+ try {
244
+ promise.resolve(nativeAddressP2WPKH(hexToBytes(pubkeyHex), network));
245
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
246
+ }
247
+
248
+ @ReactMethod
249
+ public void addressP2TR(String internalKeyXHex, int network, Promise promise) {
250
+ try {
251
+ promise.resolve(nativeAddressP2TR(hexToBytes(internalKeyXHex), network));
252
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
253
+ }
254
+
255
+ @ReactMethod
256
+ public void wifEncode(String privkeyHex, boolean compressed, int network, Promise promise) {
257
+ try {
258
+ promise.resolve(nativeWifEncode(hexToBytes(privkeyHex), compressed, network));
259
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
260
+ }
261
+
262
+ @ReactMethod
263
+ public void wifDecode(String wif, Promise promise) {
264
+ try {
265
+ Object[] result = nativeWifDecode(wif);
266
+ WritableMap map = Arguments.createMap();
267
+ map.putString("privkey", bytesToHex((byte[]) result[0]));
268
+ map.putBoolean("compressed", (boolean) result[1]);
269
+ map.putInt("network", (int) result[2]);
270
+ promise.resolve(map);
271
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
272
+ }
273
+
274
+ @ReactMethod
275
+ public void bip32MasterKey(String seedHex, Promise promise) {
276
+ try {
277
+ byte[] key = nativeBip32MasterKey(hexToBytes(seedHex));
278
+ promise.resolve(bytesToHex(key));
279
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
280
+ }
281
+
282
+ @ReactMethod
283
+ public void bip32DeriveChild(String parentKeyHex, int index, Promise promise) {
284
+ try {
285
+ byte[] key = nativeBip32DeriveChild(hexToBytes(parentKeyHex), index);
286
+ promise.resolve(bytesToHex(key));
287
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
288
+ }
289
+
290
+ @ReactMethod
291
+ public void bip32DerivePath(String masterKeyHex, String path, Promise promise) {
292
+ try {
293
+ byte[] key = nativeBip32DerivePath(hexToBytes(masterKeyHex), path);
294
+ promise.resolve(bytesToHex(key));
295
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
296
+ }
297
+
298
+ @ReactMethod
299
+ public void bip32GetPrivkey(String keyHex, Promise promise) {
300
+ try {
301
+ byte[] pk = nativeBip32GetPrivkey(hexToBytes(keyHex));
302
+ promise.resolve(bytesToHex(pk));
303
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
304
+ }
305
+
306
+ @ReactMethod
307
+ public void bip32GetPubkey(String keyHex, Promise promise) {
308
+ try {
309
+ byte[] pk = nativeBip32GetPubkey(hexToBytes(keyHex));
310
+ promise.resolve(bytesToHex(pk));
311
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
312
+ }
313
+
314
+ @ReactMethod
315
+ public void taprootOutputKey(String internalKeyXHex, @Nullable String merkleRootHex, Promise promise) {
316
+ try {
317
+ byte[] mr = merkleRootHex != null ? hexToBytes(merkleRootHex) : null;
318
+ Object[] result = nativeTaprootOutputKey(hexToBytes(internalKeyXHex), mr);
319
+ WritableMap map = Arguments.createMap();
320
+ map.putString("outputKeyX", bytesToHex((byte[]) result[0]));
321
+ map.putInt("parity", (int) result[1]);
322
+ promise.resolve(map);
323
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
324
+ }
325
+
326
+ @ReactMethod
327
+ public void taprootTweakPrivkey(String privkeyHex, @Nullable String merkleRootHex, Promise promise) {
328
+ try {
329
+ byte[] mr = merkleRootHex != null ? hexToBytes(merkleRootHex) : null;
330
+ byte[] result = nativeTaprootTweakPrivkey(hexToBytes(privkeyHex), mr);
331
+ promise.resolve(bytesToHex(result));
332
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
333
+ }
334
+
335
+ @ReactMethod
336
+ public void taprootVerifyCommitment(String outputKeyXHex, int parity,
337
+ String internalKeyXHex, @Nullable String merkleRootHex, Promise promise) {
338
+ try {
339
+ byte[] mr = merkleRootHex != null ? hexToBytes(merkleRootHex) : null;
340
+ promise.resolve(nativeTaprootVerifyCommitment(hexToBytes(outputKeyXHex), parity,
341
+ hexToBytes(internalKeyXHex), mr));
342
+ } catch (Exception e) { promise.reject("ERR", e.getMessage()); }
343
+ }
344
+
345
+ // ── Native declarations ──────────────────────────────────────────────
346
+ // These delegate to the JNI bridge (same as com.ultrafast.secp256k1.Secp256k1)
347
+
348
+ private static native int nativeInit();
349
+ private static native String nativeVersion();
350
+ private static native byte[] nativeEcPubkeyCreate(byte[] privkey);
351
+ private static native byte[] nativeEcPubkeyCreateUncompressed(byte[] privkey);
352
+ private static native byte[] nativeEcPubkeyParse(byte[] input);
353
+ private static native boolean nativeEcSeckeyVerify(byte[] privkey);
354
+ private static native byte[] nativeEcPrivkeyNegate(byte[] privkey);
355
+ private static native byte[] nativeEcPrivkeyTweakAdd(byte[] privkey, byte[] tweak);
356
+ private static native byte[] nativeEcPrivkeyTweakMul(byte[] privkey, byte[] tweak);
357
+ private static native byte[] nativeEcdsaSign(byte[] msgHash, byte[] privkey);
358
+ private static native boolean nativeEcdsaVerify(byte[] msgHash, byte[] sig, byte[] pubkey);
359
+ private static native byte[] nativeEcdsaSerializeDer(byte[] sig);
360
+ private static native Object[] nativeEcdsaSignRecoverable(byte[] msgHash, byte[] privkey);
361
+ private static native byte[] nativeEcdsaRecover(byte[] msgHash, byte[] sig, int recid);
362
+ private static native byte[] nativeSchnorrSign(byte[] msg, byte[] privkey, byte[] auxRand);
363
+ private static native boolean nativeSchnorrVerify(byte[] msg, byte[] sig, byte[] pubkeyX);
364
+ private static native byte[] nativeSchnorrPubkey(byte[] privkey);
365
+ private static native byte[] nativeEcdh(byte[] privkey, byte[] pubkey);
366
+ private static native byte[] nativeEcdhXonly(byte[] privkey, byte[] pubkey);
367
+ private static native byte[] nativeEcdhRaw(byte[] privkey, byte[] pubkey);
368
+ private static native byte[] nativeSha256(byte[] data);
369
+ private static native byte[] nativeHash160(byte[] data);
370
+ private static native byte[] nativeTaggedHash(String tag, byte[] data);
371
+ private static native String nativeAddressP2PKH(byte[] pubkey, int network);
372
+ private static native String nativeAddressP2WPKH(byte[] pubkey, int network);
373
+ private static native String nativeAddressP2TR(byte[] internalKeyX, int network);
374
+ private static native String nativeWifEncode(byte[] privkey, boolean compressed, int network);
375
+ private static native Object[] nativeWifDecode(String wif);
376
+ private static native byte[] nativeBip32MasterKey(byte[] seed);
377
+ private static native byte[] nativeBip32DeriveChild(byte[] parentKey, int index);
378
+ private static native byte[] nativeBip32DerivePath(byte[] masterKey, String path);
379
+ private static native byte[] nativeBip32GetPrivkey(byte[] key);
380
+ private static native byte[] nativeBip32GetPubkey(byte[] key);
381
+ private static native Object[] nativeTaprootOutputKey(byte[] internalKeyX, byte[] merkleRoot);
382
+ private static native byte[] nativeTaprootTweakPrivkey(byte[] privkey, byte[] merkleRoot);
383
+ private static native boolean nativeTaprootVerifyCommitment(byte[] outputKeyX, int parity,
384
+ byte[] internalKeyX, byte[] merkleRoot);
385
+ }
@@ -0,0 +1,28 @@
1
+ package com.ultrafastsecp256k1;
2
+
3
+ import androidx.annotation.NonNull;
4
+
5
+ import com.facebook.react.ReactPackage;
6
+ import com.facebook.react.bridge.NativeModule;
7
+ import com.facebook.react.bridge.ReactApplicationContext;
8
+ import com.facebook.react.uimanager.ViewManager;
9
+
10
+ import java.util.ArrayList;
11
+ import java.util.Collections;
12
+ import java.util.List;
13
+
14
+ public class UltrafastSecp256k1Package implements ReactPackage {
15
+ @NonNull
16
+ @Override
17
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
+ List<NativeModule> modules = new ArrayList<>();
19
+ modules.add(new UltrafastSecp256k1Module(reactContext));
20
+ return modules;
21
+ }
22
+
23
+ @NonNull
24
+ @Override
25
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
26
+ return Collections.emptyList();
27
+ }
28
+ }