Jeroen UbbinkandClaude Opus 4.8 0415806c5a fix(config): keep the vault the sole owner of node secrets
Two ways a stale legacy NSEC could override or resurrect an nsec the
vault already owns (issue #553):

- initialize() re-applied env/blob values onto live settings after
  bootstrap had decrypted the authoritative nsec, so a stale NSEC left
  in .env would clobber it on restart (e.g. after rotating the key in
  the admin UI). _apply_to_live_settings now never re-applies secret
  fields; bootstrap_secrets is their only writer.

- An empty encrypted_nsec could not distinguish "never migrated" from
  "intentionally cleared", so clearing the identity via the admin API
  and restarting re-imported the old NSEC from env/blob. Record vault
  ownership in a new secrets.nsec_managed column (set on legacy import
  and on every set_nsec write); bootstrap skips the legacy import once
  the vault owns the nsec, so a cleared identity stays cleared.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 10:51:20 +02:00
2026-04-28 01:01:23 +02:00
2025-10-22 12:18:00 +08:00
2025-11-23 21:51:16 +00:00
2025-10-27 12:38:55 +08:00
2025-06-09 23:46:19 +02:00
2025-08-12 15:02:22 -03:00
2026-07-07 17:22:48 +02:00
2025-04-08 21:42:32 +08:00
2026-01-24 17:55:45 +08:00
2025-08-01 22:31:18 -03:00

Routstr Payment Proxy

License Stars Issues Release

Routstr is a decentralized protocol for permissionless, private, and censorship-resistant AI inference. It combines Nostr for discovery and Cashu for private Bitcoin micropayments.

This repo contains Routstr Core: a FastAPI-based reverse proxy that sits in front of OpenAI-compatible APIs and handles pay-per-request billing.

Start Here

Basic Usage

If you are a user/developer, you just point an OpenAI-compatible SDK at a Routstr node and pay with a Cashu token.

OpenAI SDK

from openai import OpenAI

client = OpenAI(
    base_url="https://api.routstr.com/v1",
    api_key="cashuBo2FteCJodHRwczovL21...",
)

response = client.chat.completions.create(
    model="gpt-5-nano",
    messages=[{"role": "user", "content": "hello"}],
)

print(response.choices[0].message.content)

cURL

curl https://api.routstr.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "x-cashu: cashuBo2FteCJodHRwczovL21..." \
  -d '{
    "model": "gpt-5-nano",
    "messages": [{"role": "user", "content": "hello"}]
  }'

Quick Start (Docker)

If you are a node runner, start a Routstr Core instance using Docker Compose:

  1. Prepare your .env:

    # Required: encrypts secrets at rest. The node won't start without it.
    ROUTSTR_SECRET_KEY=<generated-key>
    NAME="My AI Node"
    DESCRIPTION="Fast access to models"
    NSEC=yournsec
    RECEIVE_LN_ADDRESS=yourname@wallet.com
    

    Generate ROUTSTR_SECRET_KEY once and keep it stable — changing it makes previously encrypted secrets unreadable:

    python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
    
  2. Start the services:

    docker compose up -d
    
  3. Get your admin password: On first start the node generates an admin password and logs it once with the /admin URL. Read it from the logs:

    docker compose logs routstr | grep -i admin
    

    (Lost it? Reset with python scripts/reset_admin_password.py --regenerate.)

  4. Configure: Open http://localhost:8000/admin/ to connect your AI providers and set pricing.

For full instructions, see the Provider Quick Start Guide.

Development

make setup
cp .env.example .env
fastapi run routstr
S
Description
Routstr is a decentralized protocol for permissionless, private, and censorship-resistant AI inference.
Readme GPL-3.0
13 MiB
Languages
Python 65.3%
TypeScript 32.2%
HTML 1.7%
Makefile 0.3%
Shell 0.2%
Other 0.2%