poipal 0.1.0

Blazing fast CLI tool for Proof of Indexing (POI) Investigations on The Graph
Documentation
use std::time::Duration;

use anyhow::{anyhow, Result};
use reqwest::Client;
use serde::{Deserialize, Serialize};
use serde_json::json;

#[derive(Debug, Serialize, Deserialize)]
struct JsonRpcResponse {
    result: Option<BlockResult>,
}

#[derive(Debug, Serialize, Deserialize)]
struct BlockResult {
    number: String,
}

pub struct EthClient {
    client: Client,
    url: String,
}

impl EthClient {
    pub fn new(url: String) -> Result<Self> {
        let client = Client::builder().timeout(Duration::from_secs(10)).build()?;

        Ok(Self { client, url })
    }

    pub async fn get_chain_head_block_number(&self) -> Result<u32> {
        let body = json!({
            "jsonrpc": "2.0",
            "method": "eth_getBlockByNumber",
            "params": ["latest", false],
            "id": 1
        });

        let response = self.client.post(&self.url).json(&body).send().await?;
        let json_response: JsonRpcResponse = response.json().await?;

        let block = json_response
            .result
            .ok_or_else(|| anyhow!("No result in JSON-RPC response"))?;

        let block_number = if block.number.starts_with("0x") {
            u32::from_str_radix(&block.number[2..], 16)?
        } else {
            block.number.parse::<u32>()?
        };

        Ok(block_number)
    }
}