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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
// Copyright 2026 Exochain Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0
//! # EXOCHAIN SDK — Rust
//!
//! Ergonomic Rust API for the **EXOCHAIN constitutional governance fabric** — a
//! substrate for AI agents and data sovereignty built around decentralized
//! identifiers (DIDs), scoped consent (bailments), authority-chain delegation,
//! quorum-based governance, and a constitutional kernel that enforces policy
//! *before* action rather than auditing it after.
//!
//! This crate re-exports and wraps the underlying `exo-*` workspace crates
//! behind a single, developer-friendly surface so that applications built on
//! EXOCHAIN can depend on one crate and use one coherent API. Each domain lives
//! in its own module:
//!
//! - [`identity`] — DID-backed Ed25519 identities with sign/verify.
//! - [`consent`] — scoped, time-bounded bailments (consent tokens).
//! - [`governance`] — decisions, voting, quorum checks.
//! - [`authority`] — validated delegation chains.
//! - [`kernel`] — the Constitutional Governance Runtime (CGR) kernel.
//! - [`crypto`] — hash / sign / verify primitives (BLAKE3 + Ed25519).
//! - [`dagdb`] — DAG DB DTO re-exports and REST request helpers.
//! - [`error`] — the single [`error::ExoError`] type returned by fallible ops.
//!
//! ## Why use this SDK
//!
//! EXOCHAIN turns policy into a *precondition* of action. Instead of shipping
//! agents that do things and asking an auditor to catch violations, you
//! express identity, consent, and delegation as first-class cryptographic
//! objects and ask the kernel whether an action is permitted. If the
//! [`kernel::ConstitutionalKernel`] denies an action, the action never runs.
//!
//! This SDK gives you:
//!
//! - Deterministic, content-addressed IDs for every object (bailments,
//! decisions, chains) so two parties independently building the same object
//! get the same ID.
//! - Builder APIs that validate on `build()` so invalid states are not
//! representable downstream.
//! - Pure types (no I/O) suitable for offline governance, test vectors, and
//! cross-language interop with the TypeScript and Python SDKs.
//!
//! ## End-to-end example
//!
//! The canonical lifecycle: two identities negotiate a bailment, propose a
//! decision, reach quorum, build a delegation chain, and submit an action to
//! the kernel for adjudication.
//!
//! ```
//! use exochain_sdk::prelude::*;
//! use exochain_sdk::governance::VoteChoice;
//!
//! // 1. Create identities for alice and bob.
//! let alice = Identity::generate("alice");
//! let bob = Identity::generate("bob");
//! assert!(alice.did().as_str().starts_with("did:exo:"));
//! assert_ne!(alice.did(), bob.did());
//!
//! // 2. Alice proposes a scoped bailment to bob.
//! let proposal = BailmentBuilder::new(alice.did().clone(), bob.did().clone())
//! .scope("data:medical")
//! .duration_hours(24)
//! .build()?;
//! assert_eq!(proposal.scope, "data:medical");
//! assert_eq!(proposal.proposal_id.len(), 16);
//!
//! // 3. Alice proposes a decision; bob and a third voter approve.
//! let carol = Identity::generate("carol");
//! let mut decision = DecisionBuilder::new(
//! "Ratify bailment",
//! "Allow bob to read medical records for 24h",
//! alice.did().clone(),
//! )
//! .build()?;
//! decision.cast_vote(Vote::new(bob.did().clone(), VoteChoice::Approve))?;
//! decision.cast_vote(Vote::new(carol.did().clone(), VoteChoice::Approve))?;
//! let quorum = decision.check_quorum(2);
//! assert!(quorum.met);
//! assert_eq!(quorum.approvals, 2);
//!
//! // 4. Build an authority chain: root -> alice -> bob.
//! let root = Identity::generate("root");
//! let chain = AuthorityChainBuilder::new()
//! .add_link(root.did().clone(), alice.did().clone(), vec!["delegate".into()])
//! .add_link(alice.did().clone(), bob.did().clone(), vec!["read".into()])
//! .build(bob.did())?;
//! assert_eq!(chain.depth, 2);
//! assert_eq!(&chain.terminal, bob.did());
//!
//! // 5. Ask the kernel whether bob may perform the action.
//! // The SDK kernel requires caller-supplied authority signing material.
//! let kernel = ConstitutionalKernel::with_authority_identity(root);
//! let verdict = kernel.adjudicate(bob.did(), "data:medical:read");
//! assert!(verdict.is_permitted(), "expected Permitted, got {verdict:?}");
//! # Ok::<(), exochain_sdk::error::ExoError>(())
//! ```
//!
//! ## Prelude
//!
//! Most applications want the common builders, [`Identity`](identity::Identity),
//! the error type, and the kernel facade. Import the [`prelude`]:
//!
//! ```
//! use exochain_sdk::prelude::*;
//!
//! let id = Identity::generate("agent");
//! let sig = id.sign(b"payload");
//! assert!(id.verify(b"payload", &sig));
//! ```
//!
//! ## Error handling
//!
//! All fallible operations return [`error::ExoResult<T>`], an alias for
//! `Result<T, ExoError>`. Each [`error::ExoError`] variant narrows the failure
//! to a subsystem (consent, governance, authority, kernel, crypto, serialization)
//! so callers can pattern-match without parsing strings.
//!
//! ```
//! use exochain_sdk::prelude::*;
//! use exochain_sdk::error::ExoError;
//! # use exo_core::Did;
//!
//! let alice = Did::new("did:exo:alice").expect("valid");
//! let bob = Did::new("did:exo:bob").expect("valid");
//!
//! // Forgetting to set `scope` produces a Consent error:
//! let err = BailmentBuilder::new(alice, bob)
//! .duration_hours(1)
//! .build()
//! .unwrap_err();
//! assert!(matches!(err, ExoError::Consent(_)));
//! ```
//!
//! ## Cross-language notes
//!
//! The SDK distinguishes local deterministic IDs from canonical fabric IDs.
//! [`identity::Identity::generate`] and [`identity::Identity::from_keypair`]
//! derive local Rust SDK DIDs from `BLAKE3(public_key)[..8]`. Other language
//! SDKs may use different local-only derivation primitives for zero-dependency
//! client operation.
//!
//! Applications that need canonical DIDs across languages should resolve the
//! DID from the fabric, then construct the local signing handle with
//! [`identity::Identity::from_resolved_keypair`]. That path preserves the
//! fabric DID and verifies that the supplied secret key matches the supplied
//! public key before constructing the identity.
/// Fabric protocol version this SDK speaks (A-066).
///
/// Applications may probe a target gateway on init and warn when the
/// server reports a different major/minor so users can distinguish
/// protocol skew from transport errors. All three SDKs (Rust, TypeScript,
/// Python) expose a matching `PROTOCOL_VERSION` constant.
pub const PROTOCOL_VERSION: &str = "0.2.0-beta";
/// Prelude — the symbols most applications want.
///
/// ```
/// use exochain_sdk::prelude::*;
///
/// let id = Identity::generate("agent");
/// let sig = id.sign(b"hello");
/// assert!(id.verify(b"hello", &sig));
/// ```