TrustCart is a three-layer system: an on-chain escrow contract holds order funds and enforces the marketplace lifecycle (with a protocol fee), an off-chain indexer stores human-readable item details, and a web app ties them together with wallet-signed transactions.
┌──────────────┐ wallet-signed tx ┌──────────────────────────┐
│ Web (Next) │ ─────────────────────► │ marketplace-escrow (Soroban)
│ │ ◄────── reads ────────│ • price escrow │
│ Wallets Kit │ │ • 1% protocol fee │
└──────┬───────┘ │ • lifecycle + events │
│ REST (titles, descriptions) └──────────────────────────┘
▼
┌──────────────┐
│ server (API) │ Express + Prisma + SQLite/Postgres
│ ListingMeta │ keyed by on-chain listing id
└──────────────┘
The contract stores only what must be trustless — the escrowed price, the
seller/buyer addresses, the lifecycle status, the fee config, and a short
metadata pointer. Rich item details (titles, descriptions, categories, images)
live in the indexer, referenced by the pointer.
Listed ──order──► Ordered ──deliver──► Delivered ──confirm──► Completed
│ │ (price − fee → seller, fee → collector)
│ cancel_listing │ refund_expired (past deadline)
▼ ▼
Cancelled Cancelled (price → buyer)
- order moves the full
priceinto escrow. - confirm is the only path that pays the seller; it deducts
fee_bpsand sends the fee to the configured collector. - cancel_listing (Listed) and refund_expired (Ordered, past deadline) protect the seller and buyer respectively. No path lets the contract keep funds.
The fee (basis points) is set once at construction and capped at 10%. The live
deployment uses 100 bps (1%). fee = price * fee_bps / 10000, computed on confirm.
- No custodial admin: funds only move to seller (confirm) or buyer (refund).
- Authorization: seller for create/deliver/cancel, buyer for order/confirm/refund.
- State-machine guards reject out-of-order calls (
InvalidStatus). - Inputs validated; storage TTL-bumped so live listings are not archived.