ab_contracts_test_utils/
transaction_builder.rs

1use ab_contracts_common::Address;
2use ab_contracts_common::env::Blake3Hash;
3use ab_contracts_common::method::ExternalArgs;
4use ab_system_contract_simple_wallet_base::payload::TransactionMethodContext;
5use ab_system_contract_simple_wallet_base::payload::builder::{
6    TransactionPayloadBuilder, TransactionPayloadBuilderError,
7};
8use ab_transaction::{Gas, Transaction, TransactionHeader, TransactionSlot};
9use alloc::vec::Vec;
10
11#[derive(Debug, Clone)]
12pub struct OwnedTransaction {
13    pub header: TransactionHeader,
14    pub read_slots: Vec<TransactionSlot>,
15    pub write_slots: Vec<TransactionSlot>,
16    pub payload: Vec<u128>,
17    pub seal: Vec<u8>,
18}
19
20impl OwnedTransaction {
21    /// Get [`Transaction`] out of owned transaction
22    pub fn as_ref(&self) -> Transaction<'_> {
23        Transaction {
24            header: &self.header,
25            read_slots: &self.read_slots,
26            write_slots: &self.write_slots,
27            payload: &self.payload,
28            seal: &self.seal,
29        }
30    }
31}
32
33#[derive(Debug)]
34pub struct TransactionBuilder {
35    contract: Address,
36    transaction_payload_builder: TransactionPayloadBuilder,
37}
38
39impl TransactionBuilder {
40    /// Create a transaction for `contract`
41    pub fn new(contract: Address) -> Self {
42        Self {
43            contract,
44            transaction_payload_builder: TransactionPayloadBuilder::default(),
45        }
46    }
47
48    /// Add method call to the transaction.
49    ///
50    /// See [`TransactionPayloadBuilder::with_method_call()`] for details of this API.
51    pub fn with_method_call<Args>(
52        &mut self,
53        contract: &Address,
54        external_args: &Args,
55        method_context: TransactionMethodContext,
56        slot_output_index: &[Option<u8>],
57        input_output_index: &[Option<u8>],
58    ) -> Result<(), TransactionPayloadBuilderError<'static>>
59    where
60        Args: ExternalArgs,
61    {
62        self.transaction_payload_builder.with_method_call(
63            contract,
64            external_args,
65            method_context,
66            slot_output_index,
67            input_output_index,
68        )
69    }
70
71    pub fn build(
72        self,
73        read_slots: Vec<TransactionSlot>,
74        write_slots: Vec<TransactionSlot>,
75    ) -> OwnedTransaction {
76        OwnedTransaction {
77            header: TransactionHeader {
78                block_hash: Blake3Hash::default(),
79                gas_limit: Gas::default(),
80                contract: self.contract,
81            },
82            read_slots,
83            write_slots,
84            payload: self.transaction_payload_builder.into_aligned_bytes(),
85            seal: Vec::new(),
86        }
87    }
88}