Skip to content

Commit 5919e9e

Browse files
committed
Merge #169: add extra nip11 fields
2 parents 7cd3617 + aae4c24 commit 5919e9e

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

crates/nostr/src/nips/nip11.rs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use std::net::SocketAddr;
1616
use reqwest::Proxy;
1717
use url_fork::Url;
1818

19+
use crate::types::time::Timestamp;
20+
1921
/// `NIP11` error
2022
#[derive(Debug)]
2123
pub enum Error {
@@ -69,6 +71,113 @@ pub struct RelayInformationDocument {
6971
pub software: Option<String>,
7072
/// Software version
7173
pub version: Option<String>,
74+
/// Limitations imposed by the relay on clients
75+
pub limitation: Option<Limitation>,
76+
/// The relay's retention policies
77+
#[serde(skip_serializing_if = "Vec::is_empty")]
78+
#[serde(default)]
79+
pub retention: Vec<Retention>,
80+
/// Country codes whose laws and policies may affect this relay
81+
#[serde(skip_serializing_if = "Vec::is_empty")]
82+
#[serde(default)]
83+
pub relay_countries: Vec<String>,
84+
/// Ordered list of IETF language tags indicating the major languages spoken on the relay
85+
#[serde(skip_serializing_if = "Vec::is_empty")]
86+
#[serde(default)]
87+
pub language_tags: Vec<String>,
88+
/// List of limitations on the topics to be discussed
89+
#[serde(skip_serializing_if = "Vec::is_empty")]
90+
#[serde(default)]
91+
pub tags: Vec<String>,
92+
/// Link to a human-readable page which specifies the community policies
93+
pub posting_policy: Option<String>,
94+
/// Link to relay's fee schedules
95+
pub payments_url: Option<String>,
96+
/// Relay fee schedules
97+
pub fees: Option<FeeSchedules>,
98+
/// URL pointing to an image to be used as an icon for the relay
99+
pub icon: Option<String>,
100+
}
101+
102+
/// These are limitations imposed by the relay on clients. Your client should
103+
/// expect that requests which exceed these practical limitations are rejected or fail immediately.
104+
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
105+
pub struct Limitation {
106+
/// Maximum number of bytes for incoming JSON that the relay will attempt to decode and act upon
107+
pub max_message_length: Option<i32>,
108+
/// Total number of subscriptions that may be active on a single websocket connection
109+
pub max_subscriptions: Option<i32>,
110+
/// Maximum number of filter values in each subscription
111+
pub max_filters: Option<i32>,
112+
/// Relay will clamp each filter's limit value to this number
113+
pub max_limit: Option<i32>,
114+
/// Maximum length of subscription id as a string
115+
pub max_subid_length: Option<i32>,
116+
/// Maximum number of elements in the tags list
117+
pub max_event_tags: Option<i32>,
118+
/// Maximum number of characters in the content field of any event
119+
pub max_content_length: Option<i32>,
120+
/// New events will require at least this difficulty of PoW,
121+
pub min_pow_difficulty: Option<i32>,
122+
/// Relay requires NIP-42 authentication to happen before a new connection may perform any other action
123+
pub auth_required: Option<bool>,
124+
/// Relay requires payment before a new connection may perform any action
125+
pub payment_required: Option<bool>,
126+
/// 'created_at' lower limit
127+
pub created_at_lower_limit: Option<Timestamp>,
128+
/// 'created_at' upper limit
129+
pub created_at_upper_limit: Option<Timestamp>,
130+
}
131+
132+
/// A retention shedule for the relay
133+
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
134+
pub struct Retention {
135+
/// The event kinds this retention pertains to
136+
pub kinds: Option<Vec<RetentionKind>>,
137+
/// The amount of time these events are kept
138+
pub time: Option<u64>,
139+
/// The max number of events kept before removing older events
140+
pub count: Option<u64>,
141+
}
142+
143+
/// A single kind or range of kinds the retention pertains to
144+
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
145+
#[serde(untagged)]
146+
pub enum RetentionKind {
147+
/// A single kind
148+
Single(u64),
149+
/// A kind range
150+
Range(u64, u64),
151+
}
152+
153+
/// Available fee schedules
154+
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
155+
pub struct FeeSchedules {
156+
/// Fees for admission to use the relay
157+
#[serde(skip_serializing_if = "Vec::is_empty")]
158+
#[serde(default)]
159+
pub admission: Vec<FeeSchedule>,
160+
/// Fees for subscription to use the relay
161+
#[serde(skip_serializing_if = "Vec::is_empty")]
162+
#[serde(default)]
163+
pub subscription: Vec<FeeSchedule>,
164+
/// Fees to publish to the relay
165+
#[serde(skip_serializing_if = "Vec::is_empty")]
166+
#[serde(default)]
167+
pub publication: Vec<FeeSchedule>,
168+
}
169+
170+
/// The specific information about a fee schedule
171+
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
172+
pub struct FeeSchedule {
173+
/// The fee amount
174+
pub amount: i32,
175+
/// The denomination of the feed
176+
pub unit: String,
177+
/// The duration for which the fee is valid
178+
pub period: Option<i32>,
179+
/// The event kinds the fee allows the client to publish to the relay
180+
pub kinds: Option<Vec<String>>,
72181
}
73182

74183
impl RelayInformationDocument {
@@ -169,3 +278,36 @@ impl RelayInformationDocument {
169278
Ok(url)
170279
}
171280
}
281+
282+
#[cfg(test)]
283+
mod tests {
284+
use super::*;
285+
286+
#[test]
287+
fn correctly_serializes_retention_kind() {
288+
let kinds = vec![
289+
RetentionKind::Single(0),
290+
RetentionKind::Single(1),
291+
RetentionKind::Range(5, 7),
292+
RetentionKind::Range(40, 49),
293+
];
294+
let got = serde_json::to_string(&kinds).unwrap();
295+
let expected = "[0,1,[5,7],[40,49]]".to_string();
296+
297+
assert!(got == expected, "got: {}, expected: {}", got, expected);
298+
}
299+
300+
#[test]
301+
fn correctly_deserializes_retention_kind() {
302+
let kinds = "[0, 1, [5, 7], [40, 49]]";
303+
let got = serde_json::from_str::<Vec<RetentionKind>>(kinds).unwrap();
304+
let expected = vec![
305+
RetentionKind::Single(0),
306+
RetentionKind::Single(1),
307+
RetentionKind::Range(5, 7),
308+
RetentionKind::Range(40, 49),
309+
];
310+
311+
assert!(got == expected, "got: {:?}, expected: {:?}", got, expected);
312+
}
313+
}

0 commit comments

Comments
 (0)