Draft 0.5: identity/registry spec; Phase A signed MA registry, mailbox challenge auth, key rotation, skew rejection

This commit is contained in:
George Coles
2026-09-15 05:45:02 -04:00
parent fb45cfa8cf
commit 559c260639
18 changed files with 1526 additions and 105 deletions
+31 -6
View File
@@ -13,8 +13,12 @@ pub fn config_for(dir: &Path, name: &str, relay_url: &str) -> Config {
let config = Config {
node: NodeSection {
name: name.to_string(),
id: None,
listen: "127.0.0.1:0".to_string(),
relays: vec![relay_url.to_string()],
registry: None,
ma_key: None,
dev_bootstrap: true,
responder: true,
},
query: QuerySection {
@@ -60,17 +64,33 @@ pub fn query_envelope(key: &Keypair, text: &str, max_results: usize) -> Envelope
Envelope::new(key, TYPE_QUERY, serde_json::to_value(&body).unwrap())
}
pub async fn register(client: &reqwest::Client, relay_url: &str, member: &str) {
poll(client, relay_url, member, 30).await;
pub async fn challenge(client: &reqwest::Client, relay_url: &str, member: &str) -> Option<String> {
let response = client
.get(format!("{relay_url}/v1/challenge?member={member}"))
.send()
.await
.unwrap();
if !response.status().is_success() {
return None;
}
let payload: Value = response.json().await.unwrap();
payload
.get("nonce")
.and_then(Value::as_str)
.map(str::to_string)
}
pub async fn register(client: &reqwest::Client, relay_url: &str, key: &Keypair) {
poll(client, relay_url, key, 30).await;
}
pub async fn poll_messages(
client: &reqwest::Client,
relay_url: &str,
member: &str,
key: &Keypair,
timeout_ms: u64,
) -> Vec<Value> {
let response = poll(client, relay_url, member, timeout_ms).await;
let response = poll(client, relay_url, key, timeout_ms).await;
if response.status() == reqwest::StatusCode::NO_CONTENT {
return Vec::new();
}
@@ -149,12 +169,17 @@ pub async fn unicast(
pub async fn poll(
client: &reqwest::Client,
relay_url: &str,
member: &str,
key: &Keypair,
timeout_ms: u64,
) -> reqwest::Response {
let member = key.public_hex();
let nonce = challenge(client, relay_url, &member)
.await
.expect("relay challenge");
let sig = key.sign(&frxd::crypto::poll_signing_bytes(&member, &nonce));
client
.get(format!(
"{relay_url}/v1/poll?member={member}&timeout_ms={timeout_ms}"
"{relay_url}/v1/poll?member={member}&nonce={nonce}&sig={sig}&timeout_ms={timeout_ms}"
))
.send()
.await