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}