Skip to main content
Configure the FHE test environment for your program tests.

Basic Setup

use privora_sdk_testing::prelude::*;

#[test]
fn test_my_program() {
    let mut env = FheTestEnv::new();
    // ...
}

Builder Pattern

Use the builder for custom configuration:
let mut env = FheTestEnv::builder()
    .heap_size(2 * 1024 * 1024)  // 2MB heap
    .build();

Deploying Programs

const PROGRAM_ID: Pubkey = solana_pubkey::pubkey!("MyProgram...");

let mut env = FheTestEnv::new();
env.deploy_program(PROGRAM_ID, include_bytes!("../target/deploy/my_program.so"));

Creating Accounts

Funded Keypair

let payer = env.create_funded_keypair();
// Automatically funded with 10 SOL

Manual Airdrop

let keypair = Keypair::new();
env.airdrop(&keypair.pubkey(), 1_000_000_000); // 1 SOL

Rent Exemption

let rent = env.minimum_balance_for_rent_exemption(100); // 100 bytes

Sending Transactions

use solana_sdk::transaction::Transaction;

// Build transaction
let tx = Transaction::new_signed_with_payer(
    &[instruction],
    Some(&payer.pubkey()),
    &[&payer],
    env.latest_blockhash(),
);

// Sync data before sending
env.sync_data_store_to_syscalls();

// Send transaction
let result = env.svm.send_transaction(tx);

// Sync data after sending
env.sync_data_store_from_syscalls();

// Handle result
match result {
    Ok(meta) => println!("Success: {:?}", meta.logs),
    Err(e) => panic!("Failed: {:?}", e),
}

Complete Test Example

use privora_sdk_testing::prelude::*;
use solana_sdk::{
    instruction::{AccountMeta, Instruction},
    signature::Keypair,
    signer::Signer,
    transaction::Transaction,
};

const PROGRAM_ID: Pubkey = solana_pubkey::pubkey!("MyProgram111111111111111111111111111111111");

#[test]
fn test_encrypted_add() {
    // Setup
    let mut env = FheTestEnv::new();
    env.deploy_program(PROGRAM_ID, include_bytes!("../target/deploy/my_program.so"));

    let payer = env.create_funded_keypair();
    let account = Keypair::new();

    // Create account
    let rent = env.minimum_balance_for_rent_exemption(64);
    let create_ix = solana_sdk::system_instruction::create_account(
        &payer.pubkey(),
        &account.pubkey(),
        rent,
        64,
        &PROGRAM_ID,
    );

    // Encrypt test values
    let a_hash = env.encrypt_and_submit_u8(50);
    let b_hash = env.encrypt_and_submit_u8(30);

    // Build instruction
    let mut data = vec![0u8];
    data.extend_from_slice(&a_hash);
    data.extend_from_slice(&b_hash);

    let process_ix = Instruction {
        program_id: PROGRAM_ID,
        accounts: vec![AccountMeta::new(account.pubkey(), false)],
        data,
    };

    // Send transaction
    env.sync_data_store_to_syscalls();

    let tx = Transaction::new_signed_with_payer(
        &[create_ix, process_ix],
        Some(&payer.pubkey()),
        &[&payer, &account],
        env.latest_blockhash(),
    );

    env.svm.send_transaction(tx).unwrap();
    env.sync_data_store_from_syscalls();

    // Verify result: 50 + 30 = 80
    let account_data = env.svm.get_account(&account.pubkey()).unwrap();
    let result_hash: [u8; 32] = account_data.data[0..32].try_into().unwrap();

    env.assert_encrypted_eq_u8(&result_hash, 80);
}