Skip to main content

espresso_api/axum/
routes.rs

1//! Route constants and URL builders for Axum HTTP API
2//!
3//! All routes are absolute paths including version prefixes for external use.
4
5/// Route correlation between HTTP and gRPC endpoints
6///
7/// V2 routes expose both HTTP (Axum) and gRPC (Tonic) paths for the same functionality.
8///
9/// # Example
10/// ```
11/// use espresso_api::routes::v2::REWARD_BALANCE_ROUTE;
12///
13/// // Access HTTP path for Axum
14/// let http_path = REWARD_BALANCE_ROUTE.http;
15///
16/// // Access gRPC path for Tonic (matches generated service code)
17/// let grpc_path = REWARD_BALANCE_ROUTE.grpc;
18/// ```
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub struct Route {
21    /// HTTP path for Axum handler (e.g., "/v2/rewards/balance/{height}/{address}")
22    pub http: &'static str,
23    /// gRPC path for Tonic service (e.g., "/espresso.api.v2.RewardService/GetRewardBalance")
24    pub grpc: &'static str,
25    /// OpenAPI description for the endpoint
26    pub description: &'static str,
27    /// OpenAPI tag grouping for the endpoint
28    pub tag: &'static str,
29}
30
31//=============================================================================
32// V1 Routes - Legacy Reward State V2 (backward compatibility)
33//=============================================================================
34
35pub mod v1 {
36    /// Get reward claim input for L1 contract submission
37    /// Path: GET /v1/reward-state-v2/reward-claim-input/{height}/{address}
38    pub const REWARD_CLAIM_INPUT_ROUTE: &str =
39        "/v1/reward-state-v2/reward-claim-input/{height}/{address}";
40
41    /// Get reward balance at a specific height
42    /// Path: GET /v1/reward-state-v2/reward-balance/{height}/{address}
43    pub const REWARD_BALANCE_ROUTE: &str = "/v1/reward-state-v2/reward-balance/{height}/{address}";
44
45    /// Get latest reward balance
46    /// Path: GET /v1/reward-state-v2/reward-balance/latest/{address}
47    pub const LATEST_REWARD_BALANCE_ROUTE: &str =
48        "/v1/reward-state-v2/reward-balance/latest/{address}";
49
50    /// Get reward account Merkle proof at a specific height
51    /// Path: GET /v1/reward-state-v2/proof/{height}/{address}
52    pub const REWARD_ACCOUNT_PROOF_ROUTE: &str = "/v1/reward-state-v2/proof/{height}/{address}";
53
54    /// Get latest reward account Merkle proof
55    /// Path: GET /v1/reward-state-v2/proof/latest/{address}
56    pub const LATEST_REWARD_ACCOUNT_PROOF_ROUTE: &str =
57        "/v1/reward-state-v2/proof/latest/{address}";
58
59    /// Get paginated list of reward amounts
60    /// Path: GET /v1/reward-state-v2/reward-amounts/{height}/{offset}/{limit}
61    pub const REWARD_AMOUNTS_ROUTE: &str =
62        "/v1/reward-state-v2/reward-amounts/{height}/{offset}/{limit}";
63
64    /// Get raw RewardMerkleTreeV2 snapshot
65    /// Path: GET /v1/reward-state-v2/reward-merkle-tree-v2/{height}
66    pub const REWARD_MERKLE_TREE_V2_ROUTE: &str =
67        "/v1/reward-state-v2/reward-merkle-tree-v2/{height}";
68
69    //=========================================================================
70    // Availability API Routes
71    //=========================================================================
72
73    /// Get namespace proof by block height
74    /// Path: GET /v1/availability/block/{height}/namespace/{namespace}
75    pub const NAMESPACE_PROOF_BY_HEIGHT_ROUTE: &str =
76        "/v1/availability/block/{height}/namespace/{namespace}";
77
78    /// Get namespace proof by block hash
79    /// Path: GET /v1/availability/block/hash/{hash}/namespace/{namespace}
80    pub const NAMESPACE_PROOF_BY_HASH_ROUTE: &str =
81        "/v1/availability/block/hash/{hash}/namespace/{namespace}";
82
83    /// Get namespace proof by payload hash
84    /// Path: GET /v1/availability/block/payload-hash/{payload-hash}/namespace/{namespace}
85    pub const NAMESPACE_PROOF_BY_PAYLOAD_HASH_ROUTE: &str =
86        "/v1/availability/block/payload-hash/{payload-hash}/namespace/{namespace}";
87
88    /// Get namespace proofs for a range of blocks
89    /// Path: GET /v1/availability/block/{from}/{until}/namespace/{namespace}
90    pub const NAMESPACE_PROOF_RANGE_ROUTE: &str =
91        "/v1/availability/block/{from}/{until}/namespace/{namespace}";
92
93    /// Generate proof of incorrect encoding
94    /// Path: GET /v1/availability/incorrect-encoding-proof/{block_number}/{namespace}
95    pub const INCORRECT_ENCODING_PROOF_ROUTE: &str =
96        "/v1/availability/incorrect-encoding-proof/{block_number}/{namespace}";
97
98    /// Get light client state certificate (V1)
99    /// Path: GET /v1/availability/state-cert/{epoch}
100    pub const STATE_CERT_V1_ROUTE: &str = "/v1/availability/state-cert/{epoch}";
101
102    /// Get light client state certificate (V2)
103    /// Path: GET /v1/availability/state-cert-v2/{epoch}
104    pub const STATE_CERT_V2_ROUTE: &str = "/v1/availability/state-cert-v2/{epoch}";
105
106    //=========================================================================
107    // HotShot Availability API Routes (mirrored from hotshot-query-service)
108    //=========================================================================
109
110    pub const LEAF_BY_HEIGHT_ROUTE: &str = "/v1/availability/leaf/{height}";
111    pub const LEAF_BY_HASH_ROUTE: &str = "/v1/availability/leaf/hash/{hash}";
112    pub const LEAF_RANGE_ROUTE: &str = "/v1/availability/leaf/{from}/{until}";
113
114    pub const HEADER_BY_HEIGHT_ROUTE: &str = "/v1/availability/header/{height}";
115    pub const HEADER_BY_HASH_ROUTE: &str = "/v1/availability/header/hash/{hash}";
116    pub const HEADER_BY_PAYLOAD_HASH_ROUTE: &str =
117        "/v1/availability/header/payload-hash/{payload_hash}";
118    pub const HEADER_RANGE_ROUTE: &str = "/v1/availability/header/{from}/{until}";
119
120    pub const BLOCK_BY_HEIGHT_ROUTE: &str = "/v1/availability/block/{height}";
121    pub const BLOCK_BY_HASH_ROUTE: &str = "/v1/availability/block/hash/{hash}";
122    pub const BLOCK_BY_PAYLOAD_HASH_ROUTE: &str =
123        "/v1/availability/block/payload-hash/{payload_hash}";
124    pub const BLOCK_RANGE_ROUTE: &str = "/v1/availability/block/{from}/{until}";
125
126    pub const PAYLOAD_BY_HEIGHT_ROUTE: &str = "/v1/availability/payload/{height}";
127    pub const PAYLOAD_BY_HASH_ROUTE: &str = "/v1/availability/payload/hash/{hash}";
128    pub const PAYLOAD_BY_BLOCK_HASH_ROUTE: &str =
129        "/v1/availability/payload/block-hash/{block_hash}";
130    pub const PAYLOAD_RANGE_ROUTE: &str = "/v1/availability/payload/{from}/{until}";
131
132    pub const VID_COMMON_BY_HEIGHT_ROUTE: &str = "/v1/availability/vid/common/{height}";
133    pub const VID_COMMON_BY_HASH_ROUTE: &str = "/v1/availability/vid/common/hash/{hash}";
134    pub const VID_COMMON_BY_PAYLOAD_HASH_ROUTE: &str =
135        "/v1/availability/vid/common/payload-hash/{payload_hash}";
136    pub const VID_COMMON_RANGE_ROUTE: &str = "/v1/availability/vid/common/{from}/{until}";
137
138    pub const TRANSACTION_BY_POSITION_NOPROOF_ROUTE: &str =
139        "/v1/availability/transaction/{height}/{index}/noproof";
140    pub const TRANSACTION_BY_HASH_NOPROOF_ROUTE: &str =
141        "/v1/availability/transaction/hash/{hash}/noproof";
142    pub const TRANSACTION_PROOF_BY_POSITION_ROUTE: &str =
143        "/v1/availability/transaction/{height}/{index}/proof";
144    pub const TRANSACTION_PROOF_BY_HASH_ROUTE: &str =
145        "/v1/availability/transaction/hash/{hash}/proof";
146    pub const TRANSACTION_BY_POSITION_ROUTE: &str = "/v1/availability/transaction/{height}/{index}";
147    pub const TRANSACTION_BY_HASH_ROUTE: &str = "/v1/availability/transaction/hash/{hash}";
148
149    pub const BLOCK_SUMMARY_BY_HEIGHT_ROUTE: &str = "/v1/availability/block/summary/{height}";
150    pub const BLOCK_SUMMARY_RANGE_ROUTE: &str = "/v1/availability/block/summaries/{from}/{until}";
151
152    pub const LIMITS_ROUTE: &str = "/v1/availability/limits";
153    pub const CERT2_BY_HEIGHT_ROUTE: &str = "/v1/availability/cert2/{height}";
154
155    pub const STREAM_LEAVES_ROUTE: &str = "/v1/availability/stream/leaves/{height}";
156    pub const STREAM_HEADERS_ROUTE: &str = "/v1/availability/stream/headers/{height}";
157    pub const STREAM_BLOCKS_ROUTE: &str = "/v1/availability/stream/blocks/{height}";
158    pub const STREAM_PAYLOADS_ROUTE: &str = "/v1/availability/stream/payloads/{height}";
159    pub const STREAM_VID_COMMON_ROUTE: &str = "/v1/availability/stream/vid/common/{height}";
160    pub const STREAM_TRANSACTIONS_ROUTE: &str = "/v1/availability/stream/transactions/{height}";
161    pub const STREAM_TRANSACTIONS_NS_ROUTE: &str =
162        "/v1/availability/stream/transactions/{height}/namespace/{namespace}";
163
164    pub const STREAM_NAMESPACE_PROOFS_ROUTE: &str =
165        "/v1/availability/stream/blocks/{height}/namespace/{namespace}";
166}
167
168//=============================================================================
169// V2 Routes - Rewards API
170//=============================================================================
171
172pub mod v2 {
173    use super::Route;
174
175    pub const REWARD_CLAIM_INPUT_ROUTE: Route = Route {
176        http: "/v2/rewards/claim-input",
177        grpc: "/espresso.api.v2.RewardService/GetRewardClaimInput",
178        description: "Get reward claim input for L1 contract submission. Returns lifetime rewards \
179                      and Merkle proof needed to call claimRewards() on the L1 contract.",
180        tag: "Rewards",
181    };
182
183    pub const REWARD_BALANCE_ROUTE: Route = Route {
184        http: "/v2/rewards/balance",
185        grpc: "/espresso.api.v2.RewardService/GetRewardBalance",
186        description: "Get reward balance for an address at the latest finalized height",
187        tag: "Rewards",
188    };
189
190    pub const REWARD_ACCOUNT_PROOF_ROUTE: Route = Route {
191        http: "/v2/rewards/proof",
192        grpc: "/espresso.api.v2.RewardService/GetRewardAccountProof",
193        description: "Get Merkle proof for a reward account at the latest finalized height. \
194                      Returns V2 proof with Keccak256 hashing",
195        tag: "Rewards",
196    };
197
198    pub const REWARD_BALANCES_ROUTE: Route = Route {
199        http: "/v2/rewards/balances",
200        grpc: "/espresso.api.v2.RewardService/GetRewardBalances",
201        description: "Get paginated list of all reward balances at a specific height. Limit must \
202                      be ≤ 10000",
203        tag: "Rewards",
204    };
205
206    pub const REWARD_MERKLE_TREE_V2_ROUTE: Route = Route {
207        http: "/v2/rewards/tree",
208        grpc: "/espresso.api.v2.RewardService/GetRewardMerkleTreeV2",
209        description: "Get raw RewardMerkleTreeV2 snapshot at a given height. Returns serialized \
210                      merkle tree data",
211        tag: "Rewards",
212    };
213
214    pub const OPENAPI_SPEC_ROUTE: &str = "/v2/docs/openapi.json";
215    pub const SWAGGER_ROUTE: &str = "/v2";
216    pub const SCALAR_ROUTE: &str = "/v2/scalar";
217    pub const REDOC_ROUTE: &str = "/v2/redoc";
218
219    pub const NAMESPACE_PROOF_ROUTE: Route = Route {
220        http: "/v2/data/finalized/namespace-proof",
221        grpc: "/espresso.api.v2.DataService/GetNamespaceProof",
222        description: "Get namespace proof(s) for the specified namespace. Use '?block={height}' \
223                      for a single block, or '?from={start}&to={end}' for a range. Returns \
224                      transactions for the namespace along with cryptographic proof(s) of \
225                      completeness.",
226        tag: "Data",
227    };
228
229    pub const INCORRECT_ENCODING_PROOF_ROUTE: Route = Route {
230        http: "/v2/data/finalized/incorrect-encoding-proof",
231        grpc: "/espresso.api.v2.DataService/GetIncorrectEncodingProof",
232        description: "Generate a fraud proof showing incorrect namespace encoding for a specific \
233                      block. Query param 'block' specifies the block height. Used to challenge \
234                      invalid block proposals.",
235        tag: "Data",
236    };
237
238    pub const STATE_CERTIFICATE_ROUTE: Route = Route {
239        http: "/v2/consensus/state-certificate",
240        grpc: "/espresso.api.v2.ConsensusService/GetStateCertificate",
241        description: "Get light client state update certificate for an epoch. Used to update L1 \
242                      contracts with new stake table information.",
243        tag: "Consensus",
244    };
245
246    pub const STAKE_TABLE_ROUTE: Route = Route {
247        http: "/v2/consensus/stake-table",
248        grpc: "/espresso.api.v2.ConsensusService/GetStakeTable",
249        description: "Get stake table for an epoch.",
250        tag: "Consensus",
251    };
252}