Merge 897562b0cfa689c033ba4f0809d2af62daf3cedd into a0ba6008c38665882e160fb83a9f7c52bc1789aa

This commit is contained in:
Pravdyvy 2026-07-08 11:40:22 +00:00 committed by GitHub
commit 83622b4412
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 153 additions and 3 deletions

4
Cargo.lock generated
View File

@ -1854,9 +1854,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]

View File

@ -47,6 +47,7 @@ pub mod error;
pub mod generic_transaction;
pub mod keys;
pub mod label;
pub mod pda;
pub mod pinata;
pub mod program_deployment;
pub mod sync;

84
lez/wallet-ffi/src/pda.rs Normal file
View File

@ -0,0 +1,84 @@
use lee::AccountId;
use crate::{FfiBytes32, FfiNullifierPublicKey, FfiPdaSeed, FfiProgramId, FfiU128};
/// Produce account id for public PDA.
///
/// # Parameters
/// - `program_id`: Id of the owner program
/// - `pda_seed`: 32 byte seed
///
/// # Returns
/// - `FfiBytes32` representing account id bytes
#[no_mangle]
pub extern "C" fn wallet_ffi_account_id_for_public_pda(
program_id: FfiProgramId,
pda_seed: FfiPdaSeed,
) -> FfiBytes32 {
AccountId::for_public_pda(&program_id.data, &pda_seed.into()).into()
}
/// Produce account id for private PDA.
///
/// # Parameters
/// - `program_id`: Id of the owner program
/// - `pda_seed`: 32 byte seed
/// - `npk`: 32 byte nullifier public key (can be obtained from
/// `wallet_ffi_get_private_account_keys`)
/// - `identifier`: little endian encoded `u128`
///
/// # Returns
/// - `FfiBytes32` representing account id bytes
#[no_mangle]
pub extern "C" fn wallet_ffi_account_id_for_private_pda(
program_id: FfiProgramId,
pda_seed: FfiPdaSeed,
npk: FfiNullifierPublicKey,
identifier: FfiU128,
) -> FfiBytes32 {
AccountId::for_private_pda(
&program_id.data,
&pda_seed.into(),
&npk.into(),
identifier.into(),
)
.into()
}
#[cfg(test)]
mod tests {
use lee::AccountId;
use lee_core::NullifierPublicKey;
use vault_core::PdaSeed;
use crate::pda::{wallet_ffi_account_id_for_private_pda, wallet_ffi_account_id_for_public_pda};
#[test]
fn public_pda_consistent_derivation() {
let program_id = [100_u32, 101, 102, 103, 104, 105, 106, 107];
let pda_seed = PdaSeed::new([42; 32]);
let pda_id = AccountId::for_public_pda(&program_id, &pda_seed);
let ffi_pda_id = wallet_ffi_account_id_for_public_pda(program_id.into(), pda_seed.into());
assert_eq!(pda_id.into_value(), ffi_pda_id.data);
}
#[test]
fn private_pda_consistent_derivation() {
let program_id = [100_u32, 101, 102, 103, 104, 105, 106, 107];
let pda_seed = PdaSeed::new([42; 32]);
let npk = NullifierPublicKey([43; 32]);
let identifier = 100_000_u128;
let pda_id = AccountId::for_private_pda(&program_id, &pda_seed, &npk, 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);
}
}

View File

@ -8,7 +8,7 @@ use std::{
};
use lee::{Data, ProgramId, SharedSecretKey};
use lee_core::{encryption::MlKem768EncapsulationKey, NullifierPublicKey};
use lee_core::{encryption::MlKem768EncapsulationKey, program::PdaSeed, NullifierPublicKey};
use wallet::{account::AccountIdWithPrivacy, AccountIdentity};
use crate::error::WalletFfiError;
@ -29,6 +29,36 @@ pub struct FfiBytes32 {
pub data: [u8; 32],
}
pub type FfiPdaSeed = FfiBytes32;
impl From<FfiPdaSeed> for PdaSeed {
fn from(value: FfiPdaSeed) -> Self {
Self::new(value.data)
}
}
impl From<PdaSeed> for FfiPdaSeed {
fn from(value: PdaSeed) -> Self {
Self {
data: *value.as_bytes(),
}
}
}
pub type FfiNullifierPublicKey = FfiBytes32;
impl From<FfiNullifierPublicKey> for NullifierPublicKey {
fn from(value: FfiNullifierPublicKey) -> Self {
Self(value.data)
}
}
impl From<NullifierPublicKey> for FfiNullifierPublicKey {
fn from(value: NullifierPublicKey) -> Self {
Self { data: value.0 }
}
}
/// Program ID - 8 u32 values (32 bytes total).
#[repr(C)]
#[derive(Clone, Copy, Default)]

View File

@ -320,6 +320,10 @@ typedef struct LabelList {
enum WalletFfiError error;
} LabelList;
typedef struct FfiBytes32 FfiPdaSeed;
typedef struct FfiBytes32 FfiNullifierPublicKey;
typedef struct FfiCreateWalletOutput {
struct WalletHandle *wallet;
/**
@ -914,6 +918,37 @@ struct LabelList wallet_ffi_get_all_labels_for_account(struct WalletHandle *hand
*/
enum WalletFfiError wallet_ffi_free_label_list(struct LabelList *label_list);
/**
* Produce account id for public PDA.
*
* # Parameters
* - `program_id`: Id of the owner program
* - `pda_seed`: 32 byte seed
*
* # Returns
* - `FfiBytes32` representing account id bytes
*/
struct FfiBytes32 wallet_ffi_account_id_for_public_pda(struct FfiProgramId program_id,
FfiPdaSeed pda_seed);
/**
* Produce account id for private PDA.
*
* # Parameters
* - `program_id`: Id of the owner program
* - `pda_seed`: 32 byte seed
* - `npk`: 32 byte nullifier public key (can be obtained from
* `wallet_ffi_get_private_account_keys`)
* - `identifier`: little endian encoded `u128`
*
* # Returns
* - `FfiBytes32` representing account id bytes
*/
struct FfiBytes32 wallet_ffi_account_id_for_private_pda(struct FfiProgramId program_id,
FfiPdaSeed pda_seed,
FfiNullifierPublicKey npk,
struct FfiU128 identifier);
/**
* Claim a pinata reward using a public transaction.
*