9qeklajc ed9a3417d2 fix: give the Routstr top-up threshold an explicit unit
The auto top-up field has always been labelled "When credits are below (Sats)",
but the backend compared it as `balance >= threshold * 1000` against a balance
get_balance() had already converted to sats. Its sibling topup_amount_limit is
plain sats - it goes straight to send_token(amount, "sat", ...). So one settings
blob carried two units and the UI promised the one it did not use: an operator
asking to top up below 1000 sats got one below 1,000,000.

topup_threshold_sats says what it means and is compared as written. A legacy
topup_threshold keeps the thousandfold it has always been compared with, since
reinterpreting stored values as sats would drop the trigger point by a factor of
1000 on upgrade and leave a peer to run dry. A one-off warning per provider
names the sats value to migrate to.

The settings form now edits topup_threshold_sats, seeding it from the legacy
value times 1000 so the number shown is the number in force. Editing therefore
starts from the truth rather than silently moving the trigger on the next save,
and saving drops the legacy key so the stored blob carries one unit.

Validation accepts either key and rejects a blob carrying neither.

The PPQ path keeps its own topup_threshold, which is USD and unaffected.
2026-08-24 23:03:52 +02:00
2026-08-23 11:06:06 +02:00
2025-10-22 12:18:00 +08:00
2026-08-06 22:58:44 +02:00
2026-08-14 21:48:29 +02:00
2025-10-16 16:03:39 +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
2026-08-17 00:23:15 +02:00
2026-08-17 00:23:15 +02: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:

    # Optional: encrypts node secrets at rest. If unset, the node generates a key
    # on first start, writes it to routstr_secret.key, and prints it once — back
    # up that file. Set it explicitly to manage the key yourself (recommended in
    # production).
    ROUTSTR_SECRET_KEY=<generated-key>
    NAME="My AI Node"
    DESCRIPTION="Fast access to models"
    RECEIVE_LN_ADDRESS=yourname@wallet.com
    

    Your Nostr identity (nsec) is not set in .env — configure it from the admin UI after first start, where it's stored encrypted in the database. (NSEC in .env is still read once as a legacy seed for existing deployments.)

    If you don't set one, a key is generated and printed on first start — save it somewhere safe (losing it makes previously encrypted secrets unreadable). To supply your own, generate it once and keep it stable:

    uv run 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 docker compose exec routstr /.venv/bin/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
33 MiB
Languages
Python 79.8%
TypeScript 18.3%
HTML 1.2%
JavaScript 0.2%
Makefile 0.2%
Other 0.3%