# Plan: Move Connection Instructions to On-Demand Display ## Problem The Connections section in the running TUI is verbose and confusing. It mixes server addresses with client command examples, and when multiple transports are active (Unix + TCP + HTTP) it takes up a large chunk of the status screen, pushing the Roles and Activity sections down. The connection instructions are only needed once when a user wants to know how to reach the signer — they don't need to be permanently visible. ## Solution Remove the Connections section from the default `render_status()` display. Add a new hotkey **`d`** (display connection instructions) that prints the connection info on demand, then returns to the normal status view on the next refresh/keystroke. ## Design ### Default status display (after change) The Connections section is removed. The display shows: Roles, Activity, status line, hotkey menu. A one-line hint at the top reminds the user that `d` shows connection instructions. ```text ================================================================================ n_signer v0.0.53 ================================================================================ > Main Menu Press d for connection instructions Roles Role Purpose Curve Selector -------------------- ------------ ------------ ------------ main nostr secp256k1 nostr_index ops nostr secp256k1 nostr_index backup bitcoin secp256k1 role_path Activity (latest first) 16:03:11 allow caller=uid:1000 method=get_public_key role=main 16:02:44 prompt caller=uid:1000 method=sign_event role=ops 16:02:46 allow caller=uid:1000 method=sign_event role=ops 15:59:10 deny caller=uid:1001 method=sign_event error=unauthorized session=unlocked (12 words) signer=nsigner_hairy_dog derived=3 auto-approve=OFF l lock/reunlock r refresh a toggle auto-approve d display connections q/x quit ``` ### On-demand connection display (press `d`) When the user presses `d`, the screen clears and shows **only** the connection instructions, with clear spacing between transports. Each transport block shows the **connection string** (the address/endpoint to reach), a blank line, then an **Example:** with the client command indented beneath. No "Server:" / "Client:" labels — just the address and an example. A footer tells the user how to return. ```text ================================================================================ n_signer v0.0.53 ================================================================================ > Connection Instructions Unix socket @nsigner_hairy_dog Example: nsigner --socket-name nsigner_hairy_dog client '' Qrexec (bridge-source-trusted): qrexec-client-vm qubes.NsignerRpc FIPS http://npub10vt4scusw6lq27qw83nfwp5sqer492h0tnwa8ugqjvp6l4xuz2qsdycrwd.fips:11111 Example: curl -X POST http://npub10vt4scusw6lq27qw83nfwp5sqer492h0tnwa8ugqjvp6l4xuz2qsdycrwd.fips:11111/ \ -H 'Content-Type: application/json' \ -d '' HTTP http://127.0.0.1:11112 Example: curl -X POST http://127.0.0.1:11112/ \ -H 'Content-Type: application/json' \ -d '' OTP pad: 333e9902db839d9d... (offset 288 / 1048576 bytes) session=unlocked (12 words) signer=nsigner_hairy_dog derived=3 auto-approve=OFF Press any key to return ``` ### Key differences from current display 1. **Spacing between transports** — each transport gets its own titled block with blank lines separating it from the next, instead of a flat list of `Server:` / `Client:` lines. 2. **Connection string + example, no labels** — each block shows the bare connection string (e.g. `http://127.0.0.1:11112`), then an `Example:` with the client command indented beneath. No confusing "Server:" / "Client:" labels. 3. **On-demand only** — the default running display no longer shows connections at all, just a one-line hint. The user presses `d` when they need the instructions, reads them, then presses any key to return. 4. **OTP pad status** — shown at the bottom of the connection display (it's connection-related: which pad is bound and how much has been consumed). ## Implementation Steps 1. **[`src/main.c`](src/main.c) — `render_status()`** (line 1451): - Remove the Connections section (lines 1464-1471). - Add a one-line hint after the top frame: `tui_print("Press d for connection instructions");` - Add a blank line after the hint. 2. **[`src/main.c`](src/main.c) — new function `render_connections()`**: - Clears the screen and renders the top frame. - Iterates `g_connection_info` but formats it with the spaced layout shown above. Since `g_connection_info` already stores formatted strings like `"Server: unix @nsigner_hairy_dog"` and `" Client: nsigner --socket-name ... client ''"`, either: - **Option A**: Reformat the stored strings into blocks by detecting `Server:` lines as transport boundaries and printing blank lines + indentation. - **Option B**: Store connection info in a structured form (transport type, server address, client command(s)) and render the block layout from the structured data. - Option B is cleaner but requires changing `connection_info_add()` and all its call sites. Option A is a smaller change. **Recommend Option A** for now — parse the existing flat list into blocks. - **FIPS section**: The connection string is the npub-based FIPS URL (`http://.fips:`), which FIPS resolves to the signer's TCP endpoint. The example uses `curl` since FIPS makes the endpoint HTTP-reachable for clients with FIPS installed. The raw TCP bind address (`tcp:[::]:11111`) is not shown — it's an implementation detail; the npub URL is what clients use. - Print OTP pad status if bound. - Print the status line at the bottom. - Print "Press any key to return" footer. 3. **[`src/main.c`](src/main.c) — `g_main_menu_items`** (line 825): - Add `{"^_d^: display connections", 'd'}` to the menu array. 4. **[`src/main.c`](src/main.c) — event loop** (line ~3068, the stdin keystroke handler): - Add a case for `'d'`: - Call `render_connections()`. - Read one keystroke from stdin (blocking `read()`). - Call `render_status()` to return to the normal display. 5. **[`README.md`](README.md) §3.2**: - Update the example TUI layout to match the new default display (no Connections section, `d` in hotkeys). - Add a note that pressing `d` shows the connection instructions. 6. **[`api.md`](api.md) §5 Transports**: - No changes needed — the transport documentation is already separate from the TUI display. ## Files Changed | File | Change | |------|--------| | [`src/main.c`](src/main.c) | Remove Connections from `render_status()`, add `render_connections()`, add `d` hotkey + menu item + event loop case | | [`README.md`](README.md) | Update §3.2 example display to match new layout | | [`api.md`](api.md) | No changes | ## Verification - `make dev` builds clean. - Start nsigner with all transports selected. Default display shows no Connections section, just the "Press d for connection instructions" hint. - Press `d` — connection instructions appear with clear spacing between transports. - Press any key — returns to normal status display. - All other hotkeys (`l`, `r`, `a`, `q`) still work.