miden_node_utils/
genesis.rs1use std::fmt;
2use std::path::Path;
3
4use anyhow::Context;
5use miden_protocol::block::SignedBlock;
6use miden_protocol::utils::serde::Deserializable;
7
8#[derive(clap::ValueEnum, Clone, Copy, Debug, Eq, PartialEq)]
10pub enum OfficialNetwork {
11 Devnet,
12 Testnet,
13}
14
15impl OfficialNetwork {
16 pub const fn as_str(self) -> &'static str {
17 match self {
18 Self::Devnet => "devnet",
19 Self::Testnet => "testnet",
20 }
21 }
22
23 pub fn genesis_block_url(self) -> String {
24 format!("https://genesis.{}.miden.io", self.as_str())
25 }
26}
27
28impl fmt::Display for OfficialNetwork {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 f.write_str(self.as_str())
31 }
32}
33
34pub fn read_signed_genesis_block(path: &Path) -> anyhow::Result<SignedBlock> {
36 let bytes = fs_err::read(path).context("failed to read genesis block file")?;
37 deserialize_signed_genesis_block(&bytes)
38}
39
40pub async fn fetch_signed_genesis_block(network: OfficialNetwork) -> anyhow::Result<SignedBlock> {
42 let url = network.genesis_block_url();
43 let response = reqwest::get(url.as_str())
44 .await
45 .with_context(|| format!("failed to fetch genesis block from {url}"))?
46 .error_for_status()
47 .with_context(|| format!("failed to fetch genesis block from {url}"))?;
48 let bytes = response
49 .bytes()
50 .await
51 .with_context(|| format!("failed to read genesis block response from {url}"))?;
52
53 deserialize_signed_genesis_block(&bytes)
54}
55
56fn deserialize_signed_genesis_block(bytes: &[u8]) -> anyhow::Result<SignedBlock> {
57 SignedBlock::read_from_bytes(bytes).context("failed to deserialize genesis block")
58}