This repository implements a Celestia da-server for Alt-DA mode using generic commitments. The server provides a simple HTTP API that the OP Stack's op-batcher uses to store and retrieve data availability (DA) commitments.
┌─────────────────────────────────────────────────────────────────────┐
│ PUT Request → Create blob → Submit via CoreGRPC → Return BlobID │
│ ↑ │
│ Signer (local keyring OR POPSigner) │
│ │
│ GET Request → Parse BlobID (height + commitment) → blob.Get() │
│ ↑ │
│ Bridge node JSON-RPC │
├─────────────────────────────────────────────────────────────────────┤
│ Requirements: Signer, Bridge node (read), CoreGRPC (write) │
└─────────────────────────────────────────────────────────────────────┘
Before running the DA server, you need:
- A signer for Celestia transactions - Either local keyring OR POPSigner
- Access to a Celestia bridge/light node - For reading blobs (JSON-RPC)
- Access to a Celestia consensus node - For submitting blobs (CoreGRPC)
- Go 1.21+ - For building from source
The DA server supports two signing modes:
| Mode | Description | Best For |
|---|---|---|
| Local Keyring | Filesystem-based keyring | Development, self-hosted |
| POPSigner | Remote signing service | Production, key security |
make da-server
# or
go build -o bin/da-server ./cmd/daserverChoose one of the following:
# Initialize a Celestia light node (creates keyring directory)
celestia light init --p2p.network mocha-4
# Add a new key to the keyring
celestia-appd keys add my_celes_key --keyring-backend test \
--home ~/.celestia-light-mocha-4
# Display the address to fund with TIA
celestia-appd keys show my_celes_key --keyring-backend test \
--home ~/.celestia-light-mocha-4 -a
# Fund this address with TIA from:
# - Mocha faucet: https://faucet.celestia-mocha.com/
# - Arabica faucet: https://faucet.celestia-arabica-11.com/# 1. Create account at https://popsigner.com
# 2. Generate an API key (psk_live_xxxxx)
# 3. Create a Celestia key and note the key_id (UUID)
# 4. Fund the key's Celestia address with TIA
export POPSIGNER_API_KEY="psk_live_xxxxx"With Local Keyring:
./bin/da-server --config=config.tomlWith POPSigner:
POPSIGNER_API_KEY="psk_live_xxxxx" ./bin/da-server --config=config.tomlOr using CLI flags:
./bin/da-server \
--celestia.namespace="00000000000000000000000000000000000000000000000000000000acfe" \
--celestia.server="http://localhost:26658" \
--celestia.tx-client.core-grpc.addr="consensus-full-mocha-4.celestia-mocha.com:9090" \
--celestia.tx-client.keyring-path="$HOME/.celestia-light-mocha-4/keys" \
--celestia.tx-client.key-name="my_celes_key" \
--celestia.tx-client.p2p-network="mocha-4"| Flag | Environment Variable | Default | Description |
|---|---|---|---|
--addr |
OP_ALTDA_ADDR |
127.0.0.1 |
Server listening address |
--port |
OP_ALTDA_PORT |
3100 |
Server listening port |
--celestia.server |
OP_ALTDA_CELESTIA_SERVER |
http://localhost:26658 |
Bridge node RPC endpoint |
--celestia.namespace |
OP_ALTDA_CELESTIA_NAMESPACE |
(required) | Celestia namespace (29 bytes hex) |
--celestia.auth-token |
OP_ALTDA_CELESTIA_AUTH_TOKEN |
Bridge node auth token | |
--celestia.tls-enabled |
OP_ALTDA_CELESTIA_TLS_ENABLED |
false |
Enable TLS for bridge RPC |
--celestia.compact-blobid |
OP_ALTDA_CELESTIA_BLOBID_COMPACT |
true |
Use compact blob IDs |
| Flag | Environment Variable | Default | Description |
|---|---|---|---|
--celestia.tx-client.core-grpc.addr |
OP_ALTDA_CELESTIA_TX_CLIENT_CORE_GRPC_ADDR |
(required) | CoreGRPC endpoint |
--celestia.tx-client.core-grpc.tls-enabled |
OP_ALTDA_CELESTIA_TX_CLIENT_CORE_GRPC_TLS_ENABLED |
true |
Enable TLS for CoreGRPC |
--celestia.tx-client.core-grpc.auth-token |
OP_ALTDA_CELESTIA_TX_CLIENT_CORE_GRPC_AUTH_TOKEN |
CoreGRPC auth token | |
--celestia.tx-client.p2p-network |
OP_ALTDA_CELESTIA_TX_CLIENT_P2P_NETWORK |
mocha-4 |
Network: mocha-4, arabica-11, celestia |
| Flag | Environment Variable | Default | Description |
|---|---|---|---|
--celestia.signer-mode |
OP_ALTDA_CELESTIA_SIGNER_MODE |
local |
Signer mode: local, popsigner |
--celestia.tx-client.keyring-path |
OP_ALTDA_CELESTIA_TX_CLIENT_KEYRING_PATH |
Path to keyring (local mode) | |
--celestia.tx-client.key-name |
OP_ALTDA_CELESTIA_TX_CLIENT_KEY_NAME |
my_celes_key |
Key name in keyring (local mode) |
--celestia.remote-signer.key-id |
OP_ALTDA_CELESTIA_REMOTE_SIGNER_KEY_ID |
POPSigner key UUID | |
--celestia.remote-signer.api-key |
POPSIGNER_API_KEY |
POPSigner API key (env var preferred) | |
--celestia.remote-signer.base-url |
OP_ALTDA_CELESTIA_REMOTE_SIGNER_BASE_URL |
Custom POPSigner endpoint |
| Flag | Environment Variable | Default | Description |
|---|---|---|---|
--fallback.enabled |
OP_ALTDA_FALLBACK_ENABLED |
false |
Enable fallback storage |
--fallback.provider |
OP_ALTDA_FALLBACK_PROVIDER |
s3 |
Fallback provider type |
--fallback.s3.bucket |
OP_ALTDA_FALLBACK_S3_BUCKET |
S3 bucket name | |
--fallback.s3.prefix |
OP_ALTDA_FALLBACK_S3_PREFIX |
S3 key prefix | |
--fallback.s3.endpoint |
OP_ALTDA_FALLBACK_S3_ENDPOINT |
S3 endpoint (for MinIO, etc.) | |
--fallback.s3.region |
OP_ALTDA_FALLBACK_S3_REGION |
us-east-1 |
S3 region |
--fallback.s3.credential-type |
OP_ALTDA_FALLBACK_S3_CREDENTIAL_TYPE |
Credential type: static, environment, iam | |
--fallback.s3.access-key-id |
OP_ALTDA_FALLBACK_S3_ACCESS_KEY_ID |
S3 access key | |
--fallback.s3.access-key-secret |
OP_ALTDA_FALLBACK_S3_ACCESS_KEY_SECRET |
S3 secret key | |
--fallback.s3.timeout |
OP_ALTDA_FALLBACK_S3_TIMEOUT |
30s |
S3 operation timeout |
| Flag | Environment Variable | Default | Description |
|---|---|---|---|
--metrics.enabled |
OP_ALTDA_METRICS_ENABLED |
false |
Enable Prometheus metrics |
--metrics.port |
OP_ALTDA_METRICS_PORT |
6060 |
Prometheus metrics port |
| Flag | Environment Variable | Default | Description |
|---|---|---|---|
--log.level |
OP_ALTDA_LOG_LEVEL |
INFO |
Log level (DEBUG, INFO, WARN, ERROR) |
--log.format |
OP_ALTDA_LOG_FORMAT |
text |
Log format (text, terminal, logfmt, json) |
See config.toml.example for a complete example:
# Server settings
addr = "127.0.0.1"
port = 3100
[celestia]
namespace = "00000000000000000000000000000000000000000000000000000000acfe"
bridge_addr = "http://localhost:26658"
core_grpc_addr = "consensus-full-mocha-4.celestia-mocha.com:9090"
p2p_network = "mocha-4"
# Signer configuration - choose ONE mode
[celestia.signer]
mode = "local" # or "popsigner"
# Local keyring settings
[celestia.signer.local]
keyring_path = "~/.celestia-light-mocha-4/keys"
key_name = "my_celes_key"
# POPSigner settings (when mode = "popsigner")
# [celestia.signer.popsigner]
# key_id = "your-key-uuid"
# api_key via POPSIGNER_API_KEY env var (recommended)
[submission]
timeout = "60s"
tx_priority = 2 # 1=low, 2=medium, 3=high
[metrics]
enabled = true
port = 6060A valid namespace is 29 bytes (58 hex characters). For version 0 namespaces, the first 18 bytes must be zeros:
export NAMESPACE=00000000000000000000000000000000000000$(openssl rand -hex 10)
echo $NAMESPACESee API.md for detailed API documentation.
| Endpoint | Method | Description |
|---|---|---|
/put |
PUT | Submit blob to Celestia |
/get/:commitment |
GET | Retrieve blob by commitment |
/health |
GET | Health check endpoint |
# Submit a blob
COMMITMENT=$(curl -s -X PUT http://localhost:3100/put \
-H "Content-Type: application/octet-stream" \
--data-binary "hello world")
echo "Commitment: $COMMITMENT"
# Retrieve the blob
curl http://localhost:3100/get/$COMMITMENT
# Health check
curl http://localhost:3100/healthThe server supports optional fallback storage for resilience. When enabled, fallback always performs both:
- Write-through: After successful Celestia submission, blob is also written to fallback asynchronously
- Read-fallback: If blob not found in Celestia, attempt to read from fallback
- Read-through: When blob is found in Celestia, it's also written to fallback for future requests
Fallback failures are non-fatal and logged as warnings.
./bin/da-server \
--celestia.namespace="$NAMESPACE" \
--celestia.tx-client.keyring-path="$HOME/.celestia-light-mocha-4/keys" \
--celestia.tx-client.core-grpc.addr="consensus-full-mocha-4.celestia-mocha.com:9090" \
--fallback.enabled=true \
--fallback.s3.bucket="my-da-fallback" \
--fallback.s3.region="us-east-1"When enabled (--metrics.enabled=true), Prometheus metrics are available at http://localhost:6060/metrics.
| Metric | Type | Description |
|---|---|---|
op_altda_request_duration_seconds |
Histogram | HTTP request duration by method |
op_altda_blob_size_bytes |
Histogram | Size of submitted/retrieved blobs |
op_altda_inclusion_height |
Gauge | Latest Celestia inclusion height |
celestia_submission_duration_seconds |
Histogram | Time to submit blob to Celestia |
celestia_submissions_total |
Counter | Total blob submissions |
celestia_submission_errors_total |
Counter | Failed blob submissions |
celestia_retrieval_duration_seconds |
Histogram | Time to retrieve blob from Celestia |
celestia_retrievals_total |
Counter | Total blob retrievals |
celestia_retrieval_errors_total |
Counter | Failed blob retrievals |
# All unit tests
make test
# Unit tests only
make test-unit
# Integration tests (requires Celestia devnet access)
CELESTIA_BRIDGE="http://localhost:26658" \
CELESTIA_AUTH_TOKEN="your-token" \
CELESTIA_NAMESPACE="your-namespace" \
make test-integration
# All tests
make test-all# Start the server (ensure keyring is configured)
./bin/da-server --config=config.toml
# Test PUT
curl -X PUT http://localhost:3100/put \
-H "Content-Type: application/octet-stream" \
--data-binary "hello world"
# Test GET with the returned commitment
curl http://localhost:3100/get/0x010c...
# Check metrics
curl -s http://localhost:6060/metrics | grep -E "^(op_altda|celestia)_"To use this DA server with the OP Stack:
- Configure
da_paramsin your kurtosis config:
da_params:
image: ghcr.io/celestiaorg/op-alt-da:latest- Add
altda_deploy_config:
altda_deploy_config:
use_altda: true
da_commitment_type: GenericCommitment
da_challenge_window: 100
da_resolve_window: 100
da_bond_size: 0
da_resolver_refund_percentage: 0For more details, see the Optimism Alt-DA documentation.
Ensure your keyring path is correct and contains the specified key:
# List keys in keyring
celestia-appd keys list --keyring-backend test \
--home ~/.celestia-light-mocha-4
# Verify keyring path exists
ls -la ~/.celestia-light-mocha-4/keys/Your Celestia account needs TIA to pay for transaction fees:
# Check balance
celestia-appd query bank balances $(celestia-appd keys show my_celes_key -a \
--keyring-backend test --home ~/.celestia-light-mocha-4) \
--node https://rpc-mocha.pops.one:443Verify the CoreGRPC endpoint is accessible:
# Test connection
grpcurl -plaintext consensus-full-mocha-4.celestia-mocha.com:9090 listMIT License - see LICENSE