Architecture
Repo layout
contracts/ Soroban contracts — score_registry, credit_line, lending_vault, revenue_math
backend/ underwriting engine (TS/Fastify) — indexer, independence, zktls, scoring, signer, API
packages/ @trustline-agents/agent-sdk — the agent-facing SDK
frontend/ Next.js dashboards (borrower + lender) + landing
agents/ the live agent fleet (Scout, DataCo, Analyst, Reviewer) — real, working examples
spikes/ validated de-risking spikes (x402 payer, Reclaim zkTLS)
docs/ this documentation
Data flow, end to end
Rendering diagram…
- Earn — an agent gets paid in USDC over x402. The backend indexer reads
the resulting SAC transfer events as revenue (
backend/src/indexer/). - Underwrite —
backend/src/underwrite.tsorchestrates the whole pass: index revenue → run the independence/anti-Sybil check (scoring/independence.ts) → optionally verify an off-chain zkTLS proof (zktls/) → compute a score (scoring/index.ts) → sign it (signer/). - Publish — the signed score is submitted to the on-chain
score_registrycontract. - Price —
credit_linereads the published score and derives a tier, credit limit, and APR via the sharedrevenue_mathlibrary (same math on both the contract side and the backend's scoring side, kept in sync deliberately). - Fund — a lender deposits USDC into that specific agent's isolated
vault in
lending_vault— a separate accounting bucket per agent, so one agent's default never touches another lender's exposure. - Borrow / repay — the agent (via the SDK, its own Stellar key) draws against its line and repays as it earns. Repaid interest funds a first-loss reserve and lender yield; a missed repayment triggers the on-chain default lifecycle.
The three moving systems
1. Contracts (Soroban, contracts/)
score_registry— stores each agent's latest signed score. Its history is preserved across every redeploy of the other contracts (see Contract addresses for why this ID never changes whilecredit_line/lending_vaulthave been redeployed as features shipped).credit_line— pure pricing logic: score in,{tier, limit, apr}out, viarevenue_math.lending_vault— the actual money contract: isolated per-agent accounting, shares-based lender positions, a first-loss reserve, dynamic utilization-based APR, on-chain credit ramps, and a permissionless default lifecycle (mark_default) — see How the credit engine works §4 for the full mechanics.revenue_math— the shared tier/limit/APR/risk math library, the single source of truth both the contract and the backend's scoring code read from.
2. Backend (Fastify/TypeScript, backend/)
The trusted underwriter in v1 (see Roadmap for the decentralization path). Owns:
- The indexer — reads on-chain USDC SAC transfer events (on-demand RPC, a persistent Postgres-backed payment graph for full history, and a Horizon deep-history fallback for revenue that predates both).
- The independence engine (
scoring/independence.ts) — the anti-Sybil moat; see Sybil / independence model. - The zkTLS module (
zktls/) — generates and verifies Reclaim proofs of off-chain revenue against a deployed Soroban verifier contract. - The signer (
signer/) — holds the one key that publishes scores on-chain today. - The REST API (
api/server.ts) — everything the frontend and SDK call:/agent/:address/underwrite,/agent/:address,/agents,/config,/waitlist,/faucet, and more.
3. Agent SDK (packages/agent-sdk/)
The interface an agent actually uses — register, onboard, underwrite,
creditLine, vaultState, borrow, repay, deposit, payWithCredit. The
agent holds its own Stellar key; on-chain writes are signed by that key, not
by TrustLine. See the full SDK reference.
Frontend (frontend/, Next.js)
Public-facing dashboards and the live demo: /underwrite (paste any address,
watch a live verdict), /demo (honest agent vs. a Sybil side-by-side),
/borrower and /lender (the actual credit/deposit flows against connected
wallets), and the landing page.