openzeppelin_monitor/utils/tests/builders/evm/
receipt.rs1use crate::models::{EVMBaseReceipt, EVMReceiptLog, EVMTransactionReceipt};
2use alloy::{
3 primitives::{Address, Bytes, LogData, B256, U256, U64},
4 rpc::types::Index,
5};
6use std::str::FromStr;
7
8#[derive(Debug, Default)]
10pub struct ReceiptBuilder {
11 transaction_hash: Option<B256>,
12 status: Option<bool>,
13 gas_used: Option<U256>,
14 logs: Option<Vec<EVMReceiptLog>>,
15 from: Option<Address>,
16 to: Option<Address>,
17 contract_address: Option<Address>,
18 transaction_index: Option<Index>,
19}
20
21impl ReceiptBuilder {
22 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn transaction_hash(mut self, transaction_hash: B256) -> Self {
29 self.transaction_hash = Some(transaction_hash);
30 self
31 }
32
33 pub fn status(mut self, status: bool) -> Self {
35 self.status = Some(status);
36 self
37 }
38
39 pub fn gas_used(mut self, gas_used: U256) -> Self {
41 self.gas_used = Some(gas_used);
42 self
43 }
44
45 pub fn transaction_index(mut self, transaction_index: usize) -> Self {
47 self.transaction_index = Some(Index::from(transaction_index));
48 self
49 }
50
51 pub fn logs(mut self, logs: Vec<EVMReceiptLog>) -> Self {
53 self.logs = Some(logs);
54 self
55 }
56
57 pub fn from(mut self, from: Address) -> Self {
59 self.from = Some(from);
60 self
61 }
62
63 pub fn to(mut self, to: Address) -> Self {
65 self.to = Some(to);
66 self
67 }
68
69 pub fn contract_address(mut self, contract_address: Address) -> Self {
71 self.contract_address = Some(contract_address);
72 self
73 }
74
75 pub fn value(mut self, value: U256) -> Self {
77 let event_signature = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
78 let contract_address = self.contract_address.unwrap_or_default();
79 let from_address = self.from.unwrap_or_default();
80 let to_address = self.to.unwrap_or_default();
81 let value_hex = format!("{:064x}", value);
82
83 let alloy_log = alloy::primitives::Log {
84 address: contract_address,
85 data: LogData::new_unchecked(
86 vec![
87 B256::from_str(event_signature).unwrap(),
88 B256::from_slice(&[&[0u8; 12], from_address.as_slice()].concat()),
89 B256::from_slice(&[&[0u8; 12], to_address.as_slice()].concat()),
90 ],
91 Bytes(hex::decode(value_hex).unwrap().into()),
92 ),
93 };
94
95 let base_log = EVMReceiptLog::from(alloy_log);
96 self.logs = Some(vec![base_log]);
97 self
98 }
99
100 pub fn build(self) -> EVMTransactionReceipt {
102 let status_success = self.status.unwrap_or(true);
103 let status_u64 = if status_success {
104 U64::from(1)
105 } else {
106 U64::from(0)
107 };
108
109 let base = EVMBaseReceipt {
110 transaction_hash: self.transaction_hash.unwrap_or_default(),
111 status: Some(status_u64),
112 gas_used: self.gas_used,
113 logs: self.logs.unwrap_or_default(),
114 from: self.from.unwrap_or_default(),
115 to: self.to,
116 contract_address: self.contract_address,
117 transaction_index: self.transaction_index.unwrap_or_default(),
118 ..Default::default()
119 };
120
121 EVMTransactionReceipt::from(base)
122 }
123}