2026-01-21 15:22:38 +01:00
|
|
|
//! C-compatible type definitions for the FFI layer.
|
|
|
|
|
|
|
|
|
|
use std::ffi::c_char;
|
|
|
|
|
|
|
|
|
|
/// Opaque pointer to the Wallet instance.
|
|
|
|
|
///
|
|
|
|
|
/// This type is never instantiated directly - it's used as an opaque handle
|
|
|
|
|
/// to hide the internal wallet structure from C code.
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct WalletHandle {
|
|
|
|
|
_private: [u8; 0],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 32-byte array type for AccountId, keys, hashes, etc.
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
#[derive(Clone, Copy, Default)]
|
|
|
|
|
pub struct FfiBytes32 {
|
|
|
|
|
pub data: [u8; 32],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Program ID - 8 u32 values (32 bytes total).
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
#[derive(Clone, Copy, Default)]
|
|
|
|
|
pub struct FfiProgramId {
|
|
|
|
|
pub data: [u32; 8],
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Account data structure - C-compatible version of nssa Account.
|
|
|
|
|
///
|
2026-01-26 10:15:23 +01:00
|
|
|
/// Note: `balance` and `nonce` are u128 values represented as little-endian
|
|
|
|
|
/// byte arrays since C doesn't have native u128 support.
|
2026-01-21 15:22:38 +01:00
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct FfiAccount {
|
|
|
|
|
pub program_owner: FfiProgramId,
|
2026-01-26 10:15:23 +01:00
|
|
|
/// Balance as little-endian [u8; 16]
|
|
|
|
|
pub balance: [u8; 16],
|
2026-01-21 15:22:38 +01:00
|
|
|
/// Pointer to account data bytes
|
|
|
|
|
pub data: *const u8,
|
|
|
|
|
/// Length of account data
|
|
|
|
|
pub data_len: usize,
|
2026-01-26 10:15:23 +01:00
|
|
|
/// Nonce as little-endian [u8; 16]
|
|
|
|
|
pub nonce: [u8; 16],
|
2026-01-21 15:22:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for FfiAccount {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
program_owner: FfiProgramId::default(),
|
2026-01-26 10:15:23 +01:00
|
|
|
balance: [0u8; 16],
|
2026-01-21 15:22:38 +01:00
|
|
|
data: std::ptr::null(),
|
|
|
|
|
data_len: 0,
|
2026-01-26 10:15:23 +01:00
|
|
|
nonce: [0u8; 16],
|
2026-01-21 15:22:38 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Public keys for a private account (safe to expose).
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct FfiPrivateAccountKeys {
|
|
|
|
|
/// Nullifier public key (32 bytes)
|
|
|
|
|
pub nullifier_public_key: FfiBytes32,
|
|
|
|
|
/// Incoming viewing public key (compressed secp256k1 point)
|
|
|
|
|
pub incoming_viewing_public_key: *const u8,
|
|
|
|
|
/// Length of incoming viewing public key (typically 33 bytes)
|
|
|
|
|
pub incoming_viewing_public_key_len: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for FfiPrivateAccountKeys {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
nullifier_public_key: FfiBytes32::default(),
|
|
|
|
|
incoming_viewing_public_key: std::ptr::null(),
|
|
|
|
|
incoming_viewing_public_key_len: 0,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Public key info for a public account.
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
#[derive(Clone, Copy, Default)]
|
|
|
|
|
pub struct FfiPublicAccountKey {
|
|
|
|
|
pub public_key: FfiBytes32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Single entry in the account list.
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
#[derive(Clone, Copy)]
|
|
|
|
|
pub struct FfiAccountListEntry {
|
|
|
|
|
pub account_id: FfiBytes32,
|
|
|
|
|
pub is_public: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// List of accounts returned by wallet_ffi_list_accounts.
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct FfiAccountList {
|
|
|
|
|
pub entries: *mut FfiAccountListEntry,
|
|
|
|
|
pub count: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for FfiAccountList {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
entries: std::ptr::null_mut(),
|
|
|
|
|
count: 0,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Result of a transfer operation.
|
|
|
|
|
#[repr(C)]
|
|
|
|
|
pub struct FfiTransferResult {
|
|
|
|
|
/// Transaction hash (null-terminated string, or null on failure)
|
|
|
|
|
pub tx_hash: *mut c_char,
|
|
|
|
|
/// Whether the transfer succeeded
|
|
|
|
|
pub success: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for FfiTransferResult {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
tx_hash: std::ptr::null_mut(),
|
|
|
|
|
success: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Helper functions to convert between Rust and FFI types
|
|
|
|
|
|
|
|
|
|
impl FfiBytes32 {
|
|
|
|
|
/// Create from a 32-byte array.
|
|
|
|
|
pub fn from_bytes(bytes: [u8; 32]) -> Self {
|
|
|
|
|
Self { data: bytes }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Create from an AccountId.
|
|
|
|
|
pub fn from_account_id(id: &nssa::AccountId) -> Self {
|
|
|
|
|
Self { data: *id.value() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<&nssa::AccountId> for FfiBytes32 {
|
|
|
|
|
fn from(id: &nssa::AccountId) -> Self {
|
|
|
|
|
Self::from_account_id(id)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<FfiBytes32> for nssa::AccountId {
|
|
|
|
|
fn from(bytes: FfiBytes32) -> Self {
|
|
|
|
|
nssa::AccountId::new(bytes.data)
|
|
|
|
|
}
|
|
|
|
|
}
|