redshift d1feddbd21 chore(deps): patch all Dependabot security alerts
Closes 29 of 30 open Dependabot alerts (all 3 critical, all 17 high):

Python (uv.lock):
- litellm 1.83.0 -> 1.84.10  (CVE-2026-49468, CVE-2026-42208 criticals
  + 8 more high/med/low)
- starlette 0.46.2 -> 1.6.0  (CVE-2026-54283, CVE-2026-48818,
  CVE-2026-48817, CVE-2026-48710, CVE-2025-62727, CVE-2025-54121)
- cryptography 43.0.3 -> 50.0.1  (CVE-2026-69249, CVE-2026-26007,
  CVE-2026-34073, CVE-2024-12797)
- h11 0.14.0 -> 0.16.0  (CVE-2025-43859 critical)
- fastapi 0.115.14 -> 0.141.1  (starlette 1.x support)
- httpx 0.25.2 -> 0.28.1, setuptools 75.9.1 -> 84.0.0,
  wheel 0.41.3 -> 0.48.0

cashu 0.20.x pins conservative upper bounds (httpx<0.26, h11<0.15,
fastapi<0.116, cryptography<44, setuptools<76, wheel<0.42,
importlib-metadata<7) that conflict with every patched version, so the
gated packages are lifted via [tool.uv] override-dependencies. routstr
only imports cashu's wallet-side modules, not its mint/fastapi server
paths. starlette is forced via constraint-dependencies since fastapi
0.141 permits the old in-range 0.46.2.

Code changes required by the bumps:
- httpx 0.28 removed `proxies=`: use `proxy=` in
  routstr/nostr/discovery.py (Tor .onion health fetches) and
  examples/tor.py. The discovery.py path was untested and would have
  raised TypeError at runtime on any .onion provider check.
- tests/integration/test_admin_pricing_rate_validation.py: httpx 0.28
  refuses to encode NaN/Inf client-side (allow_nan=False); send raw
  JSON bytes so the bare NaN/Infinity literals still reach the server,
  which is the behavior under test.

UI (pnpm-lock.yaml):
- browserslist 4.28.1 -> 4.28.9  (CVE-2026-73089, CVE-2026-73088)
- @humanfs/node 0.16.7 -> 0.16.8

Remaining alert: ecdsa (GHSA-wj6h-64fc-37mp, Minerva timing attack) is
already at the latest release 0.19.2 with no fix available upstream;
cashu pins ecdsa<0.20. Deferred until cashu migrates off python-ecdsa.

Verified: 1336 unit + 439 integration tests pass, mypy, ruff, UI lint /
format-check / build all clean. 2 unit test failures
(test_provider_slugs) are pre-existing environment leaks (python-dotenv
loads the parent checkout's .env containing TINFOIL_API_KEY and fail
identically on main.
EOF
)
2026-09-07 20:14:28 +02:00
2026-09-04 01:35:43 +02:00
2025-10-22 12:18:00 +08:00
2026-08-06 22:58:44 +02:00
2026-08-26 22:51:09 +02: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:

    # 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%