routstrd 0.4.9 → 0.4.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # routstrd
2
2
 
3
- Routstr daemon - A CLI tool for managing routstr processes, similar to `cocod` (a Cashu wallet daemon).
3
+ Routstr daemon - A CLI tool for managing routstr processes, with a built-in Cashu wallet.
4
4
 
5
5
  ## Overview
6
6
 
7
- routstrd is a Bun-based CLI tool that provides a background daemon for the Routstr protocol. It integrates with `cocod` for wallet management and uses the Routstr SDK to handle provider routing and model discovery.
7
+ routstrd is a Bun-based CLI tool that provides a background daemon for the Routstr protocol. It carries an in-process Cashu wallet (coco) for payments and uses the Routstr SDK to handle provider routing and model discovery.
8
8
 
9
9
  ## Routstr for Teams
10
10
 
@@ -13,7 +13,7 @@ For team-based routing, see [routstrd-auth](https://github.com/Routstr/routstrd-
13
13
  ## Features
14
14
 
15
15
  - **Daemon Mode**: Run routstrd as a background HTTP server
16
- - **Wallet Integration**: Works with cocod for Cashu token management
16
+ - **Wallet Integration**: In-process Cashu wallet, with Lightning, NWC, and NPC support
17
17
  - **Provider Routing**: Automatically discovers and routes requests to available providers
18
18
  - **Config Management**: Stores configuration in `~/.routstrd/`
19
19
 
@@ -26,7 +26,29 @@ npm or running from source requires the [Bun](https://bun.sh) runtime.
26
26
 
27
27
  ### Step 1: Install
28
28
 
29
- **Standalone binary:**
29
+ **Standalone binary (recommended):**
30
+
31
+ Installs the standalone executable for Linux or macOS (x64 or arm64) into
32
+ `$HOME/.local/bin`. No Bun, Node.js, or npm required.
33
+
34
+ ```sh
35
+ curl -fsSL https://github.com/Routstr/routstrd/releases/latest/download/install.sh | sh
36
+ ```
37
+
38
+ Pin a version, change the install directory, or print the resolved asset without
39
+ installing anything:
40
+
41
+ ```sh
42
+ curl -fsSL https://github.com/Routstr/routstrd/releases/latest/download/install.sh \
43
+ | sh -s -- --version 0.4.9 --dir /usr/local/bin
44
+ ```
45
+
46
+ The installer downloads the release archive, verifies it against the release
47
+ `SHA256SUMS`, and only replaces an existing `routstrd` once the checksum matches
48
+ and the extracted binary reports the expected version.
49
+
50
+ <details>
51
+ <summary>Manual install</summary>
30
52
 
31
53
  Download the archive for your operating system and architecture from the
32
54
  [latest GitHub Release](https://github.com/Routstr/routstrd/releases/latest).
@@ -42,6 +64,12 @@ install -m 755 routstrd "$HOME/.local/bin/routstrd"
42
64
  Substitute the version, platform, and architecture for the archive you
43
65
  downloaded, and ensure `$HOME/.local/bin` is on `PATH`.
44
66
 
67
+ </details>
68
+
69
+ Installing the standalone binary is preferred over the npm package: the npm
70
+ package runs through the Bun runtime, while the standalone executable has no
71
+ runtime dependency.
72
+
45
73
  **Global with bun:**
46
74
  ```sh
47
75
  bun i -g routstrd
@@ -74,6 +102,9 @@ routstrd clients add --claude-code # or --pi-agent / --opencode
74
102
  > **Tip:** You can also install the [routstrd skill](https://github.com/Routstr/routstrd/blob/main/SKILL.md) so the agent can manage routstrd for you.
75
103
 
76
104
  ## More Commands
105
+
106
+ [`SKILL.md`](SKILL.md) is the complete per-command reference — every command,
107
+ subcommand, and flag. The sections below cover the common ones.
77
108
  ### Start Daemon
78
109
 
79
110
  Start the background daemon:
@@ -179,9 +210,13 @@ daemon restart is required.
179
210
 
180
211
  #### Route Request
181
212
  ```
182
- POST /
213
+ POST /v1/chat/completions
183
214
  ```
184
215
 
216
+ Any unmatched `POST` path is proxied to the selected provider with the incoming
217
+ path preserved, so `POST /v1/messages` (Anthropic Messages API) and
218
+ `POST /v1/responses` (OpenAI Responses API) work in their own formats too.
219
+
185
220
  Request body:
186
221
  ```json
187
222
  {
@@ -241,6 +276,8 @@ overrides the 21-minute interval.
241
276
  - `ROUTSTRD_DIR` - Config directory (default: `~/.routstrd`)
242
277
  - `ROUTSTRD_SOCKET` - Socket path (default: `~/.routstrd/routstrd.sock`)
243
278
  - `ROUTSTRD_PID` - PID file path (default: `~/.routstrd/routstrd.pid`)
279
+ - `ROUTSTRD_WALLET_DIR` - Wallet data directory (default: `~/.routstrd/wallet`)
280
+ - `COCOD_DIR` - Legacy external cocod directory, used only for migration and exclusion (default: `~/.cocod`)
244
281
 
245
282
  ## Development
246
283
 
@@ -249,16 +286,21 @@ Install dependencies:
249
286
  bun install
250
287
  ```
251
288
 
252
- Run CLI:
289
+ Run the CLI from source:
253
290
  ```sh
254
- bun run start
291
+ bun src/index.ts <command>
255
292
  ```
256
293
 
257
- Run daemon:
294
+ Run the daemon:
258
295
  ```sh
259
296
  bun run start
260
297
  ```
261
298
 
299
+ Run the tests:
300
+ ```sh
301
+ bun test
302
+ ```
303
+
262
304
  Build a standalone executable for the current platform:
263
305
 
264
306
  ```sh
@@ -298,7 +340,7 @@ more current model IDs to the smoke script:
298
340
 
299
341
  ```sh
300
342
  routstrd clients add --name smoke-test
301
- ROUTSTRD_API_KEY=<api-key> scripts/smoke/chat-completions.sh <model> [model ...]
343
+ ROUTSTRD_API_KEY=<api-key> bun run smoke <model> [model ...]
302
344
  ```
303
345
 
304
346
  Set `ROUTSTRD_BASE_URL` to test a daemon at a different address. The script
@@ -310,10 +352,11 @@ not part of `bun test`.
310
352
  1. Set a new `package.json` version and commit it. The release tag must be the
311
353
  same version prefixed with `v`, and the tag must not already exist.
312
354
  2. Push the tag. The release workflow runs lint and tests, builds Linux and
313
- macOS executables for x64 and arm64, smoke-tests them, and publishes the
314
- archives with `SHA256SUMS`.
315
- 3. Verify all four archives appear in the GitHub Release and validate each
316
- checksum before announcing it.
355
+ macOS executables for x64 and arm64, smoke-tests them, verifies the archives
356
+ through `install.sh` itself, and publishes the archives with `SHA256SUMS` and
357
+ `install.sh`.
358
+ 3. Verify all four archives and `install.sh` appear in the GitHub Release and
359
+ validate each checksum before announcing it.
317
360
  4. In disposable environments for each platform, test `--version`, `--help`,
318
361
  foreground startup failure, and background `start`, `status`, and `stop`
319
362
  without Bun on `PATH`.
@@ -327,12 +370,17 @@ not part of `bun test`.
327
370
  ```
328
371
  routstrd/
329
372
  ├── src/
330
- │ ├── index.ts # Entry point with shebang
331
- │ ├── cli.ts # Commander CLI commands
332
- │ ├── cli-shared.ts # IPC utilities
333
- │ ├── daemon.ts # HTTP server daemon
334
- │ └── utils/
335
- │ └── config.ts # Path configuration
373
+ │ ├── index.ts # CLI entry point with shebang
374
+ │ ├── cli.ts # Commander CLI commands
375
+ │ ├── daemon.ts # Compatibility daemon entrypoint (legacy PM2 registrations)
376
+ │ ├── start-daemon.ts # Daemon process launcher
377
+ │ ├── daemon/ # HTTP server, wallet, provider routing
378
+ │ ├── integrations/ # Client integrations (Claude Code, pi, OpenCode, ...)
379
+ │ ├── tui/ # Interactive usage monitor (`routstrd monitor`)
380
+ │ └── utils/ # Config, paths, daemon client, update checker
381
+ ├── tests/ # Integration tests (unit tests sit beside their source)
382
+ ├── scripts/smoke/ # Manual end-to-end smoke test
383
+ ├── docs/plans/ # Design/migration plans not yet executed
336
384
  ├── package.json
337
385
  └── tsconfig.json
338
386
  ```
package/SECURITY.md CHANGED
@@ -1,4 +1,3 @@
1
- ## SECURITY.md
2
1
  # Security Policy
3
2
 
4
3
  ## Reporting a Vulnerability
package/SKILL.md CHANGED
@@ -1,27 +1,45 @@
1
1
  # routstrd CLI Reference
2
2
 
3
- Routstr daemon — a Bun-based CLI tool that runs a background HTTP server for the Routstr protocol. It integrates with `cocod` for Cashu wallet management and routes LLM requests to available providers.
3
+ Routstr daemon — a Bun-based CLI tool that runs a background HTTP server for the
4
+ Routstr protocol. It carries an in-process Cashu wallet (coco) for payments and
5
+ routes LLM requests to available providers.
4
6
 
5
7
  ## Quick Start
6
8
 
7
9
  ```sh
8
- routstrd onboard # Initialize (creates config, sets up cocod)
10
+ routstrd onboard # Initialize (creates config, sets up the wallet)
11
+ routstrd receive 2100 # Top up over Lightning
9
12
  routstrd start # Start the daemon
10
13
  routstrd stop # Stop the daemon
11
14
  ```
12
15
 
13
- After onboarding, the daemon listens at `http://localhost:8008` and exposes an OpenAI-compatible API.
16
+ After onboarding, the daemon listens at `http://localhost:8008` and exposes an
17
+ OpenAI-compatible API.
14
18
 
15
19
  ## Commands
16
20
 
17
21
  ### `routstrd onboard`
18
22
 
19
23
  Initialize routstrd for the first time:
20
- - Creates `~/.routstrd/` config directory
21
- - Creates `~/.routstrd/config.json` with defaults (port 8008, apikeys mode)
22
- - Installs `cocod` globally via bun if not present
23
- - Runs `cocod init` to set up the wallet
24
- - Starts the daemon and configures integrations
24
+ - Creates `~/.routstrd/` (mode 0700) and `~/.routstrd/config.json` (mode 0600)
25
+ with defaults (port 8008, host 127.0.0.1, apikeys mode)
26
+ - Generates a Nostr identity (`nsec`) for NIP-98 authentication
27
+ - Migrates a legacy `~/.cocod` wallet to `~/.routstrd/wallet` if one is present,
28
+ stopping any running external `cocod` first
29
+ - Initializes the in-process Cashu wallet
30
+ - Starts the daemon and configures a client integration
31
+
32
+ | Option | Description |
33
+ |--------|-------------|
34
+ | `--opencode` | Set up OpenCode integration (non-interactive) |
35
+ | `--openclaw` | Set up OpenClaw integration (non-interactive) |
36
+ | `--pi-agent` | Set up Pi Agent integration (non-interactive) |
37
+ | `--claude-code` | Set up Claude Code integration (non-interactive) |
38
+ | `--hermes` | Set up Hermes integration (non-interactive) |
39
+ | `--skip-integration` | Skip integration setup |
40
+
41
+ Use at most one integration flag. For several clients, run `routstrd clients add`
42
+ afterwards. `--skip-integration` cannot be combined with an integration flag.
25
43
 
26
44
  ### `routstrd start`
27
45
 
@@ -30,28 +48,50 @@ Start the background daemon process.
30
48
  | Option | Description |
31
49
  |--------|-------------|
32
50
  | `--port <port>` | Port to listen on (default: 8008) |
51
+ | `--host <host>` | Bind address (default: 127.0.0.1) |
33
52
  | `-p, --provider <provider>` | Default provider to use |
34
53
 
54
+ ### `routstrd daemon`
55
+
56
+ Run the daemon in the foreground (same options as `start`). Useful for debugging
57
+ and for process supervisors that expect a non-forking process.
58
+
35
59
  ### `routstrd stop`
36
60
 
37
61
  Stop the background daemon.
38
62
 
39
63
  ### `routstrd restart`
40
64
 
41
- Restart the daemon (stops if running, then starts).
42
-
43
- | Option | Description |
44
- |--------|-------------|
45
- | `--port <port>` | Port to listen on |
46
- | `-p, --provider <provider>` | Default provider to use |
65
+ Restart the daemon (stops if running, then starts). Same options as `start`.
47
66
 
48
67
  ### `routstrd status`
49
68
 
50
69
  Check daemon and wallet status. Returns JSON with current state.
51
70
 
71
+ ### `routstrd ping`
72
+
73
+ Test connectivity to the daemon.
74
+
52
75
  ### `routstrd balance`
53
76
 
54
- Get wallet and API key balances. Shows per-mint wallet balances, per-key API balances, and a grand total (all in sats).
77
+ Get wallet and API key balances. Shows per-mint wallet balances, per-key API
78
+ balances, and a grand total (all in sats).
79
+
80
+ | Option | Description |
81
+ |--------|-------------|
82
+ | `--api-keys` | List all stored API keys (baseUrl + key + balance) |
83
+ | `--delete-api-keys <baseUrl>` | Delete the API key stored for a provider base URL (refunds its balance first) |
84
+ | `--mint-url <url>` | Mint to refund the deleted API key balance to (defaults to the active wallet mint) |
85
+
86
+ ### `routstrd refund`
87
+
88
+ Refund pending tokens and API keys to a mint.
89
+
90
+ | Option | Default | Description |
91
+ |--------|---------|-------------|
92
+ | `-m, --mint-url <mintUrl>` | active wallet mint | Mint URL to refund to |
93
+ | `-y, --yes` | false | Skip confirmation prompt |
94
+ | `--xcashu` | false | Refund xcashu tokens only |
55
95
 
56
96
  ### `routstrd models`
57
97
 
@@ -60,6 +100,7 @@ List available routstr21 models (discovered via Nostr).
60
100
  | Option | Description |
61
101
  |--------|-------------|
62
102
  | `-r, --refresh` | Force refresh models from Nostr |
103
+ | `-m, --model <id>` | Show the providers serving a specific model |
63
104
 
64
105
  ### `routstrd usage`
65
106
 
@@ -69,7 +110,19 @@ Show recent usage logs and total sats cost.
69
110
  |--------|---------|-------------|
70
111
  | `-n, --limit <number>` | 10 | Number of recent entries (max 1000) |
71
112
 
72
- Shows timestamp, model, provider, sats cost, token counts, and request ID for each entry.
113
+ Shows timestamp, model, provider, sats cost, token counts, and request ID for
114
+ each entry.
115
+
116
+ ### `routstrd history`
117
+
118
+ Show wallet transaction history.
119
+
120
+ | Option | Default | Description |
121
+ |--------|---------|-------------|
122
+ | `-n, --limit <number>` | 50 | Number of entries to show |
123
+ | `--offset <number>` | 0 | Number of entries to skip |
124
+ | `-v, --verbose` | false | Show full details including encoded Cashu tokens |
125
+ | `--json` | false | Output raw JSON with token objects (no encoding) |
73
126
 
74
127
  ### `routstrd providers`
75
128
 
@@ -77,7 +130,12 @@ List and manage providers (subcommand required).
77
130
 
78
131
  #### `routstrd providers list`
79
132
 
80
- List all providers with their enabled/disabled status. Shows index, status, and base URL.
133
+ List all providers with their enabled/disabled status. Shows index, status, and
134
+ base URL.
135
+
136
+ | Option | Description |
137
+ |--------|-------------|
138
+ | `--refresh` | Force re-fetch all Nostr events and refresh models from every enabled provider |
81
139
 
82
140
  ```
83
141
  Providers (12 total, 2 disabled):
@@ -103,6 +161,10 @@ Enable providers by their index numbers.
103
161
  routstrd providers enable 0 2 5
104
162
  ```
105
163
 
164
+ #### `routstrd providers reviews`
165
+
166
+ Show all known providers with their stored review events and event IDs.
167
+
106
168
  ### `routstrd clients`
107
169
 
108
170
  List and manage API clients (subcommand required).
@@ -113,7 +175,11 @@ List and manage API clients (subcommand required).
113
175
  | `--disable-automatic-refresh` | Disable the daemon's scheduled refresh job |
114
176
  | `--enable-automatic-refresh` | Re-enable the daemon's scheduled refresh job |
115
177
 
116
- The daemon refreshes models and client integrations on a schedule (every 21 minutes by default). Use `--manual-refresh` to do it on demand, and `--disable-automatic-refresh` to stop the scheduled job — the setting is stored in the daemon's `config.json` (`autoRefresh.enabled`) and takes effect without a restart.
178
+ The daemon refreshes models and client integrations on a schedule (every 21
179
+ minutes by default). Use `--manual-refresh` to do it on demand, and
180
+ `--disable-automatic-refresh` to stop the scheduled job — the setting is stored
181
+ in the daemon's `config.json` (`autoRefresh.enabled`) and takes effect without a
182
+ restart.
117
183
 
118
184
  ```sh
119
185
  routstrd clients --manual-refresh # refresh models + integrations now
@@ -125,7 +191,6 @@ routstrd clients --enable-automatic-refresh # scheduled refresh back on
125
191
 
126
192
  List all registered clients with their ID, name, API key, and creation date.
127
193
 
128
-
129
194
  #### `routstrd clients add`
130
195
 
131
196
  Add a new client or set up a client integration.
@@ -137,10 +202,11 @@ Add a new client or set up a client integration.
137
202
  | `--openclaw` | Set up OpenClaw integration |
138
203
  | `--pi-agent` | Set up Pi Agent integration |
139
204
  | `--claude-code` | Set up Claude Code integration |
205
+ | `--hermes` | Set up Hermes integration |
140
206
 
141
207
  ```sh
142
208
  routstrd clients add --opencode --pi-agent --claude-code # multiple integrations
143
- routstrd clients add -n "My App" # generic client
209
+ routstrd clients add -n "My App" # generic client
144
210
  ```
145
211
 
146
212
  Returns the client ID and API key for use with the OpenAI-compatible API.
@@ -151,56 +217,58 @@ Delete a registered client by its ID.
151
217
 
152
218
  ### `routstrd npubs`
153
219
 
154
- Manage registered npubs and their roles/names (subcommand required). Management commands route through the auth proxy (`--auth-url`) and use NIP-98 auth.
220
+ Manage registered npubs and their roles/names (subcommand required). Management
221
+ commands route through the auth proxy (`--auth-url`) and use NIP-98 auth.
155
222
 
156
223
  | Command | Description |
157
224
  |---------|-------------|
158
225
  | `routstrd npubs list` | List registered npubs with role and display name |
159
226
  | `routstrd npubs register [--name <name>]` | Register yourself as the first admin (bootstrap only) |
160
- | `routstrd npubs add <npub> [--role <role>] [--name <name>]` | Add an npub (accepts hex or npub1...) |
227
+ | `routstrd npubs add <npub> [--role <role>] [--name <name>]` | Add an npub (accepts hex or npub1...); defaults to the `user` role |
161
228
  | `routstrd npubs update <npub> [--role <role>] [--name <name>]` | Update role and/or name (admin only) |
162
229
  | `routstrd npubs delete <npub>` | Delete an npub |
163
230
 
164
- ### `routstrd remote <url>`
231
+ ### `routstrd remote [url]`
232
+
233
+ With no URL, print the configured remote daemon. Pass a URL to configure one — a
234
+ Nostr identity (nsec/npub) is generated automatically for NIP-98 authentication.
165
235
 
166
- Configure a remote daemon URL. Generates a Nostr identity (nsec/npub) for NIP-98 authentication automatically.
236
+ | Option | Description |
237
+ |--------|-------------|
238
+ | `--auth-url <authUrl>` | URL of the auth proxy used by management commands (`npubs`, `clients`, `usage`) |
167
239
 
168
240
  ```sh
169
- routstrd remote https://your-remote-daemon.com
241
+ routstrd remote # show current remote
242
+ routstrd remote https://your-remote-daemon.com # configure one
170
243
  ```
171
244
 
245
+ ### `routstrd local`
246
+
247
+ Switch back to local daemon mode (clears the configured remote daemon URL).
248
+
172
249
  ### `routstrd refresh`
173
250
 
174
- Refresh routstr21 models from Nostr and re-run integrations for all registered clients. Equivalent to `routstrd clients --manual-refresh`.
251
+ Refresh routstr21 models from Nostr and re-run integrations for all registered
252
+ clients. Equivalent to `routstrd clients --manual-refresh`.
175
253
 
176
- | Field | Type | Default | Description |
177
- |-------|------|---------|-------------|
178
- | `port` | number | 8008 | Daemon HTTP port |
179
- | `provider` | string\|null | null | Default provider URL |
180
- | `daemonUrl` | string\|null | null | Remote daemon URL |
181
- | `nsec` | string\|null | null | Nostr secret key for NIP-98 auth |
182
- | `cocodPath` | string\|null | null | Custom path to cocod executable |
183
- | `mode` | string | `"apikeys"` | Client mode (`apikeys` or `xcashu`) |
184
- | `autoRefresh` | object | `{ enabled: true }` | Scheduled refresh job settings (`enabled`, `intervalMs`) |
254
+ ### `routstrd update`
185
255
 
186
- | Variable | Default | Description |
187
- |----------|---------|-------------|
188
- | `ROUTSTRD_DIR` | `~/.routstrd` | Config directory |
189
- | `ROUTSTRD_WALLET_DIR` | `~/.routstrd/wallet` | In-process Cashu wallet data directory |
190
- | `ROUTSTRD_WALLET_PID` | `<wallet>/wallet.pid` | In-process wallet lock path |
191
- | `COCOD_DIR` | `~/.cocod` | Legacy external cocod compatibility directory |
256
+ Update routstrd to the latest version. Standalone-binary installs update
257
+ in place; npm/bun installs are updated through the package manager.
192
258
 
193
259
  ### `routstrd mode`
194
260
 
195
261
  Interactive prompt to set the client mode:
196
- 1. **lazyrefund/apikeys** (default) — Pseudonymous accounts kept with Routstr nodes, refunded after 5 mins if unused.
197
- 2. **xcashu** (coming soon) — Balances never kept with nodes, all refunded in response.
262
+ 1. **lazyrefund/apikeys** (default) — Pseudonymous accounts kept with Routstr
263
+ nodes, refunded after 5 mins if unused.
264
+ 2. **xcashu** (coming soon) — Balances never kept with nodes, all refunded in
265
+ response.
198
266
 
199
267
  Changing mode restarts the daemon automatically.
200
268
 
201
- ### `routstrd monitor`
269
+ ### `routstrd monitor` / `routstrd top`
202
270
 
203
- Open an interactive TUI (htop-like) for usage monitoring.
271
+ Open an interactive TUI (htop-like) for usage monitoring. `top` is an alias.
204
272
 
205
273
  ### `routstrd logs`
206
274
 
@@ -211,17 +279,54 @@ View daemon logs.
211
279
  | `-f, --follow` | false | Follow log output (like `tail -f`) |
212
280
  | `-c, --coco` | false | Show Cashu wallet-engine (coco) logs instead of daemon logs |
213
281
  | `-n, --lines <number>` | 50 | Number of lines to show |
282
+ | `-r, --recent` | false | List recent request IDs with their model |
283
+ | `-i, --request-id <id>` | | Only show log lines for a specific request ID |
284
+
285
+ Log files are stored at `~/.routstrd/logs/YYYY-MM-DD.log`. Wallet-engine
286
+ (Cashu/coco) diagnostics go to a separate `~/.routstrd/coco-logs/YYYY-MM-DD.log`
287
+ so they don't pollute the main daemon logs.
288
+
289
+ ### `routstrd service`
214
290
 
215
- Log files are stored at `~/.routstrd/logs/YYYY-MM-DD.log`. Wallet-engine (Cashu/coco) diagnostics go to a separate `~/.routstrd/coco-logs/YYYY-MM-DD.log` so they don't pollute the main daemon logs.
291
+ Manage routstrd as a system service using PM2, so it survives reboots.
292
+
293
+ | Command | Description |
294
+ |---------|-------------|
295
+ | `routstrd service install` | Install and start routstrd under PM2 |
296
+ | `routstrd service uninstall` | Stop and remove routstrd from PM2 |
297
+ | `routstrd service logs` | View PM2 logs for routstrd |
216
298
 
217
299
  ## Wallet Commands
218
300
 
219
- New wallets automatically trust `https://mint.cubabitcoin.org` as their default mint. The default is used when a wallet command does not include `--mint-url`.
301
+ New wallets trust two mints out of the box: `https://mint.cubabitcoin.org` and
302
+ `https://mint.minibits.cash/Bitcoin`. `https://mint.cubabitcoin.org` is the
303
+ default mint, and the default is used when a wallet command does not include
304
+ `--mint-url`. An existing wallet keeps whatever default it already has; the
305
+ shipped mints are only added as trusted, never as the default. Use
306
+ `routstrd wallet mints add <url>` to trust another mint.
307
+
308
+ ### `routstrd send <target>` / `routstrd receive <value>`
309
+
310
+ Shortcuts for the common wallet operations:
311
+
312
+ | Command | Behaviour |
313
+ |---------|-----------|
314
+ | `routstrd send 2100` | Numeric target → create a Cashu token for that many sats |
315
+ | `routstrd send lnbc1...` | Non-numeric target → pay that Lightning invoice |
316
+ | `routstrd receive 2100` | Numeric value → create a Lightning invoice for that many sats and wait for payment |
317
+ | `routstrd receive cashuB...` | Non-numeric value → receive that Cashu token |
318
+
319
+ Both accept `--mint-url <url>`.
220
320
 
221
321
  ### `routstrd wallet status`
222
322
 
223
323
  Check wallet status.
224
324
 
325
+ ### `routstrd wallet doctor`
326
+
327
+ Diagnose conflicting wallets — the current routstrd wallet versus a legacy
328
+ `cocod` wallet.
329
+
225
330
  ### `routstrd wallet unlock <passphrase>`
226
331
 
227
332
  Unlock the wallet with a passphrase.
@@ -230,6 +335,17 @@ Unlock the wallet with a passphrase.
230
335
 
231
336
  Get wallet balance.
232
337
 
338
+ ### `routstrd wallet cleanup`
339
+
340
+ Clear stuck pending/in-flight wallet operations.
341
+
342
+ | Option | Default | Description |
343
+ |--------|---------|-------------|
344
+ | `--mint-url <url>` | all mints | Only clean up operations for this mint URL |
345
+ | `--min-age <hours>` | 168 | Minimum age for reclaiming sends and cancelling melts (expired mint quotes are always failed) |
346
+ | `--dry-run` | false | Report what would be cleaned without applying changes |
347
+ | `-y, --yes` | false | Skip confirmation prompt |
348
+
233
349
  ### `routstrd wallet receive cashu <token>`
234
350
 
235
351
  Receive funds via a Cashu token.
@@ -260,7 +376,7 @@ Pay a Lightning invoice.
260
376
 
261
377
  ### `routstrd wallet mints list`
262
378
 
263
- List configured wallet mints.
379
+ List configured wallet mints. Includes the mints trusted by default (`https://mint.cubabitcoin.org`, `https://mint.minibits.cash/Bitcoin`) plus any added manually.
264
380
 
265
381
  ### `routstrd wallet mints add <url>`
266
382
 
@@ -274,6 +390,41 @@ Set the persistent default mint. If necessary, the mint is added as trusted firs
274
390
 
275
391
  Get info about a specific mint.
276
392
 
393
+ ### `routstrd wallet npc`
394
+
395
+ NPC (npubx.cash) Lightning address operations.
396
+
397
+ | Command | Description |
398
+ |---------|-------------|
399
+ | `routstrd wallet npc address` | Show this wallet's NPC Lightning address |
400
+ | `routstrd wallet npc username <name> [--confirm]` | Claim an NPC username; `--confirm` pays the claim fee |
401
+ | `routstrd wallet npc sync` | Manually sync paid NPC quotes into the wallet |
402
+
403
+ ## NWC (Nostr Wallet Connect)
404
+
405
+ Connect an external Lightning wallet and let it fund the Cashu wallet.
406
+
407
+ | Command | Description |
408
+ |---------|-------------|
409
+ | `routstrd nwc connect [connection-string]` | Connect via `nostr+walletconnect://...` (prompts if omitted) |
410
+ | `routstrd nwc disconnect` | Disconnect from the NWC wallet |
411
+ | `routstrd nwc status` | Show connection status and wallet info |
412
+ | `routstrd nwc fund <amount>` | Manually fund the Cashu wallet from the connected NWC wallet |
413
+
414
+ ### `routstrd nwc auto-refill on`
415
+
416
+ Enable automatic wallet refill from NWC.
417
+
418
+ | Option | Default | Description |
419
+ |--------|---------|-------------|
420
+ | `--threshold <sats>` | 500 | Refill when the Cashu balance drops below this |
421
+ | `--amount <sats>` | 1000 | Refill this many sats at a time |
422
+ | `--cooldown <seconds>` | 300 | Minimum time between refills |
423
+
424
+ ### `routstrd nwc auto-refill off`
425
+
426
+ Disable auto-refill.
427
+
277
428
  ## Daemon API
278
429
 
279
430
  The daemon exposes an OpenAI-compatible HTTP API at `http://localhost:8008`:
@@ -298,6 +449,10 @@ Route a chat completion request.
298
449
  }
299
450
  ```
300
451
 
452
+ The incoming request path is forwarded to the provider, so the Anthropic
453
+ Messages API (`POST /v1/messages`) and the OpenAI Responses API
454
+ (`POST /v1/responses`) are proxied in their own formats as well.
455
+
301
456
  ## Configuration
302
457
 
303
458
  Config file: `~/.routstrd/config.json`
@@ -305,10 +460,20 @@ Config file: `~/.routstrd/config.json`
305
460
  | Field | Type | Default | Description |
306
461
  |-------|------|---------|-------------|
307
462
  | `port` | number | 8008 | Daemon HTTP port |
463
+ | `host` | string | `"127.0.0.1"` | Bind address |
308
464
  | `provider` | string\|null | null | Default provider URL |
309
- | `cocodPath` | string\|null | null | Custom path to cocod executable |
465
+ | `cocodPath` | string\|null | null | Custom path to a legacy cocod executable |
310
466
  | `mode` | string | `"apikeys"` | Client mode (`apikeys` or `xcashu`) |
467
+ | `maxTokens` | number | 64000 | Completion budget applied when a client sets no output-token limit |
468
+ | `daemonUrl` | string | — | Remote daemon URL (set by `routstrd remote`) |
469
+ | `authUrl` | string | — | Auth proxy URL for management commands |
470
+ | `nsec` | string | — | Nostr secret key for NIP-98 auth |
471
+ | `relays` | string[] | — | Nostr relays to use for discovery |
472
+ | `routstrPubkey` | string | — | Override the Routstr announcement pubkey |
473
+ | `routstrModelsPubkey` | string | — | Override the routstr21 models pubkey |
474
+ | `nwc` | object | — | NWC settings (`mode`, `connectionString`, `autoRefill`) |
311
475
  | `autoRefresh` | object | `{ enabled: true }` | Scheduled refresh job settings (`enabled`, `intervalMs`) |
476
+ | `requestResponseLogging` | object | — | Request/response log sink settings |
312
477
 
313
478
  ### Environment Variables
314
479
 
@@ -317,17 +482,26 @@ Config file: `~/.routstrd/config.json`
317
482
  | `ROUTSTRD_DIR` | `~/.routstrd` | Config directory |
318
483
  | `ROUTSTRD_SOCKET` | `~/.routstrd/routstrd.sock` | IPC socket path |
319
484
  | `ROUTSTRD_PID` | `~/.routstrd/routstrd.pid` | PID file path |
485
+ | `ROUTSTRD_WALLET_DIR` | `~/.routstrd/wallet` | In-process Cashu wallet data directory |
486
+ | `ROUTSTRD_WALLET_PID` | `<wallet>/wallet.pid` | In-process wallet lock path |
487
+ | `COCOD_DIR` | `~/.cocod` | Legacy external cocod compatibility directory |
320
488
 
321
489
  ## Remote Mode
322
490
 
323
- When `daemonUrl` is configured, commands connect to a remote daemon instead of a local one:
491
+ When `daemonUrl` is configured, commands connect to a remote daemon instead of a
492
+ local one:
324
493
  - Client names are suffixed with the last 7 chars of your npub
325
494
  - All requests are automatically NIP-98 signed using your local nsec
326
- - Local-only commands (`onboard`, `start`, `restart`, `mode`, `logs`, `service`) are disabled
495
+ - Local-only commands (`onboard`, `start`, `restart`, `mode`, `logs`, `service`)
496
+ are disabled
497
+
498
+ Run `routstrd local` to switch back.
327
499
 
328
500
  ## Pi Integration
329
501
 
330
- When `routstrd onboard` runs, it automatically configures a `routstr` provider in `pi`'s `models.json` with an OpenAI-compatible base URL and API key. This allows pi (the AI coding agent) to use Routstr providers seamlessly.
502
+ When `routstrd onboard` runs, it automatically configures a `routstr` provider in
503
+ `pi`'s `models.json` with an OpenAI-compatible base URL and API key. This allows
504
+ pi (the AI coding agent) to use Routstr providers seamlessly.
331
505
 
332
506
  ## File Locations
333
507
 
@@ -337,5 +511,21 @@ When `routstrd onboard` runs, it automatically configures a `routstr` provider i
337
511
  | `~/.routstrd/routstr.db` | SQLite database |
338
512
  | `~/.routstrd/routstrd.sock` | IPC socket |
339
513
  | `~/.routstrd/routstrd.pid` | PID file |
514
+ | `~/.routstrd/wallet/` | In-process Cashu wallet data (`config.json`, `coco.db`, `wallet.pid`) |
340
515
  | `~/.routstrd/logs/YYYY-MM-DD.log` | Daily daemon log files |
341
516
  | `~/.routstrd/coco-logs/YYYY-MM-DD.log` | Daily Cashu wallet-engine (coco) log files |
517
+
518
+ ## Development
519
+
520
+ ```sh
521
+ bun install
522
+ bun run lint # tsc --noEmit
523
+ bun test
524
+ bun run build # bundles dist/index.js and dist/daemon/index.js
525
+ ```
526
+
527
+ End-to-end smoke test against a running daemon (needs a funded client API key):
528
+
529
+ ```sh
530
+ ROUTSTRD_API_KEY=<api-key> bun run smoke <model-id> [model-id ...]
531
+ ```