coingecko_oracle/
coingecko_oracle.rs

1use blockless_sdk::*;
2use serde_json::json;
3use std::collections::HashMap;
4
5#[cfg_attr(feature = "serde", derive(serde::Serialize))]
6#[derive(Debug)]
7struct CoinPrice {
8    id: String,
9    price: u64,
10    currency: String,
11}
12
13fn main() {
14    // read coin id from stdin
15    let mut buf = [0; 1024];
16    let len = read_stdin(&mut buf).unwrap();
17    let coin_id = std::str::from_utf8(&buf[..len as usize])
18        .unwrap_or_default()
19        .trim();
20
21    // perform http request
22    let http_opts = HttpOptions::new("GET", 30, 10);
23    let http_res = BlocklessHttp::open(
24        format!(
25            "https://api.coingecko.com/api/v3/simple/price?ids={}&vs_currencies=usd",
26            coin_id
27        )
28        .as_str(),
29        &http_opts,
30    )
31    .unwrap();
32    let body = http_res.get_all_body().unwrap(); // e.g. {"bitcoin":{"usd":67675}}
33
34    // println!("{}", String::from_utf8(body.clone()).unwrap());
35
36    // parse the json response; extrac usd price
37    let json: serde_json::Result<HashMap<String, HashMap<String, f64>>> =
38        serde_json::from_slice(&body);
39    let Ok(data) = json else {
40        eprintln!("Failed to parse JSON");
41        return;
42    };
43    let Some(coin_data) = data.get(coin_id) else {
44        eprintln!("Coin not found in response.");
45        return;
46    };
47    let Some(usd_price) = coin_data.get("usd") else {
48        eprintln!("USD price not found for {}.", coin_id);
49        return;
50    };
51
52    let coin_price = CoinPrice {
53        id: coin_id.to_string(),
54        price: (*usd_price * 1_000_000.0) as u64, // price in 6 decimals
55        currency: "usd".to_string(),
56    };
57    println!("{}", json!(coin_price));
58}