pub use crate::indexer::{Address, Subaccount, SubaccountNumber, Usdc};
use anyhow::{anyhow as err, Error};
use bigdecimal::num_traits::ToPrimitive;
use reqwest::Client;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
pub struct FaucetConfig {
pub endpoint: String,
}
#[derive(Debug)]
pub struct FaucetClient {
config: FaucetConfig,
client: Client,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct FillReq<'t> {
address: &'t Address,
subaccount_number: &'t SubaccountNumber,
amount: u64,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
struct FillNativeReq<'t> {
address: &'t Address,
}
impl FaucetClient {
pub fn new(config: FaucetConfig) -> Self {
Self {
config,
client: Client::default(),
}
}
pub async fn fill(&self, subaccount: &Subaccount, amount: &Usdc) -> Result<(), Error> {
const URI: &str = "/faucet/tokens";
let url = format!("{}{URI}", self.config.endpoint);
let body = FillReq {
address: &subaccount.address,
subaccount_number: &subaccount.number,
amount: amount
.to_u64()
.ok_or_else(|| err!("Failed converting USDC amount to u64"))?,
};
let _resp = self
.client
.post(url)
.json(&body)
.send()
.await?
.error_for_status()?;
Ok(())
}
pub async fn fill_native(&self, address: &Address) -> Result<(), Error> {
const URI: &str = "/faucet/native-token";
let url = format!("{}{URI}", self.config.endpoint);
let body = FillNativeReq { address };
let _resp = self
.client
.post(url)
.json(&body)
.send()
.await?
.error_for_status()?;
Ok(())
}
}