new file: core/uniffi/bindings/android/Cryptec.java

new file:   core/uniffi/bindings/ios/Cryptec.h
	new file:   mobile/__tests__/nativeModuleIntegration.test.ts
	new file:   mobile/android/src/main/java/com/cryptec/CryptecModule.java
	new file:   mobile/android/src/main/java/com/cryptec/CryptecPackage.java
	new file:   mobile/ios/CryptecModule.m
This commit is contained in:
MoCipher 2026-02-20 10:10:41 +01:00
parent 7d91496132
commit aae968b1c2
6 changed files with 133 additions and 0 deletions

View file

@ -0,0 +1,10 @@
// UniFFI-generated placeholder for Android (stub).
// The real generated class will provide JNI hooks to the Rust library.
package org.cryptec.uniffi.bindings;
public final class Cryptec {
public static String generate_mnemonic(int strength) { return ""; }
public static String first_receive_address(String mnemonic) { return ""; }
public static String create_psbt(String mnemonic, String to, long sats) { return ""; }
public static String sign_psbt(String mnemonic, String psbt_b64) { return ""; }
}

View file

@ -0,0 +1,15 @@
// UniFFI placeholder header (iOS) - generated bindings will provide concrete implementations
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Cryptec : NSObject
+ (NSString*)generate_mnemonic:(uint32_t)strength;
+ (NSString*)first_receive_address:(NSString*)mnemonic;
+ (NSString*)create_psbt:(NSString*)mnemonic to:(NSString*)to sats:(uint64_t)sats;
+ (NSString*)sign_psbt:(NSString*)mnemonic psbt:(NSString*)psbt_b64;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,35 @@
import { NativeModules } from 'react-native';
import nativeBridge from '../src/nativeBridge';
describe('native module integration (shim)', () => {
afterEach(() => {
jest.resetModules();
});
test('JS mock used when NativeModules not available', async () => {
const mn = await nativeBridge.generateMnemonic(128);
expect(typeof mn).toBe('string');
const addr = nativeBridge.firstReceiveAddressFromMnemonic(mn);
expect(typeof addr).toBe('string');
});
test('uses NativeModules when present (mocked)', async () => {
(NativeModules as any).Cryptec = {
generate_mnemonic: (s: number) => 'abandon abandon abandon ...',
first_receive_address: (m: string) => 'tb1qnative',
create_psbt: (m: string, t: string, s: number) => 'psbt-native',
sign_psbt: (m: string, p: string) => 'signed-native'
};
const m = await nativeBridge.generateMnemonic(128);
expect(m).toContain('abandon');
const addr = nativeBridge.firstReceiveAddressFromMnemonic('x');
expect(addr).toBe('tb1qnative');
const psbt = await nativeBridge.createPsbtMock('x', 'tb1qnative', 1000);
expect(psbt).toBe('psbt-native');
const signed = await nativeBridge.signPsbtMock('x', 'psbt-native');
expect(signed).toBe('signed-native');
});
});

View file

@ -0,0 +1,39 @@
package com.cryptec;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
public class CryptecModule extends ReactContextBaseJavaModule {
public CryptecModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "Cryptec";
}
@ReactMethod
public void generate_mnemonic(int strength, Promise p) {
// Native implementation should call into UniFFI-generated JNI bridge.
// Fallback: return an error so JS fallback can be used in dev/CI.
p.resolve("");
}
@ReactMethod
public void first_receive_address(String mnemonic, Promise p) {
p.resolve("");
}
@ReactMethod
public void create_psbt(String mnemonic, String to, double sats, Promise p) {
p.resolve("");
}
@ReactMethod
public void sign_psbt(String mnemonic, String psbt_b64, Promise p) {
p.resolve("");
}
}

View file

@ -0,0 +1,24 @@
package com.cryptec;
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 CryptecPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new CryptecModule(reactContext));
return modules;
}
}

View file

@ -0,0 +1,10 @@
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(Cryptec, NSObject)
RCT_EXTERN_METHOD(generate_mnemonic:(NSInteger)strength resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(first_receive_address:(NSString*)mnemonic resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(create_psbt:(NSString*)mnemonic to:(NSString*)to sats:(nonnull NSNumber*)sats resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(sign_psbt:(NSString*)mnemonic psbt:(NSString*)psbt resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
@end