Skip to content

Commit

Permalink
feat: add blockscout-chains crate
Browse files Browse the repository at this point in the history
  • Loading branch information
lok52 committed Oct 3, 2024
1 parent 20ec9b0 commit 1625a2c
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions libs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"blockscout-auth",
"blockscout-chains",
"blockscout-client/crate",
"blockscout-db",
"endpoints/swagger",
Expand Down
17 changes: 17 additions & 0 deletions libs/blockscout-chains/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "blockscout-chains"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
reqwest = { version = "0.12", features = ["json"] }
reqwest-middleware = "0.3"
reqwest-retry = "0.6"

[dev-dependencies]
tokio = { version = "1.0", features = ["macros"] }
58 changes: 58 additions & 0 deletions libs/blockscout-chains/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use reqwest_middleware::ClientBuilder;
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
use serde::Deserialize;
use std::collections::HashMap;

const CHAINS_URL: &str = "https://chains.blockscout.com/api/chains";

pub async fn get_blockscout_chains() -> anyhow::Result<BlockscoutChains> {
let max_retries = 3;
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(max_retries);
let client = ClientBuilder::new(reqwest::Client::new())
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
.build();
let res = client.get(CHAINS_URL).send().await?;
let chains: BlockscoutChains = res.json().await?;
Ok(chains)
}

pub type BlockscoutChains = HashMap<i64, BlockscoutChainData>;

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct BlockscoutChainData {
pub name: String,
pub description: String,
pub ecosystem: Ecosystem,
pub is_testnet: Option<bool>,
pub layer: Option<u8>,
pub rollup_type: Option<String>,
pub website: String,
pub explorers: Vec<ExplorerConfig>,
pub logo: String,
}

#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum Ecosystem {
Single(String),
Multiple(Vec<String>),
}

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ExplorerConfig {
pub url: String,
pub hosted_by: String,
}

#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn test_get_blockscout_chains() {
let chains = get_blockscout_chains().await.unwrap();
assert!(!chains.is_empty());
}
}

0 comments on commit 1625a2c

Please sign in to comment.