Core Concepts
These are the ideas that make zkde.fi work. If you've read The Primitive, you know the system is live on mainnet with portfolio rebalancing and portable reputation, with a full proof pipeline on Sepolia. This page explains the building blocks underneath both deployments.
Computation oracles
You're probably familiar with data oracles — Chainlink, Pyth, Pragma. They prove what happened: "ETH is trading at $3,200." That's useful, but it's not enough.
A computation oracle proves what the data means. "Given these 8 risk factors, this pool scored safe, computed by this specific model, on this specific input data." That's a much stronger statement — and it's the one that should gate capital decisions.
Data Oracle (Chainlink, Pyth) Computation Oracle (zkde.fi)
──────────────────────────── ────────────────────────────
"ETH price is $3,200" "This pool scored safe based on
8 risk factors, computed by
model 0x7a3f..., on input
snapshot 0xbe91..."zkde.fi's zkML circuits are computation oracles. They don't just relay data — they prove interpretation. And because the proof covers the model, the inputs, and the output, you can verify the entire reasoning chain on-chain.
Trust boundary separation
This is a design principle that a lot of "AI + crypto" projects get wrong. They treat the LLM as the source of truth. It's not. LLMs hallucinate, drift, and can be prompt-injected. You should never let an LLM directly control capital.
zkde.fi draws an explicit trust boundary:
| Layer | Trust model | What it does |
|---|---|---|
| LLM reasoning | Advisory — not proven, but auditable via llm_provider_hash | Chooses which skills to invoke, synthesizes context, explains recommendations |
| ML inference | Proven — every output is covered by a ZK circuit | Risk scoring, anomaly detection, yield forecasting — the actual quantitative signals |
| Execution | Verified on-chain | Smart contracts check proofs before capital moves |
The LLM decides what to think about. The ML models produce proven signals. The smart contracts enforce verified execution. Each layer has a different trust assumption, and they don't bleed into each other.
Verifiable AI agents
An autonomous agent whose critical decisions produce cryptographic proofs. The key word is "critical" — not everything needs a proof. The LLM layer reasons and selects strategies (that's advisory). The ML layer produces risk scores and classifications (that's proven). The smart contracts verify the proofs before allowing the agent to act (that's enforced).
flowchart TB A[AI Agent — LLM reasoning<br/><i>advisory, auditable</i>] B[Provable Skill Modules<br/><i>risk score, anomaly, yield</i>] C[ZK Proof Generation<br/><i>Groth16 via EZKL + Garaga</i>] D[Proof Registry — ERC-8004<br/><i>ObsqraFactRegistry on L3</i>] E[Smart Contract Verification<br/><i>on-chain gate check</i>] F[Execution<br/><i>capital moves</i>] A --> B --> C --> D --> E --> F
The result: an agent that can act autonomously but can't act arbitrarily. Every material decision leaves a verifiable trail.
Proof-gating
This is the enforcement mechanism. A smart contract will only execute an autonomous action if a valid proof is provided. The proof attests that the action satisfies the user's constraints — max position size, allowed protocols, slippage bounds, risk tier requirements.
Proofs are verified on-chain via Starknet's Integrity fact registry (SHARP). No proof, no execution. It's that simple.
The important nuance: not every route in the app enforces proof-gating identically. Some flows are gate-critical (proof required), some are advisory (proof generated but not blocking), and some are wallet-first (sign and execute, reconcile after). See flow-specific verification below.
Session keys
You don't want to sign every single transaction your agent makes. That defeats the purpose of automation. But you also don't want to give an agent unlimited access to your wallet. Session keys are the middle ground.
You sign once — "this agent can act for the next 24 hours, with a max position of 500 USDC, only on Ekubo pools, with slippage capped at 1%." The agent submits proof-gated transactions within those bounds. If it tries to exceed them, the contract rejects the action. You can revoke anytime.
The session key lifecycle is managed through the Session Keys surface: grant → confirm on-chain → agent operates → revoke when done.
Flow-specific verification
In the real world, not every action needs the same proof weight. Checking pool safety is not the same as deploying $10,000 into a liquidity position. The system recognizes this with three verification modes:
Gate-critical — proof is required before execution proceeds. Used for deployments, automated rebalancing, and high-value operations.
Advisory — a risk signal is generated and returned to the UI, but it doesn't block the action. Used for low-stakes screening where the user should see the data but makes their own call.
Wallet-first — the user signs and executes directly, and proof/reconciliation happens after. Used for manual swaps where latency matters more than pre-execution verification.
This isn't a compromise — it's a design choice. Forcing full dual-lane proofs on a $5 test swap would cost more in gas than the swap is worth. The system matches verification intensity to risk.
Selective disclosure
Here's where privacy gets interesting. You can prove a statement about your data without revealing the data itself:
- "My balance exceeds $10,000" — without revealing the exact amount
- "My portfolio's VaR is below 5%" — without revealing the positions
- "My 30-day return exceeded 12%" — without revealing the equity curve
- "I passed the risk screening" — without revealing the score
This is implemented via dedicated Circom circuits (BalanceAboveThreshold, TenureAboveThreshold) and the SelectiveDisclosure contract on Starknet Sepolia. The proof is registered on-chain; verifiers see the statement but not your history.
The applications go beyond personal privacy. A lending protocol could accept "this borrower is creditworthy" without seeing their portfolio. An insurance contract could verify "this position has been healthy for 90 days" without tracking the position. Privacy becomes a feature for counterparties, not just for the user.
Confidential transfers
Confidential transfers hide amounts on the public ledger. Instead of "Alice sent 100 USDC to the pool," the chain stores a commitment — a hash of (secret, nullifier, amount). Only the holder can spend or reveal it.
The flow: deposit creates a commitment and inserts it into a Merkle tree. Withdrawal reveals a nullifier (prevents double-spend), proves Merkle membership (proves you own a leaf), and produces a ZK proof of entitlement — all without linking the withdrawal to the deposit.
Optionally, a relayer submits the withdrawal transaction on your behalf, breaking the tx-graph link between depositor and withdrawer. The full pipeline is documented in Privacy Rails.