Skip to main content

dpp_crypto/access/credential/
types.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4/// Re-export the canonical `AccessTier` from dpp-domain.
5pub use dpp_domain::AccessTier;
6
7// ─── Credential role ─────────────────────────────────────────────────────────
8
9/// The access role granted by a Verifiable Credential.
10///
11/// Maps to the ESPR access tiers and the specific operator roles
12/// defined in the transfer-of-responsibility model.
13#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
14#[serde(rename_all = "snake_case")]
15pub enum CredentialRole {
16    /// Authorised repairer — can access disassembly instructions, spare parts info.
17    AuthorisedRepairer,
18    /// Recycler — can access material composition, SVHC data, recycling instructions.
19    Recycler,
20    /// Remanufacturer — can access full technical specifications.
21    Remanufacturer,
22    /// Preparer for reuse — can access quality and safety data.
23    PreparerForReuse,
24    /// Distributor with professional access.
25    Distributor,
26    /// Market surveillance authority — full access to all tiers.
27    MarketSurveillanceAuthority,
28    /// Customs authority — access for border control.
29    CustomsAuthority,
30    /// Notified body — conformity assessment.
31    NotifiedBody,
32    /// Custom role (extension point for sector-specific roles).
33    Custom(String),
34}
35
36impl CredentialRole {
37    /// Returns the minimum access tier this role grants.
38    pub fn access_tier(&self) -> AccessTier {
39        match self {
40            Self::MarketSurveillanceAuthority | Self::CustomsAuthority | Self::NotifiedBody => {
41                AccessTier::Confidential
42            }
43            _ => AccessTier::Professional,
44        }
45    }
46}
47
48// ─── Credential subject ─────────────────────────────────────────────────────
49
50/// The claims inside a DPP access credential.
51#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
52#[serde(rename_all = "camelCase")]
53pub struct DppCredentialSubject {
54    /// DID of the credential holder (the entity being granted access).
55    pub id: String,
56    /// Legal name of the credential holder.
57    pub name: String,
58    /// The role being granted.
59    pub role: CredentialRole,
60    /// ISO 3166-1 alpha-2 country code of the holder's registration.
61    pub country: String,
62    /// Sector(s) this credential applies to (e.g., `["textile"]`).
63    /// Empty means all sectors.
64    #[serde(skip_serializing_if = "Vec::is_empty", default)]
65    pub sectors: Vec<String>,
66    /// Specific product categories this credential covers.
67    /// Empty means all categories within the sectors.
68    #[serde(skip_serializing_if = "Vec::is_empty", default)]
69    pub product_categories: Vec<String>,
70}
71
72// ─── Verifiable Credential envelope ─────────────────────────────────────────
73
74/// A W3C Verifiable Credential for DPP access.
75///
76/// Follows the VC Data Model v2.0 structure with DPP-specific extensions.
77#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
78#[serde(rename_all = "camelCase")]
79pub struct DppAccessCredential {
80    /// JSON-LD context (always includes the VC context).
81    #[serde(rename = "@context")]
82    pub context: Vec<String>,
83    /// Credential type (always includes "VerifiableCredential").
84    #[serde(rename = "type")]
85    pub credential_type: Vec<String>,
86    /// Unique credential ID (UUID-based URI).
87    pub id: String,
88    /// DID of the issuer (the authority granting access).
89    pub issuer: String,
90    /// When the credential was issued.
91    pub valid_from: DateTime<Utc>,
92    /// When the credential expires (mandatory for DPP credentials).
93    pub valid_until: DateTime<Utc>,
94    /// The access claims.
95    pub credential_subject: DppCredentialSubject,
96    /// Credential status for revocation checking.
97    #[serde(skip_serializing_if = "Option::is_none")]
98    pub credential_status: Option<CredentialStatus>,
99}
100
101/// Credential status descriptor for revocation checking.
102#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
103#[serde(rename_all = "camelCase")]
104pub struct CredentialStatus {
105    /// URL to check revocation status.
106    pub id: String,
107    /// Status method type. Per W3C Bitstring Status List v1.0 this is
108    /// `"BitstringStatusListEntry"` (the older `"StatusList2021Entry"` is dated).
109    #[serde(rename = "type")]
110    pub status_type: String,
111    /// Index in the status list.
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub status_list_index: Option<String>,
114    /// URL of the status list credential.
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub status_list_credential: Option<String>,
117}