1use secp256k1::{Keypair, PublicKey, Secp256k1, SecretKey, XOnlyPublicKey};
4use std::fmt;
5
6use super::auth::{AuthResponse, auth_challenge_digest};
7use super::encoding::{decode_secret, encode_npub};
8use super::{FipsAddress, IdentityError, NodeAddr, sha256};
9
10pub struct Identity {
15 keypair: Keypair,
16 node_addr: NodeAddr,
17 address: FipsAddress,
18}
19
20impl Identity {
21 pub fn generate() -> Self {
23 let mut secret_bytes = [0u8; 32];
24 rand::Rng::fill_bytes(&mut rand::rng(), &mut secret_bytes);
25 let secret_key =
26 SecretKey::from_slice(&secret_bytes).expect("32 random bytes is a valid secret key");
27 Self::from_secret_key(secret_key)
28 }
29
30 pub fn from_keypair(keypair: Keypair) -> Self {
32 let (pubkey, _parity) = keypair.x_only_public_key();
33 let node_addr = NodeAddr::from_pubkey(&pubkey);
34 let address = FipsAddress::from_node_addr(&node_addr);
35 Self {
36 keypair,
37 node_addr,
38 address,
39 }
40 }
41
42 pub fn from_secret_key(secret_key: SecretKey) -> Self {
44 let secp = Secp256k1::new();
45 let keypair = Keypair::from_secret_key(&secp, &secret_key);
46 Self::from_keypair(keypair)
47 }
48
49 pub fn from_secret_bytes(bytes: &[u8; 32]) -> Result<Self, IdentityError> {
51 let secret_key = SecretKey::from_slice(bytes)?;
52 Ok(Self::from_secret_key(secret_key))
53 }
54
55 pub fn from_secret_str(s: &str) -> Result<Self, IdentityError> {
57 let secret_key = decode_secret(s)?;
58 Ok(Self::from_secret_key(secret_key))
59 }
60
61 pub fn keypair(&self) -> Keypair {
65 self.keypair
66 }
67
68 pub fn pubkey(&self) -> XOnlyPublicKey {
70 self.keypair.x_only_public_key().0
71 }
72
73 pub fn pubkey_full(&self) -> PublicKey {
75 self.keypair.public_key()
76 }
77
78 pub fn npub(&self) -> String {
80 encode_npub(&self.pubkey())
81 }
82
83 pub fn node_addr(&self) -> &NodeAddr {
85 &self.node_addr
86 }
87
88 pub fn address(&self) -> &FipsAddress {
90 &self.address
91 }
92
93 pub fn sign(&self, data: &[u8]) -> secp256k1::schnorr::Signature {
95 let secp = Secp256k1::new();
96 let digest = sha256(data);
97 secp.sign_schnorr(&digest, &self.keypair)
98 }
99
100 pub fn sign_challenge(&self, challenge: &[u8; 32], timestamp: u64) -> AuthResponse {
104 let digest = auth_challenge_digest(challenge, timestamp);
105 let secp = Secp256k1::new();
106 let signature = secp.sign_schnorr(&digest, &self.keypair);
107 AuthResponse {
108 pubkey: self.pubkey(),
109 timestamp,
110 signature,
111 }
112 }
113}
114
115impl fmt::Debug for Identity {
116 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117 f.debug_struct("Identity")
118 .field("node_addr", &self.node_addr)
119 .field("address", &self.address)
120 .finish_non_exhaustive()
121 }
122}