Add React Native Nitro bindings for CDK#1982
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1982 +/- ##
==========================================
+ Coverage 71.60% 71.74% +0.13%
==========================================
Files 356 357 +1
Lines 74126 74543 +417
==========================================
+ Hits 53078 53480 +402
- Misses 21048 21063 +15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
1dc1d1c to
c7c2964
Compare
08e9361 to
f5d4910
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6963f16291
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| # Link against pre-built cdk_ffi native library | ||
| # The .so must be placed at: android/src/main/jniLibs/<abi>/libcdk_ffi.so | ||
| find_library(CDK_FFI cdk_ffi PATHS |
There was a problem hiding this comment.
Link Android against the generated Nitro library
For Android package consumers, this CMake file searches for libcdk_ffi.so, but this binding crate is named cdk_nitro and the publish workflow copies libcdk_nitro.so into android/src/main/jniLibs/<abi>. As a result the packaged React Native module will not link/load its Rust symbols on Android; the CMake target should find and link cdk_nitro instead of cdk_ffi.
Useful? React with 👍 / 👎.
b1d57ab to
9e59899
Compare
|
@crodas Are the codex reviews addressed they are not marked resolved? |
Some of it is revisited; lemme double-check and close the addressed feedback |
cdk-bot
left a comment
There was a problem hiding this comment.
Verified findings approved for disclosure:
- Validate custom split sums against requested amount (medium) - Callers can accidentally create blinded output requests whose total value differs from the amount they requested, leading to over/under-requested minting or change outputs in the new React Native binding.
- Check seed pointer before from_raw_parts (medium) - A malformed FFI call can trigger undefined behavior in the new React Native Nitro Rust binding instead of returning a null result for invalid seed input.
- Check FFI string pointers before CStr::from_ptr (medium) - Malformed FFI calls with null string pointers can trigger undefined behavior in the new React Native Nitro Rust binding instead of returning a null result.
cdk-bot
left a comment
There was a problem hiding this comment.
Verified findings approved for disclosure:
- React Native P2PK bindings omit refund multisig threshold (medium) - React Native callers cannot create multisig refund P2PK conditions; multiple refund keys are downgraded to the default one required refund signature.
Additional locations included in summary:- bindings/react-native/src/specs/OutputDataCreator.nitro.ts:35
- bindings/react-native/cpp/HybridOutputDataCreator.cpp:106
Unanchored locations included in summary: - bindings/react-native/cpp/cdk_nitro.h:79
| refund_keys: refund_pks, | ||
| num_sigs: if num_sigs > 1 { Some(num_sigs) } else { None }, | ||
| sig_flag, | ||
| num_sigs_refund: None, |
There was a problem hiding this comment.
The new React Native P2PK binding exposes refundPubkeys, but it never exposes or forwards the corresponding num_sigs_refund setting. At this PR head, the TS P2PKOptions has no numSigsRefund, the C++/C FFI call has no refund-signature-count argument, and Rust always serializes Conditions { num_sigs_refund: None }.
That means callers can create a refund path with multiple refund pubkeys but cannot require (for example) 2-of-2 refund signatures; CDK will fall back to the default single refund signature requirement (unwrap_or(1) in the core spending checks). Please plumb a numSigsRefund option through the Nitro spec, C++ bridge, C header, and Rust FFI into Conditions.num_sigs_refund, just like numSigs is handled for the primary path.
Add a new `cdk-nitro` crate and React Native package that exposes CDK functionality via Nitro Modules. The bindings provide a C FFI layer with a C++ HybridObject bridge that lets React Native apps create and manipulate Cashu tokens (OutputData, proofs, keysets, etc.). Includes: - Rust FFI crate (`bindings/react-native/rust`) with OutputDataCreator - C++ HybridObject bridge wrapping the FFI calls - TypeScript Nitro spec and package entry point - Android CMakeLists and iOS podspec for native builds - Node.js FFI test suite using native addon loading - CI job (nitro-binding-tests) and justfile recipes (test-nitro, test-nitro-node) - Added nodejs to the bindings Nix devshell
Add CI workflow (.github/workflows/nitro-publish.yml) that syncs React Native bindings to a separate cdk-nitro repo, cross-compiles native libraries for iOS and Android, creates an XCFramework, and publishes to npm with prebuilt binaries. Add ffi-release-nitro justfile recipe and hook it into the main release flow alongside Swift, Kotlin, and Go.
Add README.md for the React Native Nitro bindings with installation from GitHub, usage examples, API reference, and supported platforms. Make npm publish step conditional on NPM_TOKEN secret availability, emitting a warning with the git install URL when skipped.
- Rename kotlin-build → cross-build in flake.nix (with backwards-compat alias) - Add aarch64-apple-ios-sim to cross-build targets - Use cdk#cross-build instead of cdk#bindings in nitro workflow - Stop copying rust-toolchain.toml to cdk-nitro (conflicts with Nix toolchain) - Remove any rust-toolchain.toml before building as safety measure
- Add bindings/react-native/nitrogen/generated/ and lib/ to .gitignore - Add npm install + codegen step to nitro-publish.yml so generated files sync to cdk-nitro repo - Add codegen verification step to ci.yml nitro-binding-tests job
CMakeLists.txt searched for libcdk_ffi.so but the publish workflow ships libcdk_nitro.so. Similarly the podspec referenced a nonexistent libcdk_ffi.a instead of the CdkNitro.xcframework that gets built.
Parse the sig_flag C string into SigFlag::SigInputs or SigFlag::SigAll, reject unknown values, and default to SigInputs only when null.
parse_pubkey_array now returns Result<Option<Vec<_>>, ()> so a bad entry in additional_pubkeys or refund_pubkeys aborts the call rather than being treated as if the caller omitted the array entirely.
Five tests covering the two previous fixes: - SigAll flag appears in serialized NUT-10 secret - null sig_flag defaults to SIG_INPUTS - unknown sig_flag rejected with null - malformed additional/refund pubkeys rejected with null
…tion - Validate seed pointer and length before slice::from_raw_parts in deterministic blinding - Add null checks for pubkey_hex, keyset_id, and parse_pubkey_array entries - Validate custom split sums to requested amount and contains valid denominations
Description
Fixes #1902
Add a new
cdk-nitrocrate and React Native package that exposes CDK functionality via Nitro Modules. The bindings provide a C FFI layer with a C++ HybridObject bridge that lets React Native apps create and manipulate Cashu tokens (OutputData, proofs, keysets, etc.).Includes:
bindings/react-native/rust) with OutputDataCreatorNotes to the reviewers
Suggested CHANGELOG Updates
CHANGED
ADDED
REMOVED
FIXED
Checklist
just quick-checkbefore committingcrates/cdk-ffi)