Skip to main content

light_event/
event.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2use light_compressed_account::{
3    instruction_data::{
4        data::OutputCompressedAccountWithPackedContext,
5        insert_into_queues::MerkleTreeSequenceNumber as InstructionDataSequenceNumber,
6    },
7    Pubkey,
8};
9
10#[derive(Debug, Clone, Default, PartialEq)]
11pub struct BatchPublicTransactionEvent {
12    pub event: PublicTransactionEvent,
13    pub new_addresses: Vec<NewAddress>,
14    pub input_sequence_numbers: Vec<MerkleTreeSequenceNumber>,
15    pub address_sequence_numbers: Vec<MerkleTreeSequenceNumber>,
16    pub tx_hash: [u8; 32],
17    pub batch_input_accounts: Vec<BatchNullifyContext>,
18}
19
20#[derive(Debug, Clone, BorshSerialize, BorshDeserialize, Default, PartialEq)]
21pub struct PublicTransactionEvent {
22    pub input_compressed_account_hashes: Vec<[u8; 32]>,
23    pub output_compressed_account_hashes: Vec<[u8; 32]>,
24    pub output_compressed_accounts: Vec<OutputCompressedAccountWithPackedContext>,
25    pub output_leaf_indices: Vec<u32>,
26    pub sequence_numbers: Vec<MerkleTreeSequenceNumberV1>,
27    pub relay_fee: Option<u64>,
28    pub is_compress: bool,
29    pub compress_or_decompress_lamports: Option<u64>,
30    pub pubkey_array: Vec<Pubkey>,
31    pub message: Option<Vec<u8>>,
32    /// ATA owner info for compressed ATAs (output_index -> wallet_owner_pubkey).
33    /// Only populated for compress_and_close operations where is_ata=true.
34    pub ata_owners: Vec<AssociatedTokenAccountOwnerInfo>,
35}
36
37/// ATA owner info extracted from compress_and_close operations.
38#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize, Default, PartialEq, Eq)]
39pub struct AssociatedTokenAccountOwnerInfo {
40    /// Index into output_compressed_accounts
41    pub output_index: u8,
42    /// The wallet owner pubkey that the ATA is derived from
43    pub wallet_owner: Pubkey,
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47pub struct NewAddress {
48    pub address: [u8; 32],
49    pub mt_pubkey: Pubkey,
50    pub queue_index: u64,
51}
52
53#[derive(Default, Debug, Clone, PartialEq, Eq)]
54pub struct BatchNullifyContext {
55    pub tx_hash: [u8; 32],
56    pub account_hash: [u8; 32],
57    pub nullifier: [u8; 32],
58    pub nullifier_queue_index: u64,
59}
60
61// Separate type because zerocopy::U64 doesn't implement BorshSerialize.
62#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize, Default, PartialEq)]
63pub struct MerkleTreeSequenceNumber {
64    pub tree_pubkey: Pubkey,
65    pub queue_pubkey: Pubkey,
66    pub tree_type: u64,
67    pub seq: u64,
68}
69
70#[derive(Debug, Clone, Copy, BorshSerialize, BorshDeserialize, Default, PartialEq)]
71pub struct MerkleTreeSequenceNumberV1 {
72    pub tree_pubkey: Pubkey,
73    pub seq: u64,
74}
75
76impl MerkleTreeSequenceNumber {
77    pub fn is_empty(&self) -> bool {
78        self.tree_pubkey == Pubkey::default()
79    }
80}
81
82impl From<&InstructionDataSequenceNumber> for MerkleTreeSequenceNumber {
83    fn from(seq: &InstructionDataSequenceNumber) -> Self {
84        Self {
85            tree_pubkey: seq.tree_pubkey,
86            queue_pubkey: seq.queue_pubkey,
87            tree_type: seq.tree_type.into(),
88            seq: seq.seq.into(),
89        }
90    }
91}