|
1 | 1 | use crate::client::{normalize_write_response, BuzzClient}; |
2 | 2 | use crate::error::CliError; |
3 | 3 | use crate::validate::validate_hex64; |
| 4 | +use nostr::ToBech32; |
4 | 5 |
|
5 | 6 | // TODO(phase-4): Replace raw nostr::EventBuilder usage in cmd_set_presence with buzz-sdk builder |
6 | 7 |
|
| 8 | +/// Build identity JSON for `buzz users me` (unit-testable without a live client). |
| 9 | +pub(crate) fn me_identity_json(pubkey_hex: &str, npub_bech32: &str) -> serde_json::Value { |
| 10 | + serde_json::json!({ |
| 11 | + "pubkey": pubkey_hex, |
| 12 | + "npub": npub_bech32, |
| 13 | + }) |
| 14 | +} |
| 15 | + |
| 16 | +/// Print the active CLI identity (hex pubkey + npub) from the loaded private key. |
| 17 | +/// |
| 18 | +/// No relay I/O — agents can resolve "who am I?" before connecting. Refs #2663. |
| 19 | +pub async fn cmd_me( |
| 20 | + client: &BuzzClient, |
| 21 | + _format: &crate::OutputFormat, |
| 22 | +) -> Result<(), CliError> { |
| 23 | + let pk = client.keys().public_key(); |
| 24 | + let hex = pk.to_hex(); |
| 25 | + let npub = pk |
| 26 | + .to_bech32() |
| 27 | + .map_err(|e| CliError::Other(format!("npub encode failed: {e}")))?; |
| 28 | + println!("{}", me_identity_json(&hex, &npub)); |
| 29 | + Ok(()) |
| 30 | +} |
| 31 | + |
7 | 32 | /// Get user profiles (kind:0 metadata events). |
8 | 33 | /// |
9 | 34 | /// - 0 pubkeys, no name → query our own profile |
@@ -311,6 +336,7 @@ pub async fn dispatch( |
311 | 336 | ) -> Result<(), CliError> { |
312 | 337 | use crate::UsersCmd; |
313 | 338 | match cmd { |
| 339 | + UsersCmd::Me => cmd_me(client, format).await, |
314 | 340 | UsersCmd::Get { pubkeys, name } => { |
315 | 341 | cmd_get_users(client, &pubkeys, name.as_deref(), format).await |
316 | 342 | } |
@@ -356,4 +382,26 @@ mod tests { |
356 | 382 | let event = json!({"pubkey": "user", "tags": [["p"]]}); |
357 | 383 | assert_eq!(presence_subject(&event), "user"); |
358 | 384 | } |
| 385 | + |
| 386 | + #[test] |
| 387 | + fn me_identity_json_includes_pubkey_and_npub() { |
| 388 | + let hex = "a".repeat(64); |
| 389 | + let v = super::me_identity_json( |
| 390 | + &hex, |
| 391 | + "npub1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq5s0xov", |
| 392 | + ); |
| 393 | + assert_eq!(v["pubkey"], hex); |
| 394 | + assert!(v["npub"].as_str().unwrap().starts_with("npub1")); |
| 395 | + } |
| 396 | + |
| 397 | + #[test] |
| 398 | + fn me_identity_from_generated_keys_roundtrips_bech32() { |
| 399 | + use nostr::{Keys, ToBech32}; |
| 400 | + let keys = Keys::generate(); |
| 401 | + let hex = keys.public_key().to_hex(); |
| 402 | + let npub = keys.public_key().to_bech32().expect("npub"); |
| 403 | + let v = super::me_identity_json(&hex, &npub); |
| 404 | + assert_eq!(v["pubkey"].as_str().unwrap().len(), 64); |
| 405 | + assert_eq!(v["npub"].as_str().unwrap(), npub); |
| 406 | + } |
359 | 407 | } |
0 commit comments