reth_rpc_api/
otterscan.rs

1use alloy_eips::{eip1898::LenientBlockNumberOrTag, BlockId};
2use alloy_json_rpc::RpcObject;
3use alloy_primitives::{Address, Bytes, TxHash, B256};
4use alloy_rpc_types_trace::otterscan::{
5    BlockDetails, ContractCreator, InternalOperation, OtsBlockTransactions, TraceEntry,
6    TransactionsWithReceipts,
7};
8use jsonrpsee::{core::RpcResult, proc_macros::rpc};
9
10/// Otterscan rpc interface.
11#[cfg_attr(not(feature = "client"), rpc(server, namespace = "ots"))]
12#[cfg_attr(feature = "client", rpc(server, client, namespace = "ots"))]
13pub trait Otterscan<T: RpcObject, H: RpcObject> {
14    /// Get the block header by block number, required by otterscan.
15    /// Otterscan currently requires this endpoint, used as:
16    ///
17    /// 1. check if the node is Erigon or not
18    /// 2. get block header instead of the full block
19    ///
20    /// Ref: <https://github.com/otterscan/otterscan/blob/071d8c55202badf01804f6f8d53ef9311d4a9e47/src/useProvider.ts#L71>
21    #[method(name = "getHeaderByNumber", aliases = ["erigon_getHeaderByNumber"])]
22    async fn get_header_by_number(
23        &self,
24        block_number: LenientBlockNumberOrTag,
25    ) -> RpcResult<Option<H>>;
26
27    /// Check if a certain address contains a deployed code.
28    #[method(name = "hasCode")]
29    async fn has_code(&self, address: Address, block_id: Option<BlockId>) -> RpcResult<bool>;
30
31    /// Very simple API versioning scheme. Every time we add a new capability, the number is
32    /// incremented. This allows for Otterscan to check if the node contains all API it
33    /// needs.
34    #[method(name = "getApiLevel")]
35    async fn get_api_level(&self) -> RpcResult<u64>;
36
37    /// Return the internal ETH transfers inside a transaction.
38    #[method(name = "getInternalOperations")]
39    async fn get_internal_operations(&self, tx_hash: TxHash) -> RpcResult<Vec<InternalOperation>>;
40
41    /// Given a transaction hash, returns its raw revert reason.
42    #[method(name = "getTransactionError")]
43    async fn get_transaction_error(&self, tx_hash: TxHash) -> RpcResult<Option<Bytes>>;
44
45    /// Extract all variations of calls, contract creation and self-destructs and returns a call
46    /// tree.
47    #[method(name = "traceTransaction")]
48    async fn trace_transaction(&self, tx_hash: TxHash) -> RpcResult<Option<Vec<TraceEntry>>>;
49
50    /// Tailor-made and expanded version of `eth_getBlockByNumber` for block details page in
51    /// Otterscan.
52    #[method(name = "getBlockDetails")]
53    async fn get_block_details(
54        &self,
55        block_number: LenientBlockNumberOrTag,
56    ) -> RpcResult<BlockDetails<H>>;
57
58    /// Tailor-made and expanded version of `eth_getBlockByHash` for block details page in
59    /// Otterscan.
60    #[method(name = "getBlockDetailsByHash")]
61    async fn get_block_details_by_hash(&self, block_hash: B256) -> RpcResult<BlockDetails<H>>;
62
63    /// Get paginated transactions for a certain block. Also remove some verbose fields like logs.
64    #[method(name = "getBlockTransactions")]
65    async fn get_block_transactions(
66        &self,
67        block_number: LenientBlockNumberOrTag,
68        page_number: usize,
69        page_size: usize,
70    ) -> RpcResult<OtsBlockTransactions<T, H>>;
71
72    /// Gets paginated inbound/outbound transaction calls for a certain address.
73    #[method(name = "searchTransactionsBefore")]
74    async fn search_transactions_before(
75        &self,
76        address: Address,
77        block_number: LenientBlockNumberOrTag,
78        page_size: usize,
79    ) -> RpcResult<TransactionsWithReceipts>;
80
81    /// Gets paginated inbound/outbound transaction calls for a certain address.
82    #[method(name = "searchTransactionsAfter")]
83    async fn search_transactions_after(
84        &self,
85        address: Address,
86        block_number: LenientBlockNumberOrTag,
87        page_size: usize,
88    ) -> RpcResult<TransactionsWithReceipts>;
89
90    /// Gets the transaction hash for a certain sender address, given its nonce.
91    #[method(name = "getTransactionBySenderAndNonce")]
92    async fn get_transaction_by_sender_and_nonce(
93        &self,
94        sender: Address,
95        nonce: u64,
96    ) -> RpcResult<Option<TxHash>>;
97
98    /// Gets the transaction hash and the address who created a contract.
99    #[method(name = "getContractCreator")]
100    async fn get_contract_creator(&self, address: Address) -> RpcResult<Option<ContractCreator>>;
101}