225 lines
7.5 KiB
Rust
225 lines
7.5 KiB
Rust
|
|
//! RPC handlers for multi-identity management.
|
||
|
|
|
||
|
|
use super::RpcHandler;
|
||
|
|
use crate::identity_manager::{IdentityManager, IdentityPurpose};
|
||
|
|
use anyhow::Result;
|
||
|
|
|
||
|
|
impl RpcHandler {
|
||
|
|
/// List all identities with their default status.
|
||
|
|
pub(super) async fn handle_identity_list(
|
||
|
|
&self,
|
||
|
|
_params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let (identities, default_id) = manager.list().await?;
|
||
|
|
|
||
|
|
let items: Vec<serde_json::Value> = identities
|
||
|
|
.into_iter()
|
||
|
|
.map(|id| {
|
||
|
|
let is_default = default_id.as_deref() == Some(&id.id);
|
||
|
|
serde_json::json!({
|
||
|
|
"id": id.id,
|
||
|
|
"name": id.name,
|
||
|
|
"purpose": id.purpose,
|
||
|
|
"pubkey": id.pubkey_hex,
|
||
|
|
"did": id.did,
|
||
|
|
"created_at": id.created_at,
|
||
|
|
"is_default": is_default,
|
||
|
|
})
|
||
|
|
})
|
||
|
|
.collect();
|
||
|
|
|
||
|
|
Ok(serde_json::json!({ "identities": items }))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Create a new identity.
|
||
|
|
pub(super) async fn handle_identity_create(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let name = params
|
||
|
|
.get("name")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.unwrap_or("Personal")
|
||
|
|
.to_string();
|
||
|
|
|
||
|
|
let purpose_str = params
|
||
|
|
.get("purpose")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.unwrap_or("personal");
|
||
|
|
|
||
|
|
let purpose = match purpose_str {
|
||
|
|
"business" => IdentityPurpose::Business,
|
||
|
|
"anonymous" => IdentityPurpose::Anonymous,
|
||
|
|
_ => IdentityPurpose::Personal,
|
||
|
|
};
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let record = manager.create(name, purpose).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({
|
||
|
|
"id": record.id,
|
||
|
|
"name": record.name,
|
||
|
|
"purpose": record.purpose,
|
||
|
|
"pubkey": record.pubkey_hex,
|
||
|
|
"did": record.did,
|
||
|
|
"created_at": record.created_at,
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Get a single identity by ID.
|
||
|
|
pub(super) async fn handle_identity_get(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let id = params
|
||
|
|
.get("id")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: id"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let record = manager.get(id).await?;
|
||
|
|
let (_, default_id) = manager.list().await?;
|
||
|
|
let is_default = default_id.as_deref() == Some(&record.id);
|
||
|
|
|
||
|
|
Ok(serde_json::json!({
|
||
|
|
"id": record.id,
|
||
|
|
"name": record.name,
|
||
|
|
"purpose": record.purpose,
|
||
|
|
"pubkey": record.pubkey_hex,
|
||
|
|
"did": record.did,
|
||
|
|
"created_at": record.created_at,
|
||
|
|
"is_default": is_default,
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Delete an identity.
|
||
|
|
pub(super) async fn handle_identity_delete(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let id = params
|
||
|
|
.get("id")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: id"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
manager.delete(id).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({ "ok": true }))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Set the default identity.
|
||
|
|
pub(super) async fn handle_identity_set_default(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let id = params
|
||
|
|
.get("id")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: id"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
manager.set_default(id).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({ "ok": true }))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Sign a message with a specific identity.
|
||
|
|
pub(super) async fn handle_identity_sign(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let id = params
|
||
|
|
.get("id")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: id"))?;
|
||
|
|
let message = params
|
||
|
|
.get("message")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: message"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let signature = manager.sign(id, message.as_bytes()).await?;
|
||
|
|
let record = manager.get(id).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({
|
||
|
|
"did": record.did,
|
||
|
|
"message": message,
|
||
|
|
"signature": signature,
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Verify a signature against a DID.
|
||
|
|
pub(super) async fn handle_identity_verify(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let did = params
|
||
|
|
.get("did")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: did"))?;
|
||
|
|
let message = params
|
||
|
|
.get("message")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: message"))?;
|
||
|
|
let signature = params
|
||
|
|
.get("signature")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: signature"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let valid = manager.verify(did, message.as_bytes(), signature).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({ "valid": valid }))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Create a Nostr keypair linked to an identity.
|
||
|
|
pub(super) async fn handle_identity_create_nostr_key(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let id = params
|
||
|
|
.get("id")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: id"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let pubkey = manager.create_nostr_key(id).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({
|
||
|
|
"nostr_pubkey": pubkey,
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Sign a Nostr event hash with an identity's Nostr key.
|
||
|
|
pub(super) async fn handle_identity_nostr_sign(
|
||
|
|
&self,
|
||
|
|
params: Option<serde_json::Value>,
|
||
|
|
) -> Result<serde_json::Value> {
|
||
|
|
let params = params.unwrap_or_default();
|
||
|
|
let id = params
|
||
|
|
.get("id")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: id"))?;
|
||
|
|
let event_hash = params
|
||
|
|
.get("event_hash")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow::anyhow!("Missing required parameter: event_hash"))?;
|
||
|
|
|
||
|
|
let manager = IdentityManager::new(&self.config.data_dir).await?;
|
||
|
|
let signature = manager.nostr_sign(id, event_hash).await?;
|
||
|
|
|
||
|
|
Ok(serde_json::json!({
|
||
|
|
"signature": signature,
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
}
|