ccnext_abi_encoding/abi/
mod.rs1use super::common::AbiEncodeResult;
2use alloy::{
3 dyn_abi::DynSolValue,
4 primitives::U256,
5 rpc::types::{Transaction, TransactionReceipt},
6};
7use thiserror::Error;
8
9mod v1;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub enum EncodingVersion {
13 V1 = 1,
14}
15
16fn encode_receipt(rx: TransactionReceipt) -> Vec<DynSolValue> {
17 let log_blooms = rx.inner.logs_bloom().0.to_vec();
18 let result = vec![
19 DynSolValue::Uint(U256::from(rx.status()), 8),
20 DynSolValue::Uint(U256::from(rx.gas_used), 64),
21 DynSolValue::Array(
22 rx.inner
23 .logs()
24 .iter()
25 .map(|log| {
26 let topics = DynSolValue::Array(
27 log.topics()
28 .iter()
29 .map(|topic| DynSolValue::FixedBytes(*topic, 32))
30 .collect(),
31 );
32
33 DynSolValue::Tuple(vec![
34 DynSolValue::Address(log.address()),
35 topics,
36 DynSolValue::Bytes(log.data().data.to_vec()),
37 ])
38 })
39 .collect(),
40 ),
41 DynSolValue::Bytes(log_blooms),
42 ];
43
44 result
45}
46
47#[derive(Debug, Error)]
48pub enum EncodeError {
49 #[error("Custom error: {0}")]
50 Custom(String),
51}
52pub fn abi_encode(
53 tx: Transaction,
54 rx: TransactionReceipt,
55 version: EncodingVersion,
56) -> Result<AbiEncodeResult, Box<dyn std::error::Error>> {
57 let transaction_fields = match version {
58 EncodingVersion::V1 => v1::encode_transaction(tx),
59 };
60 let receipt_fields = encode_receipt(rx);
61 let mut all_fields = Vec::new();
62 all_fields.extend(transaction_fields);
63 all_fields.extend(receipt_fields);
64 let tuple = DynSolValue::Tuple(all_fields.clone());
65 let final_bytes = match tuple.abi_encode_sequence() {
66 Some(final_bytes) => final_bytes,
67 None => {
68 return Err(Box::new(EncodeError::Custom(
69 "Failed to encode sequence".into(),
70 )));
71 }
72 };
73
74 let field_types: Vec<String> = all_fields
75 .into_iter()
76 .map(|field| match field.as_type() {
77 Some(sol_type) => sol_type.sol_type_name().into_owned(),
78 None => "unknown".into(),
79 })
80 .collect();
81
82 Ok(AbiEncodeResult {
83 types: field_types,
84 abi: final_bytes,
85 })
86}