Skip to main content

dpp_vc/credential/
builder.rs

1use chrono::Utc;
2use uuid::Uuid;
3
4use super::types::{CredentialStatus, DppAccessCredential, DppCredentialSubject};
5
6/// Builder for constructing DPP access credentials.
7pub struct CredentialBuilder {
8    issuer_did: String,
9    subject: DppCredentialSubject,
10    expiration: chrono::DateTime<Utc>,
11    status: Option<CredentialStatus>,
12}
13
14impl CredentialBuilder {
15    /// Start building a credential from an issuer DID and subject claims.
16    #[must_use]
17    pub fn new(issuer_did: String, subject: DppCredentialSubject) -> Self {
18        Self {
19            issuer_did,
20            subject,
21            expiration: Utc::now() + chrono::Duration::days(365),
22            status: None,
23        }
24    }
25
26    /// Set the expiration date.
27    #[must_use]
28    pub fn expires_at(mut self, expiration: chrono::DateTime<Utc>) -> Self {
29        self.expiration = expiration;
30        self
31    }
32
33    /// Set the expiration to N days from now.
34    #[must_use]
35    pub fn expires_in_days(mut self, days: i64) -> Self {
36        self.expiration = Utc::now() + chrono::Duration::days(days);
37        self
38    }
39
40    /// Add a credential status for revocation checking.
41    #[must_use]
42    pub fn with_status(mut self, status: CredentialStatus) -> Self {
43        self.status = Some(status);
44        self
45    }
46
47    /// Build the unsigned credential.
48    #[must_use]
49    pub fn build(self) -> DppAccessCredential {
50        DppAccessCredential {
51            context: vec![
52                "https://www.w3.org/ns/credentials/v2".into(),
53                "https://schema.odal-node.io/credentials/dpp-access/v1".into(),
54            ],
55            credential_type: vec!["VerifiableCredential".into(), "DppAccessCredential".into()],
56            id: format!("urn:uuid:{}", Uuid::now_v7()),
57            issuer: self.issuer_did,
58            valid_from: Utc::now(),
59            valid_until: self.expiration,
60            credential_subject: self.subject,
61            credential_status: self.status,
62        }
63    }
64}