eth-icons 0.0.2

Retrieve ethereum icons
Documentation
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use crate::{Error, IconFetcher, IconQuery, IconResult, IconSource};

#[derive(Clone)]
pub struct Blockscout;

#[async_trait::async_trait]
impl IconSource for Blockscout {
    fn name(&self) -> &'static str {
        "blockscout"
    }

    fn url(&self, query: &IconQuery) -> Option<String> {
        match query {
            IconQuery::ERC20(network_id, address) => {
                if *network_id != 1 {
                    return None;
                }
                Some(format!(
                    "https://eth.blockscout.com/api/v2/tokens/{}",
                    address.to_lowercase()
                ))
            }
            _ => None,
        }
    }

    async fn fetch(&self, fetcher: &IconFetcher, query: &IconQuery) -> Result<IconResult, Error> {
        let Some(url) = self.url(query) else {
            return Ok(IconResult::Unsupported);
        };

        let Some(metadata) = fetcher.fetch_json::<BlockscoutAssetMetadata>(&url).await? else {
            return Ok(IconResult::NotFound);
        };

        let Some(icon_url) = metadata.icon_url else {
            return Ok(IconResult::NotFound);
        };

        fetcher.fetch_image_url(&icon_url).await
    }
}

#[derive(Debug, Serialize, Deserialize)]
pub struct BlockscoutAssetMetadata {
    pub icon_url: Option<String>,
    #[serde(flatten)]
    pub other: HashMap<String, serde_json::Value>,
}