polyoxide_clob/api/
notifications.rs1use polyoxide_core::{HttpClient, QueryBuilder};
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 account::{Credentials, Signer, Wallet},
6 error::ClobError,
7 request::{AuthMode, Request},
8 types::SignatureType,
9};
10
11#[derive(Clone)]
13pub struct Notifications {
14 pub(crate) http_client: HttpClient,
15 pub(crate) wallet: Wallet,
16 pub(crate) credentials: Credentials,
17 pub(crate) signer: Signer,
18 pub(crate) chain_id: u64,
19 pub(crate) signature_type: SignatureType,
20}
21
22impl Notifications {
23 fn l2_auth(&self) -> AuthMode {
24 AuthMode::L2 {
25 address: self.wallet.address(),
26 credentials: self.credentials.clone(),
27 signer: self.signer.clone(),
28 }
29 }
30
31 pub fn list(&self) -> Request<Vec<Notification>> {
36 Request::get(
37 self.http_client.clone(),
38 "/notifications",
39 self.l2_auth(),
40 self.chain_id,
41 )
42 .query("signature_type", self.signature_type as u8)
43 }
44
45 pub async fn drop(&self, ids: impl Into<Vec<String>>) -> Result<serde_json::Value, ClobError> {
47 #[derive(Serialize)]
48 struct Body {
49 ids: Vec<String>,
50 }
51
52 Request::<serde_json::Value>::delete(
53 self.http_client.clone(),
54 "/notifications",
55 self.l2_auth(),
56 self.chain_id,
57 )
58 .body(&Body { ids: ids.into() })?
59 .send()
60 .await
61 }
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct Notification {
67 pub id: String,
68 #[serde(rename = "type")]
69 pub notification_type: u32,
70 pub owner: String,
71 #[serde(default)]
72 pub payload: serde_json::Value,
73 #[serde(default)]
74 pub timestamp: Option<String>,
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn notification_deserializes() {
83 let json = r#"{
84 "id": "notif-1",
85 "type": 1,
86 "owner": "0xabc123",
87 "payload": {"order_id": "order-456", "side": "BUY"},
88 "timestamp": "2024-01-01T00:00:00Z"
89 }"#;
90 let notif: Notification = serde_json::from_str(json).unwrap();
91 assert_eq!(notif.id, "notif-1");
92 assert_eq!(notif.notification_type, 1);
93 assert_eq!(notif.owner, "0xabc123");
94 assert_eq!(notif.payload["order_id"], "order-456");
95 assert_eq!(notif.timestamp.as_deref(), Some("2024-01-01T00:00:00Z"));
96 }
97
98 #[test]
99 fn notification_null_payload() {
100 let json = r#"{
101 "id": "notif-2",
102 "type": 0,
103 "owner": "0xdef456",
104 "payload": null
105 }"#;
106 let notif: Notification = serde_json::from_str(json).unwrap();
107 assert_eq!(notif.id, "notif-2");
108 assert_eq!(notif.notification_type, 0);
109 assert!(notif.payload.is_null());
110 assert!(notif.timestamp.is_none());
111 }
112
113 #[test]
114 fn notification_missing_payload() {
115 let json = r#"{
116 "id": "notif-3",
117 "type": 2,
118 "owner": "0x789"
119 }"#;
120 let notif: Notification = serde_json::from_str(json).unwrap();
121 assert_eq!(notif.id, "notif-3");
122 assert_eq!(notif.notification_type, 2);
123 assert!(notif.payload.is_null());
124 }
125}