Skip to main content

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}