ContextVM server for creating and verifying OpenTimestamps-backed NIP-03 attestations for Nostr events.
Verification uses a public Bitcoin JSON-RPC API and does not require running a local Bitcoin node.
Local development:
bun install
bun run devEasy deployment with the published image:
docker pull ghcr.io/contextvm-org/ots-cvm:latest
docker run --rm --env-file .env -v ./data:/app/data ghcr.io/contextvm-org/ots-cvm:latestDocker:
docker compose up --buildMain environment variables:
SERVER_PRIVATE_KEY: hex-encoded Nostr secret key used by the serverRELAYS: comma-separated relay URLs for fetch and publish operationsATTESTATION_RELAYS: comma-separated relay URLs used specifically to publish NIP-03 attestation eventsBITCOIN_API_URL: Bitcoin JSON-RPC endpoint used by verificationLOG_LEVEL:infoordebug
Optional environment variables:
SQLITE_PATH: SQLite database file pathOTS_DATA_DIR: directory used for cached proof filesOTS_PROOF_TTL_DAYS: retention window for proof artifacts written toOTS_DATA_DIR(default: 30)OTS_VERIFY_CACHE_DIR: directory used by Python verification upgrades to cache calendar responsesOTS_VERIFY_CACHE_TTL_DAYS: retention window for verification cache files (default: 3)CLEANUP_INTERVAL_MINUTES: how often expired filesystem artifacts are removed (default: 1440, once per day)OTS_CALENDARS: comma-separated OpenTimestamps calendar URLsOTS_PYTHON_BIN: optional Python executable override for local host development only
Create a local .env file before starting the service:
cp .env.example .envThen edit .env and set at least SERVER_PRIVATE_KEY.
Notes:
SERVER_PRIVATE_KEYis the only variable you should treat as required for production.RELAYS,ATTESTATION_RELAYS,BITCOIN_API_URL, andLOG_LEVELare optional because the app has defaults..env.examplecontains the minimal starter template for local and Docker usage.docker-compose.ymlalready loads values from.envviaenv_file, so Docker deployments only need that file present next to the compose file.- Proof and verification cache files are cleaned up automatically on startup and periodically afterwards using the configured TTL values.
Docker bundles Bun, Python, and the OpenTimestamps dependencies. No extra Python setup is needed on the host.
docker compose up --buildTo run the published image directly, pass the same variables with --env-file:
docker run --rm \
--env-file .env \
-v ./data:/app/data \
ghcr.io/contextvm-org/ots-cvm:latestThe container persists runtime data in data/ and exposes logs through docker compose logs.
For Docker deployments, you normally do not need to set OTS_PYTHON_BIN.