use polyoxide_core::HttpClient;
use serde::{Deserialize, Serialize};
use crate::{
account::{Credentials, Signer, Wallet},
request::{AuthMode, Request},
};
#[derive(Clone)]
pub struct Rewards {
pub(crate) http_client: HttpClient,
pub(crate) wallet: Wallet,
pub(crate) credentials: Credentials,
pub(crate) signer: Signer,
pub(crate) chain_id: u64,
}
impl Rewards {
fn l2_auth(&self) -> AuthMode {
AuthMode::L2 {
address: self.wallet.address(),
credentials: self.credentials.clone(),
signer: self.signer.clone(),
}
}
pub fn earnings(&self) -> Request<RewardEarnings> {
Request::get(
self.http_client.clone(),
"/rewards/user",
self.l2_auth(),
self.chain_id,
)
}
pub fn total_earnings(&self) -> Request<RewardTotalEarnings> {
Request::get(
self.http_client.clone(),
"/rewards/user/total",
self.l2_auth(),
self.chain_id,
)
}
pub fn percentages(&self) -> Request<RewardPercentages> {
Request::get(
self.http_client.clone(),
"/rewards/user/percentages",
self.l2_auth(),
self.chain_id,
)
}
pub fn market_earnings(&self) -> Request<Vec<RewardMarketEarning>> {
Request::get(
self.http_client.clone(),
"/rewards/user/markets",
self.l2_auth(),
self.chain_id,
)
}
pub fn current_markets(&self) -> Request<Vec<RewardMarket>> {
Request::get(
self.http_client.clone(),
"/rewards/markets/current",
AuthMode::None,
self.chain_id,
)
}
pub fn market(&self, condition_id: impl Into<String>) -> Request<RewardMarket> {
Request::get(
self.http_client.clone(),
format!(
"/rewards/markets/{}",
urlencoding::encode(&condition_id.into())
),
AuthMode::None,
self.chain_id,
)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RewardEarnings {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RewardTotalEarnings {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RewardPercentages {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RewardMarketEarning {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RewardMarket {
#[serde(flatten)]
pub data: serde_json::Value,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reward_earnings_deserializes() {
let json = r#"{"amount": "1.5", "day": "2024-01-15"}"#;
let resp: RewardEarnings = serde_json::from_str(json).unwrap();
assert_eq!(resp.data["amount"], "1.5");
assert_eq!(resp.data["day"], "2024-01-15");
}
#[test]
fn reward_total_earnings_deserializes() {
let json = r#"{"total": "42.0"}"#;
let resp: RewardTotalEarnings = serde_json::from_str(json).unwrap();
assert_eq!(resp.data["total"], "42.0");
}
#[test]
fn reward_percentages_deserializes() {
let json = r#"{"maker": "0.5", "taker": "0.3"}"#;
let resp: RewardPercentages = serde_json::from_str(json).unwrap();
assert_eq!(resp.data["maker"], "0.5");
}
#[test]
fn reward_market_earning_list_deserializes() {
let json = r#"[
{"condition_id": "0xabc", "amount": "10.0"},
{"condition_id": "0xdef", "amount": "5.0"}
]"#;
let resp: Vec<RewardMarketEarning> = serde_json::from_str(json).unwrap();
assert_eq!(resp.len(), 2);
assert_eq!(resp[0].data["condition_id"], "0xabc");
}
#[test]
fn reward_market_deserializes() {
let json = r#"{"condition_id": "0xabc", "reward_rate": "0.01"}"#;
let resp: RewardMarket = serde_json::from_str(json).unwrap();
assert_eq!(resp.data["condition_id"], "0xabc");
}
#[test]
fn reward_market_list_deserializes() {
let json = r#"[{"condition_id": "0xabc"}, {"condition_id": "0xdef"}]"#;
let resp: Vec<RewardMarket> = serde_json::from_str(json).unwrap();
assert_eq!(resp.len(), 2);
}
#[test]
fn reward_earnings_empty_object_deserializes() {
let json = r#"{}"#;
let resp: RewardEarnings = serde_json::from_str(json).unwrap();
assert!(resp.data.is_object());
}
}