Skip to main content

self_agent_sdk/
agent_card.rs

1// SPDX-FileCopyrightText: 2025-2026 Social Connect Labs, Inc.
2// SPDX-License-Identifier: BUSL-1.1
3// NOTE: Converts to Apache-2.0 on 2029-06-11 per LICENSE.
4
5use serde::{Deserialize, Serialize};
6
7// ─── Types ───────────────────────────────────────────────────────────────────
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct A2AAgentCard {
12    pub a2a_version: String,
13    pub name: String,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub description: Option<String>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub url: Option<String>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub capabilities: Option<Vec<String>>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub skills: Option<Vec<AgentSkill>>,
22    pub self_protocol: SelfProtocolExtension,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub struct AgentSkill {
28    pub name: String,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub description: Option<String>,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
34#[serde(rename_all = "camelCase")]
35pub struct SelfProtocolExtension {
36    pub agent_id: u64,
37    pub registry: String,
38    pub chain_id: u64,
39    pub proof_provider: String,
40    pub provider_name: String,
41    pub verification_strength: u8,
42    pub trust_model: TrustModel,
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub credentials: Option<CardCredentials>,
45}
46
47#[derive(Debug, Clone, Serialize, Deserialize)]
48#[serde(rename_all = "camelCase")]
49pub struct TrustModel {
50    pub proof_type: String,
51    pub sybil_resistant: bool,
52    pub ofac_screened: bool,
53    pub minimum_age_verified: u64,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct CardCredentials {
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub nationality: Option<String>,
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub issuing_state: Option<String>,
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub older_than: Option<u64>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub ofac_clean: Option<bool>,
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub has_name: Option<bool>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub has_date_of_birth: Option<bool>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub has_gender: Option<bool>,
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub document_expiry: Option<String>,
75}
76
77// ─── Provider Scoring ────────────────────────────────────────────────────────
78
79pub fn get_provider_label(strength: u8) -> &'static str {
80    match strength {
81        100..=u8::MAX => "passport",
82        80..=99 => "kyc",
83        60..=79 => "govt_id",
84        40..=59 => "liveness",
85        _ => "unknown",
86    }
87}
88
89pub fn get_strength_color(strength: u8) -> &'static str {
90    match strength {
91        80..=u8::MAX => "green",
92        60..=79 => "blue",
93        40..=59 => "amber",
94        _ => "gray",
95    }
96}