Human-readable Soroban contract events on Stellar. Instead of raw XDR bytes, users see: "Address GABCβ¦ swapped 100 USDC β 98.7 XLM on StellarSwap at ledger #4521983."
Stellar block explorers have excellent support for classic assets but poor support for Soroban smart contracts. When a user calls swap on a DEX, explorers show raw XDR bytes β unreadable to anyone. This "black box" experience dampens DeFi, NFT, and web3 growth on Stellar.
Soroban Smart Block Explorer decodes contract calls on the fly using an ABI-like metadata registry, turning opaque XDR into plain English.
| Before | After |
|---|---|
AAAAA9hZ...[Raw XDR]...== |
Address GABCβ¦ swapped 100 USDC β 98.7 XLM on StellarSwap at ledger #4521983 |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Soroban RPC / Horizon β
β (getEvents, getTransaction) β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β poll every 5 s
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β Indexer (Node.js) β
β β’ Fetches raw events via SorobanRpc.getEvents() β
β β’ Decodes XDR β human text using ABI registry β
β β’ Stores decoded events in PostgreSQL β
β β’ Exposes REST API on :3001 β
ββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β REST /api/*
ββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββ
β React Frontend (Vite + TanStack Query) β
β β’ Home: paginated event feed + function filter β
β β’ /contract/:id β ABI metadata + event history β
β β’ /wallet/:address β wallet transaction history β
β β’ /event/:seq β full decoded event detail β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β²
ββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββ
β Soroban Contract (Rust) β
β β’ ContractRegistry β stores ABI-like metadata β
β β’ EventDecoder β persists decoded events on-chain β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Rust +
wasm32-unknown-unknowntarget - Stellar CLI
- Node.js β₯ 20
- PostgreSQL
git clone https://github.com/your-org/Soroban-Smart-Block
cd Soroban-Smart-Block
cp .env.example .env
# Edit .env with your RPC URL and DATABASE_URLmake build # compile to WASM
make test # run unit tests
make deploy # deploy to testnet, prints CONTRACT_IDCopy the printed contract ID into .env as EXPLORER_CONTRACT_ID.
make indexer-install
make indexermake frontend-install
make frontend
# Open http://localhost:5173Or run both together:
make install
make dev| Function | Description |
|---|---|
init(admin) |
Initialise contract with admin address |
register_contract(caller, contract_id, meta) |
Register ABI metadata for a contract |
update_contract(caller, contract_id, meta) |
Update metadata (admin or registrant) |
get_contract(contract_id) |
Fetch contract metadata |
submit_event(...) |
Persist a decoded event (admin only) |
get_event(seq) |
Fetch event by sequence number |
get_events(from, limit) |
Paginated event list |
event_count() |
Total stored events |
| Endpoint | Description |
|---|---|
GET /api/events?contract=&fn=&page= |
Paginated event list |
GET /api/events/:seq |
Single event |
GET /api/contracts/:id |
Contract ABI metadata |
POST /api/contracts |
Register contract metadata |
GET /api/wallet/:address |
Wallet event history |
The decoder recognises SEP-41 token events (transfer, mint, burn) and formats amounts with the correct symbol, alongside classic Stellar assets fetched from Horizon.
- Confirmed gap: StellarExpert and Stellar.expert (the two primary Stellar explorers) show raw XDR bytes for all Soroban contract events as of May 2026 β no human-readable decoding exists.
- Community signal: Developers in
#soroban-devon Stellar Discord regularly ask how to inspect their own contract events in a readable form. No existing tool answers this. - Comparable success: Etherscan's ABI decoder is one of its most-used features. Solscan built the same for Solana and became the primary explorer for Solana DeFi. Stellar has no equivalent for Soroban.
- Target users: Soroban dApp developers, DeFi users, NFT traders, auditors β anyone who needs to understand what is happening on-chain.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Stellar Network β
β βββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ β
β β Soroban RPC β β Horizon API β β
β β getEvents() β β Classic asset metadata β β
β β getTransaction() β β (asset codes, issuers) β β
β ββββββββββββ¬βββββββββββ ββββββββββββββββ¬ββββββββββββββββ β
βββββββββββββββΌβββββββββββββββββββββββββββββΌββββββββββββββββββ
β poll every 5 s β on-demand
βββββββββββββββΌβββββββββββββββββββββββββββββΌββββββββββββββββββ
β Indexer (Node.js) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β decoder.js β β
β β scValToNative(topic/data) β match ABI registry β β
β β β "Address GAβ¦ swapped 100 USDC β 98.7 XLM" β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ β
β β db.js (PostgreSQL) β β
β β events table Β· contracts table β β
β β indexes on contract_id, function, ledger β β
β ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ β
β ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ β
β β api.js (Express REST) β β
β β GET /api/events Β· GET /api/contracts/:id β β
β β GET /api/wallet/:address Β· POST /api/contracts β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββ
β REST /api/*
βββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββ
β React Frontend (Vite + TanStack Query) β
β / β paginated feed, function filter β
β /contract/:id β ABI metadata + event history β
β /wallet/:addr β all events for a Stellar address β
β /event/:seq β full decoded event detail β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β²
βββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββ
β Soroban Contract (Rust) β on-chain source of truth β
β ContractRegistry register_contract / get_contract β
β EventDecoder submit_event / get_events / event_count β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Data flow for a decoded event:
- Soroban contract emits an event (e.g.,
swapon StellarSwap) - Indexer fetches it via
SorobanRpc.getEvents() decoder.jscallsscValToNative()on topics/data, looks up registered ABI- Produces human-readable string β stored in PostgreSQL + submitted to on-chain contract
- Frontend queries REST API and displays the decoded event
| Document | Description |
|---|---|
| docs/ROADMAP.md | 3-tranche milestone plan (MVP β Testnet β Mainnet) |
| docs/BUDGET.md | Engineering hours and cost breakdown per tranche |
| docs/TEAM.md | Team bios and qualification evidence |
| docs/MANIFEST.md | Full project manifest |
| stellar.toml | SEP-1 compliant network info |
A full developer documentation site lives under docs/:
- Documentation home β guides, reference, and search.
- Getting started and other step-by-step guides.
- API playground (Swagger UI) and an interactive try-it console with curl / JS / Python / Rust snippets.
- OpenAPI spec and API changelog.
- Interactive architecture explorer.
The site is published to GitHub Pages by
.github/workflows/docs.yml, which also generates
JSDoc (indexer) and Rustdoc (contract) reference.
See CONTRIBUTING.md for the workflow, commit conventions, and PR checklist. Please open an issue first for large changes.