fix(wallet_ffi): merge upfix

This commit is contained in:
Pravdyvy 2026-07-15 13:35:53 +03:00
parent e4fd9b2397
commit 651229c454
2 changed files with 98 additions and 27 deletions

View File

@ -1,6 +1,9 @@
use lee::AccountId; use lee::AccountId;
use crate::{FfiBytes32, FfiNullifierPublicKey, FfiPdaSeed, FfiProgramId, FfiU128}; use crate::{
error::WalletFfiError, FfiBytes32, FfiNullifierPublicKey, FfiPdaSeed, FfiPrivateAccountKeys,
FfiProgramId, FfiU128,
};
/// Produce account id for public PDA. /// Produce account id for public PDA.
/// ///
@ -25,33 +28,71 @@ pub extern "C" fn wallet_ffi_account_id_for_public_pda(
/// - `pda_seed`: 32 byte seed /// - `pda_seed`: 32 byte seed
/// - `npk`: 32 byte nullifier public key (can be obtained from /// - `npk`: 32 byte nullifier public key (can be obtained from
/// `wallet_ffi_get_private_account_keys`) /// `wallet_ffi_get_private_account_keys`)
/// - `viewing_public_key`: pointer to u8 (can be obtained from
/// `wallet_ffi_get_private_account_keys`)
/// - `viewing_public_key_len`: length of a `viewing_public_key` (can be obtained from
/// `wallet_ffi_get_private_account_keys`), must be `1184`
/// - `identifier`: little endian encoded `u128` /// - `identifier`: little endian encoded `u128`
/// - `account_id`: valid pointer to `FfiBytes32`
/// ///
/// # Returns /// # Returns
/// - `FfiBytes32` representing account id bytes /// - `Success` on successful parsing
/// - Error code on failure
///
/// # Safety
/// - `viewing_public_key` must be a valid pointer to a `u8`
/// - `account_id` must be a valid pointer to a `FfiBytes32` struct
#[no_mangle] #[no_mangle]
pub extern "C" fn wallet_ffi_account_id_for_private_pda( pub unsafe extern "C" fn wallet_ffi_account_id_for_private_pda(
program_id: FfiProgramId, program_id: FfiProgramId,
pda_seed: FfiPdaSeed, pda_seed: FfiPdaSeed,
npk: FfiNullifierPublicKey, npk: FfiNullifierPublicKey,
viewing_public_key: *const u8,
viewing_public_key_len: usize,
identifier: FfiU128, identifier: FfiU128,
) -> FfiBytes32 { account_id: *mut FfiBytes32,
AccountId::for_private_pda( ) -> WalletFfiError {
&program_id.data, if viewing_public_key.is_null() {
&pda_seed.into(), return WalletFfiError::NullPointer;
&npk.into(), }
identifier.into(),
) let ffi_private_keys = FfiPrivateAccountKeys {
.into() nullifier_public_key: npk,
viewing_public_key,
viewing_public_key_len,
};
let vpk = ffi_private_keys.vpk();
if vpk.is_err() {
return vpk.err().unwrap();
}
unsafe {
*account_id = AccountId::for_private_pda(
&program_id.data,
&pda_seed.into(),
&ffi_private_keys.npk(),
&vpk.unwrap(),
identifier.into(),
)
.into();
}
WalletFfiError::Success
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use lee::AccountId; use lee::AccountId;
use lee_core::NullifierPublicKey; use lee_core::{encryption::ViewingPublicKey, NullifierPublicKey};
use vault_core::PdaSeed; use vault_core::PdaSeed;
use crate::pda::{wallet_ffi_account_id_for_private_pda, wallet_ffi_account_id_for_public_pda}; use crate::{
error::WalletFfiError,
pda::{wallet_ffi_account_id_for_private_pda, wallet_ffi_account_id_for_public_pda},
FfiBytes32,
};
#[test] #[test]
fn public_pda_consistent_derivation() { fn public_pda_consistent_derivation() {
@ -68,17 +109,34 @@ mod tests {
fn private_pda_consistent_derivation() { fn private_pda_consistent_derivation() {
let program_id = [100_u32, 101, 102, 103, 104, 105, 106, 107]; let program_id = [100_u32, 101, 102, 103, 104, 105, 106, 107];
let pda_seed = PdaSeed::new([42; 32]); let pda_seed = PdaSeed::new([42; 32]);
let npk = NullifierPublicKey([43; 32]); let vpk = ViewingPublicKey::from_bytes(vec![43; 1184]).unwrap();
let npk = NullifierPublicKey([44; 32]);
let identifier = 100_000_u128; let identifier = 100_000_u128;
let pda_id = AccountId::for_private_pda(&program_id, &pda_seed, &npk, identifier); let pda_id = AccountId::for_private_pda(&program_id, &pda_seed, &npk, &vpk, identifier);
let ffi_pda_id = wallet_ffi_account_id_for_private_pda(
program_id.into(),
pda_seed.into(),
npk.into(),
identifier.into(),
);
assert_eq!(pda_id.into_value(), ffi_pda_id.data); let vpk_ptr = Box::into_raw(vpk.to_bytes().to_vec().into_boxed_slice()) as *const u8;
let mut ffi_pda_id_base = FfiBytes32 { data: [0; 32] };
let ffi_pda_id = &raw mut ffi_pda_id_base;
let err = unsafe {
wallet_ffi_account_id_for_private_pda(
program_id.into(),
pda_seed.into(),
npk.into(),
vpk_ptr,
1184,
identifier.into(),
ffi_pda_id,
)
};
assert_eq!(err, WalletFfiError::Success);
assert_eq!(pda_id.into_value(), unsafe { (*ffi_pda_id).data });
let vpk_slice = unsafe { std::slice::from_raw_parts_mut(vpk_ptr.cast_mut(), 1184) };
drop(unsafe { Box::from_raw(std::ptr::from_mut(vpk_slice)) });
} }
} }

View File

@ -939,15 +939,28 @@ struct FfiBytes32 wallet_ffi_account_id_for_public_pda(struct FfiProgramId progr
* - `pda_seed`: 32 byte seed * - `pda_seed`: 32 byte seed
* - `npk`: 32 byte nullifier public key (can be obtained from * - `npk`: 32 byte nullifier public key (can be obtained from
* `wallet_ffi_get_private_account_keys`) * `wallet_ffi_get_private_account_keys`)
* - `viewing_public_key`: pointer to u8 (can be obtained from
* `wallet_ffi_get_private_account_keys`)
* - `viewing_public_key_len`: length of a `viewing_public_key` (can be obtained from
* `wallet_ffi_get_private_account_keys`), must be `1184`
* - `identifier`: little endian encoded `u128` * - `identifier`: little endian encoded `u128`
* - `account_id`: valid pointer to `FfiBytes32`
* *
* # Returns * # Returns
* - `FfiBytes32` representing account id bytes * - `Success` on successful parsing
* - Error code on failure
*
* # Safety
* - `viewing_public_key` must be a valid pointer to a `u8`
* - `account_id` must be a valid pointer to a `FfiBytes32` struct
*/ */
struct FfiBytes32 wallet_ffi_account_id_for_private_pda(struct FfiProgramId program_id, enum WalletFfiError wallet_ffi_account_id_for_private_pda(struct FfiProgramId program_id,
FfiPdaSeed pda_seed, FfiPdaSeed pda_seed,
FfiNullifierPublicKey npk, FfiNullifierPublicKey npk,
struct FfiU128 identifier); const uint8_t *viewing_public_key,
uintptr_t viewing_public_key_len,
struct FfiU128 identifier,
struct FfiBytes32 *account_id);
/** /**
* Claim a pinata reward using a public transaction. * Claim a pinata reward using a public transaction.