@qntx/nostr-native 0.0.0-stage → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/NostrNative.podspec +37 -0
- package/README.md +30 -2
- package/android/CMakeLists.txt +38 -0
- package/android/build.gradle +136 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +7 -0
- package/android/src/main/java/com/margelo/nitro/nostrnative/NostrNativePackage.java +29 -0
- package/cpp/HybridNostrNative.cpp +52 -0
- package/cpp/HybridNostrNative.hpp +22 -0
- package/cpp/nostr_core.c +128 -0
- package/cpp/nostr_core.h +65 -0
- package/cpp/nostr_native.c +54 -0
- package/cpp/nostr_native.h +47 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.mjs +26 -0
- package/dist/index.mjs.map +1 -0
- package/nitro.json +19 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/NostrNative+autolinking.cmake +81 -0
- package/nitrogen/generated/android/NostrNative+autolinking.gradle +27 -0
- package/nitrogen/generated/android/NostrNativeOnLoad.cpp +49 -0
- package/nitrogen/generated/android/NostrNativeOnLoad.hpp +34 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nostrnative/NostrNativeOnLoad.kt +35 -0
- package/nitrogen/generated/ios/NostrNative+autolinking.rb +62 -0
- package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.cpp +17 -0
- package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.hpp +27 -0
- package/nitrogen/generated/ios/NostrNative-Swift-Cxx-Umbrella.hpp +38 -0
- package/nitrogen/generated/ios/NostrNativeAutolinking.mm +35 -0
- package/nitrogen/generated/ios/NostrNativeAutolinking.swift +16 -0
- package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridNostrNativeSpec.hpp +64 -0
- package/package.json +86 -4
- package/react-native.config.js +12 -0
- package/vendor/secp256k1/COPYING +19 -0
- package/vendor/secp256k1/include/secp256k1.h +931 -0
- package/vendor/secp256k1/include/secp256k1_ecdh.h +63 -0
- package/vendor/secp256k1/include/secp256k1_ellswift.h +200 -0
- package/vendor/secp256k1/include/secp256k1_extrakeys.h +250 -0
- package/vendor/secp256k1/include/secp256k1_musig.h +588 -0
- package/vendor/secp256k1/include/secp256k1_preallocated.h +134 -0
- package/vendor/secp256k1/include/secp256k1_recovery.h +123 -0
- package/vendor/secp256k1/include/secp256k1_schnorrsig.h +179 -0
- package/vendor/secp256k1/include/secp256k1_silentpayments.h +396 -0
- package/vendor/secp256k1/src/assumptions.h +87 -0
- package/vendor/secp256k1/src/checkmem.h +117 -0
- package/vendor/secp256k1/src/ecdsa.h +21 -0
- package/vendor/secp256k1/src/ecdsa_impl.h +309 -0
- package/vendor/secp256k1/src/eckey.h +28 -0
- package/vendor/secp256k1/src/eckey_impl.h +94 -0
- package/vendor/secp256k1/src/ecmult.h +64 -0
- package/vendor/secp256k1/src/ecmult_compute_table.h +16 -0
- package/vendor/secp256k1/src/ecmult_compute_table_impl.h +49 -0
- package/vendor/secp256k1/src/ecmult_const.h +38 -0
- package/vendor/secp256k1/src/ecmult_const_impl.h +402 -0
- package/vendor/secp256k1/src/ecmult_gen.h +145 -0
- package/vendor/secp256k1/src/ecmult_gen_compute_table.h +14 -0
- package/vendor/secp256k1/src/ecmult_gen_compute_table_impl.h +108 -0
- package/vendor/secp256k1/src/ecmult_gen_impl.h +347 -0
- package/vendor/secp256k1/src/ecmult_impl.h +869 -0
- package/vendor/secp256k1/src/field.h +351 -0
- package/vendor/secp256k1/src/field_10x26.h +57 -0
- package/vendor/secp256k1/src/field_10x26_impl.h +1210 -0
- package/vendor/secp256k1/src/field_5x52.h +62 -0
- package/vendor/secp256k1/src/field_5x52_impl.h +496 -0
- package/vendor/secp256k1/src/field_5x52_int128_impl.h +274 -0
- package/vendor/secp256k1/src/field_impl.h +457 -0
- package/vendor/secp256k1/src/group.h +218 -0
- package/vendor/secp256k1/src/group_impl.h +1014 -0
- package/vendor/secp256k1/src/hash.h +56 -0
- package/vendor/secp256k1/src/hash_impl.h +397 -0
- package/vendor/secp256k1/src/hsort.h +33 -0
- package/vendor/secp256k1/src/hsort_impl.h +125 -0
- package/vendor/secp256k1/src/int128.h +90 -0
- package/vendor/secp256k1/src/int128_impl.h +18 -0
- package/vendor/secp256k1/src/int128_native.h +19 -0
- package/vendor/secp256k1/src/int128_native_impl.h +94 -0
- package/vendor/secp256k1/src/int128_struct.h +14 -0
- package/vendor/secp256k1/src/int128_struct_impl.h +205 -0
- package/vendor/secp256k1/src/modinv32.h +43 -0
- package/vendor/secp256k1/src/modinv32_impl.h +725 -0
- package/vendor/secp256k1/src/modinv64.h +47 -0
- package/vendor/secp256k1/src/modinv64_impl.h +780 -0
- package/vendor/secp256k1/src/modules/extrakeys/main_impl.h +292 -0
- package/vendor/secp256k1/src/modules/schnorrsig/main_impl.h +256 -0
- package/vendor/secp256k1/src/precomputed_ecmult.c +16456 -0
- package/vendor/secp256k1/src/precomputed_ecmult.h +40 -0
- package/vendor/secp256k1/src/precomputed_ecmult_gen.c +1779 -0
- package/vendor/secp256k1/src/precomputed_ecmult_gen.h +28 -0
- package/vendor/secp256k1/src/scalar.h +105 -0
- package/vendor/secp256k1/src/scalar_4x64.h +19 -0
- package/vendor/secp256k1/src/scalar_4x64_impl.h +1005 -0
- package/vendor/secp256k1/src/scalar_8x32.h +19 -0
- package/vendor/secp256k1/src/scalar_8x32_impl.h +820 -0
- package/vendor/secp256k1/src/scalar_impl.h +321 -0
- package/vendor/secp256k1/src/scalar_low.h +24 -0
- package/vendor/secp256k1/src/scalar_low_impl.h +217 -0
- package/vendor/secp256k1/src/scratch.h +44 -0
- package/vendor/secp256k1/src/scratch_impl.h +99 -0
- package/vendor/secp256k1/src/secp256k1.c +855 -0
- package/vendor/secp256k1/src/selftest.h +41 -0
- package/vendor/secp256k1/src/util.h +479 -0
- package/vendor/secp256k1/src/util_local_visibility.h +12 -0
- package/vendor/secp256k1/vendored.json +6 -0
package/cpp/nostr_core.c
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The vendored libsecp256k1 is compiled as a single translation unit inside this file:
|
|
3
|
+
* secp256k1.c includes every implementation header plus the modules enabled with
|
|
4
|
+
* -DENABLE_MODULE_EXTRAKEYS / -DENABLE_MODULE_SCHNORRSIG, so this TU also sees the library's
|
|
5
|
+
* internal SHA-256 (nostr_native_secp256k1_sha256_*) and
|
|
6
|
+
* nostr_native_secp256k1_memclear_explicit. Those are internal APIs of the pinned vendor tree —
|
|
7
|
+
* the NIST SHA-256 vectors in tests/host guard them.
|
|
8
|
+
*
|
|
9
|
+
* The vendor script prefixes every secp256k1_ identifier with nostr_native_ (see
|
|
10
|
+
* scripts/vendor-secp256k1.ts): React Native pods are statically linked into one binary and an
|
|
11
|
+
* unprefixed libsecp256k1 would collide with any other pod embedding it. This is the only TU
|
|
12
|
+
* that may include secp256k1.c — the two precomputed-table TUs stay separate. It must come
|
|
13
|
+
* before nostr_core.h: secp256k1.c defines SECP256K1_BUILD and refuses to be the second
|
|
14
|
+
* includer of its own public header.
|
|
15
|
+
*/
|
|
16
|
+
#include "../vendor/secp256k1/src/secp256k1.c"
|
|
17
|
+
#include "../vendor/secp256k1/include/secp256k1_extrakeys.h"
|
|
18
|
+
#include "../vendor/secp256k1/include/secp256k1_schnorrsig.h"
|
|
19
|
+
|
|
20
|
+
#include "nostr_core.h"
|
|
21
|
+
|
|
22
|
+
void nostr_core_wipe(void *ptr, size_t len) {
|
|
23
|
+
nostr_native_secp256k1_memclear_explicit(ptr, len);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
int nostr_core_verify(const nostr_native_secp256k1_context *ctx, const unsigned char id[32],
|
|
27
|
+
const unsigned char pubkey[32], const unsigned char sig[64]) {
|
|
28
|
+
nostr_native_secp256k1_xonly_pubkey parsed;
|
|
29
|
+
|
|
30
|
+
if (ctx == NULL || id == NULL || pubkey == NULL || sig == NULL) {
|
|
31
|
+
return NOSTR_CORE_INVALID_INPUT;
|
|
32
|
+
}
|
|
33
|
+
if (!nostr_native_secp256k1_xonly_pubkey_parse(ctx, &parsed, pubkey)) {
|
|
34
|
+
return NOSTR_CORE_INVALID_INPUT;
|
|
35
|
+
}
|
|
36
|
+
return nostr_native_secp256k1_schnorrsig_verify(ctx, sig, id, 32, &parsed)
|
|
37
|
+
? NOSTR_CORE_OK
|
|
38
|
+
: NOSTR_CORE_VERIFY_FAILED;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
int nostr_core_verify_serialized(const nostr_native_secp256k1_context *ctx,
|
|
42
|
+
const unsigned char *serialized, size_t len,
|
|
43
|
+
const unsigned char id[32], const unsigned char pubkey[32],
|
|
44
|
+
const unsigned char sig[64]) {
|
|
45
|
+
unsigned char digest[32];
|
|
46
|
+
nostr_native_secp256k1_sha256 sha;
|
|
47
|
+
const nostr_native_secp256k1_hash_ctx *hash_ctx;
|
|
48
|
+
size_t i;
|
|
49
|
+
|
|
50
|
+
if (ctx == NULL || serialized == NULL || id == NULL || pubkey == NULL || sig == NULL) {
|
|
51
|
+
return NOSTR_CORE_INVALID_INPUT;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
hash_ctx = nostr_native_secp256k1_get_hash_context(ctx);
|
|
55
|
+
nostr_native_secp256k1_sha256_initialize(&sha);
|
|
56
|
+
nostr_native_secp256k1_sha256_write(hash_ctx, &sha, serialized, len);
|
|
57
|
+
nostr_native_secp256k1_sha256_finalize(hash_ctx, &sha, digest);
|
|
58
|
+
for (i = 0; i < 32; i++) {
|
|
59
|
+
if (digest[i] != id[i]) {
|
|
60
|
+
return NOSTR_CORE_VERIFY_FAILED;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return nostr_core_verify(ctx, id, pubkey, sig);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
int nostr_core_sign(const nostr_native_secp256k1_context *ctx, const unsigned char id[32],
|
|
67
|
+
const unsigned char seckey[32], const unsigned char aux[32],
|
|
68
|
+
unsigned char out_sig[64]) {
|
|
69
|
+
nostr_native_secp256k1_keypair keypair;
|
|
70
|
+
int ok;
|
|
71
|
+
|
|
72
|
+
if (ctx == NULL || id == NULL || seckey == NULL || aux == NULL || out_sig == NULL) {
|
|
73
|
+
return NOSTR_CORE_INVALID_INPUT;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
ok = nostr_native_secp256k1_keypair_create(ctx, &keypair, seckey) &&
|
|
77
|
+
nostr_native_secp256k1_schnorrsig_sign32(ctx, out_sig, id, &keypair, aux);
|
|
78
|
+
nostr_native_secp256k1_memclear_explicit(&keypair, sizeof(keypair));
|
|
79
|
+
return ok ? NOSTR_CORE_OK : NOSTR_CORE_INVALID_INPUT;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
int nostr_core_public_key(const nostr_native_secp256k1_context *ctx,
|
|
83
|
+
const unsigned char seckey[32], unsigned char out_xonly[32]) {
|
|
84
|
+
nostr_native_secp256k1_keypair keypair;
|
|
85
|
+
nostr_native_secp256k1_xonly_pubkey pubkey;
|
|
86
|
+
int ok;
|
|
87
|
+
|
|
88
|
+
if (ctx == NULL || seckey == NULL || out_xonly == NULL) {
|
|
89
|
+
return NOSTR_CORE_INVALID_INPUT;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
ok = nostr_native_secp256k1_keypair_create(ctx, &keypair, seckey) &&
|
|
93
|
+
nostr_native_secp256k1_keypair_xonly_pub(ctx, &pubkey, NULL, &keypair) &&
|
|
94
|
+
nostr_native_secp256k1_xonly_pubkey_serialize(ctx, out_xonly, &pubkey);
|
|
95
|
+
nostr_native_secp256k1_memclear_explicit(&keypair, sizeof(keypair));
|
|
96
|
+
return ok ? NOSTR_CORE_OK : NOSTR_CORE_INVALID_INPUT;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#ifdef NOSTR_NATIVE_TEST
|
|
100
|
+
|
|
101
|
+
nostr_native_secp256k1_context *nostr_native_test_context(void) {
|
|
102
|
+
static nostr_native_secp256k1_context *ctx;
|
|
103
|
+
if (ctx == NULL) {
|
|
104
|
+
ctx = nostr_native_secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
|
105
|
+
}
|
|
106
|
+
return ctx;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
void nostr_native_test_sha256(const unsigned char *data, size_t len, unsigned char out32[32]) {
|
|
110
|
+
nostr_native_secp256k1_context *ctx = nostr_native_test_context();
|
|
111
|
+
const nostr_native_secp256k1_hash_ctx *hash_ctx = nostr_native_secp256k1_get_hash_context(ctx);
|
|
112
|
+
nostr_native_secp256k1_sha256 sha;
|
|
113
|
+
nostr_native_secp256k1_sha256_initialize(&sha);
|
|
114
|
+
nostr_native_secp256k1_sha256_write(hash_ctx, &sha, data, len);
|
|
115
|
+
nostr_native_secp256k1_sha256_finalize(hash_ctx, &sha, out32);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
int nostr_native_test_schnorr_verify(const unsigned char *msg, size_t msglen,
|
|
119
|
+
const unsigned char pubkey[32], const unsigned char sig[64]) {
|
|
120
|
+
nostr_native_secp256k1_context *ctx = nostr_native_test_context();
|
|
121
|
+
nostr_native_secp256k1_xonly_pubkey parsed;
|
|
122
|
+
if (!nostr_native_secp256k1_xonly_pubkey_parse(ctx, &parsed, pubkey)) {
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
return nostr_native_secp256k1_schnorrsig_verify(ctx, sig, msg, msglen, &parsed);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
#endif
|
package/cpp/nostr_core.h
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#ifndef NOSTR_CORE_H
|
|
2
|
+
#define NOSTR_CORE_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
|
|
6
|
+
#include "../vendor/secp256k1/include/secp256k1.h"
|
|
7
|
+
|
|
8
|
+
#ifdef __cplusplus
|
|
9
|
+
extern "C" {
|
|
10
|
+
#endif
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Platform-independent secp256k1 operations shared by the React Native layer
|
|
14
|
+
* (nostr_native.c) and the wasm32 layer (packages/nostr-wasm/c/nostr_wasm.c).
|
|
15
|
+
* Every entry point takes the caller's context; status codes:
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/* Success, or the signature verified. */
|
|
19
|
+
#define NOSTR_CORE_OK 0
|
|
20
|
+
/* The hash or signature check failed. */
|
|
21
|
+
#define NOSTR_CORE_VERIFY_FAILED 1
|
|
22
|
+
/* NULL argument, invalid scalar, or a non-point public key. */
|
|
23
|
+
#define NOSTR_CORE_INVALID_INPUT 2
|
|
24
|
+
|
|
25
|
+
/* BIP-340 verify of the 32-byte `id` for the x-only `pubkey`. */
|
|
26
|
+
int nostr_core_verify(const nostr_native_secp256k1_context *ctx, const unsigned char id[32],
|
|
27
|
+
const unsigned char pubkey[32], const unsigned char sig[64]);
|
|
28
|
+
|
|
29
|
+
/* `sha256(serialized[0..len])` must equal `id`, then BIP-340 verify. */
|
|
30
|
+
int nostr_core_verify_serialized(const nostr_native_secp256k1_context *ctx,
|
|
31
|
+
const unsigned char *serialized, size_t len,
|
|
32
|
+
const unsigned char id[32], const unsigned char pubkey[32],
|
|
33
|
+
const unsigned char sig[64]);
|
|
34
|
+
|
|
35
|
+
/* BIP-340 sign the 32-byte `id` with caller-supplied `aux` randomness; writes
|
|
36
|
+
* 64 signature bytes on NOSTR_CORE_OK. The keypair is wiped on every path. */
|
|
37
|
+
int nostr_core_sign(const nostr_native_secp256k1_context *ctx, const unsigned char id[32],
|
|
38
|
+
const unsigned char seckey[32], const unsigned char aux[32],
|
|
39
|
+
unsigned char out_sig[64]);
|
|
40
|
+
|
|
41
|
+
/* Write the 32-byte x-only public key of `seckey` to `out_xonly`. */
|
|
42
|
+
int nostr_core_public_key(const nostr_native_secp256k1_context *ctx,
|
|
43
|
+
const unsigned char seckey[32], unsigned char out_xonly[32]);
|
|
44
|
+
|
|
45
|
+
/* Secure wipe for platform layers that must clear caller-provided regions. */
|
|
46
|
+
void nostr_core_wipe(void *ptr, size_t len);
|
|
47
|
+
|
|
48
|
+
#ifdef NOSTR_NATIVE_TEST
|
|
49
|
+
/* Test-only entry points (host suite only): expose the SHA-256 and Schnorr halves individually
|
|
50
|
+
* so BIP-340 vectors with arbitrary-length messages and raw SHA-256 vectors can run. */
|
|
51
|
+
|
|
52
|
+
/* A lazily created context owned by the test binary; never destroyed. */
|
|
53
|
+
nostr_native_secp256k1_context *nostr_native_test_context(void);
|
|
54
|
+
|
|
55
|
+
void nostr_native_test_sha256(const unsigned char *data, size_t len, unsigned char out32[32]);
|
|
56
|
+
|
|
57
|
+
int nostr_native_test_schnorr_verify(const unsigned char *msg, size_t msglen,
|
|
58
|
+
const unsigned char pubkey[32], const unsigned char sig[64]);
|
|
59
|
+
#endif
|
|
60
|
+
|
|
61
|
+
#ifdef __cplusplus
|
|
62
|
+
}
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
#endif /* NOSTR_CORE_H */
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#include "nostr_native.h"
|
|
2
|
+
|
|
3
|
+
#include "nostr_core.h"
|
|
4
|
+
|
|
5
|
+
#include <pthread.h>
|
|
6
|
+
#include <stdlib.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
/*
|
|
10
|
+
* React Native platform layer: owns the process context (pthread_once creation plus an
|
|
11
|
+
* arc4random seed) and delegates the crypto work to nostr_core.c — the single TU that
|
|
12
|
+
* compiles the vendored libsecp256k1. CONTEXT_NONE runs the library self test; randomizing
|
|
13
|
+
* with an arc4random seed blinds ecmult_gen against side-channel leakage of the secret key
|
|
14
|
+
* while signing. Every public entry point resolves the context first.
|
|
15
|
+
*/
|
|
16
|
+
static nostr_native_secp256k1_context *module_ctx;
|
|
17
|
+
static pthread_once_t module_ctx_once = PTHREAD_ONCE_INIT;
|
|
18
|
+
|
|
19
|
+
static void init_module_context(void) {
|
|
20
|
+
unsigned char seed[32];
|
|
21
|
+
nostr_native_secp256k1_context *created =
|
|
22
|
+
nostr_native_secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
|
23
|
+
if (created == NULL) {
|
|
24
|
+
abort();
|
|
25
|
+
}
|
|
26
|
+
arc4random_buf(seed, sizeof(seed));
|
|
27
|
+
if (!nostr_native_secp256k1_context_randomize(created, seed)) {
|
|
28
|
+
abort();
|
|
29
|
+
}
|
|
30
|
+
nostr_core_wipe(seed, sizeof(seed));
|
|
31
|
+
module_ctx = created;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static nostr_native_secp256k1_context *module_context(void) {
|
|
35
|
+
pthread_once(&module_ctx_once, init_module_context);
|
|
36
|
+
return module_ctx;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
int nostr_native_verify_serialized(const unsigned char *serialized, size_t len,
|
|
40
|
+
const unsigned char id[32],
|
|
41
|
+
const unsigned char pubkey[32],
|
|
42
|
+
const unsigned char sig[64]) {
|
|
43
|
+
return nostr_core_verify_serialized(module_context(), serialized, len, id, pubkey, sig) ==
|
|
44
|
+
NOSTR_CORE_OK;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
int nostr_native_public_key(const unsigned char seckey[32], unsigned char out_xonly[32]) {
|
|
48
|
+
return nostr_core_public_key(module_context(), seckey, out_xonly) == NOSTR_CORE_OK;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
int nostr_native_sign(const unsigned char id[32], const unsigned char seckey[32],
|
|
52
|
+
const unsigned char aux_rand[32], unsigned char out_sig[64]) {
|
|
53
|
+
return nostr_core_sign(module_context(), id, seckey, aux_rand, out_sig) == NOSTR_CORE_OK;
|
|
54
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#ifndef NOSTR_NATIVE_H
|
|
2
|
+
#define NOSTR_NATIVE_H
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
extern "C" {
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Return 1 iff `sha256(serialized[0..len])` equals `id` and `sig` is a valid BIP-340 signature of
|
|
12
|
+
* `id` for the x-only `pubkey`. `id`/`pubkey` are 32 bytes and `sig` is 64 bytes; NULL pointers
|
|
13
|
+
* return 0.
|
|
14
|
+
*/
|
|
15
|
+
int nostr_native_verify_serialized(const unsigned char *serialized, size_t len,
|
|
16
|
+
const unsigned char id[32],
|
|
17
|
+
const unsigned char pubkey[32],
|
|
18
|
+
const unsigned char sig[64]);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Write the 32-byte x-only BIP-340 public key of `seckey` to `out_xonly`.
|
|
22
|
+
* Returns 1 on success; 0 on NULL input or an invalid secret key (zero or >= group order).
|
|
23
|
+
*/
|
|
24
|
+
int nostr_native_public_key(const unsigned char seckey[32], unsigned char out_xonly[32]);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Write the 64-byte BIP-340 signature of `id` by `seckey` with `aux_rand` auxiliary randomness
|
|
28
|
+
* to `out_sig`. Returns 1 on success; 0 on NULL input or an invalid secret key.
|
|
29
|
+
*/
|
|
30
|
+
int nostr_native_sign(const unsigned char id[32], const unsigned char seckey[32],
|
|
31
|
+
const unsigned char aux_rand[32], unsigned char out_sig[64]);
|
|
32
|
+
|
|
33
|
+
#ifdef NOSTR_NATIVE_TEST
|
|
34
|
+
/* Test-only entry points (host suite only): expose the SHA-256 and Schnorr halves individually
|
|
35
|
+
* so BIP-340 vectors with arbitrary-length messages and raw SHA-256 vectors can run. */
|
|
36
|
+
|
|
37
|
+
void nostr_native_test_sha256(const unsigned char *data, size_t len, unsigned char out32[32]);
|
|
38
|
+
|
|
39
|
+
int nostr_native_test_schnorr_verify(const unsigned char *msg, size_t msglen,
|
|
40
|
+
const unsigned char pubkey[32], const unsigned char sig[64]);
|
|
41
|
+
#endif
|
|
42
|
+
|
|
43
|
+
#ifdef __cplusplus
|
|
44
|
+
}
|
|
45
|
+
#endif
|
|
46
|
+
|
|
47
|
+
#endif /* NOSTR_NATIVE_H */
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SerializedEventVerifier, SigningBackend } from "@qntx/nostr/core";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* `SerializedEventVerifier` backed by native libsecp256k1 — plug into `createEventVerifier` from
|
|
5
|
+
* `@qntx/nostr/core`. The Nitro hybrid object is created once at module load.
|
|
6
|
+
*/
|
|
7
|
+
export declare const verifySerialized: SerializedEventVerifier;
|
|
8
|
+
/**
|
|
9
|
+
* `SigningBackend` backed by native libsecp256k1 — plug into `Keys.fromSecretKey(secretKey,
|
|
10
|
+
* signing)` or `Keys.generate(signing)` so signing runs on the same randomized context as
|
|
11
|
+
* verification. Throws on an invalid secret key or wrong-length input.
|
|
12
|
+
*/
|
|
13
|
+
export declare const signing: SigningBackend;
|
|
14
|
+
//#endregion
|
|
15
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { NitroModules } from "react-native-nitro-modules";
|
|
2
|
+
//#region src/index.ts
|
|
3
|
+
const nostrNative = NitroModules.createHybridObject("NostrNative");
|
|
4
|
+
function asArrayBuffer(view) {
|
|
5
|
+
const { buffer, byteOffset, byteLength } = view;
|
|
6
|
+
if (buffer instanceof ArrayBuffer && byteOffset === 0 && byteLength === buffer.byteLength) return buffer;
|
|
7
|
+
return new Uint8Array(view).buffer;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* `SerializedEventVerifier` backed by native libsecp256k1 — plug into `createEventVerifier` from
|
|
11
|
+
* `@qntx/nostr/core`. The Nitro hybrid object is created once at module load.
|
|
12
|
+
*/
|
|
13
|
+
const verifySerialized = (serializedUtf8, id, pubkey, sig) => nostrNative.verifySerialized(asArrayBuffer(serializedUtf8), asArrayBuffer(id), asArrayBuffer(pubkey), asArrayBuffer(sig));
|
|
14
|
+
/**
|
|
15
|
+
* `SigningBackend` backed by native libsecp256k1 — plug into `Keys.fromSecretKey(secretKey,
|
|
16
|
+
* signing)` or `Keys.generate(signing)` so signing runs on the same randomized context as
|
|
17
|
+
* verification. Throws on an invalid secret key or wrong-length input.
|
|
18
|
+
*/
|
|
19
|
+
const signing = {
|
|
20
|
+
publicKey: (secretKey) => new Uint8Array(nostrNative.publicKey(asArrayBuffer(secretKey))),
|
|
21
|
+
sign: (id, secretKey, auxRand) => new Uint8Array(nostrNative.sign(asArrayBuffer(id), asArrayBuffer(secretKey), asArrayBuffer(auxRand)))
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { signing, verifySerialized };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { NitroModules } from \"react-native-nitro-modules\";\n\nimport type { SerializedEventVerifier, SigningBackend } from \"@qntx/nostr/core\";\n\nimport type { NostrNative } from \"./specs/nostr-native.nitro.ts\";\n\nconst nostrNative = NitroModules.createHybridObject<NostrNative>(\"NostrNative\");\n\nfunction asArrayBuffer(view: Uint8Array): ArrayBuffer {\n const { buffer, byteOffset, byteLength } = view;\n if (buffer instanceof ArrayBuffer && byteOffset === 0 && byteLength === buffer.byteLength) {\n return buffer;\n }\n return new Uint8Array(view).buffer;\n}\n\n/**\n * `SerializedEventVerifier` backed by native libsecp256k1 — plug into `createEventVerifier` from\n * `@qntx/nostr/core`. The Nitro hybrid object is created once at module load.\n */\nexport const verifySerialized: SerializedEventVerifier = (serializedUtf8, id, pubkey, sig) =>\n nostrNative.verifySerialized(\n asArrayBuffer(serializedUtf8),\n asArrayBuffer(id),\n asArrayBuffer(pubkey),\n asArrayBuffer(sig),\n );\n\n/**\n * `SigningBackend` backed by native libsecp256k1 — plug into `Keys.fromSecretKey(secretKey,\n * signing)` or `Keys.generate(signing)` so signing runs on the same randomized context as\n * verification. Throws on an invalid secret key or wrong-length input.\n */\nexport const signing: SigningBackend = {\n publicKey: (secretKey) => new Uint8Array(nostrNative.publicKey(asArrayBuffer(secretKey))),\n sign: (id, secretKey, auxRand) =>\n new Uint8Array(\n nostrNative.sign(asArrayBuffer(id), asArrayBuffer(secretKey), asArrayBuffer(auxRand)),\n ),\n};\n"],"mappings":";;AAMA,MAAM,cAAc,aAAa,mBAAgC,aAAa;AAE9E,SAAS,cAAc,MAA+B;CACpD,MAAM,EAAE,QAAQ,YAAY,eAAe;CAC3C,IAAI,kBAAkB,eAAe,eAAe,KAAK,eAAe,OAAO,YAC7E,OAAO;CAET,OAAO,IAAI,WAAW,IAAI,CAAC,CAAC;AAC9B;;;;;AAMA,MAAa,oBAA6C,gBAAgB,IAAI,QAAQ,QACpF,YAAY,iBACV,cAAc,cAAc,GAC5B,cAAc,EAAE,GAChB,cAAc,MAAM,GACpB,cAAc,GAAG,CACnB;;;;;;AAOF,MAAa,UAA0B;CACrC,YAAY,cAAc,IAAI,WAAW,YAAY,UAAU,cAAc,SAAS,CAAC,CAAC;CACxF,OAAO,IAAI,WAAW,YACpB,IAAI,WACF,YAAY,KAAK,cAAc,EAAE,GAAG,cAAc,SAAS,GAAG,cAAc,OAAO,CAAC,CACtF;AACJ"}
|
package/nitro.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://nitro.margelo.com/nitro.schema.json",
|
|
3
|
+
"cxxNamespace": ["nostrnative"],
|
|
4
|
+
"ios": {
|
|
5
|
+
"iosModuleName": "NostrNative"
|
|
6
|
+
},
|
|
7
|
+
"android": {
|
|
8
|
+
"androidNamespace": ["nostrnative"],
|
|
9
|
+
"androidCxxLibName": "NostrNative"
|
|
10
|
+
},
|
|
11
|
+
"autolinking": {
|
|
12
|
+
"NostrNative": {
|
|
13
|
+
"all": {
|
|
14
|
+
"language": "c++",
|
|
15
|
+
"implementationClassName": "HybridNostrNative"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
** linguist-generated=true
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#
|
|
2
|
+
# NostrNative+autolinking.cmake
|
|
3
|
+
# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
# https://github.com/mrousavy/nitro
|
|
5
|
+
# Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
# This is a CMake file that adds all files generated by Nitrogen
|
|
9
|
+
# to the current CMake project.
|
|
10
|
+
#
|
|
11
|
+
# To use it, add this to your CMakeLists.txt:
|
|
12
|
+
# ```cmake
|
|
13
|
+
# include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/NostrNative+autolinking.cmake)
|
|
14
|
+
# ```
|
|
15
|
+
|
|
16
|
+
# Define a flag to check if we are building properly
|
|
17
|
+
add_definitions(-DBUILDING_NOSTRNATIVE_WITH_GENERATED_CMAKE_PROJECT)
|
|
18
|
+
|
|
19
|
+
# Enable Raw Props parsing in react-native (for Nitro Views)
|
|
20
|
+
add_definitions(-DRN_SERIALIZABLE_STATE)
|
|
21
|
+
|
|
22
|
+
# Add all headers that were generated by Nitrogen
|
|
23
|
+
include_directories(
|
|
24
|
+
"../nitrogen/generated/shared/c++"
|
|
25
|
+
"../nitrogen/generated/android/c++"
|
|
26
|
+
"../nitrogen/generated/android/"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Add all .cpp sources that were generated by Nitrogen
|
|
30
|
+
target_sources(
|
|
31
|
+
# CMake project name (Android C++ library name)
|
|
32
|
+
NostrNative PRIVATE
|
|
33
|
+
# Autolinking Setup
|
|
34
|
+
../nitrogen/generated/android/NostrNativeOnLoad.cpp
|
|
35
|
+
# Shared Nitrogen C++ sources
|
|
36
|
+
../nitrogen/generated/shared/c++/HybridNostrNativeSpec.cpp
|
|
37
|
+
# Android-specific Nitrogen C++ sources
|
|
38
|
+
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
|
|
42
|
+
# Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
|
|
43
|
+
target_compile_definitions(
|
|
44
|
+
NostrNative PRIVATE
|
|
45
|
+
-DFOLLY_NO_CONFIG=1
|
|
46
|
+
-DFOLLY_HAVE_CLOCK_GETTIME=1
|
|
47
|
+
-DFOLLY_USE_LIBCPP=1
|
|
48
|
+
-DFOLLY_CFG_NO_COROUTINES=1
|
|
49
|
+
-DFOLLY_MOBILE=1
|
|
50
|
+
-DFOLLY_HAVE_RECVMMSG=1
|
|
51
|
+
-DFOLLY_HAVE_PTHREAD=1
|
|
52
|
+
# Once we target android-23 above, we can comment
|
|
53
|
+
# the following line. NDK uses GNU style stderror_r() after API 23.
|
|
54
|
+
-DFOLLY_HAVE_XSI_STRERROR_R=1
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Add all libraries required by the generated specs
|
|
58
|
+
find_package(fbjni REQUIRED) # <-- Used for communication between Java <-> C++
|
|
59
|
+
find_package(ReactAndroid REQUIRED) # <-- Used to set up React Native bindings (e.g. CallInvoker/TurboModule)
|
|
60
|
+
find_package(react-native-nitro-modules REQUIRED) # <-- Used to create all HybridObjects and use the Nitro core library
|
|
61
|
+
|
|
62
|
+
# Link all libraries together
|
|
63
|
+
target_link_libraries(
|
|
64
|
+
NostrNative
|
|
65
|
+
fbjni::fbjni # <-- Facebook C++ JNI helpers
|
|
66
|
+
ReactAndroid::jsi # <-- RN: JSI
|
|
67
|
+
react-native-nitro-modules::NitroModules # <-- NitroModules Core :)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Link react-native (different prefab between RN 0.75 and RN 0.76)
|
|
71
|
+
if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
|
|
72
|
+
target_link_libraries(
|
|
73
|
+
NostrNative
|
|
74
|
+
ReactAndroid::reactnative # <-- RN: Native Modules umbrella prefab
|
|
75
|
+
)
|
|
76
|
+
else()
|
|
77
|
+
target_link_libraries(
|
|
78
|
+
NostrNative
|
|
79
|
+
ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core
|
|
80
|
+
)
|
|
81
|
+
endif()
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NostrNative+autolinking.gradle
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
/// This is a Gradle file that adds all files generated by Nitrogen
|
|
9
|
+
/// to the current Gradle project.
|
|
10
|
+
///
|
|
11
|
+
/// To use it, add this to your build.gradle:
|
|
12
|
+
/// ```gradle
|
|
13
|
+
/// apply from: '../nitrogen/generated/android/NostrNative+autolinking.gradle'
|
|
14
|
+
/// ```
|
|
15
|
+
|
|
16
|
+
logger.warn("[NitroModules] 🔥 NostrNative is boosted by nitro!")
|
|
17
|
+
|
|
18
|
+
android {
|
|
19
|
+
sourceSets {
|
|
20
|
+
main {
|
|
21
|
+
java.srcDirs += [
|
|
22
|
+
// Nitrogen files
|
|
23
|
+
"${project.projectDir}/../nitrogen/generated/android/kotlin"
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NostrNativeOnLoad.cpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#ifndef BUILDING_NOSTRNATIVE_WITH_GENERATED_CMAKE_PROJECT
|
|
9
|
+
#error NostrNativeOnLoad.cpp is not being built with the autogenerated CMakeLists.txt project. Is a different CMakeLists.txt building this?
|
|
10
|
+
#endif
|
|
11
|
+
|
|
12
|
+
#include "NostrNativeOnLoad.hpp"
|
|
13
|
+
|
|
14
|
+
#include <jni.h>
|
|
15
|
+
#include <fbjni/fbjni.h>
|
|
16
|
+
#include <NitroModules/HybridObjectRegistry.hpp>
|
|
17
|
+
|
|
18
|
+
#include "HybridNostrNative.hpp"
|
|
19
|
+
|
|
20
|
+
namespace margelo::nitro::nostrnative {
|
|
21
|
+
|
|
22
|
+
int initialize(JavaVM* vm) {
|
|
23
|
+
return facebook::jni::initialize(vm, []() {
|
|
24
|
+
::margelo::nitro::nostrnative::registerAllNatives();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
void registerAllNatives() {
|
|
31
|
+
using namespace margelo::nitro;
|
|
32
|
+
using namespace margelo::nitro::nostrnative;
|
|
33
|
+
|
|
34
|
+
// Register native JNI methods
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// Register Nitro Hybrid Objects
|
|
38
|
+
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
39
|
+
"NostrNative",
|
|
40
|
+
[]() -> std::shared_ptr<HybridObject> {
|
|
41
|
+
static_assert(std::is_default_constructible_v<HybridNostrNative>,
|
|
42
|
+
"The HybridObject \"HybridNostrNative\" is not default-constructible! "
|
|
43
|
+
"Create a public constructor that takes zero arguments to be able to autolink this HybridObject.");
|
|
44
|
+
return std::make_shared<HybridNostrNative>();
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
} // namespace margelo::nitro::nostrnative
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NostrNativeOnLoad.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#include <jni.h>
|
|
9
|
+
#include <functional>
|
|
10
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
11
|
+
|
|
12
|
+
namespace margelo::nitro::nostrnative {
|
|
13
|
+
|
|
14
|
+
[[deprecated("Use registerNatives() instead.")]]
|
|
15
|
+
int initialize(JavaVM* vm);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Register the native (C++) part of NostrNative, and autolinks all Hybrid Objects.
|
|
19
|
+
* Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`),
|
|
20
|
+
* inside a `facebook::jni::initialize(vm, ...)` call.
|
|
21
|
+
* Example:
|
|
22
|
+
* ```cpp (cpp-adapter.cpp)
|
|
23
|
+
* JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
|
|
24
|
+
* return facebook::jni::initialize(vm, []() {
|
|
25
|
+
* // register all NostrNative HybridObjects
|
|
26
|
+
* margelo::nitro::nostrnative::registerNatives();
|
|
27
|
+
* // any other custom registrations go here.
|
|
28
|
+
* });
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
void registerAllNatives();
|
|
33
|
+
|
|
34
|
+
} // namespace margelo::nitro::nostrnative
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// NostrNativeOnLoad.kt
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
package com.margelo.nitro.nostrnative
|
|
9
|
+
|
|
10
|
+
import android.util.Log
|
|
11
|
+
|
|
12
|
+
internal class NostrNativeOnLoad {
|
|
13
|
+
companion object {
|
|
14
|
+
private const val TAG = "NostrNativeOnLoad"
|
|
15
|
+
private var didLoad = false
|
|
16
|
+
/**
|
|
17
|
+
* Initializes the native part of "NostrNative".
|
|
18
|
+
* This method is idempotent and can be called more than once.
|
|
19
|
+
*/
|
|
20
|
+
@JvmStatic
|
|
21
|
+
fun initializeNative() {
|
|
22
|
+
if (didLoad) return
|
|
23
|
+
try {
|
|
24
|
+
Log.i(TAG, "Loading NostrNative C++ library...")
|
|
25
|
+
System.loadLibrary("NostrNative")
|
|
26
|
+
Log.i(TAG, "Successfully loaded NostrNative C++ library!")
|
|
27
|
+
didLoad = true
|
|
28
|
+
} catch (e: Error) {
|
|
29
|
+
Log.e(TAG, "Failed to load NostrNative C++ library! Is it properly installed and linked? " +
|
|
30
|
+
"Is the name correct? (see `CMakeLists.txt`, at `add_library(...)`)", e)
|
|
31
|
+
throw e
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#
|
|
2
|
+
# NostrNative+autolinking.rb
|
|
3
|
+
# This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
# https://github.com/mrousavy/nitro
|
|
5
|
+
# Copyright © Marc Rousavy @ Margelo
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
# This is a Ruby script that adds all files generated by Nitrogen
|
|
9
|
+
# to the given podspec.
|
|
10
|
+
#
|
|
11
|
+
# To use it, add this to your .podspec:
|
|
12
|
+
# ```ruby
|
|
13
|
+
# Pod::Spec.new do |spec|
|
|
14
|
+
# # ...
|
|
15
|
+
#
|
|
16
|
+
# # Add all files generated by Nitrogen
|
|
17
|
+
# load 'nitrogen/generated/ios/NostrNative+autolinking.rb'
|
|
18
|
+
# add_nitrogen_files(spec)
|
|
19
|
+
# end
|
|
20
|
+
# ```
|
|
21
|
+
|
|
22
|
+
def add_nitrogen_files(spec)
|
|
23
|
+
Pod::UI.puts "[NitroModules] 🔥 NostrNative is boosted by nitro!"
|
|
24
|
+
|
|
25
|
+
spec.dependency "NitroModules"
|
|
26
|
+
|
|
27
|
+
current_source_files = Array(spec.attributes_hash['source_files'])
|
|
28
|
+
spec.source_files = current_source_files + [
|
|
29
|
+
# Generated cross-platform specs
|
|
30
|
+
"nitrogen/generated/shared/**/*.{h,hpp,c,cpp,swift}",
|
|
31
|
+
# Generated bridges for the cross-platform specs
|
|
32
|
+
"nitrogen/generated/ios/**/*.{h,hpp,c,cpp,mm,swift}",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
current_public_header_files = Array(spec.attributes_hash['public_header_files'])
|
|
36
|
+
spec.public_header_files = current_public_header_files + [
|
|
37
|
+
# Generated specs
|
|
38
|
+
"nitrogen/generated/shared/**/*.{h,hpp}",
|
|
39
|
+
# Swift to C++ bridging helpers
|
|
40
|
+
"nitrogen/generated/ios/NostrNative-Swift-Cxx-Bridge.hpp"
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
current_private_header_files = Array(spec.attributes_hash['private_header_files'])
|
|
44
|
+
spec.private_header_files = current_private_header_files + [
|
|
45
|
+
# iOS specific specs
|
|
46
|
+
"nitrogen/generated/ios/c++/**/*.{h,hpp}",
|
|
47
|
+
# Views are framework-specific and should be private
|
|
48
|
+
"nitrogen/generated/shared/**/views/**/*"
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
current_pod_target_xcconfig = spec.attributes_hash['pod_target_xcconfig'] || {}
|
|
52
|
+
spec.pod_target_xcconfig = current_pod_target_xcconfig.merge({
|
|
53
|
+
# Use C++ 20
|
|
54
|
+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
55
|
+
# Enables C++ <-> Swift interop (by default it's only ObjC)
|
|
56
|
+
"SWIFT_OBJC_INTEROP_MODE" => "objcxx",
|
|
57
|
+
# Enables stricter modular headers
|
|
58
|
+
"DEFINES_MODULE" => "YES",
|
|
59
|
+
# Disable auto-generated ObjC header for Swift (Static linkage on Xcode 26.4 breaks here)
|
|
60
|
+
"SWIFT_INSTALL_OBJC_HEADER" => "NO",
|
|
61
|
+
})
|
|
62
|
+
end
|