-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Expand file tree
/
Copy pathnip11.rs
More file actions
125 lines (114 loc) · 4.43 KB
/
Copy pathnip11.rs
File metadata and controls
125 lines (114 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! NIP-11 relay information document.
use serde::{Deserialize, Serialize};
use crate::connection::MAX_FRAME_BYTES;
/// NIPs supported by this relay, advertised in the NIP-11 document.
/// Kept as a module-level constant so tests can verify it without constructing
/// a full `Config` (which reads env vars and races with config.rs tests).
pub(crate) const SUPPORTED_NIPS: &[u32] = &[1, 2, 10, 11, 16, 17, 23, 25, 29, 33, 38, 42, 50];
/// Relay information document served at `GET /` with `Accept: application/nostr+json`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RelayInfo {
/// Human-readable relay name.
pub name: String,
/// Human-readable relay description.
pub description: String,
/// Relay operator's public key (hex), if published.
pub pubkey: Option<String>,
/// Contact address for the relay operator.
pub contact: Option<String>,
/// NIPs supported by this relay.
pub supported_nips: Vec<u32>,
/// URL of the relay software repository.
pub software: String,
/// Relay software version string.
pub version: String,
/// Protocol and resource limits advertised to clients.
pub limitation: Option<RelayLimitation>,
}
/// Protocol and resource limits advertised in the NIP-11 document.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RelayLimitation {
/// Maximum WebSocket frame size in bytes.
pub max_message_length: Option<u64>,
/// Maximum number of concurrent subscriptions per connection.
pub max_subscriptions: Option<u32>,
/// Maximum number of filters per subscription.
pub max_filters: Option<u32>,
/// Maximum value of the `limit` field in a filter.
pub max_limit: Option<u32>,
/// Maximum length of a subscription ID string.
pub max_subid_length: Option<u32>,
/// Minimum proof-of-work difficulty required for events.
pub min_pow_difficulty: Option<u32>,
/// Whether NIP-42 authentication is required before sending events.
pub auth_required: bool,
/// Whether payment is required to use the relay.
pub payment_required: bool,
/// Whether writes are restricted to authorized pubkeys.
pub restricted_writes: bool,
}
impl RelayInfo {
/// Builds a `RelayInfo` document from the relay's runtime config.
pub fn from_config(config: &crate::config::Config) -> Self {
Self {
name: "Sprout Relay".to_string(),
description: "Sprout — private team communication relay".to_string(),
pubkey: None,
contact: None,
supported_nips: SUPPORTED_NIPS.to_vec(),
software: "https://github.com/sprout-rs/sprout".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
limitation: Some(RelayLimitation {
max_message_length: Some(MAX_FRAME_BYTES as u64),
max_subscriptions: Some(1024),
max_filters: Some(10),
max_limit: Some(500),
max_subid_length: Some(256),
min_pow_difficulty: None,
auth_required: config.require_auth_token,
payment_required: false,
restricted_writes: true,
}),
}
}
}
/// Axum handler that returns the NIP-11 relay information document as JSON.
pub async fn relay_info_handler(
axum::extract::State(state): axum::extract::State<std::sync::Arc<crate::state::AppState>>,
) -> axum::response::Json<RelayInfo> {
axum::response::Json(RelayInfo::from_config(&state.config))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn supported_nips_includes_nip23_and_nip33() {
// Tests the production SUPPORTED_NIPS constant directly — no Config::from_env()
// needed, avoiding the env-var race with config.rs tests.
assert!(
SUPPORTED_NIPS.contains(&23),
"NIP-23 (long-form content) must be advertised"
);
assert!(
SUPPORTED_NIPS.contains(&33),
"NIP-33 (parameterized replaceable) must be advertised"
);
}
#[test]
fn supported_nips_includes_nip38() {
assert!(
SUPPORTED_NIPS.contains(&38),
"NIP-38 (user statuses) must be advertised"
);
}
#[test]
fn supported_nips_are_sorted() {
let mut sorted = SUPPORTED_NIPS.to_vec();
sorted.sort();
assert_eq!(
SUPPORTED_NIPS,
&sorted[..],
"supported_nips should be sorted"
);
}
}