mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-07-16 10:49:32 +00:00
Merge pull request #582 from logos-blockchain/Pravdyvy/pda-account-id-generation
feat(wallet_ffi): pda account id generation in FFI
This commit is contained in:
commit
ea41d5a738
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -9519,9 +9519,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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;
|
||||
|
||||
142
lez/wallet-ffi/src/pda.rs
Normal file
142
lez/wallet-ffi/src/pda.rs
Normal file
@ -0,0 +1,142 @@
|
||||
use lee::AccountId;
|
||||
|
||||
use crate::{
|
||||
error::WalletFfiError, FfiBytes32, FfiNullifierPublicKey, FfiPdaSeed, FfiPrivateAccountKeys,
|
||||
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`)
|
||||
/// - `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`
|
||||
/// - `account_id`: valid pointer to `FfiBytes32`
|
||||
///
|
||||
/// # Returns
|
||||
/// - `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]
|
||||
pub unsafe extern "C" fn wallet_ffi_account_id_for_private_pda(
|
||||
program_id: FfiProgramId,
|
||||
pda_seed: FfiPdaSeed,
|
||||
npk: FfiNullifierPublicKey,
|
||||
viewing_public_key: *const u8,
|
||||
viewing_public_key_len: usize,
|
||||
identifier: FfiU128,
|
||||
account_id: *mut FfiBytes32,
|
||||
) -> WalletFfiError {
|
||||
if viewing_public_key.is_null() {
|
||||
return WalletFfiError::NullPointer;
|
||||
}
|
||||
|
||||
let ffi_private_keys = FfiPrivateAccountKeys {
|
||||
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)]
|
||||
mod tests {
|
||||
use lee::AccountId;
|
||||
use lee_core::{encryption::ViewingPublicKey, NullifierPublicKey};
|
||||
use vault_core::PdaSeed;
|
||||
|
||||
use crate::{
|
||||
error::WalletFfiError,
|
||||
pda::{wallet_ffi_account_id_for_private_pda, wallet_ffi_account_id_for_public_pda},
|
||||
FfiBytes32,
|
||||
};
|
||||
|
||||
#[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 vpk = ViewingPublicKey::from_bytes(vec![43; 1184]).unwrap();
|
||||
let npk = NullifierPublicKey([44; 32]);
|
||||
let identifier = 100_000_u128;
|
||||
|
||||
let pda_id = AccountId::for_private_pda(&program_id, &pda_seed, &npk, &vpk, identifier);
|
||||
|
||||
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)) });
|
||||
}
|
||||
}
|
||||
@ -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)]
|
||||
|
||||
@ -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,50 @@ 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`)
|
||||
* - `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`
|
||||
* - `account_id`: valid pointer to `FfiBytes32`
|
||||
*
|
||||
* # Returns
|
||||
* - `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
|
||||
*/
|
||||
enum WalletFfiError wallet_ffi_account_id_for_private_pda(struct FfiProgramId program_id,
|
||||
FfiPdaSeed pda_seed,
|
||||
FfiNullifierPublicKey npk,
|
||||
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.
|
||||
*
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user