1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! # `vta-sdk` — SDK for Verifiable Trust Agents
//!
//! A Verifiable Trust Agent (VTA) holds a BIP-39 master seed, derives keys
//! via BIP-32, and exposes a REST + DIDComm API to operators and integrations.
//! This crate is the typed client that lets a Rust service:
//!
//! * authenticate against a VTA over REST or DIDComm,
//! * call into every management surface (keys, contexts, ACL, DID templates,
//! audit, backup, WebVH),
//! * receive secret-bearing bundles via the `sealed_transfer` envelope
//! (HPKE + ASCII armor + producer assertion),
//! * provision integrations (mediators, WebVH hosts, app identities) end-to-end
//! via VP-framed bootstrap requests + VC-issued admin authorization.
//!
//! ## Quick start
//!
//! Two-step pattern: import a credential, then call the typed client.
//!
//! ```rust,no_run,ignore
//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
//! use vta_sdk::client::VtaClient;
//! use vta_sdk::credentials::CredentialBundle;
//!
//! // The credential is what the operator hands you (a base64 blob the VTA
//! // setup wizard printed, or the result of `pnm bootstrap connect`).
//! let credential = CredentialBundle::decode("<base64-credential>")?;
//! let client = VtaClient::from_credential(&credential, None).await?;
//!
//! // Typed REST surface — `?` returns a `VtaError` with HTTP-aware variants
//! // (Conflict, Gone, Forbidden, NotFound, …) so callers can surface targeted
//! // operator errors instead of stringifying generic failures.
//! let contexts = client.list_contexts().await?;
//! for ctx in contexts {
//! println!("{} — {}", ctx.id, ctx.label);
//! }
//! # Ok(()) }
//! ```
//!
//! ## Sealed-transfer round-trip
//!
//! See [`sealed_transfer`] for the HPKE envelope used to move credentials,
//! mediator secrets, and DID-secrets bundles between operator hosts:
//!
//! ```rust,ignore
//! use vta_sdk::sealed_transfer::{seal_payload, open_bundle, generate_keypair, ...};
//! ```
//!
//! ## Feature flags
//!
//! The crate is split into opt-in features so a thin types-only consumer
//! doesn't pay the dependency cost of the full client. Pick the smallest
//! set that compiles for your use case.
//!
//! | Feature | What it enables |
//! |---|---|
//! | `client` | Synchronous REST [`client::VtaClient`] (depends on reqwest, ed25519) |
//! | `didcomm` | DIDComm transport types and message helpers |
//! | `session` | Session storage + auth state machine. Needs a persistence backend (`keyring` or `config-session`). |
//! | `keyring` | OS-native session storage via `keyring-core` (macOS Keychain / Windows Credential Manager / Linux Secret Service) |
//! | `config-session` | Plaintext on-disk session storage (dev / non-sensitive contexts only) |
//! | `azure-secrets` | Azure Key Vault session backend (requires `azure-secrets` env). Mutually exclusive with `keyring` at the SDK level. |
//! | `sealed-transfer` | HPKE-sealed bundle envelope (seal, open, armor, producer assertions) |
//! | `provision-integration` | VP-framed bootstrap requests + VC-issued admin authorization |
//! | `provision-client` | Higher-level orchestration over `provision-integration` (TUI-agnostic) |
//! | `attest-verify` | Full AWS Nitro attestation verification (cert chain to AWS root) |
//! | `vp` | DCQL credential selection + holder-bound OID4VP `vp_token` assembly ([`vp`]) |
//! | `integration` | Pull-bundle service-startup pattern (combines `client` + `session`) |
//! | `test-support` | In-memory mocks (`SessionBackend`, fixtures) for downstream tests |
//!
//! ## Module map
//!
//! * [`client`] — synchronous REST client + typed request/response shapes
//! * `agent_session` (feature `session`) — high-level personal-AI-agent runtime:
//! enroll + heartbeat + inbound-wake loop on top of the DIDComm client
//! * [`didcomm_session`] / [`didcomm_light`] — DIDComm transport
//! * [`session`] — credential storage, login, refresh-token rotation
//! * [`sealed_transfer`] — HPKE envelope (seal/open/armor/verify)
//! * [`provision_integration`] — VP/VC bootstrap flow + typestate verifier
//! * `integration` (feature-gated) — service-startup pull pattern with offline-cache resilience
//! * [`did_templates`] — render-side helpers for the VTA's template registry
//! * [`error`] — [`error::VtaError`] (typed, HTTP-aware, DIDComm-aware)
// Pure, dependency-light validators shared with clients so they apply the
// VTA's canonical context-path / identifier rules without mirroring them.
// `resolver` wraps `affinidi-did-resolver-cache-sdk`, which is only a
// dependency under the `didcomm` feature.
// `protocol` itself is always-on (its `services` submodule holds pure
// wire types + the shared `validate_service_url` validator that
// vta-service uses without ever talking to a `VtaClient`). The
// `impl VtaClient` blocks inside are individually `cfg(feature = "client")`-
// gated, so disabling the `client` feature still drops the network
// machinery — but consumers no longer need to flip the feature on
// just to import `protocol::services::validate_service_url`.
/// Canonical Trust-Task URLs for VTA operations. Mirrors
/// `did-hosting-common::did_hosting_tasks` for the webvh-service side.
// DCQL credential selection + holder-bound OID4VP `vp_token` assembly. The
// client-side counterpart to the `join-requests` / `credential-exchange`
// protocol types: turns a verifier's `presentation_definition` + held
// credentials into a signed `vp_token` the VTC's join verifier accepts.