Files
client/plans/ai-routstr-endpoint-fixes.md
2026-04-17 16:52:51 -04:00

4.9 KiB

AI Page — Routstr Endpoint Fixes

Provider Selection

The Routstr network has multiple providers. The ai.html page uses a single configurable Base URL in the sidenav config. When the user selects "Routstr" as the provider, the Base URL is set to https://api.routstr.com. All Routstr providers run the same routstr-core software and expose the same API endpoints, so the endpoint paths below work for any provider:

  • routstr.cypherpunk.today (cheapest)
  • api.nonkycai.com
  • privateprovider.xyz
  • routstr.otrta.me
  • api.routstr.com
  • ai.redsh1ft.com

The user does NOT need to select a provider before using the payment controls — they just need to have the correct Base URL set in the config section above the payment section. The current default providers in ai.html are ppq.ai and Routstr (api.routstr.com).

Future enhancement: We could add all discovered Routstr providers to the provider dropdown, but that is out of scope for this fix.

Problem

The Routstr payment controls in ai.html sidenav have several bugs:

  1. Lightning invoice endpoints use wrong paths — The lightning router is nested under the balance router at /v1/balance, so the full path is /v1/balance/lightning/invoice, NOT /lightning/invoice
  2. Balance probe fires on page load without a valid key — Causes 401/404/400 console noise
  3. No invoice status polling — After creating a lightning invoice, user has no way to know when it's paid

Server Endpoint Structure

From routstr-core/routstr/balance.py and routstr-core/routstr/lightning.py:

balance_router = APIRouter(prefix="/v1/balance")
lightning_router = APIRouter(prefix="/lightning")
balance_router.include_router(lightning_router)
balance_router.include_router(router)

Correct Endpoint Paths

Action Method Path
Get balance info GET /v1/balance/info
Create balance from Cashu GET /v1/balance/create?initial_balance_token=...
Top-up with Cashu POST /v1/balance/topup
Refund POST /v1/balance/refund
Create Lightning invoice POST /v1/balance/lightning/invoice
Check invoice status GET /v1/balance/lightning/invoice/{id}/status
Recover invoice by bolt11 POST /v1/balance/lightning/recover

Changes Required in www/ai.html

1. Fix Lightning Invoice Endpoints

File: www/ai.html

Change both lightning invoice fetch calls from:

fetch(`${baseUrl}/lightning/invoice`, ...)

To:

fetch(`${baseUrl}/v1/balance/lightning/invoice`, ...)

This affects:

  • btnRoutstrCreateInvoice click handler (deposit invoice)
  • btnRoutstrTopupInvoice click handler (top-up invoice)

2. Fix refreshRoutstrWalletState

File: www/ai.html

  • Remove the fallback endpoint candidates /v1/wallet/balance and /v1/balance
  • Only probe /v1/balance/info which is the correct endpoint
  • Skip the balance probe entirely if the API key does not start with sk- since raw cashu tokens need to be imported first via /v1/balance/create
  • Show a helpful message when no sk- key is configured

3. Add Invoice Status Polling

File: www/ai.html

After a lightning invoice is created successfully:

  • Extract invoice_id from the response
  • Start polling GET /v1/balance/lightning/invoice/{invoice_id}/status every 5 seconds
  • When status changes to paid, extract the api_key from the response
  • Auto-populate the API Key field with the returned sk- key
  • Stop polling after payment detected, expiry, or 60 polls max
  • Show bolt11 string so user can copy it to pay

4. Suppress Console Noise

Wrap the balance probe fetch in the refreshRoutstrWalletState function so it does not fire when there is no valid key, eliminating the 401/404/400 errors on page load.

Flow Diagrams

Lightning Deposit Flow

sequenceDiagram
    participant User
    participant SideNav as ai.html Sidenav
    participant Routstr as api.routstr.com

    User->>SideNav: Enter amount, click Create Deposit Invoice
    SideNav->>Routstr: POST /v1/balance/lightning/invoice<br/>amount_sats + purpose=create
    Routstr-->>SideNav: invoice_id + bolt11 + expires_at
    SideNav->>SideNav: Display bolt11 for user to pay
    loop Every 5 seconds
        SideNav->>Routstr: GET /v1/balance/lightning/invoice/ID/status
        Routstr-->>SideNav: status=pending or status=paid + api_key
    end
    Note over SideNav: When status=paid
    SideNav->>SideNav: Auto-fill API Key field with sk-...
    SideNav->>SideNav: Save config + refresh wallet state

Cashu Import Flow

sequenceDiagram
    participant User
    participant SideNav as ai.html Sidenav
    participant Routstr as api.routstr.com

    User->>SideNav: Paste cashuA... token, click Import
    SideNav->>Routstr: GET /v1/balance/create?initial_balance_token=cashuA...
    Routstr-->>SideNav: api_key=sk-... + balance
    SideNav->>SideNav: Auto-fill API Key field with sk-...
    SideNav->>SideNav: Save config + refresh wallet state