The Graph for Soroban โ index, query, and subscribe to smart contract events.
SoroScan is a developer-focused indexing service for Soroban smart contract events on the Stellar blockchain. It combines a Rust-based Soroban smart contract with a Django backend to provide real-time event ingestion, GraphQL/REST APIs, and webhook notifications.
Built for developers who need reliable event data without running their own infrastructure.
- ๐ฆ Soroban Native: Rust smart contract with admin-controlled indexer whitelist and standardized event emission.
- ๐ Django Backend: Production-ready REST API with Django Rest Framework and PostgreSQL storage.
- ๐ GraphQL Playground: Flexible event queries with Strawberry GraphQL โ filter by contract, event type, ledger, or time range.
- ๐ Webhook Subscriptions: Real-time event notifications with HMAC-signed payloads via Celery + Redis.
- โก Horizon Integration: Stream ledger events directly from Stellar's Horizon API using
stellar-sdk.
SoroScan follows a hybrid on-chain/off-chain pattern for maximum flexibility and reliability.
โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ Soroban Contract โโโโโโถโ Django Backend โโโโโโถโ PostgreSQL โ
โ (Event Emitter) โ โ (Ingestion Layer) โ โ (Storage) โ
โโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
REST API GraphQL API Webhooks
- Smart Contract: Emits structured
EventRecordevents with admin-controlled access. - Ingestion Layer: Streams events from Horizon/Soroban RPC and persists to PostgreSQL.
- Query Layer: Exposes data via REST, GraphQL, and push-based webhooks.
soroscan/
โโโ soroban-contracts/ # Rust smart contracts
โ โโโ soroscan_core/ # Core indexing contract
โ โโโ src/lib.rs # Contract logic & event emission
โโโ django-backend/ # Python backend API
โโโ soroscan/
โโโ ingest/ # Ingestion & API module
โโโ models.py # TrackedContract, ContractEvent, WebhookSubscription
โโโ views.py # REST API viewsets
โโโ schema.py # GraphQL schema (Strawberry)
โโโ stellar_client.py # Soroban RPC interaction
โโโ tasks.py # Celery webhook dispatcher
Get SoroScan running locally in under 5 minutes with Docker Compose.
- Docker and Docker Compose
- (Optional) Rust + Soroban CLI for contract development
# 1. Clone the repository
git clone https://github.com/SoroScan/soroscan.git
cd soroscan
# 2. Copy environment file and configure if needed
cp django-backend/.env.example django-backend/.env
# 3. Start all services (PostgreSQL, Redis, Django, Celery)
docker-compose up --build
# The backend will be available at:
# - REST API: http://localhost:8000/api/events/
# - GraphQL Playground: http://localhost:8000/graphql/
# - Django Admin: http://localhost:8000/admin/That's it! The stack auto-runs migrations on startup and supports live code reloading.
Port Conflicts? Edit django-backend/.env and uncomment the port override variables.
Click to expand manual installation steps
- Python 3.11+
- PostgreSQL 15+
- Redis 7+
cd django-backend
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Edit .env and set DATABASE_URL to your local PostgreSQL instance
# Run migrations and start server
python manage.py migrate
python manage.py runservercd django-backend
source venv/bin/activate
celery -A soroscan worker --loglevel=infocd django-backend
source venv/bin/activate
celery -A soroscan beat --loglevel=infocd soroban-contracts/soroscan_core
cargo build --target wasm32-unknown-unknown --release
# Deploy to testnet
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/soroscan_core.wasm \
--network testnet
# Update SOROSCAN_CONTRACT_ID in django-backend/.envSoroScan includes production-ready Kubernetes manifests for self-hosted deployments.
- Kubernetes cluster (1.19+)
- kubectl configured
- PostgreSQL database (managed or self-hosted)
- Redis instance (managed or self-hosted)
- Container registry with SoroScan image
- (Optional) External Secrets Operator for secret management
Build the backend image with gunicorn:
cd django-backend
# Create Dockerfile if not exists
cat > Dockerfile <<EOF
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Create non-root user
RUN useradd -u 1000 -m appuser && chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
# Default command uses gunicorn (override in k8s manifests for workers)
CMD ["gunicorn", "soroscan.wsgi:application", "--bind", "0.0.0.0:8000"]
EOF
# Build and push
docker build -t your-registry/soroscan-backend:v1.0.0 .
docker push your-registry/soroscan-backend:v1.0.0Create secrets using kubectl or External Secrets Operator:
kubectl create secret generic soroscan-secrets \
--from-literal=SECRET_KEY='your-django-secret-key' \
--from-literal=DATABASE_URL='postgresql://user:pass@host:5432/dbname' \
--from-literal=REDIS_URL='redis://redis:6379/0' \
--from-literal=SOROSCAN_CONTRACT_ID='CXXXXXXXX' \
--from-literal=INDEXER_SECRET_KEY='your-indexer-key' \
-n soroscanOr use External Secrets Operator (see k8s/secret-reference.yaml).
Edit k8s/configmap.yaml:
- Set
ALLOWED_HOSTSto your domain - Configure
SOROBAN_RPC_URLandSTELLAR_NETWORK_PASSPHRASEfor your network - Set
CORS_ALLOWED_ORIGINSif needed
Edit k8s/backend-deployment.yaml, k8s/worker-deployment.yaml, k8s/beat-cronjob.yaml:
- Replace
soroscan/backend:v1.0.0with your image
Edit k8s/ingress.yaml:
- Set your domain in
hostandtlssections - Configure ingress class and annotations for your ingress controller
# Apply all manifests
kubectl apply -f k8s/
# Verify deployment
kubectl get pods -n soroscan
kubectl get svc -n soroscan
kubectl get ingress -n soroscan
# Check backend logs
kubectl logs -f deployment/soroscan-backend -n soroscan
# Check worker logs
kubectl logs -f deployment/soroscan-worker -n soroscan# Check readiness
kubectl get pods -n soroscan -w
# Test API endpoint
curl https://your-domain.com/api/events/
# Check migrations completed
kubectl logs deployment/soroscan-backend -n soroscan --previousThe Kubernetes deployment includes:
- Backend Deployment: Django + gunicorn with readinessProbe on
/api/events/ - Worker Deployment: Celery workers for default queue
- Worker Backfill Deployment: Dedicated workers for backfill queue
- Beat Deployment: Celery beat scheduler (single replica)
- Service: ClusterIP service exposing backend
- Ingress: HTTP/HTTPS routing to backend service
# Scale backend pods
kubectl scale deployment/soroscan-backend --replicas=4 -n soroscan
# Scale worker pods
kubectl scale deployment/soroscan-worker --replicas=3 -n soroscan
# Note: Beat scheduler must remain at 1 replica- Migrations not running: Check init container logs:
kubectl logs pod/soroscan-backend-xxx -n soroscan -c migrate - Database connection failed: Verify
DATABASE_URLsecret is correct - Redis connection failed: Verify
REDIS_URLsecret and Redis accessibility - Readiness probe failing: Check
/api/events/endpoint is accessible after migrations
- Fork the repository and create your feature branch.
- Look for issues labeled
good-first-issueorhelp-wanted. - Submit a PR referencing the issue.
- Soroban smart contract with event emission
- Django backend with REST API
- GraphQL schema with Strawberry
- Webhook subscriptions with Celery
- Docker Compose setup for local development
- Kubernetes manifests for production deployment
- Rate limiting and API authentication
- Comprehensive test suite
- Multi-contract indexing dashboard
- Historical backfill from Horizon archives
- Real-time WebSocket subscriptions
- SDK packages (Python, JavaScript)
This project is licensed under the MIT License.