feat(uniffi): add UniFFI bridge functions + tests (generate_mnemonic, first_receive_address, create_psbt, sign_psbt)

This commit is contained in:
MoCipher 2026-02-20 09:58:56 +01:00
parent 662c118000
commit 7d91496132
3 changed files with 67 additions and 0 deletions

View file

@ -30,6 +30,9 @@ pub use swap_manager::SwapOffer;
pub use swap_sim::SwapSimulation;
pub use wallet_manager::{register_decrypted_db, close_decrypted_db, register_inmemory_db, close_inmemory_db, close_all, list_handles};
mod uniffi;
pub use uniffi::{generate_mnemonic, first_receive_address, create_psbt, sign_psbt};
/// WalletCore: minimal demonstrative API
pub struct WalletCore {
// In a real implementation, secrets should be stored in a secure enclave or encrypted storage

44
core/src/uniffi.rs Normal file
View file

@ -0,0 +1,44 @@
use crate::bip39::Mnemonic as LocalMnemonic;
use crate::wallet_bdk::{BdkWallet, PersistentBdkWallet};
use bitcoin::Network;
/// UniFFI-compatible thin bridge functions consumed by mobile/native bindings.
/// These mirror the `cryptec.udl` UDL surface and delegate to existing core logic.
/// Generate a BIP39 mnemonic (wordlist phrase)
pub fn generate_mnemonic(strength: u32) -> String {
// Accept strengths like 128, 160, 192, 224, 256
let s = match strength {
128 | 160 | 192 | 224 | 256 => strength as usize,
_ => 128,
};
let m = LocalMnemonic::generate(s);
m.phrase
}
/// Return the first (external 0) receive address for the given mnemonic (Testnet)
pub fn first_receive_address(mnemonic: &str) -> String {
// Reuse the BDK wallet helper which already derives descriptors/addresses
let w = match BdkWallet::new_from_mnemonic(mnemonic, "", Network::Testnet) {
Ok(x) => x,
Err(_) => return String::new(),
};
match w.get_new_address() {
Ok(a) => a,
Err(_) => String::new(),
}
}
/// Create a PSBT (base64) using the mnemonic (Testnet)
pub fn create_psbt(mnemonic: &str, to_address: &str, satoshis: u64) -> String {
let w = BdkWallet::new_from_mnemonic(mnemonic, "", Network::Testnet)
.expect("create wallet");
w.create_psbt(to_address, satoshis).expect("create psbt")
}
/// Sign a PSBT (base64) with the wallet's internal keys (Testnet)
pub fn sign_psbt(mnemonic: &str, psbt_b64: &str) -> String {
let w = BdkWallet::new_from_mnemonic(mnemonic, "", Network::Testnet)
.expect("create wallet");
w.sign_psbt_base64(psbt_b64).expect("sign psbt")
}

View file

@ -0,0 +1,20 @@
use crate::uniffi::{generate_mnemonic, first_receive_address, create_psbt, sign_psbt};
#[test]
fn uniffi_generate_and_address() {
let m = generate_mnemonic(128);
assert!(!m.is_empty());
let addr = first_receive_address(&m);
assert!(!addr.is_empty());
}
#[test]
fn uniffi_psbt_roundtrip_mock() {
let m = generate_mnemonic(128);
let addr = first_receive_address(&m);
assert!(!addr.is_empty());
let psbt = create_psbt(&m, &addr, 1000);
assert!(!psbt.is_empty());
let signed = sign_psbt(&m, &psbt);
assert!(!signed.is_empty());
}