use polyoxide_core::HttpClient;
use serde::{Deserialize, Serialize};
use crate::{
account::{Credentials, Signer, Wallet},
error::ClobError,
request::{AuthMode, Request},
};
#[derive(Clone)]
pub struct Notifications {
pub(crate) http_client: HttpClient,
pub(crate) wallet: Wallet,
pub(crate) credentials: Credentials,
pub(crate) signer: Signer,
pub(crate) chain_id: u64,
}
impl Notifications {
fn l2_auth(&self) -> AuthMode {
AuthMode::L2 {
address: self.wallet.address(),
credentials: self.credentials.clone(),
signer: self.signer.clone(),
}
}
pub fn list(&self) -> Request<Vec<Notification>> {
Request::get(
self.http_client.clone(),
"/notifications",
self.l2_auth(),
self.chain_id,
)
}
pub async fn drop(&self, ids: impl Into<Vec<String>>) -> Result<serde_json::Value, ClobError> {
#[derive(Serialize)]
struct Body {
ids: Vec<String>,
}
Request::<serde_json::Value>::delete(
self.http_client.clone(),
"/notifications",
self.l2_auth(),
self.chain_id,
)
.body(&Body { ids: ids.into() })?
.send()
.await
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Notification {
pub id: String,
#[serde(rename = "type")]
pub notification_type: u32,
pub owner: String,
#[serde(default)]
pub payload: serde_json::Value,
#[serde(default)]
pub timestamp: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn notification_deserializes() {
let json = r#"{
"id": "notif-1",
"type": 1,
"owner": "0xabc123",
"payload": {"order_id": "order-456", "side": "BUY"},
"timestamp": "2024-01-01T00:00:00Z"
}"#;
let notif: Notification = serde_json::from_str(json).unwrap();
assert_eq!(notif.id, "notif-1");
assert_eq!(notif.notification_type, 1);
assert_eq!(notif.owner, "0xabc123");
assert_eq!(notif.payload["order_id"], "order-456");
assert_eq!(notif.timestamp.as_deref(), Some("2024-01-01T00:00:00Z"));
}
#[test]
fn notification_null_payload() {
let json = r#"{
"id": "notif-2",
"type": 0,
"owner": "0xdef456",
"payload": null
}"#;
let notif: Notification = serde_json::from_str(json).unwrap();
assert_eq!(notif.id, "notif-2");
assert_eq!(notif.notification_type, 0);
assert!(notif.payload.is_null());
assert!(notif.timestamp.is_none());
}
#[test]
fn notification_missing_payload() {
let json = r#"{
"id": "notif-3",
"type": 2,
"owner": "0x789"
}"#;
let notif: Notification = serde_json::from_str(json).unwrap();
assert_eq!(notif.id, "notif-3");
assert_eq!(notif.notification_type, 2);
assert!(notif.payload.is_null());
}
}