Production-ready Soroban smart contract for peer-to-peer marketplace escrow on Stellar blockchain, with a comprehensive event indexing service.
StellarEscrow is a decentralized escrow system that enables secure peer-to-peer trades using USDC stablecoin. The platform connects buyers and sellers with optional arbitrators who can resolve disputes, with the smart contract managing escrow, fee collection, and settlement.
The project includes:
- Smart Contract: Soroban contract written in Rust
- Event Indexer: High-performance indexing service for real-time event monitoring and querying
- Escrow-Based Trading: Secure USDC deposits held in contract until trade completion
- Arbitrator Network: Registered arbitrators handle dispute resolution
- Automated Fee Collection: Platform fees calculated and accumulated automatically
- Multi-Status Tracking: Trades tracked through Created, Funded, Completed, Disputed, and Cancelled states
- Authorization Security: Role-based access control for all operations
- Event Emission: Comprehensive event logging for off-chain monitoring
- Dispute Resolution: Arbitrators can release funds to buyer or seller
- Cancellation Support: Sellers can cancel unfunded trades
- Admin Controls: Platform fee management and fee withdrawal capabilities
- Event Indexing: Real-time event monitoring, storage, and querying
- WebSocket Streaming: Live event updates for connected clients
- REST API: Efficient event querying and replay functionality
Core Components
lib.rs: Main contract implementation with all public functionstypes.rs: Data structures (Trade, TradeStatus, DisputeResolution)storage.rs: Persistent and instance storage managementerrors.rs: Custom error types for contract operationsevents.rs: Event emission functions for monitoring
Core Components
main.rs: Service entry point and server setupconfig.rs: Configuration managementdatabase.rs: PostgreSQL database operationsevent_monitor.rs: Stellar network event monitoringhandlers.rs: REST API endpoint handlerswebsocket.rs: WebSocket connection managementmodels.rs: Data structures and typeserror.rs: Error handling
- Rust 1.70+
- PostgreSQL 13+
- Soroban CLI (for contract deployment)
- Stellar account with XLM for fees
cd contract
cargo build --target wasm32-unknown-unknown --release# Using Soroban CLI
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/stellar_escrow_contract.wasm \
--source <your-secret-key> \
--network testnetcd indexer
# Install sqlx CLI
cargo install sqlx-cli
# Setup database
createdb stellar_escrow
sqlx migrate run
# Configure
cp config.toml config.local.toml
# Edit config.local.toml with your contract ID and database URLcargo run -- --config config.local.tomlinitialize(admin, usdc_token, fee_bps)- One-time contract initializationregister_arbitrator(arbitrator)- Add arbitrator to approved list (admin only)remove_arbitrator_fn(arbitrator)- Remove arbitrator from approved list (admin only)update_fee(fee_bps)- Update platform fee percentage (admin only)withdraw_fees(to)- Withdraw accumulated fees (admin only)
create_trade(seller, buyer, amount, arbitrator)- Create new trade (seller auth required)fund_trade(trade_id)- Buyer funds the escrow (buyer auth required)complete_trade(trade_id)- Seller confirms delivery (seller auth required)confirm_receipt(trade_id)- Buyer confirms receipt and releases funds (buyer auth required)raise_dispute(trade_id)- Either party raises dispute (buyer/seller auth required)resolve_dispute(trade_id, resolution)- Arbitrator resolves dispute (arbitrator auth required)cancel_trade(trade_id)- Cancel unfunded trade (seller auth required)
get_trade(trade_id)- Retrieve trade detailsget_accumulated_fees()- Check total platform fees collectedis_arbitrator_registered(arbitrator)- Verify arbitrator registration statusget_platform_fee_bps()- Get current fee percentage
GET /health
GET /events?limit=50&event_type=trade_created&trade_id=123
GET /events/{uuid}
GET /events/trade/{trade_id}
POST /events/replay
{
"from_ledger": 123456,
"to_ledger": 123500
}
Connect to /ws for real-time event updates:
const ws = new WebSocket('ws://localhost:3000/ws');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('New event:', data);
};- Authorization Checks: All state-changing operations require proper authorization
- Status Validation: Prevents invalid state transitions
- Overflow Protection: Safe math operations with overflow checks
- Arbitrator Verification: Only registered arbitrators can resolve disputes
- Ownership Validation: Only trade parties can perform specific actions
cd contract
cargo testcd indexer
cargo testThe contract includes comprehensive tests covering: ✅ Initialization and configuration ✅ Arbitrator registration and removal ✅ Fee updates and validation ✅ Trade creation and funding ✅ Trade completion flow ✅ Dispute raising and resolution ✅ Cancellation logic ✅ Fee withdrawal by admin ✅ Authorization enforcement ✅ Error conditions ✅ Event emission verification ✅ Multiple trades handling ✅ Fee calculation accuracy
- Build optimized WASM:
cd contract
cargo build --target wasm32-unknown-unknown --release- Deploy using Soroban CLI or your preferred deployment tool
- Build release binary:
cd indexer
cargo build --release- Configure production settings in
config.toml - Run migrations on production database
- Start the service
StellarEscrow/
├── contract/ # Soroban smart contract
│ ├── src/
│ │ ├── lib.rs # Main contract logic
│ │ ├── types.rs # Data structures
│ │ ├── storage.rs # Storage operations
│ │ ├── errors.rs # Error types
│ │ └── events.rs # Event emission
│ └── Cargo.toml
├── indexer/ # Event indexing service
│ ├── src/
│ │ ├── main.rs # Service entry point
│ │ ├── config.rs # Configuration
│ │ ├── database.rs # DB operations
│ │ ├── event_monitor.rs # Stellar monitoring
│ │ ├── handlers.rs # HTTP handlers
│ │ ├── websocket.rs # WS connections
│ │ ├── models.rs # Data models
│ │ └── error.rs # Error handling
│ ├── migrations/ # DB migrations
│ ├── config.toml # Default config
│ └── Cargo.toml
└── Cargo.toml # Workspace config
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
This project is licensed under the MIT License.
initialize(admin, usdc_token, fee_bps)- One-time contract initializationregister_arbitrator(arbitrator)- Add arbitrator to approved list (admin only)remove_arbitrator_fn(arbitrator)- Remove arbitrator from approved list (admin only)update_fee(fee_bps)- Update platform fee percentage (admin only)withdraw_fees(to)- Withdraw accumulated fees (admin only)
create_trade(seller, buyer, amount, arbitrator)- Create new trade (seller auth required)fund_trade(trade_id)- Buyer funds the escrow (buyer auth required)complete_trade(trade_id)- Seller confirms delivery (seller auth required)confirm_receipt(trade_id)- Buyer confirms receipt and releases funds (buyer auth required)raise_dispute(trade_id)- Either party raises dispute (buyer/seller auth required)resolve_dispute(trade_id, resolution)- Arbitrator resolves dispute (arbitrator auth required)cancel_trade(trade_id)- Cancel unfunded trade (seller auth required)
get_trade(trade_id)- Retrieve trade detailsget_accumulated_fees()- Check total platform fees collectedis_arbitrator_registered(arbitrator)- Verify arbitrator registration statusget_platform_fee_bps()- Get current fee percentage
- Authorization Checks: All state-changing operations require proper authorization
- Status Validation: Prevents invalid state transitions
- Overflow Protection: Safe math operations with overflow checks
- Arbitrator Verification: Only registered arbitrators can resolve disputes
- Ownership Validation: Only trade parties can perform specific actions
The contract includes comprehensive tests covering:
✅ Initialization and configuration
✅ Arbitrator registration and removal
✅ Fee updates and validation
✅ Trade creation and funding
✅ Trade completion flow
✅ Dispute raising and resolution
✅ Cancellation logic
✅ Fee withdrawal by admin
✅ Authorization enforcement
✅ Error conditions
✅ Event emission verification
✅ Multiple trades handling
✅ Fee calculation accuracy
Run tests with:
cargo testcd StellarEscrow
cargo build --target wasm32-unknown-unknown --release
soroban contract optimize --wasm target/wasm32-unknown-unknown/release/stellar_escrow.wasmsoroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/stellar_escrow.optimized.wasm \
--source deployer \
--network testnetsoroban contract invoke \
--id <CONTRACT_ID> \
--source deployer \
--network testnet \
-- \
initialize \
--admin <ADMIN_ADDRESS> \
--usdc_token <USDC_TOKEN_ADDRESS> \
--fee_bps 100See DEPLOYMENT.md for complete deployment instructions.
- Deploy contract
- Initialize with admin address, USDC token, and fee percentage
- Register trusted arbitrators
- Seller creates trade with buyer address, amount, and optional arbitrator
- Trade ID returned for tracking
- Buyer approves USDC transfer to contract
- Buyer calls
fund_tradewith trade ID - Contract transfers USDC from buyer to escrow
- Seller delivers goods/services off-chain
- Seller calls
complete_trade - Buyer calls
confirm_receipt - Contract transfers USDC minus fee to seller
- Fee added to accumulated platform fees
- Either party calls
raise_dispute - Arbitrator investigates off-chain
- Arbitrator calls
resolve_disputewith resolution (ReleaseToBuyer or ReleaseToSeller) - Contract transfers funds accordingly minus arbitration fee
- Admin monitors accumulated fees
- Admin calls
withdraw_feesto collect platform revenue
| Code | Error | Description |
|---|---|---|
| 1 | AlreadyInitialized | Contract already initialized |
| 2 | NotInitialized | Contract not initialized |
| 3 | InvalidAmount | Amount must be greater than 0 |
| 4 | InvalidFeeBps | Fee must be between 0-10000 bps |
| 5 | ArbitratorNotRegistered | Arbitrator not in approved list |
| 6 | TradeNotFound | Trade ID does not exist |
| 7 | InvalidStatus | Operation not allowed in current status |
| 8 | Overflow | Arithmetic overflow detected |
| 9 | NoFeesToWithdraw | No accumulated fees available |
| 10 | Unauthorized | Caller not authorized for this operation |
The contract emits events for monitoring:
created- New trade createdfunded- Buyer funded escrowcomplete- Seller marked as deliveredconfirm- Buyer confirmed receipt and settleddispute- Dispute initiatedresolved- Arbitrator resolved disputecancel- Trade cancelledarb_reg- Arbitrator registeredarb_rem- Arbitrator removedfee_upd- Platform fee updatedfees_out- Fees withdrawn by admin
soroban-sdk = "21.7.0"- Latest Soroban SDK
- ARCHITECTURE.md - Technical architecture and design decisions
- DEPLOYMENT.md - Complete deployment guide
- CONTRIBUTING.md - Contribution guidelines
MIT
For issues and questions:
- GitHub Issues: Create an issue
- Stellar Discord: https://discord.gg/stellar
- Soroban Docs: https://soroban.stellar.org
Contributions welcome! Please ensure:
- All tests pass:
cargo test - Code follows Rust best practices
- New features include tests
- Documentation is updated
See CONTRIBUTING.md for detailed guidelines.
- Multi-currency support
- Batch trade processing
- Arbitrator reputation system
- Time-locked escrow options
- Partial release mechanism
- Multi-signature arbitration
- Integration with decentralized identity
StellarEscrow is a Soroban smart contract built in Rust that enables secure, escrow-based peer-to-peer trading on the Stellar network.
This project demonstrates production-ready patterns for escrow systems, dispute resolution, and fee management on Stellar blockchain.