Skip to main content

espresso_api/v1/
reward_state_v2.rs

1//! Reward State V2 API trait for v1
2//!
3//! Returns internal espresso-types (legacy, no OpenAPI docs).
4
5use alloy::primitives::Address;
6use async_trait::async_trait;
7use espresso_types::{
8    v0::sparse_mt::KeccakNode,
9    v0_3::{RewardAccountQueryDataV1, RewardAccountV1, RewardAmount, RewardMerkleTreeV1},
10    v0_4::{RewardAccountQueryDataV2, RewardAccountV2, RewardMerkleTreeV2},
11};
12use hotshot_contract_adapter::reward::RewardClaimInput;
13use jf_merkle_tree_compat::{
14    MerkleTreeScheme,
15    prelude::{MerkleProof, Sha3Node},
16};
17
18use crate::v1::merklized_state::Snapshot;
19
20pub type RewardStatePathV1 = MerkleProof<
21    RewardAmount,
22    RewardAccountV1,
23    Sha3Node,
24    { <RewardMerkleTreeV1 as MerkleTreeScheme>::ARITY },
25>;
26
27pub type RewardStatePathV2 = MerkleProof<
28    RewardAmount,
29    RewardAccountV2,
30    KeccakNode,
31    { <RewardMerkleTreeV2 as MerkleTreeScheme>::ARITY },
32>;
33
34#[async_trait]
35pub trait RewardApi {
36    /// Get the height of the last persisted reward-state-v1 merklized state snapshot
37    async fn get_reward_state_height(&self) -> anyhow::Result<u64>;
38
39    /// Get the height of the last persisted reward-state-v2 merklized state snapshot
40    async fn get_reward_state_v2_height(&self) -> anyhow::Result<u64>;
41
42    /// Get Merkle proof for a reward account against the V1 (RewardMerkleTreeV1) tree
43    ///
44    /// # Arguments
45    /// * `height` - Block height to query
46    /// * `address` - Ethereum address to query proof for
47    async fn get_reward_account_proof_v1(
48        &self,
49        height: u64,
50        address: String,
51    ) -> anyhow::Result<RewardAccountQueryDataV1>;
52
53    /// Get reward claim input for L1 contract submission
54    ///
55    /// Returns all data needed to call the claimRewards function on the L1 contract,
56    /// including lifetime rewards and the Merkle proof.
57    ///
58    /// # Arguments
59    /// * `block_height` - Must match the height finalized in the Light Client contract
60    /// * `address` - Ethereum address to query rewards for (hex format)
61    async fn get_reward_claim_input(
62        &self,
63        block_height: u64,
64        address: String,
65    ) -> anyhow::Result<RewardClaimInput>;
66
67    /// Get reward balance at a specific height
68    ///
69    /// # Arguments
70    /// * `height` - Block height to query
71    /// * `address` - Ethereum address to query rewards for
72    async fn get_reward_balance(
73        &self,
74        height: u64,
75        address: String,
76    ) -> anyhow::Result<RewardAmount>;
77
78    /// Get latest reward balance at the most recent finalized height
79    ///
80    /// # Arguments
81    /// * `address` - Ethereum address to query rewards for
82    async fn get_latest_reward_balance(&self, address: String) -> anyhow::Result<RewardAmount>;
83
84    /// Get Merkle proof for a reward account at a specific height
85    ///
86    /// Returns complete query data with balance and expanded merkle proof
87    ///
88    /// # Arguments
89    /// * `height` - Block height to query
90    /// * `address` - Ethereum address to query proof for
91    async fn get_reward_account_proof(
92        &self,
93        height: u64,
94        address: String,
95    ) -> anyhow::Result<RewardAccountQueryDataV2>;
96
97    /// Get Merkle proof for a reward account at the latest finalized height
98    ///
99    /// Returns complete query data with balance and expanded merkle proof
100    ///
101    /// # Arguments
102    /// * `address` - Ethereum address to query proof for
103    async fn get_latest_reward_account_proof(
104        &self,
105        address: String,
106    ) -> anyhow::Result<RewardAccountQueryDataV2>;
107
108    /// Get paginated list of reward amounts at a specific height
109    ///
110    /// # Arguments
111    /// * `height` - Block height to query
112    /// * `offset` - Starting index for pagination
113    /// * `limit` - Maximum number of results (≤ 10000)
114    async fn get_reward_amounts(
115        &self,
116        height: u64,
117        offset: u64,
118        limit: u64,
119    ) -> anyhow::Result<Vec<(Address, RewardAmount)>>;
120
121    /// Get raw RewardMerkleTreeV2 snapshot at a given height
122    ///
123    /// Returns the serialized merkle tree data
124    ///
125    /// # Arguments
126    /// * `height` - Block height to query
127    async fn get_reward_merkle_tree_v2(&self, height: u64) -> anyhow::Result<Vec<u8>>;
128
129    /// Get the Merkle path for a key in the reward-state (RewardMerkleTreeV1) tree
130    ///
131    /// Mirrors the legacy `merklized_state` `get_path`, inherited by the reward-state mount
132    /// from `hotshot-query-service`'s merklized-state base routes (same as block-state/fee-state).
133    ///
134    /// # Arguments
135    /// * `snapshot` - Height or commitment identifying the tree snapshot
136    /// * `key` - Reward account address to query
137    async fn get_reward_state_path_v1(
138        &self,
139        snapshot: Snapshot,
140        key: String,
141    ) -> anyhow::Result<RewardStatePathV1>;
142
143    /// Get the Merkle path for a key in the reward-state-v2 (RewardMerkleTreeV2) tree
144    ///
145    /// # Arguments
146    /// * `snapshot` - Height or commitment identifying the tree snapshot
147    /// * `key` - Reward account address to query
148    async fn get_reward_state_path_v2(
149        &self,
150        snapshot: Snapshot,
151        key: String,
152    ) -> anyhow::Result<RewardStatePathV2>;
153}