coingecko_oracle/
coingecko_oracle.rs

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