feat: working queries

This commit is contained in:
Pravdyvy 2026-04-28 19:36:23 +03:00
parent 37f59281c0
commit 89ea884207
14 changed files with 618 additions and 103 deletions

2
Cargo.lock generated
View File

@ -3484,10 +3484,10 @@ version = "0.1.0"
dependencies = [
"cbindgen",
"indexer_service",
"indexer_service_protocol",
"indexer_service_rpc",
"log",
"nssa",
"nssa_core",
"sequencer_core",
"tokio",
"url",

View File

@ -5,11 +5,11 @@ name = "indexer_ffi"
version = "0.1.0"
[dependencies]
nssa_core.workspace = true
nssa.workspace = true
indexer_service.workspace = true
sequencer_core.workspace = true
indexer_service_rpc.workspace = true
indexer_service_protocol.workspace = true
url.workspace = true
log = { workspace = true }

View File

@ -10,6 +10,18 @@ typedef enum OperationStatus {
ClientError = 3,
} OperationStatus;
typedef enum FfiTransactionKind {
Public = 0,
Private,
ProgramDeploy,
} FfiTransactionKind;
typedef enum FfiBedrockStatus {
Pending = 0,
Safe,
Finalized,
} FfiBedrockStatus;
typedef struct IndexerServiceFFI {
void *indexer_handle;
void *runtime;
@ -40,16 +52,255 @@ typedef struct PointerResult_u64__OperationStatus {
enum OperationStatus error;
} PointerResult_u64__OperationStatus;
typedef uint64_t FfiBlockId;
/**
* 32-byte array type for `AccountId`, keys, hashes, etc.
*/
typedef struct FfiBytes32 {
uint8_t data[32];
} FfiBytes32;
typedef struct FfiBytes32 FfiHashType;
typedef uint64_t FfiTimestamp;
/**
* 64-byte array type for signatures, etc.
*/
typedef struct FfiBytes64 {
uint8_t data[64];
} FfiBytes64;
typedef struct FfiBytes64 FfiSignature;
typedef struct FfiBlockHeader {
FfiBlockId block_id;
FfiHashType prev_block_hash;
FfiHashType hash;
FfiTimestamp timestamp;
FfiSignature signature;
} FfiBlockHeader;
/**
* Program ID - 8 u32 values (32 bytes total).
*/
typedef struct FfiProgramId {
uint32_t data[8];
} FfiProgramId;
typedef struct FfiBytes32 FfiAccountId;
typedef struct FfiVec_FfiAccountId {
FfiAccountId *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiAccountId;
typedef struct FfiVec_FfiAccountId FfiAccountIdList;
/**
* U128 - 16 bytes little endian.
*/
typedef struct FfiU128 {
uint8_t data[16];
} FfiU128;
typedef struct FfiU128 FfiNonce;
typedef struct FfiVec_FfiNonce {
FfiNonce *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiNonce;
typedef struct FfiVec_FfiNonce FfiNonceList;
typedef struct FfiVec_u32 {
uint32_t *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_u32;
typedef struct FfiVec_u32 FfiInstructionDataList;
typedef struct FfiPublicMessage {
struct FfiProgramId program_id;
FfiAccountIdList account_ids;
FfiNonceList nonces;
FfiInstructionDataList instruction_data;
} FfiPublicMessage;
typedef struct FfiBytes32 FfiPublicKey;
typedef struct FfiSignaturePubKeyEntry {
FfiSignature signature;
FfiPublicKey public_key;
} FfiSignaturePubKeyEntry;
typedef struct FfiVec_FfiSignaturePubKeyEntry {
struct FfiSignaturePubKeyEntry *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiSignaturePubKeyEntry;
typedef struct FfiVec_FfiSignaturePubKeyEntry FfiSignaturePubKeyList;
typedef struct FfiPublicTransactionBody {
FfiHashType hash;
struct FfiPublicMessage message;
FfiSignaturePubKeyList witness_set;
} FfiPublicTransactionBody;
/**
* Account data structure - C-compatible version of nssa Account.
*
* Note: `balance` and `nonce` are u128 values represented as little-endian
* byte arrays since C doesn't have native u128 support.
*/
typedef struct FfiAccount {
struct FfiProgramId program_owner;
/**
* Balance as little-endian [u8; 16].
*/
struct FfiU128 balance;
/**
* Pointer to account data bytes.
*/
const uint8_t *data;
/**
* Length of account data.
*/
uintptr_t data_len;
/**
* Nonce as little-endian [u8; 16].
*/
struct FfiU128 nonce;
} FfiAccount;
typedef struct FfiVec_FfiAccount {
struct FfiAccount *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiAccount;
typedef struct FfiVec_FfiAccount FfiAccountList;
typedef struct FfiVec_u8 {
uint8_t *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_u8;
typedef struct FfiVec_u8 FfiVecU8;
typedef struct FfiEncryptedAccountData {
FfiVecU8 ciphertext;
FfiVecU8 epk;
uint8_t view_tag;
} FfiEncryptedAccountData;
typedef struct FfiVec_FfiEncryptedAccountData {
struct FfiEncryptedAccountData *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiEncryptedAccountData;
typedef struct FfiVec_FfiEncryptedAccountData FfiEncryptedAccountDataList;
typedef struct FfiVec_FfiBytes32 {
struct FfiBytes32 *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiBytes32;
typedef struct FfiVec_FfiBytes32 FfiVecBytes32;
typedef struct FfiNullifierCommitmentSet {
struct FfiBytes32 nullifier;
struct FfiBytes32 commitment_set_digest;
} FfiNullifierCommitmentSet;
typedef struct FfiVec_FfiNullifierCommitmentSet {
struct FfiNullifierCommitmentSet *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiNullifierCommitmentSet;
typedef struct FfiVec_FfiNullifierCommitmentSet FfiNullifierCommitmentSetList;
typedef struct FfiPrivacyPreservingMessage {
FfiAccountIdList public_account_ids;
FfiNonceList nonces;
FfiAccountList public_post_states;
FfiEncryptedAccountDataList encrypted_private_post_states;
FfiVecBytes32 new_commitments;
FfiNullifierCommitmentSetList new_nullifiers;
uint64_t block_validity_window[2];
uint64_t timestamp_validity_window[2];
} FfiPrivacyPreservingMessage;
typedef FfiVecU8 FfiProof;
typedef struct FfiPrivateTransactionBody {
FfiHashType hash;
struct FfiPrivacyPreservingMessage message;
FfiSignaturePubKeyList witness_set;
FfiProof proof;
} FfiPrivateTransactionBody;
typedef FfiVecU8 FfiProgramDeploymentMessage;
typedef struct FfiProgramDeploymentTransactionBody {
FfiHashType hash;
FfiProgramDeploymentMessage message;
} FfiProgramDeploymentTransactionBody;
typedef struct FfiTransactionBody {
struct FfiPublicTransactionBody *public_body;
struct FfiPrivateTransactionBody *private_body;
struct FfiProgramDeploymentTransactionBody *program_deployment_body;
} FfiTransactionBody;
typedef struct FfiTransaction {
struct FfiTransactionBody body;
enum FfiTransactionKind kind;
} FfiTransaction;
typedef struct FfiVec_FfiTransaction {
struct FfiTransaction *entries;
uintptr_t len;
uintptr_t capacity;
} FfiVec_FfiTransaction;
typedef struct FfiVec_FfiTransaction FfiBlockBody;
typedef struct FfiBytes32 FfiMsgId;
typedef struct FfiBlock {
struct FfiBlockHeader header;
FfiBlockBody body;
enum FfiBedrockStatus bedrock_status;
FfiMsgId bedrock_parent_id;
} FfiBlock;
typedef struct FfiOption_FfiBlock {
struct FfiBlock *value;
bool is_some;
} FfiOption_FfiBlock;
typedef struct FfiOption_FfiBlock FfiBlockOpt;
/**
* Simple wrapper around a pointer to a value or an error.
*
* Pointer is not guaranteed. You should check the error field before
* dereferencing the pointer.
*/
typedef struct PointerResult_BlockOpt__OperationStatus {
BlockOpt *value;
typedef struct PointerResult_FfiBlockOpt__OperationStatus {
FfiBlockOpt *value;
enum OperationStatus error;
} PointerResult_BlockOpt__OperationStatus;
} PointerResult_FfiBlockOpt__OperationStatus;
/**
* Creates and starts an indexer based on the provided
@ -133,8 +384,8 @@ struct PointerResult_u64__OperationStatus query_last_block(const struct IndexerS
* - The `IndexerServiceFFI` instance was created by this library
* - The pointer will not be used after this function returns
*/
struct PointerResult_BlockOpt__OperationStatus query_block(const struct IndexerServiceFFI *indexer,
BlockId block_id);
struct PointerResult_FfiBlockOpt__OperationStatus query_block(const struct IndexerServiceFFI *indexer,
FfiBlockId block_id);
bool is_ok(const enum OperationStatus *self);

View File

@ -1,16 +0,0 @@
use crate::api::types::BlockOpt;
impl From<Option<sequencer_core::block_settlement_client::Block>> for BlockOpt {
fn from(value: Option<sequencer_core::block_settlement_client::Block>) -> Self {
match value {
None => BlockOpt {
block: std::ptr::null_mut(),
is_ok: false,
},
Some(block_orig) => BlockOpt {
block: block_orig.into(),
is_ok: true,
},
}
}
}

View File

@ -1,6 +1,6 @@
use std::{ffi::c_char, path::PathBuf};
use sequencer_core::indexer_client::{IndexerClient, IndexerClientTrait};
use sequencer_core::indexer_client::{IndexerClient, IndexerClientTrait as _};
use tokio::runtime::Runtime;
use crate::{

View File

@ -1,7 +1,6 @@
pub use result::PointerResult;
pub mod client;
pub mod convert;
pub mod lifecycle;
pub mod memory;
pub mod query;

View File

@ -1,10 +1,10 @@
use indexer_service_rpc::RpcClient;
use indexer_service_rpc::RpcClient as _;
use crate::{
IndexerServiceFFI,
api::{
PointerResult,
types::{Block, BlockId, BlockOpt},
types::{FfiBlockId, block::FfiBlockOpt},
},
errors::OperationStatus,
};
@ -66,8 +66,8 @@ pub unsafe extern "C" fn query_last_block(
#[unsafe(no_mangle)]
pub unsafe extern "C" fn query_block(
indexer: *const IndexerServiceFFI,
block_id: BlockId,
) -> PointerResult<BlockOpt, OperationStatus> {
block_id: FfiBlockId,
) -> PointerResult<FfiBlockOpt, OperationStatus> {
if indexer.is_null() {
log::error!("Attempted to query a null indexer pointer. This is a bug. Aborting.");
return PointerResult::from_error(OperationStatus::NullPointer);
@ -82,6 +82,12 @@ pub unsafe extern "C" fn query_block(
.block_on(client.get_block_by_id(block_id))
.map_or_else(
|_| PointerResult::from_error(OperationStatus::ClientError),
|block| PointerResult::from_value(block.into()),
|block_opt| {
let block_ffi = block_opt.map_or_else(FfiBlockOpt::from_none, |block| {
FfiBlockOpt::from_value(block.into())
});
PointerResult::from_value(block_ffi)
},
)
}

View File

@ -2,7 +2,7 @@
use std::ptr;
use crate::api::types::FfiVec;
use indexer_service_protocol::ProgramId;
/// 32-byte array type for `AccountId`, keys, hashes, etc.
#[repr(C)]
@ -31,6 +31,12 @@ pub struct FfiProgramId {
pub data: [u32; 8],
}
impl From<ProgramId> for FfiProgramId {
fn from(value: ProgramId) -> Self {
Self { data: value.0 }
}
}
/// U128 - 16 bytes little endian.
#[repr(C)]
#[derive(Clone, Copy, Default)]
@ -55,12 +61,6 @@ pub struct FfiAccount {
pub nonce: FfiU128,
}
#[repr(C)]
pub struct FfiAccountList {
pub entries: *const FfiAccount,
pub len: usize,
}
impl Default for FfiAccount {
fn default() -> Self {
Self {
@ -101,32 +101,6 @@ pub struct FfiPublicAccountKey {
pub public_key: FfiBytes32,
}
/// Single entry in the account list.
#[repr(C)]
#[derive(Clone, Copy)]
pub struct FfiAccountIdListEntry {
pub account_id: FfiBytes32,
pub is_public: bool,
}
/// List of accounts returned by `wallet_ffi_list_accounts`.
#[repr(C)]
pub struct FfiAccountIdList {
pub entries: *mut FfiAccountIdListEntry,
pub count: usize,
}
impl Default for FfiAccountIdList {
fn default() -> Self {
Self {
entries: std::ptr::null_mut(),
count: 0,
}
}
}
pub type FfiVecBytes32 = FfiVec<FfiBytes32>;
// Helper functions to convert between Rust and FFI types
impl FfiBytes32 {

View File

@ -1,6 +1,7 @@
use indexer_service_protocol::{BedrockStatus, Block, BlockHeader};
use crate::api::types::{
FfiBlockId, FfiHashType, FfiMsgId, FfiSignature, FfiTimestamp, FfiVec,
transaction::FfiTransaction,
FfiBlockId, FfiHashType, FfiMsgId, FfiOption, FfiSignature, FfiTimestamp, vectors::FfiBlockBody,
};
#[repr(C)]
@ -11,13 +12,24 @@ pub struct FfiBlock {
pub bedrock_parent_id: FfiMsgId,
}
#[repr(C)]
pub struct FfiBlockOpt {
pub block: *const FfiBlock,
pub is_some: bool,
impl From<Block> for FfiBlock {
fn from(value: Block) -> Self {
Self {
header: value.header.into(),
body: value
.body
.transactions
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
bedrock_status: value.bedrock_status.into(),
bedrock_parent_id: value.bedrock_parent_id.into(),
}
}
}
pub type FfiBlockBody = FfiVec<FfiTransaction>;
pub type FfiBlockOpt = FfiOption<FfiBlock>;
#[repr(C)]
pub struct FfiBlockHeader {
@ -28,9 +40,31 @@ pub struct FfiBlockHeader {
pub signature: FfiSignature,
}
impl From<BlockHeader> for FfiBlockHeader {
fn from(value: BlockHeader) -> Self {
Self {
block_id: value.block_id,
prev_block_hash: value.prev_block_hash.into(),
hash: value.hash.into(),
timestamp: value.timestamp,
signature: value.signature.into(),
}
}
}
#[repr(C)]
pub enum FfiBedrockStatus {
Pending = 0x0,
Safe,
Finalized,
}
impl From<BedrockStatus> for FfiBedrockStatus {
fn from(value: BedrockStatus) -> Self {
match value {
BedrockStatus::Finalized => Self::Finalized,
BedrockStatus::Pending => Self::Pending,
BedrockStatus::Safe => Self::Safe,
}
}
}

View File

@ -1,8 +1,11 @@
use indexer_service_protocol::{AccountId, HashType, MantleMsgId, PublicKey, Signature};
use crate::api::types::account::{FfiBytes32, FfiBytes64, FfiU128};
pub mod account;
pub mod block;
pub mod transaction;
pub mod vectors;
pub type FfiHashType = FfiBytes32;
pub type FfiMsgId = FfiBytes32;
@ -13,17 +16,73 @@ pub type FfiAccountId = FfiBytes32;
pub type FfiNonce = FfiU128;
pub type FfiPublicKey = FfiBytes32;
#[repr(C)]
pub struct FfiVec<T> {
pub entries: *const T,
pub len: usize,
impl From<HashType> for FfiHashType {
fn from(value: HashType) -> Self {
Self { data: value.0 }
}
}
impl<T> Default for FfiVec<T> {
fn default() -> Self {
impl From<MantleMsgId> for FfiMsgId {
fn from(value: MantleMsgId) -> Self {
Self { data: value.0 }
}
}
impl From<Signature> for FfiSignature {
fn from(value: Signature) -> Self {
Self { data: value.0 }
}
}
impl From<AccountId> for FfiAccountId {
fn from(value: AccountId) -> Self {
Self { data: value.value }
}
}
impl From<PublicKey> for FfiPublicKey {
fn from(value: PublicKey) -> Self {
Self { data: value.0 }
}
}
#[repr(C)]
pub struct FfiVec<T> {
pub entries: *mut T,
pub len: usize,
pub capacity: usize,
}
impl<T> From<Vec<T>> for FfiVec<T> {
fn from(value: Vec<T>) -> Self {
let (entries, len, capacity) = value.into_raw_parts();
Self {
entries: std::ptr::null(),
len: 0,
entries,
len,
capacity,
}
}
}
#[repr(C)]
pub struct FfiOption<T> {
pub value: *mut T,
pub is_some: bool,
}
impl<T> FfiOption<T> {
pub fn from_value(val: T) -> Self {
Self {
value: Box::into_raw(Box::new(val)),
is_some: true,
}
}
#[must_use]
pub const fn from_none() -> Self {
Self {
value: std::ptr::null_mut(),
is_some: false,
}
}
}

View File

@ -1,6 +1,17 @@
use indexer_service_protocol::{
CommitmentSetDigest, EncryptedAccountData, Nullifier, PrivacyPreservingMessage,
PrivacyPreservingTransaction, ProgramDeploymentTransaction, PublicKey, PublicMessage,
PublicTransaction, Signature, Transaction, ValidityWindow,
};
use crate::api::types::{
FfiHashType, FfiNonce, FfiPublicKey, FfiSignature, FfiVec,
account::{FfiAccountIdList, FfiAccountList, FfiBytes32, FfiProgramId, FfiVecBytes32},
FfiHashType, FfiPublicKey, FfiSignature,
account::{FfiBytes32, FfiProgramId},
vectors::{
FfiAccountIdList, FfiAccountList, FfiEncryptedAccountDataList, FfiInstructionDataList,
FfiNonceList, FfiNullifierCommitmentSetList, FfiProgramDeploymentMessage, FfiProof,
FfiSignaturePubKeyList, FfiVecBytes32, FfiVecU8,
},
};
#[repr(C)]
@ -10,9 +21,21 @@ pub struct FfiPublicTransactionBody {
pub witness_set: FfiSignaturePubKeyList,
}
pub type FfiNonceList = FfiVec<FfiNonce>;
pub type FfiInstructionDataList = FfiVec<u32>;
impl From<PublicTransaction> for FfiPublicTransactionBody {
fn from(value: PublicTransaction) -> Self {
Self {
hash: value.hash.into(),
message: value.message.into(),
witness_set: value
.witness_set
.signatures_and_public_keys
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
}
}
}
#[repr(C)]
pub struct FfiPublicMessage {
@ -22,12 +45,55 @@ pub struct FfiPublicMessage {
pub instruction_data: FfiInstructionDataList,
}
impl From<PublicMessage> for FfiPublicMessage {
fn from(value: PublicMessage) -> Self {
Self {
program_id: value.program_id.into(),
account_ids: value
.account_ids
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
nonces: value
.nonces
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
instruction_data: value.instruction_data.into(),
}
}
}
#[repr(C)]
pub struct FfiPrivateTransactionBody {
pub hash: FfiHashType,
pub message: FfiPrivacyPreservingMessage,
pub witness_set: FfiSignaturePubKeyList,
pub proof: FfiProofOpt,
pub proof: FfiProof,
}
impl From<PrivacyPreservingTransaction> for FfiPrivateTransactionBody {
fn from(value: PrivacyPreservingTransaction) -> Self {
Self {
hash: value.hash.into(),
message: value.message.into(),
witness_set: value
.witness_set
.signatures_and_public_keys
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
proof: value
.witness_set
.proof
.expect("Private execution: proof must be present")
.0
.into(),
}
}
}
#[repr(C)]
@ -35,41 +101,106 @@ pub struct FfiPrivacyPreservingMessage {
pub public_account_ids: FfiAccountIdList,
pub nonces: FfiNonceList,
pub public_post_states: FfiAccountList,
pub encrypted_private_post_states: FfiVec<FfiEncryptedAccountData>,
pub encrypted_private_post_states: FfiEncryptedAccountDataList,
pub new_commitments: FfiVecBytes32,
pub new_nullifiers: FfiVec<NullifierCommitmentSet>,
pub new_nullifiers: FfiNullifierCommitmentSetList,
pub block_validity_window: [u64; 2],
pub timestamp_validity_window: [u64; 2],
}
impl From<PrivacyPreservingMessage> for FfiPrivacyPreservingMessage {
fn from(value: PrivacyPreservingMessage) -> Self {
Self {
public_account_ids: value
.public_account_ids
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
nonces: value
.nonces
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
public_post_states: value
.public_post_states
.into_iter()
.map(|acc_ind| -> nssa::Account {
acc_ind.try_into().expect("Source is in blocks, must fit")
})
.map(Into::into)
.collect::<Vec<_>>()
.into(),
encrypted_private_post_states: value
.encrypted_private_post_states
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
new_commitments: value
.new_commitments
.into_iter()
.map(|comm| FfiBytes32 { data: comm.0 })
.collect::<Vec<_>>()
.into(),
new_nullifiers: value
.new_nullifiers
.into_iter()
.map(Into::into)
.collect::<Vec<_>>()
.into(),
block_validity_window: cast_validity_window(value.block_validity_window),
timestamp_validity_window: cast_validity_window(value.timestamp_validity_window),
}
}
}
#[repr(C)]
pub struct NullifierCommitmentSet {
pub struct FfiNullifierCommitmentSet {
pub nullifier: FfiBytes32,
pub commitment_set_digest: FfiBytes32,
}
impl From<(Nullifier, CommitmentSetDigest)> for FfiNullifierCommitmentSet {
fn from(value: (Nullifier, CommitmentSetDigest)) -> Self {
Self {
nullifier: FfiBytes32 { data: value.0.0 },
commitment_set_digest: FfiBytes32 { data: value.1.0 },
}
}
}
#[repr(C)]
pub struct FfiEncryptedAccountData {
pub ciphertext: FfiVec<u8>,
pub epk: FfiVec<u8>,
pub ciphertext: FfiVecU8,
pub epk: FfiVecU8,
pub view_tag: u8,
}
impl From<EncryptedAccountData> for FfiEncryptedAccountData {
fn from(value: EncryptedAccountData) -> Self {
Self {
ciphertext: value.ciphertext.0.into(),
epk: value.epk.0.into(),
view_tag: value.view_tag,
}
}
}
#[repr(C)]
pub struct FfiSignaturePubKeyEntry {
pub signature: FfiSignature,
pub public_key: FfiPublicKey,
}
pub struct FfiSignaturePubKeyList {
pub entries: *const FfiSignaturePubKeyEntry,
pub len: usize,
}
#[repr(C)]
pub struct FfiProofOpt {
pub proof: FfiVec<u8>,
pub is_some: bool,
impl From<(Signature, PublicKey)> for FfiSignaturePubKeyEntry {
fn from(value: (Signature, PublicKey)) -> Self {
Self {
signature: value.0.into(),
public_key: value.1.into(),
}
}
}
#[repr(C)]
@ -78,13 +209,20 @@ pub struct FfiProgramDeploymentTransactionBody {
pub message: FfiProgramDeploymentMessage,
}
pub type FfiProgramDeploymentMessage = FfiVec<u8>;
impl From<ProgramDeploymentTransaction> for FfiProgramDeploymentTransactionBody {
fn from(value: ProgramDeploymentTransaction) -> Self {
Self {
hash: value.hash.into(),
message: value.message.bytecode.into(),
}
}
}
#[repr(C)]
pub struct FfiTransactionBody {
pub public_body: *const FfiPublicTransactionBody,
pub private_body: *const FfiPrivateTransactionBody,
pub program_deployment_body: *const FfiProgramDeploymentTransactionBody,
pub public_body: *mut FfiPublicTransactionBody,
pub private_body: *mut FfiPrivateTransactionBody,
pub program_deployment_body: *mut FfiProgramDeploymentTransactionBody,
}
#[repr(C)]
@ -93,9 +231,47 @@ pub struct FfiTransaction {
pub kind: FfiTransactionKind,
}
impl From<Transaction> for FfiTransaction {
fn from(value: Transaction) -> Self {
match value {
Transaction::Public(pub_tx) => Self {
body: FfiTransactionBody {
public_body: Box::into_raw(Box::new(pub_tx.into())),
private_body: std::ptr::null_mut(),
program_deployment_body: std::ptr::null_mut(),
},
kind: FfiTransactionKind::Public,
},
Transaction::PrivacyPreserving(priv_tx) => Self {
body: FfiTransactionBody {
public_body: std::ptr::null_mut(),
private_body: Box::into_raw(Box::new(priv_tx.into())),
program_deployment_body: std::ptr::null_mut(),
},
kind: FfiTransactionKind::Public,
},
Transaction::ProgramDeployment(pr_dep_tx) => Self {
body: FfiTransactionBody {
public_body: std::ptr::null_mut(),
private_body: std::ptr::null_mut(),
program_deployment_body: Box::into_raw(Box::new(pr_dep_tx.into())),
},
kind: FfiTransactionKind::Public,
},
}
}
}
#[repr(C)]
pub enum FfiTransactionKind {
Public = 0x0,
Private,
ProgramDeploy,
}
fn cast_validity_window(window: ValidityWindow) -> [u64; 2] {
[
window.0.0.unwrap_or_default(),
window.0.1.unwrap_or(u64::MAX),
]
}

View File

@ -0,0 +1,31 @@
use crate::api::types::{
FfiAccountId, FfiNonce, FfiVec,
account::{FfiAccount, FfiBytes32},
transaction::{
FfiEncryptedAccountData, FfiNullifierCommitmentSet, FfiSignaturePubKeyEntry, FfiTransaction,
},
};
pub type FfiVecU8 = FfiVec<u8>;
pub type FfiAccountList = FfiVec<FfiAccount>;
pub type FfiAccountIdList = FfiVec<FfiAccountId>;
pub type FfiVecBytes32 = FfiVec<FfiBytes32>;
pub type FfiBlockBody = FfiVec<FfiTransaction>;
pub type FfiNonceList = FfiVec<FfiNonce>;
pub type FfiInstructionDataList = FfiVec<u32>;
pub type FfiSignaturePubKeyList = FfiVec<FfiSignaturePubKeyEntry>;
pub type FfiProof = FfiVecU8;
pub type FfiProgramDeploymentMessage = FfiVecU8;
pub type FfiEncryptedAccountDataList = FfiVec<FfiEncryptedAccountData>;
pub type FfiNullifierCommitmentSetList = FfiVec<FfiNullifierCommitmentSet>;

View File

@ -271,7 +271,7 @@ impl BlockingTestContextFFI {
#[must_use]
pub const fn indexer_ffi(&self) -> *const IndexerServiceFFI {
&(self.indexer_ffi)
&raw const (self.indexer_ffi)
}
}

View File

@ -1,6 +1,7 @@
#![expect(
clippy::shadow_unrelated,
clippy::tests_outside_test_module,
clippy::undocumented_unsafe_blocks,
reason = "We don't care about these in tests"
)]