1mod builder;
2
3mod either;
4use alloy_consensus::TxEnvelope;
5use alloy_eips::{eip7702::SignedAuthorization, Typed2718};
6use alloy_primitives::{Bytes, ChainId, TxKind, B256, U256};
7pub use either::{AnyTxEnvelope, AnyTypedTransaction};
8
9mod unknowns;
10pub use unknowns::{AnyTxType, UnknownTxEnvelope, UnknownTypedTransaction};
11
12pub use alloy_consensus_any::{AnyHeader, AnyReceiptEnvelope};
13
14use crate::Network;
15use alloy_consensus::{
16    error::ValueError,
17    transaction::{Either, Recovered},
18};
19use alloy_network_primitives::{BlockResponse, TransactionResponse};
20pub use alloy_rpc_types_any::{AnyRpcHeader, AnyTransactionReceipt};
21use alloy_rpc_types_eth::{AccessList, Block, BlockTransactions, Transaction, TransactionRequest};
22use alloy_serde::WithOtherFields;
23use derive_more::From;
24use serde::{Deserialize, Serialize};
25use std::ops::{Deref, DerefMut};
26
27#[derive(Clone, Copy, Debug)]
56pub struct AnyNetwork {
57    _private: (),
58}
59
60impl Network for AnyNetwork {
61    type TxType = AnyTxType;
62
63    type TxEnvelope = AnyTxEnvelope;
64
65    type UnsignedTx = AnyTypedTransaction;
66
67    type ReceiptEnvelope = AnyReceiptEnvelope;
68
69    type Header = AnyHeader;
70
71    type TransactionRequest = WithOtherFields<TransactionRequest>;
72
73    type TransactionResponse = AnyRpcTransaction;
74
75    type ReceiptResponse = AnyTransactionReceipt;
76
77    type HeaderResponse = AnyRpcHeader;
78
79    type BlockResponse = AnyRpcBlock;
80}
81
82#[derive(Clone, Debug, From, PartialEq, Eq, Deserialize, Serialize)]
88pub struct AnyRpcBlock(pub WithOtherFields<Block<AnyRpcTransaction, AnyRpcHeader>>);
89
90impl AnyRpcBlock {
91    pub fn new(inner: WithOtherFields<Block<AnyRpcTransaction, AnyRpcHeader>>) -> Self {
93        Self(inner)
94    }
95
96    pub fn into_inner(self) -> Block<AnyRpcTransaction, AnyRpcHeader> {
98        self.0.into_inner()
99    }
100
101    pub fn try_into_transactions(
105        self,
106    ) -> Result<Vec<AnyRpcTransaction>, ValueError<BlockTransactions<AnyRpcTransaction>>> {
107        self.0.inner.try_into_transactions()
108    }
109
110    pub fn into_transactions_iter(self) -> impl Iterator<Item = AnyRpcTransaction> {
112        self.into_inner().transactions.into_transactions()
113    }
114}
115
116impl BlockResponse for AnyRpcBlock {
117    type Header = AnyRpcHeader;
118    type Transaction = AnyRpcTransaction;
119
120    fn header(&self) -> &Self::Header {
121        &self.0.inner.header
122    }
123
124    fn transactions(&self) -> &BlockTransactions<Self::Transaction> {
125        &self.0.inner.transactions
126    }
127
128    fn transactions_mut(&mut self) -> &mut BlockTransactions<Self::Transaction> {
129        &mut self.0.inner.transactions
130    }
131
132    fn other_fields(&self) -> Option<&alloy_serde::OtherFields> {
133        self.0.other_fields()
134    }
135}
136
137impl AsRef<WithOtherFields<Block<AnyRpcTransaction, AnyRpcHeader>>> for AnyRpcBlock {
138    fn as_ref(&self) -> &WithOtherFields<Block<AnyRpcTransaction, AnyRpcHeader>> {
139        &self.0
140    }
141}
142
143impl Deref for AnyRpcBlock {
144    type Target = WithOtherFields<Block<AnyRpcTransaction, AnyRpcHeader>>;
145
146    fn deref(&self) -> &Self::Target {
147        &self.0
148    }
149}
150
151impl DerefMut for AnyRpcBlock {
152    fn deref_mut(&mut self) -> &mut Self::Target {
153        &mut self.0
154    }
155}
156
157impl From<Block> for AnyRpcBlock {
158    fn from(value: Block) -> Self {
159        let block = value
160            .map_header(|h| h.map(|h| alloy_consensus_any::AnyHeader { ..h.into() }))
161            .map_transactions(|tx| {
162                AnyRpcTransaction::new(WithOtherFields::new(tx.map(AnyTxEnvelope::Ethereum)))
163            });
164
165        Self(WithOtherFields::new(block))
166    }
167}
168
169impl From<AnyRpcBlock> for Block<AnyRpcTransaction, AnyRpcHeader> {
170    fn from(value: AnyRpcBlock) -> Self {
171        value.into_inner()
172    }
173}
174impl From<AnyRpcBlock> for WithOtherFields<Block<AnyRpcTransaction, AnyRpcHeader>> {
175    fn from(value: AnyRpcBlock) -> Self {
176        value.0
177    }
178}
179
180#[derive(Clone, Debug, From, PartialEq, Eq, Deserialize, Serialize)]
182pub struct AnyRpcTransaction(pub WithOtherFields<Transaction<AnyTxEnvelope>>);
183
184impl AnyRpcTransaction {
185    pub fn new(inner: WithOtherFields<Transaction<AnyTxEnvelope>>) -> Self {
187        Self(inner)
188    }
189
190    pub fn into_parts(self) -> (Transaction<AnyTxEnvelope>, alloy_serde::OtherFields) {
192        let WithOtherFields { inner, other } = self.0;
193        (inner, other)
194    }
195
196    pub fn into_inner(self) -> Transaction<AnyTxEnvelope> {
198        self.0.into_inner()
199    }
200
201    pub fn as_envelope(&self) -> Option<&TxEnvelope> {
204        self.inner.inner.as_envelope()
205    }
206
207    pub fn try_into_envelope(self) -> Result<TxEnvelope, ValueError<AnyTxEnvelope>> {
210        self.0.inner.inner.into_inner().try_into_envelope()
211    }
212
213    pub fn try_into_either<T>(self) -> Result<Either<TxEnvelope, T>, T::Error>
219    where
220        T: TryFrom<Self>,
221    {
222        if self.0.inner.inner.inner().is_ethereum() {
223            Ok(Either::Left(self.0.inner.inner.into_inner().try_into_envelope().unwrap()))
224        } else {
225            T::try_from(self).map(Either::Right)
226        }
227    }
228
229    pub fn try_unknown_into_either<T>(self) -> Result<Either<TxEnvelope, T>, T::Error>
235    where
236        T: TryFrom<UnknownTxEnvelope>,
237    {
238        self.0.inner.inner.into_inner().try_into_either()
239    }
240
241    pub fn map<Tx>(self, f: impl FnOnce(AnyTxEnvelope) -> Tx) -> Transaction<Tx> {
246        self.into_inner().map(f)
247    }
248
249    pub fn try_map<Tx, E>(
253        self,
254        f: impl FnOnce(AnyTxEnvelope) -> Result<Tx, E>,
255    ) -> Result<Transaction<Tx>, E> {
256        self.into_inner().try_map(f)
257    }
258
259    pub fn convert<U>(self) -> Transaction<U>
263    where
264        U: From<AnyTxEnvelope>,
265    {
266        self.into_inner().map(U::from)
267    }
268
269    pub fn try_convert<U>(self) -> Result<Transaction<U>, U::Error>
275    where
276        U: TryFrom<AnyTxEnvelope>,
277    {
278        self.into_inner().try_map(U::try_from)
279    }
280}
281
282impl AsRef<AnyTxEnvelope> for AnyRpcTransaction {
283    fn as_ref(&self) -> &AnyTxEnvelope {
284        &self.0.inner.inner
285    }
286}
287
288impl Deref for AnyRpcTransaction {
289    type Target = WithOtherFields<Transaction<AnyTxEnvelope>>;
290
291    fn deref(&self) -> &Self::Target {
292        &self.0
293    }
294}
295
296impl DerefMut for AnyRpcTransaction {
297    fn deref_mut(&mut self) -> &mut Self::Target {
298        &mut self.0
299    }
300}
301
302impl From<Transaction<TxEnvelope>> for AnyRpcTransaction {
303    fn from(tx: Transaction<TxEnvelope>) -> Self {
304        let tx = tx.map(AnyTxEnvelope::Ethereum);
305        Self(WithOtherFields::new(tx))
306    }
307}
308
309impl From<AnyRpcTransaction> for AnyTxEnvelope {
310    fn from(tx: AnyRpcTransaction) -> Self {
311        tx.0.inner.into_inner()
312    }
313}
314
315impl From<AnyRpcTransaction> for Transaction<AnyTxEnvelope> {
316    fn from(tx: AnyRpcTransaction) -> Self {
317        tx.0.inner
318    }
319}
320
321impl From<AnyRpcTransaction> for WithOtherFields<Transaction<AnyTxEnvelope>> {
322    fn from(tx: AnyRpcTransaction) -> Self {
323        tx.0
324    }
325}
326
327impl From<AnyRpcTransaction> for Recovered<AnyTxEnvelope> {
328    fn from(tx: AnyRpcTransaction) -> Self {
329        tx.0.inner.inner
330    }
331}
332
333impl TryFrom<AnyRpcTransaction> for TxEnvelope {
334    type Error = ValueError<AnyTxEnvelope>;
335
336    fn try_from(value: AnyRpcTransaction) -> Result<Self, Self::Error> {
337        value.try_into_envelope()
338    }
339}
340
341impl alloy_consensus::Transaction for AnyRpcTransaction {
342    fn chain_id(&self) -> Option<ChainId> {
343        self.inner.chain_id()
344    }
345
346    fn nonce(&self) -> u64 {
347        self.inner.nonce()
348    }
349
350    fn gas_limit(&self) -> u64 {
351        self.inner.gas_limit()
352    }
353
354    fn gas_price(&self) -> Option<u128> {
355        alloy_consensus::Transaction::gas_price(&self.0.inner)
356    }
357
358    fn max_fee_per_gas(&self) -> u128 {
359        alloy_consensus::Transaction::max_fee_per_gas(&self.inner)
360    }
361
362    fn max_priority_fee_per_gas(&self) -> Option<u128> {
363        self.inner.max_priority_fee_per_gas()
364    }
365
366    fn max_fee_per_blob_gas(&self) -> Option<u128> {
367        self.inner.max_fee_per_blob_gas()
368    }
369
370    fn priority_fee_or_price(&self) -> u128 {
371        self.inner.priority_fee_or_price()
372    }
373
374    fn effective_gas_price(&self, base_fee: Option<u64>) -> u128 {
375        self.inner.effective_gas_price(base_fee)
376    }
377
378    fn is_dynamic_fee(&self) -> bool {
379        self.inner.is_dynamic_fee()
380    }
381
382    fn kind(&self) -> TxKind {
383        self.inner.kind()
384    }
385
386    fn is_create(&self) -> bool {
387        self.inner.is_create()
388    }
389
390    fn value(&self) -> U256 {
391        self.inner.value()
392    }
393
394    fn input(&self) -> &Bytes {
395        self.inner.input()
396    }
397
398    fn access_list(&self) -> Option<&AccessList> {
399        self.inner.access_list()
400    }
401
402    fn blob_versioned_hashes(&self) -> Option<&[B256]> {
403        self.inner.blob_versioned_hashes()
404    }
405
406    fn authorization_list(&self) -> Option<&[SignedAuthorization]> {
407        self.inner.authorization_list()
408    }
409}
410
411impl TransactionResponse for AnyRpcTransaction {
412    fn tx_hash(&self) -> alloy_primitives::TxHash {
413        self.inner.tx_hash()
414    }
415
416    fn block_hash(&self) -> Option<alloy_primitives::BlockHash> {
417        self.0.inner.block_hash
418    }
419
420    fn block_number(&self) -> Option<u64> {
421        self.inner.block_number
422    }
423
424    fn transaction_index(&self) -> Option<u64> {
425        self.inner.transaction_index
426    }
427
428    fn from(&self) -> alloy_primitives::Address {
429        self.inner.from()
430    }
431
432    fn gas_price(&self) -> Option<u128> {
433        self.inner.effective_gas_price
434    }
435}
436
437impl Typed2718 for AnyRpcTransaction {
438    fn ty(&self) -> u8 {
439        self.inner.ty()
440    }
441}