● Restructure native module for Expo auto-discovery, fix 3 test failures

Move native code from native/ to Expo-compatible layout with android/
  and ios/ at package root. Add Android JNI bridge (OnLoad.cpp,
  ExpoSalviumCryptoModule.java, ExpoSalviumCryptoPackage.java).
  Prebuilt binaries now go in prebuilt/ instead of native/lib/.

  Test fixes:
  - wallet-sync: update stale DEFAULT_BATCH_SIZE assertion (10 -> 100)
  - bulletproofs+: fix hashToPoint -> hashToPointMonero rename in test,
    fix serializeProof to include V array matching parseProof format
  - transaction-builder: expect 2 outputs for exact-amount tx (zero-change
    output is always added for privacy)
This commit is contained in:
Matt Hess
2026-02-09 22:50:15 +00:00
parent 23afd269e1
commit 01bcb742ae
15 changed files with 139 additions and 33 deletions
+31
View File
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.18)
project(ExpoSalviumCrypto)
set(CMAKE_CXX_STANDARD 17)
# React Native JSI headers (provided by React Native)
find_package(fbjni REQUIRED CONFIG)
find_package(ReactAndroid REQUIRED CONFIG)
# Pre-built Rust .so
add_library(salvium_crypto SHARED IMPORTED)
set_target_properties(salvium_crypto PROPERTIES
IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/../prebuilt/android/${ANDROID_ABI}/libsalvium_crypto.so"
)
# JSI bridge module
add_library(${PROJECT_NAME} SHARED
../cpp/SalviumCryptoModule.cpp
../cpp/OnLoad.cpp
)
target_include_directories(${PROJECT_NAME} PRIVATE
../cpp
../crates/salvium-crypto/include
)
target_link_libraries(${PROJECT_NAME}
salvium_crypto
ReactAndroid::jsi
fbjni::fbjni
)
+51
View File
@@ -0,0 +1,51 @@
// ExpoSalviumCrypto — Android build config
// Links the Rust-compiled .so + C++ JSI module
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:8.1.0"
}
}
apply plugin: "com.android.library"
android {
namespace "com.salvium.crypto"
compileSdkVersion 34
defaultConfig {
minSdkVersion 21
targetSdkVersion 34
externalNativeBuild {
cmake {
cppFlags "-std=c++17 -fexceptions"
arguments "-DANDROID_STL=c++_shared"
}
}
ndk {
abiFilters "arm64-v8a", "armeabi-v7a", "x86_64"
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
sourceSets {
main {
jniLibs.srcDirs = ["../prebuilt/android"]
}
}
}
dependencies {
implementation "com.facebook.react:react-android"
}
+3
View File
@@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.salvium.crypto">
</manifest>
@@ -0,0 +1,53 @@
package com.salvium.crypto;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
/**
* React Native module that installs the JSI crypto bindings.
*
* The actual crypto functions are exposed via JSI (C++ -> Rust FFI),
* not through the React Native bridge. This Java module only handles
* loading the native library and calling the C++ install function.
*/
@ReactModule(name = ExpoSalviumCryptoModule.NAME)
public class ExpoSalviumCryptoModule extends ReactContextBaseJavaModule {
public static final String NAME = "ExpoSalviumCrypto";
static {
System.loadLibrary("ExpoSalviumCrypto");
System.loadLibrary("salvium_crypto");
}
public ExpoSalviumCryptoModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return NAME;
}
/**
* Called from JS to install the JSI bindings.
* Must be called after the JSI runtime is available.
*/
@ReactMethod(isBlockingSynchronousMethod = true)
public boolean install() {
try {
ReactApplicationContext context = getReactApplicationContext();
long jsiRuntimePtr = context.getJavaScriptContextHolder().get();
if (jsiRuntimePtr == 0) {
return false;
}
nativeInstall(jsiRuntimePtr);
return true;
} catch (Exception e) {
return false;
}
}
private native void nativeInstall(long jsiRuntimePtr);
}
@@ -0,0 +1,24 @@
package com.salvium.crypto;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ExpoSalviumCryptoPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ExpoSalviumCryptoModule(reactContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}