auths_cli/commands/id/
register.rs1use std::path::Path;
2use std::sync::Arc;
3
4use anyhow::{Result, bail};
5use serde::Serialize;
6
7use auths_id::ports::registry::RegistryBackend;
8use auths_id::storage::attestation::AttestationSource;
9use auths_id::storage::identity::IdentityStorage;
10use auths_infra_http::HttpRegistryClient;
11use auths_sdk::error::RegistrationError;
12pub use auths_sdk::registration::DEFAULT_REGISTRY_URL;
13use auths_sdk::result::RegistrationOutcome;
14use auths_storage::git::{
15 GitRegistryBackend, RegistryAttestationStorage, RegistryConfig, RegistryIdentityStorage,
16};
17
18use crate::ux::format::{JsonResponse, Output, is_json_mode};
19
20#[derive(Serialize)]
21struct RegisterJsonResponse {
22 did_prefix: String,
23 registry: String,
24 platform_claims_indexed: usize,
25}
26
27pub fn handle_register(repo_path: &Path, registry: &str) -> Result<()> {
38 let rt = tokio::runtime::Runtime::new()?;
39
40 let backend: Arc<dyn RegistryBackend + Send + Sync> = Arc::new(
41 GitRegistryBackend::from_config_unchecked(RegistryConfig::single_tenant(repo_path)),
42 );
43 let identity_storage: Arc<dyn IdentityStorage + Send + Sync> =
44 Arc::new(RegistryIdentityStorage::new(repo_path.to_path_buf()));
45 let attestation_store = Arc::new(RegistryAttestationStorage::new(repo_path));
46 let attestation_source: Arc<dyn AttestationSource + Send + Sync> = attestation_store;
47
48 let registry_client = HttpRegistryClient::new();
49
50 match rt.block_on(auths_sdk::registration::register_identity(
51 identity_storage,
52 backend,
53 attestation_source,
54 registry,
55 None,
56 ®istry_client,
57 )) {
58 Ok(outcome) => display_registration_result(&outcome),
59 Err(RegistrationError::AlreadyRegistered) => {
60 bail!("Identity already registered at this registry.");
61 }
62 Err(RegistrationError::QuotaExceeded) => {
63 bail!("Registration quota exceeded. Try again next month or use a paid tier.");
64 }
65 Err(RegistrationError::NetworkError(e)) => {
66 bail!("Failed to connect to registry server: {e}");
67 }
68 Err(RegistrationError::LocalDataError(e)) => {
69 bail!("{e}");
70 }
71 Err(e) => {
72 bail!("Registration failed: {e}");
73 }
74 }
75}
76
77fn display_registration_result(outcome: &RegistrationOutcome) -> Result<()> {
78 if is_json_mode() {
79 let json_resp = JsonResponse::success(
80 "id register",
81 RegisterJsonResponse {
82 did_prefix: outcome.did_prefix.clone(),
83 registry: outcome.registry.clone(),
84 platform_claims_indexed: outcome.platform_claims_indexed,
85 },
86 );
87 json_resp.print()?;
88 } else {
89 let out = Output::stdout();
90 println!(
91 "{} Identity registered at {}",
92 out.success("Success!"),
93 out.bold(&outcome.registry)
94 );
95 println!("DID: {}", out.info(&outcome.did_prefix));
96 if outcome.platform_claims_indexed > 0 {
97 println!(
98 "Platform claims indexed: {}",
99 outcome.platform_claims_indexed
100 );
101 }
102 println!();
103 println!(
104 "{}",
105 out.bold("Next step: Anchor a cryptographic attestation for your code")
106 );
107 println!(
108 "Run: {}",
109 out.dim(
110 "auths artifact publish --signature <path-to.auths.json> --package <ecosystem:name>"
111 )
112 );
113 }
114 Ok(())
115}