diff --git a/src/lib.rs b/src/lib.rs
index ba07248..356be25 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -260,7 +260,7 @@ async fn handle_http_request(
if let Some(accept) = request.headers().get("Accept") {
if let Ok(s) = accept.to_str() {
if s == "application/nostr+json" {
- return web::serve_nip11(peer).await;
+ return web::nip11::serve_nip11(peer).await;
}
}
}
diff --git a/src/web/mod.rs b/src/web/mod.rs
index d77e045..9f61aee 100644
--- a/src/web/mod.rs
+++ b/src/web/mod.rs
@@ -1,6 +1,6 @@
-use crate::config::Config;
+pub mod nip11;
+
use crate::error::Error;
-use crate::globals::GLOBALS;
use crate::ip::HashedPeer;
use hyper::{Body, Request, Response, StatusCode};
@@ -15,123 +15,3 @@ pub async fn serve_http(peer: HashedPeer, request: Request
) -> Result Result, Error> {
- log::debug!(target: "Client", "{}: sent NIP-11", peer);
- let rid = {
- let config = &*GLOBALS.config.read();
- GLOBALS.rid.get_or_init(|| build_rid(config))
- };
-
- let response = Response::builder()
- .header("Access-Control-Allow-Origin", "*")
- .header("Access-Control-Allow-Headers", "*")
- .header("Access-Control-Allow-Methods", "*")
- .header("Content-Type", "application/nostr+json")
- .status(StatusCode::OK)
- .body(rid.clone().into())?;
- Ok(response)
-}
-
-fn build_rid(config: &Config) -> String {
- let mut rid: String = String::with_capacity(255);
-
- const SUPPORTED_NIPS: [u8; 8] = [
- 1, // nostr
- 4, // DMs
- 9, // Event Deletion
- 11, // relay information document
- 40, // Expiration Timestamp
- 42, // AUTH
- 59, // GiftWrap
- 65, // Relay List Metadata
- ];
- const _UNSUPPORTED_NIPS: [u8; 6] = [
- 26, // Delegated Event Signing
- 29, // Relay-based Groups
- 45, // Counting results
- 50, // SEARCH
- 94, // File Metadata
- 96, // HTTP File Storage Integration
- ];
- const _INAPPLICABLE_NIPS: [u8; 45] = [
- 2, 3, 5, 6, 7, 8, 10, 13, 14, 15, 18, 19, 21, 23, 24, 25, 27, 28, 30, 31, 32, 34, 36, 38,
- 39, 44, 46, 47, 48, 49, 51, 52, 53, 56, 57, 58, 72, 75, 78, 84, 89, 90, 92, 98, 99,
- ];
-
- let s = SUPPORTED_NIPS
- .iter()
- .map(|i| format!("{}", i))
- .collect::>()
- .join(",");
- rid.push_str(&format!("{{\"supported_nips\":[{}],", s));
-
- let software = env!("CARGO_PKG_NAME");
- rid.push_str("\"software\":\"");
- rid.push_str(software);
- rid.push('\"');
-
- let version = env!("CARGO_PKG_VERSION");
- rid.push(',');
- rid.push_str("\"version\":\"");
- rid.push_str(version);
- rid.push('\"');
-
- if let Some(name) = &config.name {
- rid.push(',');
- rid.push_str("\"name\":\"");
- rid.push_str(name);
- rid.push('\"');
- }
- if let Some(description) = &config.description {
- rid.push(',');
- rid.push_str("\"description\":\"");
- rid.push_str(description);
- rid.push('\"');
- }
- if let Some(contact) = &config.contact {
- rid.push(',');
- rid.push_str("\"contact\":\"");
- rid.push_str(contact);
- rid.push('\"');
- }
- if let Some(pubkey) = &config.public_key {
- let mut pkh: [u8; 64] = [0; 64];
- pubkey.write_hex(&mut pkh).unwrap();
- rid.push(',');
- rid.push_str("\"pubkey\":\"");
- rid.push_str(unsafe { std::str::from_utf8_unchecked(pkh.as_slice()) });
- rid.push('\"');
- }
-
- // Limitation
- rid.push(',');
- rid.push_str("\"limitation\":{");
- {
- rid.push_str("\"payment_required\":false,\"auth_required\":false,\"restricted_writes\":true,\"max_message_length\":1048576");
- rid.push_str(&format!(
- ",\"max_subscriptions\":{}",
- config.max_subscriptions
- ));
- }
- rid.push('}');
-
- // Retention
- rid.push(',');
- rid.push_str("\"retention\":[{\"time\": null}]");
-
- // Services
- rid.push(',');
- rid.push_str("\"services\":{");
- rid.push_str("\"public\":[\"ephemeral\",\"directory\"]");
- rid.push(',');
- rid.push_str("\"private\":[\"outbox\",\"inbox\"]");
- rid.push(',');
- rid.push_str("\"paid\":[]");
- rid.push(',');
- rid.push_str("\"unavailable\":[\"search\"]");
- rid.push('}');
-
- rid.push('}');
-
- rid
-}
diff --git a/src/web/nip11.rs b/src/web/nip11.rs
new file mode 100644
index 0000000..36d5135
--- /dev/null
+++ b/src/web/nip11.rs
@@ -0,0 +1,126 @@
+use crate::config::Config;
+use crate::error::Error;
+use crate::globals::GLOBALS;
+use crate::ip::HashedPeer;
+use hyper::{Body, Response, StatusCode};
+
+pub async fn serve_nip11(peer: HashedPeer) -> Result, Error> {
+ log::debug!(target: "Client", "{}: sent NIP-11", peer);
+ let rid = {
+ let config = &*GLOBALS.config.read();
+ GLOBALS.rid.get_or_init(|| build_rid(config))
+ };
+
+ let response = Response::builder()
+ .header("Access-Control-Allow-Origin", "*")
+ .header("Access-Control-Allow-Headers", "*")
+ .header("Access-Control-Allow-Methods", "*")
+ .header("Content-Type", "application/nostr+json")
+ .status(StatusCode::OK)
+ .body(rid.clone().into())?;
+ Ok(response)
+}
+
+fn build_rid(config: &Config) -> String {
+ let mut rid: String = String::with_capacity(255);
+
+ const SUPPORTED_NIPS: [u8; 8] = [
+ 1, // nostr
+ 4, // DMs
+ 9, // Event Deletion
+ 11, // relay information document
+ 40, // Expiration Timestamp
+ 42, // AUTH
+ 59, // GiftWrap
+ 65, // Relay List Metadata
+ ];
+ const _UNSUPPORTED_NIPS: [u8; 6] = [
+ 26, // Delegated Event Signing
+ 29, // Relay-based Groups
+ 45, // Counting results
+ 50, // SEARCH
+ 94, // File Metadata
+ 96, // HTTP File Storage Integration
+ ];
+ const _INAPPLICABLE_NIPS: [u8; 45] = [
+ 2, 3, 5, 6, 7, 8, 10, 13, 14, 15, 18, 19, 21, 23, 24, 25, 27, 28, 30, 31, 32, 34, 36, 38,
+ 39, 44, 46, 47, 48, 49, 51, 52, 53, 56, 57, 58, 72, 75, 78, 84, 89, 90, 92, 98, 99,
+ ];
+
+ let s = SUPPORTED_NIPS
+ .iter()
+ .map(|i| format!("{}", i))
+ .collect::>()
+ .join(",");
+ rid.push_str(&format!("{{\"supported_nips\":[{}],", s));
+
+ let software = env!("CARGO_PKG_NAME");
+ rid.push_str("\"software\":\"");
+ rid.push_str(software);
+ rid.push('\"');
+
+ let version = env!("CARGO_PKG_VERSION");
+ rid.push(',');
+ rid.push_str("\"version\":\"");
+ rid.push_str(version);
+ rid.push('\"');
+
+ if let Some(name) = &config.name {
+ rid.push(',');
+ rid.push_str("\"name\":\"");
+ rid.push_str(name);
+ rid.push('\"');
+ }
+ if let Some(description) = &config.description {
+ rid.push(',');
+ rid.push_str("\"description\":\"");
+ rid.push_str(description);
+ rid.push('\"');
+ }
+ if let Some(contact) = &config.contact {
+ rid.push(',');
+ rid.push_str("\"contact\":\"");
+ rid.push_str(contact);
+ rid.push('\"');
+ }
+ if let Some(pubkey) = &config.public_key {
+ let mut pkh: [u8; 64] = [0; 64];
+ pubkey.write_hex(&mut pkh).unwrap();
+ rid.push(',');
+ rid.push_str("\"pubkey\":\"");
+ rid.push_str(unsafe { std::str::from_utf8_unchecked(pkh.as_slice()) });
+ rid.push('\"');
+ }
+
+ // Limitation
+ rid.push(',');
+ rid.push_str("\"limitation\":{");
+ {
+ rid.push_str("\"payment_required\":false,\"auth_required\":false,\"restricted_writes\":true,\"max_message_length\":1048576");
+ rid.push_str(&format!(
+ ",\"max_subscriptions\":{}",
+ config.max_subscriptions
+ ));
+ }
+ rid.push('}');
+
+ // Retention
+ rid.push(',');
+ rid.push_str("\"retention\":[{\"time\": null}]");
+
+ // Services
+ rid.push(',');
+ rid.push_str("\"services\":{");
+ rid.push_str("\"public\":[\"ephemeral\",\"directory\"]");
+ rid.push(',');
+ rid.push_str("\"private\":[\"outbox\",\"inbox\"]");
+ rid.push(',');
+ rid.push_str("\"paid\":[]");
+ rid.push(',');
+ rid.push_str("\"unavailable\":[\"search\"]");
+ rid.push('}');
+
+ rid.push('}');
+
+ rid
+}