use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use time::{Duration, OffsetDateTime};
use crate::action::{Chain, TokenKey};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Caps {
pub per_action: BTreeMap<TokenKey, u128>,
pub per_day: BTreeMap<TokenKey, u128>,
pub period: Duration,
pub per_period: BTreeMap<TokenKey, u128>,
pub max_slippage_bps: u64,
}
impl Caps {
#[must_use]
pub fn uniform(
token: &TokenKey,
per_action: u128,
per_day: u128,
per_period: u128,
period: Duration,
max_slippage_bps: u64,
) -> Self {
let one = |v: u128| BTreeMap::from([(token.clone(), v)]);
Self {
per_action: one(per_action),
per_day: one(per_day),
period,
per_period: one(per_period),
max_slippage_bps,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SpendEntry {
pub key: TokenKey,
pub micro_usd: u128,
}
#[derive(Debug, Clone, thiserror::Error)]
#[error("prices: {0}")]
pub struct PricesError(pub String);
#[async_trait]
pub trait Prices: Send + Sync {
async fn micro_usd(
&self,
chain: &Chain,
token: &str,
raw_amount: u128,
) -> Result<Option<u128>, PricesError>;
}
#[derive(Debug, Clone, thiserror::Error)]
#[error("spend ledger: {0}")]
pub struct LedgerError(pub String);
#[async_trait]
pub trait SpendLedger: Send + Sync {
async fn spent(
&self,
subject: &str,
token: &TokenKey,
since: OffsetDateTime,
) -> Result<u128, LedgerError>;
async fn record(
&self,
subject: &str,
entries: &[SpendEntry],
at: OffsetDateTime,
) -> Result<(), LedgerError>;
}