1use libp2p_identity::PeerId;
2
3use crate::{Did, Document, EncryptionKey, MaError, Result, SigningKey, VerificationMethod};
4
5#[derive(Debug, Clone)]
10pub struct GeneratedIdentity {
11 pub subject_url: Did,
12 pub document: Document,
13 pub signing_private_key_hex: String,
14 pub encryption_private_key_hex: String,
15}
16
17fn build_identity(ipns: &str) -> Result<GeneratedIdentity> {
18 let subject_url = Did::new_url(ipns, None::<String>)?;
19 let sign_url = Did::new_url(ipns, None::<String>)?;
20 let enc_url = Did::new_url(ipns, None::<String>)?;
21
22 let signing_key = SigningKey::generate(sign_url)?;
23 let encryption_key = EncryptionKey::generate(enc_url)?;
24
25 let mut document = Document::new(&subject_url, &subject_url);
26
27 let assertion_vm = VerificationMethod::new(
28 subject_url.base_id(),
29 subject_url.base_id(),
30 signing_key.key_type.clone(),
31 signing_key.did.fragment.as_deref().unwrap_or_default(),
32 signing_key.public_key_multibase.clone(),
33 )?;
34
35 let key_agreement_vm = VerificationMethod::new(
36 subject_url.base_id(),
37 subject_url.base_id(),
38 encryption_key.key_type.clone(),
39 encryption_key.did.fragment.as_deref().unwrap_or_default(),
40 encryption_key.public_key_multibase.clone(),
41 )?;
42
43 let assertion_vm_id = assertion_vm.id.clone();
44 document.add_verification_method(assertion_vm.clone())?;
45 document.add_verification_method(key_agreement_vm.clone())?;
46 document.assertion_method = vec![assertion_vm_id];
47 document.key_agreement = vec![key_agreement_vm.id.clone()];
48 document.sign(&signing_key, &assertion_vm)?;
49
50 Ok(GeneratedIdentity {
51 subject_url,
52 document,
53 signing_private_key_hex: hex::encode(signing_key.private_key_bytes()),
54 encryption_private_key_hex: hex::encode(encryption_key.private_key_bytes()),
55 })
56}
57
58pub fn ipns_from_secret(secret: [u8; 32]) -> Result<String> {
63 let keypair = libp2p_identity::Keypair::ed25519_from_bytes(secret)
64 .map_err(|_| MaError::InvalidIdentitySecret)?;
65 let peer_id = PeerId::from_public_key(&keypair.public());
66 Ok(peer_id.to_string())
67}
68
69pub fn generate_identity(ipns: &str) -> Result<GeneratedIdentity> {
95 build_identity(ipns)
96}
97
98pub fn generate_identity_from_secret(secret: [u8; 32]) -> Result<GeneratedIdentity> {
117 let ipns = ipns_from_secret(secret)?;
118 build_identity(&ipns)
119}