miden_client/rpc/mod.rs
1//! Provides an interface for the client to communicate with a Miden node using
2//! Remote Procedure Calls (RPC).
3//!
4//! This module defines the [`NodeRpcClient`] trait which abstracts calls to the RPC protocol used
5//! to:
6//!
7//! - Submit proven transactions.
8//! - Submit proven batches.
9//! - Retrieve block headers (optionally with MMR proofs).
10//! - Sync state updates (including notes, nullifiers, and account updates).
11//! - Fetch details for specific notes and accounts.
12//!
13//! The client implementation adapts to the target environment automatically:
14//! - Native targets use `tonic` transport with TLS.
15//! - `wasm32` targets use `tonic-web-wasm-client` transport.
16//!
17//! ## Example
18//!
19//! ```no_run
20//! # use miden_client::rpc::{Endpoint, NodeRpcClient, GrpcClient};
21//! # use miden_protocol::block::BlockNumber;
22//! # #[tokio::main]
23//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
24//! // Create a gRPC client instance (assumes default endpoint configuration).
25//! let endpoint = Endpoint::new("https".into(), "localhost".into(), Some(57291));
26//! let mut rpc_client = GrpcClient::new(&endpoint, 1000);
27//!
28//! // Fetch the latest block header (by passing None).
29//! let (block_header, mmr_proof) = rpc_client.get_block_header_by_number(None, true).await?;
30//!
31//! println!("Latest block number: {}", block_header.block_num());
32//! if let Some(proof) = mmr_proof {
33//! println!("MMR proof received accordingly");
34//! }
35//!
36//! # Ok(())
37//! # }
38//! ```
39//! The client also makes use of this component in order to communicate with the node.
40//!
41//! For further details and examples, see the documentation for the individual methods in the
42//! [`NodeRpcClient`] trait.
43
44use alloc::boxed::Box;
45use alloc::collections::{BTreeMap, BTreeSet};
46use alloc::string::String;
47use alloc::vec::Vec;
48use core::fmt;
49
50use domain::account::{
51 AccountDetails,
52 AccountProof,
53 GetAccountRequest,
54 StorageMapEntries,
55 StorageMapEntry,
56 StorageMapFetch,
57 VaultFetch,
58};
59use domain::note::{FetchedNote, NoteSyncBlock, SyncedNoteDetails};
60use domain::nullifier::NullifierUpdate;
61use domain::sync::{ChainMmrInfo, SyncTarget};
62use miden_protocol::Word;
63use miden_protocol::account::{Account, AccountId};
64use miden_protocol::address::NetworkId;
65use miden_protocol::batch::{ProposedBatch, ProvenBatch};
66use miden_protocol::block::{BlockHeader, BlockNumber, ProvenBlock};
67use miden_protocol::crypto::merkle::mmr::MmrProof;
68use miden_protocol::note::{NoteId, NoteMetadata, NoteScript, NoteTag, NoteType, Nullifier};
69use miden_protocol::transaction::{ProvenTransaction, TransactionInputs};
70
71use crate::rpc::domain::storage_map::StorageMapInfo;
72
73/// Contains domain types related to RPC requests and responses, as well as utility functions
74/// for dealing with them.
75pub mod domain;
76
77mod errors;
78pub use errors::*;
79
80mod endpoint;
81pub(crate) use domain::limits::RPC_LIMITS_STORE_SETTING;
82pub use domain::limits::RpcLimits;
83pub use domain::status::{NetworkNoteStatus, NetworkNoteStatusInfo, RpcStatusInfo};
84pub use endpoint::Endpoint;
85
86#[cfg(not(feature = "testing"))]
87mod generated;
88#[cfg(feature = "testing")]
89pub mod generated;
90
91#[cfg(feature = "tonic")]
92mod tonic_client;
93#[cfg(feature = "tonic")]
94pub use tonic_client::GrpcClient;
95
96use crate::rpc::domain::account_vault::AccountVaultInfo;
97use crate::rpc::domain::transaction::TransactionRecord;
98use crate::store::InputNoteRecord;
99use crate::store::input_note_states::UnverifiedNoteState;
100
101/// Represents the state that we want to retrieve from the network
102#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
103pub enum AccountStateAt {
104 /// Gets the latest state, for the current chain tip
105 #[default]
106 ChainTip,
107 /// Gets the state at a specific block number
108 Block(BlockNumber),
109}
110
111/// Returns `true` if the note's metadata advertises at least one attachment.
112///
113/// Sync records carry attachment scheme markers (not the attachment content), so a present scheme
114/// in any header slot indicates the note has attachments whose content must be fetched separately.
115fn metadata_has_attachments(metadata: &NoteMetadata) -> bool {
116 metadata.attachment_headers().iter().any(|header| header.scheme().is_some())
117}
118
119// NODE RPC CLIENT TRAIT
120// ================================================================================================
121
122/// Defines the interface for communicating with the Miden node.
123///
124/// The implementers are responsible for connecting to the Miden node, handling endpoint
125/// requests/responses, and translating responses into domain objects relevant for each of the
126/// endpoints.
127#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
128#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
129pub trait NodeRpcClient: Send + Sync {
130 /// Sets the genesis commitment for the client and reconnects to the node providing the
131 /// genesis commitment in the request headers. If the genesis commitment is already set,
132 /// this method does nothing.
133 async fn set_genesis_commitment(&self, commitment: Word) -> Result<(), RpcError>;
134
135 /// Returns the genesis commitment if it has been set, without fetching from the node.
136 fn has_genesis_commitment(&self) -> Option<Word>;
137
138 /// Given a Proven Transaction, send it to the node for it to be included in a future block
139 /// using the `/SubmitProvenTransaction` RPC endpoint.
140 ///
141 /// Returns the node's chain tip at submission (not the block the transaction is committed in).
142 async fn submit_proven_transaction(
143 &self,
144 proven_transaction: ProvenTransaction,
145 transaction_inputs: TransactionInputs,
146 ) -> Result<BlockNumber, RpcError>;
147
148 /// Given a Proven Batch together with the corresponding [`ProposedBatch`] and the list of
149 /// [`TransactionInputs`] (one per transaction, matching the ordering of the batch), sends
150 /// the batch to the node for inclusion in a future block using the `/SubmitProvenBatch`
151 /// RPC endpoint. All transactions in the batch must build on the current mempool state
152 /// following normal transaction submission rules.
153 ///
154 /// Returns the node's chain tip at submission (not the block the batch is committed in).
155 async fn submit_proven_batch(
156 &self,
157 proven_batch: ProvenBatch,
158 proposed_batch: ProposedBatch,
159 transaction_inputs: Vec<TransactionInputs>,
160 ) -> Result<BlockNumber, RpcError>;
161
162 /// Given a block number, fetches the block header corresponding to that height from the node
163 /// using the `/GetBlockHeaderByNumber` endpoint.
164 /// If `include_mmr_proof` is set to true and the function returns an `Ok`, the second value
165 /// of the return tuple should always be Some(MmrProof).
166 ///
167 /// When `None` is provided, returns info regarding the latest block.
168 async fn get_block_header_by_number(
169 &self,
170 block_num: Option<BlockNumber>,
171 include_mmr_proof: bool,
172 ) -> Result<(BlockHeader, Option<MmrProof>), RpcError>;
173
174 /// Given a block number, fetches the block corresponding to that height from the node using
175 /// the `/GetBlockByNumber` RPC endpoint.
176 ///
177 /// If `include_proof` is set to true, the block proof will be included in the response.
178 async fn get_block_by_number(
179 &self,
180 block_num: BlockNumber,
181 include_proof: bool,
182 ) -> Result<ProvenBlock, RpcError>;
183
184 /// Fetches note-related data for a list of [`NoteId`] using the `/GetNotesById`
185 /// RPC endpoint.
186 ///
187 /// For [`miden_protocol::note::NoteType::Private`] notes, the response includes only the
188 /// [`miden_protocol::note::NoteMetadata`].
189 ///
190 /// For [`miden_protocol::note::NoteType::Public`] notes, the response includes all note details
191 /// (recipient, assets, script, etc.).
192 ///
193 /// In both cases, a [`miden_protocol::note::NoteInclusionProof`] is returned so the caller can
194 /// verify that each note is part of the block's note tree.
195 async fn get_notes_by_id(&self, note_ids: &[NoteId]) -> Result<Vec<FetchedNote>, RpcError>;
196
197 /// Fetches the MMR delta for a given block range using the `/SyncChainMmr` RPC endpoint.
198 ///
199 /// - `current_block_height` is the last block number already present in the caller's MMR.
200 /// - `upper_bound` determines the upper bound of the sync range. Can be a specific block number
201 /// (`BlockNumber`), or a chain tip finality level: `CommittedChainTip` syncs up to the latest
202 /// committed block (the chain tip), while `ProvenChainTip` syncs up to the latest proven
203 /// block which may be behind the committed tip.
204 async fn sync_chain_mmr(
205 &self,
206 current_block_height: BlockNumber,
207 upper_bound: SyncTarget,
208 ) -> Result<ChainMmrInfo, RpcError>;
209
210 /// Fetches the full state of a public account from the node using the `/GetAccount` endpoint,
211 /// and then resolves oversized vault and storage map entries via the `SyncVault` and
212 /// `SyncStorageMap` endpoints when needed.
213 ///
214 /// - `account_id` is the ID of the wanted account.
215 ///
216 /// Returns `Ok(None)` for accounts without public state.
217 async fn get_account_details(
218 &self,
219 account_id: AccountId,
220 ) -> Result<Option<Account>, RpcError> {
221 // Accounts without public state have no full state to fetch; only a commitment is on-chain.
222 if !account_id.is_public() {
223 return Ok(None);
224 }
225
226 // A single request fetches the full public state: every storage map's entries plus the
227 // vault, with the storage layout discovered server-side.
228 let (block_number, mut proof) = self
229 .get_account(
230 account_id,
231 GetAccountRequest::new()
232 .with_storage(StorageMapFetch::All)
233 .with_vault(VaultFetch::Always),
234 )
235 .await?;
236
237 if let Some(details) = proof.details_mut() {
238 self.resolve_oversize_vault(account_id, block_number, details).await?;
239 self.resolve_oversize_storage_maps(account_id, block_number, details).await?;
240 }
241
242 let details = proof.into_details().ok_or(RpcError::ExpectedDataMissing(
243 "public account returned without details".into(),
244 ))?;
245
246 Ok(Some(Account::try_from(&details)?))
247 }
248
249 /// Fetches notes related to the specified tags using the `/SyncNotes` RPC endpoint,
250 /// paginating over the full block range and returning, in block-number order, every block in
251 /// that range that contains at least one note matching the requested tags.
252 ///
253 /// - `block_from`: The starting block number for the range (inclusive).
254 /// - `block_to`: The ending block number for the range (inclusive).
255 /// - `note_tags` is the set of tags used to filter the notes the client is interested in.
256 ///
257 /// Notes with attachments will have header-only metadata after this call; use
258 /// [`NodeRpcClient::sync_notes_with_details`] to also resolve their full metadata and
259 /// fetch public note bodies in a single follow-up call.
260 async fn sync_notes(
261 &self,
262 block_from: BlockNumber,
263 block_to: BlockNumber,
264 note_tags: &BTreeSet<NoteTag>,
265 ) -> Result<Vec<NoteSyncBlock>, RpcError>;
266
267 /// Calls [`NodeRpcClient::sync_notes`] for the requested range, then makes a single
268 /// [`NodeRpcClient::get_notes_by_id`] call to fetch full note bodies (scripts, assets,
269 /// recipient) for public notes and attachment content for private notes that carry
270 /// attachments.
271 ///
272 /// All public notes in the range are fetched (not just the ones the client tracks) to
273 /// avoid revealing which specific notes the client is interested in. Private notes are only
274 /// fetched when their synced metadata indicates non-empty attachments, since the sync record
275 /// carries attachment scheme markers but not the attachment content, which is needed to
276 /// reconstruct the note's ID.
277 ///
278 /// Returns the resolved note blocks paired with a map of the fetched content (public note
279 /// bodies and private-note attachments), keyed by note ID.
280 async fn sync_notes_with_details(
281 &self,
282 block_from: BlockNumber,
283 block_to: BlockNumber,
284 note_tags: &BTreeSet<NoteTag>,
285 ) -> Result<(Vec<NoteSyncBlock>, BTreeMap<NoteId, SyncedNoteDetails>), RpcError> {
286 let blocks = self.sync_notes(block_from, block_to, note_tags).await?;
287
288 let note_ids: Vec<NoteId> = blocks
289 .iter()
290 .flat_map(|b| b.notes.values())
291 .filter(|n| n.note_type() == NoteType::Public || metadata_has_attachments(n.metadata()))
292 .map(|n| *n.note_id())
293 .collect();
294
295 let mut synced_notes: BTreeMap<NoteId, SyncedNoteDetails> = BTreeMap::new();
296
297 if !note_ids.is_empty() {
298 let fetched = self.get_notes_by_id(¬e_ids).await?;
299
300 for fetched_note in fetched {
301 match fetched_note {
302 FetchedNote::Public(note, _) => {
303 synced_notes.insert(note.id(), SyncedNoteDetails::Public(note));
304 },
305 FetchedNote::Private(note_id, _, attachments, _) => {
306 let attachments = (!attachments.is_empty()).then_some(attachments);
307 synced_notes.insert(note_id, SyncedNoteDetails::Private(attachments));
308 },
309 }
310 }
311 }
312
313 Ok((blocks, synced_notes))
314 }
315
316 /// Fetches the nullifiers corresponding to a list of prefixes using the
317 /// `/SyncNullifiers` RPC endpoint.
318 ///
319 /// - `prefix` is a list of nullifiers prefixes to search for.
320 /// - `block_from`: The starting block number for the range (inclusive).
321 /// - `block_to`: The ending block number for the range (inclusive).
322 async fn sync_nullifiers(
323 &self,
324 prefix: &[u16],
325 block_from: BlockNumber,
326 block_to: BlockNumber,
327 ) -> Result<Vec<NullifierUpdate>, RpcError>;
328
329 /// Fetches the account from the node, using the `/GetAccount` endpoint.
330 ///
331 /// The response carries an
332 /// [`AccountWitness`](miden_protocol::block::account_tree::AccountWitness) and the target
333 /// block. Public accounts additionally get [`AccountDetails`]; for private accounts the
334 /// other `request` fields are ignored.
335 ///
336 /// For a fully oversize-resolved account, use [`NodeRpcClient::get_account_details`].
337 ///
338 /// Errors if the account isn't found.
339 async fn get_account(
340 &self,
341 account_id: AccountId,
342 request: GetAccountRequest,
343 ) -> Result<(BlockNumber, AccountProof), RpcError>;
344
345 /// Fills in the asset list when the vault came back flagged `too_many_assets`, by
346 /// querying [`NodeRpcClient::sync_account_vault`] over `[GENESIS, block_to]`. No-op when
347 /// the flag isn't set.
348 async fn resolve_oversize_vault(
349 &self,
350 account_id: AccountId,
351 block_to: BlockNumber,
352 details: &mut AccountDetails,
353 ) -> Result<(), RpcError> {
354 if !details.vault_details.too_many_assets {
355 return Ok(());
356 }
357 let vault_info =
358 self.sync_account_vault(BlockNumber::GENESIS, block_to, account_id).await?;
359 let mut updates = vault_info.updates;
360 // The node returns the full history of vault entries, so a given key may appear in more
361 // than one block. Sort by block so the BTreeMap keeps the latest value per key.
362 updates.sort_by_key(|u| u.block_num);
363 details.vault_details.assets = updates
364 .into_iter()
365 .map(|u| (u.vault_key, u.asset))
366 .collect::<BTreeMap<_, _>>()
367 .into_values()
368 .flatten()
369 .collect();
370 details.vault_details.too_many_assets = false;
371 Ok(())
372 }
373
374 /// Fills in the entries of any storage map flagged `too_many_entries`, by querying
375 /// [`NodeRpcClient::sync_storage_maps`] over `[GENESIS, block_to]`. No-op when no map
376 /// has the flag set.
377 async fn resolve_oversize_storage_maps(
378 &self,
379 account_id: AccountId,
380 block_to: BlockNumber,
381 details: &mut AccountDetails,
382 ) -> Result<(), RpcError> {
383 if !details.storage_details.map_details.iter().any(|m| m.too_many_entries) {
384 return Ok(());
385 }
386 let info = self.sync_storage_maps(BlockNumber::GENESIS, block_to, account_id).await?;
387 for map_details in &mut details.storage_details.map_details {
388 if !map_details.too_many_entries {
389 continue;
390 }
391 // The node returns the full history of map entries, so a given key may appear in
392 // more than one block. Sort by block so the BTreeMap keeps the latest value per key.
393 let mut sorted: Vec<_> =
394 info.updates.iter().filter(|u| u.slot_name == map_details.slot_name).collect();
395 sorted.sort_by_key(|u| u.block_num);
396 let entries: Vec<StorageMapEntry> = sorted
397 .into_iter()
398 .map(|u| (u.key, u.value))
399 .collect::<BTreeMap<_, _>>()
400 .into_iter()
401 .map(|(key, value)| StorageMapEntry { key, value })
402 .collect();
403 map_details.too_many_entries = false;
404 map_details.entries = StorageMapEntries::AllEntries(entries);
405 }
406 Ok(())
407 }
408
409 /// Fetches the commit height where the nullifier was consumed. If the nullifier isn't found,
410 /// then `None` is returned.
411 /// The `block_num` parameter is the block number to start the search from (inclusive).
412 ///
413 /// The default implementation of this method makes two RPC requests: one to
414 /// [`NodeRpcClient::get_block_header_by_number`] to resolve the chain tip, and one to
415 /// [`NodeRpcClient::sync_nullifiers`] to search up to that tip.
416 async fn get_nullifier_commit_heights(
417 &self,
418 requested_nullifiers: BTreeSet<Nullifier>,
419 block_from: BlockNumber,
420 ) -> Result<BTreeMap<Nullifier, Option<BlockNumber>>, RpcError> {
421 let prefixes: Vec<u16> =
422 requested_nullifiers.iter().map(crate::note::Nullifier::prefix).collect();
423 let (chain_tip, _) = self.get_block_header_by_number(None, false).await?;
424 let retrieved_nullifiers =
425 self.sync_nullifiers(&prefixes, block_from, chain_tip.block_num()).await?;
426
427 let mut nullifiers_height = BTreeMap::new();
428 for nullifier in requested_nullifiers {
429 if let Some(update) =
430 retrieved_nullifiers.iter().find(|update| update.nullifier == nullifier)
431 {
432 nullifiers_height.insert(nullifier, Some(update.block_num));
433 } else {
434 nullifiers_height.insert(nullifier, None);
435 }
436 }
437
438 Ok(nullifiers_height)
439 }
440
441 /// Fetches public note-related data for a list of [`NoteId`] and builds [`InputNoteRecord`]s
442 /// with it. If a note is not found or it's private, it is ignored and will not be included
443 /// in the returned list.
444 ///
445 /// The default implementation of this method uses [`NodeRpcClient::get_notes_by_id`].
446 async fn get_public_note_records(
447 &self,
448 note_ids: &[NoteId],
449 current_timestamp: Option<u64>,
450 ) -> Result<Vec<InputNoteRecord>, RpcError> {
451 if note_ids.is_empty() {
452 return Ok(vec![]);
453 }
454
455 let mut public_notes = Vec::with_capacity(note_ids.len());
456 let note_details = self.get_notes_by_id(note_ids).await?;
457
458 for detail in note_details {
459 if let FetchedNote::Public(note, inclusion_proof) = detail {
460 let state = UnverifiedNoteState {
461 metadata: *note.metadata(),
462 inclusion_proof,
463 }
464 .into();
465 let attachments = note.attachments().clone();
466 let note = InputNoteRecord::new(note.into(), attachments, current_timestamp, state);
467
468 public_notes.push(note);
469 }
470 }
471
472 Ok(public_notes)
473 }
474
475 /// Given a block number, fetches the block header corresponding to that height from the node
476 /// along with the MMR proof.
477 ///
478 /// The default implementation of this method uses
479 /// [`NodeRpcClient::get_block_header_by_number`].
480 async fn get_block_header_with_proof(
481 &self,
482 block_num: BlockNumber,
483 ) -> Result<(BlockHeader, MmrProof), RpcError> {
484 let (header, proof) = self.get_block_header_by_number(Some(block_num), true).await?;
485 Ok((header, proof.ok_or(RpcError::ExpectedDataMissing(String::from("MmrProof")))?))
486 }
487
488 /// Fetches the note with the specified ID.
489 ///
490 /// The default implementation of this method uses [`NodeRpcClient::get_notes_by_id`].
491 ///
492 /// Errors:
493 /// - [`RpcError::NoteNotFound`] if the note with the specified ID is not found.
494 async fn get_note_by_id(&self, note_id: NoteId) -> Result<FetchedNote, RpcError> {
495 let notes = self.get_notes_by_id(&[note_id]).await?;
496 notes.into_iter().next().ok_or(RpcError::NoteNotFound(note_id))
497 }
498
499 /// Fetches the note script with the specified root, returning `None` if the node has no script
500 /// registered for that root.
501 ///
502 /// Implementations must verify that a returned script's root matches the requested `root` and
503 /// return [`RpcError::InvalidResponse`] otherwise; callers may rely on this invariant.
504 ///
505 /// Errors:
506 /// - [`RpcError::InvalidResponse`] if the node returns a script whose root does not match the
507 /// requested `root`.
508 async fn get_note_script_by_root(&self, root: Word) -> Result<Option<NoteScript>, RpcError>;
509
510 /// Fetches storage map updates for specified account and storage slots within a block range,
511 /// using the `/SyncStorageMaps` RPC endpoint.
512 ///
513 /// - `block_from`: The starting block number for the range (inclusive).
514 /// - `block_to`: The ending block number for the range (inclusive). The node rejects values
515 /// greater than the chain tip.
516 /// - `account_id`: The account ID for which to fetch storage map updates.
517 async fn sync_storage_maps(
518 &self,
519 block_from: BlockNumber,
520 block_to: BlockNumber,
521 account_id: AccountId,
522 ) -> Result<StorageMapInfo, RpcError>;
523
524 /// Fetches account vault updates for specified account within a block range,
525 /// using the `/SyncAccountVault` RPC endpoint.
526 ///
527 /// - `block_from`: The starting block number for the range (inclusive).
528 /// - `block_to`: The ending block number for the range (inclusive). The node rejects values
529 /// greater than the chain tip.
530 /// - `account_id`: The account ID for which to fetch storage map updates.
531 async fn sync_account_vault(
532 &self,
533 block_from: BlockNumber,
534 block_to: BlockNumber,
535 account_id: AccountId,
536 ) -> Result<AccountVaultInfo, RpcError>;
537
538 /// Fetches transaction records for specific accounts within a block range using the
539 /// `/SyncTransactions` RPC endpoint.
540 ///
541 /// - `block_from`: The starting block number for the range (inclusive).
542 /// - `block_to`: The ending block number for the range (inclusive).
543 /// - `account_ids`: The account IDs for which to fetch transactions.
544 async fn sync_transactions(
545 &self,
546 block_from: BlockNumber,
547 block_to: BlockNumber,
548 account_ids: Vec<AccountId>,
549 ) -> Result<Vec<TransactionRecord>, RpcError>;
550
551 /// Fetches the network ID of the node.
552 /// Errors:
553 /// - [`RpcError::ExpectedDataMissing`] if the note with the specified root is not found.
554 async fn get_network_id(&self) -> Result<NetworkId, RpcError>;
555
556 /// Fetches the RPC limits configured on the node.
557 ///
558 /// Implementations may cache the result internally to avoid repeated network calls.
559 async fn get_rpc_limits(&self) -> Result<RpcLimits, RpcError>;
560
561 /// Returns the RPC limits if they have been set, without fetching from the node.
562 fn has_rpc_limits(&self) -> Option<RpcLimits>;
563
564 /// Sets the RPC limits internally to be used by the client.
565 async fn set_rpc_limits(&self, limits: RpcLimits);
566
567 /// Fetches the RPC status without requiring Accept header validation.
568 ///
569 /// This is useful for diagnostics when version negotiation fails, as it allows
570 /// retrieving node information even when there's a version mismatch.
571 async fn get_status_unversioned(&self) -> Result<RpcStatusInfo, RpcError>;
572
573 /// Fetches the status of a specific network note ID.
574 ///
575 /// This is useful for debugging when a network note fails.
576 async fn get_network_note_status(
577 &self,
578 note_id: NoteId,
579 ) -> Result<NetworkNoteStatusInfo, RpcError>;
580}
581
582// RPC API ENDPOINT
583// ================================================================================================
584//
585/// RPC methods for the Miden protocol.
586#[derive(Debug, Clone, Copy)]
587pub enum RpcEndpoint {
588 Status,
589 SyncNullifiers,
590 GetAccount,
591 GetBlockByNumber,
592 GetBlockHeaderByNumber,
593 GetNotesById,
594 SyncChainMmr,
595 SubmitProvenTx,
596 SubmitProvenBatch,
597 SyncNotes,
598 GetNoteScriptByRoot,
599 SyncStorageMaps,
600 SyncAccountVault,
601 SyncTransactions,
602 GetLimits,
603 GetNetworkNoteStatus,
604}
605
606impl RpcEndpoint {
607 /// Returns the endpoint name as used in the RPC service definition.
608 pub fn proto_name(&self) -> &'static str {
609 match self {
610 RpcEndpoint::Status => "Status",
611 RpcEndpoint::SyncNullifiers => "SyncNullifiers",
612 RpcEndpoint::GetAccount => "GetAccount",
613 RpcEndpoint::GetBlockByNumber => "GetBlockByNumber",
614 RpcEndpoint::GetBlockHeaderByNumber => "GetBlockHeaderByNumber",
615 RpcEndpoint::GetNotesById => "GetNotesById",
616 RpcEndpoint::SyncChainMmr => "SyncChainMmr",
617 RpcEndpoint::SubmitProvenTx => "SubmitProvenTransaction",
618 RpcEndpoint::SubmitProvenBatch => "SubmitProvenBatch",
619 RpcEndpoint::SyncNotes => "SyncNotes",
620 RpcEndpoint::GetNoteScriptByRoot => "GetNoteScriptByRoot",
621 RpcEndpoint::SyncStorageMaps => "SyncStorageMaps",
622 RpcEndpoint::SyncAccountVault => "SyncAccountVault",
623 RpcEndpoint::SyncTransactions => "SyncTransactions",
624 RpcEndpoint::GetLimits => "GetLimits",
625 RpcEndpoint::GetNetworkNoteStatus => "GetNetworkNoteStatus",
626 }
627 }
628}
629
630impl fmt::Display for RpcEndpoint {
631 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632 match self {
633 RpcEndpoint::Status => write!(f, "status"),
634 RpcEndpoint::SyncNullifiers => {
635 write!(f, "sync_nullifiers")
636 },
637 RpcEndpoint::GetAccount => write!(f, "get_account"),
638 RpcEndpoint::GetBlockByNumber => write!(f, "get_block_by_number"),
639 RpcEndpoint::GetBlockHeaderByNumber => {
640 write!(f, "get_block_header_by_number")
641 },
642 RpcEndpoint::GetNotesById => write!(f, "get_notes_by_id"),
643 RpcEndpoint::SyncChainMmr => write!(f, "sync_chain_mmr"),
644 RpcEndpoint::SubmitProvenTx => write!(f, "submit_proven_transaction"),
645 RpcEndpoint::SubmitProvenBatch => write!(f, "submit_proven_batch"),
646 RpcEndpoint::SyncNotes => write!(f, "sync_notes"),
647 RpcEndpoint::GetNoteScriptByRoot => write!(f, "get_note_script_by_root"),
648 RpcEndpoint::SyncStorageMaps => write!(f, "sync_storage_maps"),
649 RpcEndpoint::SyncAccountVault => write!(f, "sync_account_vault"),
650 RpcEndpoint::SyncTransactions => write!(f, "sync_transactions"),
651 RpcEndpoint::GetLimits => write!(f, "get_limits"),
652 RpcEndpoint::GetNetworkNoteStatus => write!(f, "get_network_note_status"),
653 }
654 }
655}