Configuration
walletrs is configured entirely through environment variables — there is no config file. This page lists every knob, then drills into the storage-backend variants.
Environment variables
Section titled “Environment variables”| Variable | Default | Required when | Notes |
|---|---|---|---|
WALLETRS_HOST | 127.0.0.1 | always | Bind host shared by gRPC + HTTP. Use 0.0.0.0 inside containers. |
WALLETRS_PORT | 50051 | always | gRPC port |
WALLETRS_HTTP_PORT | 8080 | always | HTTP / JSON port |
BITCOIN_NETWORK | regtest | always | mainnet / testnet / signet / regtest |
ELECTRS_URL | tcp://127.0.0.1:60401 | always | Electrum-Rust server URL |
WALLETRS_STORAGE_KIND | local | always | local or s3 |
WALLETRS_STORAGE_PATH | ./data | local-only | Filesystem root for wallet data |
WALLETRS_S3_ENDPOINT | — | s3 | Leave unset for AWS S3, set for R2 / MinIO |
WALLETRS_S3_BUCKET | — | s3 | |
WALLETRS_S3_REGION | auto | s3 | R2 takes auto; AWS takes the actual region name |
WALLETRS_S3_ACCESS_KEY_ID | — | s3 | |
WALLETRS_S3_SECRET_ACCESS_KEY | — | s3 | |
WALLETRS_S3_PREFIX | — | s3 | Object-key namespace inside the bucket |
WALLETRS_S3_FORCE_PATH_STYLE | true | s3 | Required for MinIO; safe for R2 |
WALLETRS_KEK | — | system-keys | Base64-encoded 32-byte envelope KEK |
WALLETRS_AUTH_TOKEN | — | optional | Bearer token for gRPC + HTTP; auto-generated when unset |
WALLETRS_AUTH_DISABLED | 0 | optional | Disables auth on both surfaces |
WALLETRS_SIGVAULT_TOKEN | — | BYO walletrs | One-shot pairing token from sigvault — only needed on the first start of a BYO walletrs |
WALLETRS_SIGVAULT_ENDPOINT | https://api.sigvault.org | BYO walletrs | Override only when self-hosting sigvault |
WALLETRS_SIGVAULT_DISABLED | 0 | optional | Disables the sigvault agent even with paired credentials on disk |
RUST_LOG | info,walletrs=debug | optional | Standard env_logger directive |
Networks
Section titled “Networks”BITCOIN_NETWORK selects the chain walletrs operates on:
mainnet(alias:bitcoin) — production. Pair with a realELECTRS_URLand a hardened deployment.testnet— long-running test chain. Useful when you need the exact mainnet address format with throwaway coins.signet— the modern, controllable test chain. Cleaner reorgs and a more reliable faucet network than testnet.regtest— local development. Pair with a regtestbitcoindandelectrs. The bundled Docker Compose stack defaults here.
The descriptor compiler uses the network to pick address prefixes (bcrt1..., tb1..., bc1...).
Storage backends
Section titled “Storage backends”Two backends ship in-tree; both implement the same StorageBackend trait so the rest of the system doesn’t care.
Local filesystem
Section titled “Local filesystem”WALLETRS_STORAGE_KIND=local plus WALLETRS_STORAGE_PATH=/some/dir.
Wallet state, managed keys, and PSBTs all live under that directory. The path is created on first start. Back this directory up — losing it means losing the wallet.
S3 / R2 / MinIO
Section titled “S3 / R2 / MinIO”WALLETRS_STORAGE_KIND=s3 plus the WALLETRS_S3_* family. Two reasons to prefer this in production:
- The
R2BackedStoreuploads the BDK file_store on everywallet.persist(), so a container can be ephemeral — restart, pull state from object storage, keep going. - Encrypted blobs at rest: even if an attacker exfiltrates the bucket, they need
WALLETRS_KEKto read system-managed key material.
Cloudflare R2 example:
WALLETRS_STORAGE_KIND=s3WALLETRS_S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.comWALLETRS_S3_BUCKET=walletrs-prodWALLETRS_S3_REGION=autoWALLETRS_S3_ACCESS_KEY_ID=...WALLETRS_S3_SECRET_ACCESS_KEY=...WALLETRS_S3_PREFIX=mainnetWALLETRS_S3_FORCE_PATH_STYLE=trueThe pinned BehaviorVersion in crates/server/src/storage/s3.rs works around an AWS SDK regression where x-amz-checksum-* headers got added to mutating requests, breaking R2 / MinIO compatibility. Don’t downgrade the AWS SDK without re-validating.
Envelope KEK
Section titled “Envelope KEK”WALLETRS_KEK is a base64-encoded 32-byte key that wraps system-managed private key material. Customer keys (xpub-only) don’t use the KEK.
Generate one with:
openssl rand -base64 32There is no built-in rotation flow today. The pragmatic procedure:
- Stop walletrs.
- Decrypt every
StoredManagedKeyblob with the old KEK (e.g. via a one-off script usingcrates/server/src/storage/crypto.rs). - Re-encrypt under the new KEK.
- Set the new
WALLETRS_KEKand start.
If you lose the KEK, system-managed private material is unrecoverable — wallets remain valid for receive-only use, but signing requires re-creating new system keys and migrating funds.
RUST_LOG=info,walletrs=debug is the default. Crank to walletrs=trace for verbose PSBT and BDK logs while debugging signing flows. Output is human-readable env_logger format; structured / JSON logs are on the roadmap.