Represents a buy or sell order with encrypted price and quantity.
Copy
use privora_sdk_program::prelude::EncryptedRef;#[derive(BorshSerialize, BorshDeserialize, Clone, Debug)]pub struct Order { /// Owner of the order pub owner: Pubkey, /// Typed reference to encrypted price data (u8) pub price_ref: EncryptedRef<u8>, /// Typed reference to encrypted quantity data (u8) pub qty_ref: EncryptedRef<u8>, /// Order side (Buy or Sell) pub side: OrderSide, /// Order status pub status: OrderStatus, /// Order ID pub order_id: u64,}impl Order { pub const LEN: usize = 32 + // owner 32 + // price_ref (EncryptedRef is 32 bytes) 32 + // qty_ref 1 + // side 1 + // status 8; // order_id (106 bytes total)}
EncryptedRef<u8> is exactly 32 bytes - the SHA256 hash of the ciphertext. The actual encrypted data (potentially kilobytes) lives in the content-addressable store, not on-chain.
// Load order from accountlet order = Order::try_from_slice(&order_account.data.borrow())?;// Load encrypted price for computationlet price = order.price_ref.load()?;
let mut order = Order::try_from_slice(&order_account.data.borrow())?;order.status = OrderStatus::Matched;order.serialize(&mut *order_account.data.borrow_mut())?;
The generic parameter in EncryptedRef<T> provides compile-time type safety:
Copy
// These are different types - can't mix them up!price_ref: EncryptedRef<u8>, // Price is u8qty_ref: EncryptedRef<u32>, // Quantity could be u32// Loading preserves the typelet price: Encrypted<u8> = order.price_ref.load()?;let qty: Encrypted<u32> = order.qty_ref.load()?;// Type errors caught at compile timelet _wrong = price.add(&qty); // Error: mismatched types