scemadex_sdk/lib.rs
1//! # ScemaDEX SDK — an Agentic Liquidity Layer
2//!
3//! ScemaDEX is not "a DEX." It is an SDK in which **the routing intelligence
4//! itself is a metered, learning, accountable product.** Autonomous agents
5//! solve swap *intents*, **bond** their promises, sell their inferences, and
6//! trade learned experience with one another — all settled in stablecoins over
7//! the x402 payment rails.
8//!
9//! ## The four composing primitives
10//!
11//! - **A · Metered inference routing.** Every quote is produced by a learning
12//! policy and can be sold per-call via x402. The *quality of the decision* is
13//! the SKU. See [`policy`].
14//! - **B · Intent solving.** Callers express *what they want*
15//! ([`intent::Intent`] with an [`intent::Objective`]), not a path spec. The
16//! policy decides venue / split / timing.
17//! - **C · Signal & reputation oracle.** Reputation, pool scores and advice are
18//! monetized read endpoints. See [`oracle`].
19//! - **D · Conviction Routing (the defining pillar).** The policy escrows a
20//! slashable performance **bond** against its own promise. Meet the
21//! guarantee → reclaim the bond and collect the fee; miss it → the bond
22//! settles to the caller. This is what makes a paid black-box inference
23//! *trustworthy*. See [`bond`].
24//!
25//! ## The headline: a mesh of agents trading intelligence
26//!
27//! Compose A–D across many nodes and you get the revolutionary endgame: a
28//! [`mesh::PeerMarket`] where agents **sell bonded inferences and learned
29//! experience, and buy better ones from peers** — an economy of machine
30//! intelligence, not a swap widget. An agent earns USDC selling what it knows
31//! and spends USDC to learn faster.
32//!
33//! ## The adversarial layer: four primitives with no precedent
34//!
35//! - **E · The Counter-Market.** Any agent can stake *against* an open bond
36//! ([`counter::CounterMarket`]) — the first market that prices individual
37//! machine inferences. The gap between self-conviction and market-implied
38//! conviction (the *doubt spread*) is a brand-new policy feature.
39//! - **F · The Scar Market.** Slashed bonds are the only un-fakeable proof a
40//! decision cost real collateral; [`scar::certify_scar`] turns the trajectory
41//! behind a slash into sellable, verified negative training data.
42//! - **G · Experience royalties.** [`lineage::LineageLedger`] records which
43//! purchased experience trained which policy, and streams a royalty slice of
44//! every downstream fee back to the sellers — training data as a
45//! yield-bearing asset.
46//! - **H · Bonded teaching.** A teacher answers a student's most uncertain
47//! states per metered query, bonding its tuition against the student's
48//! *measured* improvement ([`teach::TeachingEngine`]) — distillation with a
49//! money-back guarantee.
50//!
51//! ## Architecture: lean core, injected power
52//!
53//! The published crate carries **no `solana-sdk` or bot dependency**. It defines
54//! the trait surface ([`policy::RoutePolicy`], [`bond::BondEngine`],
55//! [`venue::VenueExecutor`], [`oracle::SignalSource`], [`mesh::PeerMarket`]) plus
56//! reference implementations. Enabling the `scematica` feature injects the real
57//! Deep Q* agent, the Raydium/Orca/Meteora/Jupiter executors, and the x402
58//! facilitator from the bot workspace.
59//!
60//! ```
61//! use scemadex_sdk::reference_client;
62//! # async fn run() -> scemadex_sdk::Result<()> {
63//! let dex = reference_client();
64//! let intent = scemadex_sdk::demo_intent();
65//! let (solution, bond) = dex.quote(&intent).await?;
66//! assert!(solution.route.splits_valid());
67//! let _ = bond;
68//! # Ok(()) }
69//! ```
70#![cfg_attr(docsrs, feature(doc_cfg))]
71
72pub mod bond;
73pub mod client;
74pub mod coordinator;
75pub mod counter;
76pub mod error;
77pub mod forecast;
78pub mod insurance;
79pub mod intent;
80pub mod lineage;
81pub mod mesh;
82pub mod oracle;
83pub mod policy;
84pub mod primitives;
85pub mod promise;
86pub mod route;
87pub mod scar;
88pub mod settlement;
89pub mod teach;
90pub mod venue;
91pub mod zkbackend;
92pub mod zkbond;
93pub mod zkproof;
94
95/// A real zk-SNARK (arkworks Groth16 / BN254) proof-of-inference backend behind the
96/// [`zkproof::InferenceProof`] role. Requires the `snark` feature (heavy, default-off).
97#[cfg(feature = "snark")]
98#[cfg_attr(docsrs, doc(cfg(feature = "snark")))]
99pub mod zksnark;
100
101/// Concrete wiring of the SDK traits to the real Scematica Deep Q* agent. Only
102/// compiled with the `scematica` feature; the default published crate carries no
103/// such dependency.
104#[cfg(feature = "scematica")]
105#[cfg_attr(docsrs, doc(cfg(feature = "scematica")))]
106pub mod integration;
107
108/// Natural-language intent parsing + route/bond narration via an LLM. Requires
109/// the `ai` feature.
110#[cfg(feature = "ai")]
111#[cfg_attr(docsrs, doc(cfg(feature = "ai")))]
112pub mod ai;
113
114/// Networked [`PeerMarket`] client over an HTTP/JSON relay. Requires the `net`
115/// feature.
116#[cfg(feature = "net")]
117#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
118pub mod net;
119
120pub use bond::{
121 Bond, BondConfig, BondEngine, BondLedger, BondOutcome, EscrowBondEngine, NoBondEngine,
122};
123pub use client::ScemaDex;
124pub use coordinator::{DisputeCoordinator, SettlementReport};
125pub use counter::{Challenge, ChallengeSettlement, CounterMarket, CounterStats};
126pub use error::{Result, ScemaDexError};
127pub use forecast::ForecastVenue;
128pub use insurance::{InsurancePool, InsuranceTerms, Payout, Policy, PremiumConfig};
129pub use intent::{Constraints, Intent, Objective, Side};
130pub use lineage::{LineageEntry, LineageLedger, RoyaltySplit};
131pub use mesh::{ExperienceBatch, InferenceOffer, LocalPeerMarket, PeerMarket};
132pub use oracle::{Advice, PoolScore, Reputation, SignalSource};
133pub use policy::{Conviction, ReferenceRoutePolicy, RoutePolicy, Solution};
134pub use primitives::{Address, Amount, Usdc};
135pub use promise::{Measurement, Outcome, Promise};
136pub use route::{Fill, Route, RouteLeg, Venue};
137pub use scar::{certify_scar, LocalScarMarket, ScarMarket, ScarRecord};
138pub use settlement::{
139 BondState, Clock, FinalizeReason, ManualClock, SettlementConfig, SettlementMachine,
140 SlashDistribution, SlashRouting, SystemClock,
141};
142pub use teach::{
143 ReferenceTeacher, TeachAnswer, TeachReceipt, TeachTerms, Teacher, TeachingEngine,
144};
145pub use venue::{SimVenueExecutor, SwapInstructions, VenueExecutor};
146pub use zkbackend::{
147 prove as prove_inference, DenseLayer, LayerShape, OpenedCell, SpotCheckConfig, SpotCheckProof,
148 TracedMlp,
149};
150pub use zkproof::{InferenceProof, SNARK_SOUNDNESS};
151#[cfg(feature = "snark")]
152pub use zksnark::{ProvenModel, SnarkConfig, SnarkInferenceProof};
153pub use zkbond::{
154 CommittableModel, InferenceAttestation, InferenceProofSystem, ModelCommitment,
155 ReexecutionProofSystem, VerifiedBond,
156};
157
158/// Build a [`ScemaDex`] wired with the lean reference implementations. Useful for
159/// examples, tests, and consumers who haven't enabled the `scematica` feature.
160///
161/// Note the bond engine here is [`NoBondEngine`], which escrows a *zero* bond —
162/// it exercises the intent/route surface but does **not** demonstrate Conviction
163/// Routing (Primitive D). For the conviction-weighted, ledger-tracking bond
164/// engine, use [`conviction_client`].
165pub fn reference_client() -> ScemaDex<ReferenceRoutePolicy, NoBondEngine, SimVenueExecutor> {
166 ScemaDex::new(ReferenceRoutePolicy, NoBondEngine, SimVenueExecutor)
167}
168
169/// Build a [`ScemaDex`] whose bond engine is the conviction-weighted
170/// [`EscrowBondEngine`] — the lean reference wiring that actually exercises
171/// **Conviction Routing** (Primitive D) end-to-end, offline.
172///
173/// Unlike [`reference_client`], each [`ScemaDex::quote`] here escrows a real,
174/// conviction-sized bond with a guaranteed-minimum-output haircut, and
175/// [`ScemaDex::execute`] settles it (honored or slashed) into the engine's
176/// [`BondLedger`]. The only thing missing versus the `scematica` feature is the
177/// on-chain x402 USDC transfer; the settlement state machine is identical.
178///
179/// ```
180/// use scemadex_sdk::{conviction_client, demo_intent, BondOutcome};
181/// # async fn run() -> scemadex_sdk::Result<()> {
182/// let dex = conviction_client();
183/// let (solution, bond) = dex.quote(&demo_intent()).await?;
184/// assert!(bond.amount.0 > 0, "conviction-weighted bond is escrowed");
185/// assert!(bond.min_out_raw <= solution.route.expected_out.raw);
186/// let (_fill, outcome) = dex.execute(&demo_intent()).await?;
187/// assert_eq!(outcome, BondOutcome::Honored);
188/// # Ok(()) }
189/// ```
190pub fn conviction_client() -> ScemaDex<ReferenceRoutePolicy, EscrowBondEngine, SimVenueExecutor> {
191 ScemaDex::new(
192 ReferenceRoutePolicy,
193 EscrowBondEngine::with_defaults(),
194 SimVenueExecutor,
195 )
196}
197
198/// A canonical WSOL → USDC demo intent used by docs and tests.
199pub fn demo_intent() -> Intent {
200 Intent {
201 input_mint: Address::new("So11111111111111111111111111111111111111112")
202 .expect("valid WSOL mint"),
203 output_mint: Address::new("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")
204 .expect("valid USDC mint"),
205 amount_in: Amount::new(1_000_000_000, 9), // 1 SOL
206 side: Side::Sell,
207 objective: Objective::Price,
208 constraints: Constraints {
209 max_slippage_bps: 150,
210 deadline_unix: 0,
211 max_legs: Some(3),
212 },
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[tokio::test]
221 async fn quote_produces_valid_bonded_solution() {
222 let dex = reference_client();
223 let (solution, bond) = dex.quote(&demo_intent()).await.unwrap();
224 assert!(solution.route.splits_valid(), "splits must sum to 10_000 bps");
225 assert!((0.0..=1.0).contains(&solution.conviction.0));
226 assert_eq!(bond.intent_digest, solution.intent_digest);
227 }
228
229 #[tokio::test]
230 async fn execute_honors_bond_when_fill_meets_promise() {
231 let dex = reference_client();
232 let (fill, outcome) = dex.execute(&demo_intent()).await.unwrap();
233 assert!(fill.amount_out.raw > 0);
234 assert_eq!(outcome, BondOutcome::Honored);
235 }
236
237 #[test]
238 fn intent_digest_is_stable() {
239 let a = demo_intent().digest();
240 let b = demo_intent().digest();
241 assert_eq!(a, b);
242 }
243}