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
See ENVIRONMENT.md for the complete list of required and optional environment variables, their types and defaults, and development, testing, and production examples.
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/
## Deployment Docs
For complete production deployment and operations guidance, see the `docs/deployment` section:
- Local Docker Compose: [docs/deployment/docker-compose](docs/deployment/docker-compose)
- Kubernetes (Helm + Terraform): [docs/deployment/kubernetes](docs/deployment/kubernetes)
- AWS EKS example: [docs/deployment/aws](docs/deployment/aws)
- Monitoring, backups, runbooks and troubleshooting: [docs/deployment/monitoring](docs/deployment/monitoring)
# 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.
- CELERY.md β Celery worker queues, concurrency settings, and deployment examples
- Architecture Overview β end-to-end system design, data flows, component interaction, and deployment architecture
- Architecture Decision Records β rationale for core technology and design choices
- DATABASE_TUNING.md β Recommended configuration settings for high-volume write workloads and indexing optimizations.