Skip to content

Commit

Permalink
add extra nip11 fields
Browse files Browse the repository at this point in the history
  • Loading branch information
w3irdrobot committed Sep 17, 2023
1 parent 978cda4 commit aae4c24
Showing 1 changed file with 142 additions and 0 deletions.
142 changes: 142 additions & 0 deletions crates/nostr/src/nips/nip11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use std::net::SocketAddr;
use reqwest::Proxy;
use url_fork::Url;

use crate::types::time::Timestamp;

/// `NIP11` error
#[derive(Debug)]
pub enum Error {
Expand Down Expand Up @@ -69,6 +71,113 @@ pub struct RelayInformationDocument {
pub software: Option<String>,
/// Software version
pub version: Option<String>,
/// Limitations imposed by the relay on clients
pub limitation: Option<Limitation>,
/// The relay's retention policies
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub retention: Vec<Retention>,
/// Country codes whose laws and policies may affect this relay
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub relay_countries: Vec<String>,
/// Ordered list of IETF language tags indicating the major languages spoken on the relay
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub language_tags: Vec<String>,
/// List of limitations on the topics to be discussed
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub tags: Vec<String>,
/// Link to a human-readable page which specifies the community policies
pub posting_policy: Option<String>,
/// Link to relay's fee schedules
pub payments_url: Option<String>,
/// Relay fee schedules
pub fees: Option<FeeSchedules>,
/// URL pointing to an image to be used as an icon for the relay
pub icon: Option<String>,
}

/// These are limitations imposed by the relay on clients. Your client should
/// expect that requests which exceed these practical limitations are rejected or fail immediately.
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Limitation {
/// Maximum number of bytes for incoming JSON that the relay will attempt to decode and act upon
pub max_message_length: Option<i32>,
/// Total number of subscriptions that may be active on a single websocket connection
pub max_subscriptions: Option<i32>,
/// Maximum number of filter values in each subscription
pub max_filters: Option<i32>,
/// Relay will clamp each filter's limit value to this number
pub max_limit: Option<i32>,
/// Maximum length of subscription id as a string
pub max_subid_length: Option<i32>,
/// Maximum number of elements in the tags list
pub max_event_tags: Option<i32>,
/// Maximum number of characters in the content field of any event
pub max_content_length: Option<i32>,
/// New events will require at least this difficulty of PoW,
pub min_pow_difficulty: Option<i32>,
/// Relay requires NIP-42 authentication to happen before a new connection may perform any other action
pub auth_required: Option<bool>,
/// Relay requires payment before a new connection may perform any action
pub payment_required: Option<bool>,
/// 'created_at' lower limit
pub created_at_lower_limit: Option<Timestamp>,
/// 'created_at' upper limit
pub created_at_upper_limit: Option<Timestamp>,
}

/// A retention shedule for the relay
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Retention {
/// The event kinds this retention pertains to
pub kinds: Option<Vec<RetentionKind>>,
/// The amount of time these events are kept
pub time: Option<u64>,
/// The max number of events kept before removing older events
pub count: Option<u64>,
}

/// A single kind or range of kinds the retention pertains to
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(untagged)]
pub enum RetentionKind {
/// A single kind
Single(u64),
/// A kind range
Range(u64, u64),
}

/// Available fee schedules
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct FeeSchedules {
/// Fees for admission to use the relay
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub admission: Vec<FeeSchedule>,
/// Fees for subscription to use the relay
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub subscription: Vec<FeeSchedule>,
/// Fees to publish to the relay
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub publication: Vec<FeeSchedule>,
}

/// The specific information about a fee schedule
#[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct FeeSchedule {
/// The fee amount
pub amount: i32,
/// The denomination of the feed
pub unit: String,
/// The duration for which the fee is valid
pub period: Option<i32>,
/// The event kinds the fee allows the client to publish to the relay
pub kinds: Option<Vec<String>>,
}

impl RelayInformationDocument {
Expand Down Expand Up @@ -157,3 +266,36 @@ impl RelayInformationDocument {
Ok(url)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn correctly_serializes_retention_kind() {
let kinds = vec![
RetentionKind::Single(0),
RetentionKind::Single(1),
RetentionKind::Range(5, 7),
RetentionKind::Range(40, 49),
];
let got = serde_json::to_string(&kinds).unwrap();
let expected = "[0,1,[5,7],[40,49]]".to_string();

assert!(got == expected, "got: {}, expected: {}", got, expected);
}

#[test]
fn correctly_deserializes_retention_kind() {
let kinds = "[0, 1, [5, 7], [40, 49]]";
let got = serde_json::from_str::<Vec<RetentionKind>>(kinds).unwrap();
let expected = vec![
RetentionKind::Single(0),
RetentionKind::Single(1),
RetentionKind::Range(5, 7),
RetentionKind::Range(40, 49),
];

assert!(got == expected, "got: {:?}, expected: {:?}", got, expected);
}
}

0 comments on commit aae4c24

Please sign in to comment.