From 821245ac1da77c30497d0dfb5660951726784f08 Mon Sep 17 00:00:00 2001 From: Laan Tungir Date: Tue, 4 Aug 2026 21:31:18 -0400 Subject: [PATCH] v0.1.14 - Update README with named path-roles documentation, wizard changes, set syntax, fixed paths --- README.md | 53 ++++++++++++++++++++++++++++++++++++++++++----------- src/main.c | 4 ++-- 2 files changed, 44 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0415c67..2212fd1 100644 --- a/README.md +++ b/README.md @@ -495,42 +495,72 @@ Selector resolution order: `role` → `nostr_index` → `role_path` → default #### Named path-roles -In the interactive wizard, you can define **named path-roles** that bind a role name (which acts as an access token for clients) to a derivation path template with a range and default index. The derivation path is hidden from clients — they only know the role name. +In the interactive wizard, you can define **named path-roles** that bind a role name (which acts as an access token for clients) to a derivation path template. The derivation path is hidden from clients — they only know the role name. ``` Wizard: + Define a named path role? [y/N] y Role name: myrole - Purpose [nostr]: nostr - Curve [secp256k1]: secp256k1 - Path template: m/44'/1237'/0-3/1/0 - Default index [0]: 1 + Curve: + 1) secp256k1 (Nostr, Bitcoin) + 2) ed25519 (SSH) + 3) x25519 (key agreement, Age) + 4) ml-dsa-65 (post-quantum signatures) + 5) slh-dsa-128s (post-quantum signatures) + 6) ml-kem-768 (post-quantum KEM) + Select [1]: 1 + Path template (use N-M for range, A+B+C for set, e.g. m/44'/1237'/1-100/2/0): + (arrow keys to edit, Enter to accept): + m/44'/1237'/0-3/1/0 + Default index [0]: ``` +Purpose is auto-detected from the path prefix (e.g. `m/44'/1237'` → nostr, `m/44'/102001'` → ssh). The path template is pre-filled with `m/44'/1237'/0'/0/0` and can be edited inline with arrow keys, backspace, and delete. + +**Path template syntax:** +- **Range**: `m/44'/1237'/0-3/1/0` — index 0..3, hardened if segment ends with `'` (e.g. `0-3'`) +- **Set**: `m/44'/1237'/1+34+54/1/0` — specific indices 1, 34, 54 +- **Fixed path**: `m/44'/1237'/0'/0/0` — no variable segment, single fixed key (no index needed) +- The first segment that is a plain number, range (`N-M`), or set (`A+B+C`) becomes the variable (`%d`). Segments with `'` (like `44'`, `1237'`) are treated as literal hardened constants. + +**Default index**: Defaults to 0 if 0 is within the allowed range/set, otherwise the first element. The user can override at the prompt. + +When named path-roles are defined, the path whitelist prompt is skipped (the roles themselves define the allowed paths). + Clients then request keys by role name, optionally with an `index` within the allowed range: ```json -{"id":"1","method":"nostr_get_public_key","params":[{},{"role":"myrole"}]} +{"id":"1","method":"nostr_get_public_key","params":[{"role":"myrole"}]} ``` -→ derives `m/44'/1237'/1/1/0` (default index 1). +→ derives `m/44'/1237'/0/1/0` (default index 0). ```json -{"id":"2","method":"nostr_get_public_key","params":[{},{"role":"myrole","index":2}]} +{"id":"2","method":"nostr_get_public_key","params":[{"role":"myrole","index":2}]} ``` → derives `m/44'/1237'/2/1/0` (index 2, within range 0-3). ```json -{"id":"3","method":"nostr_get_public_key","params":[{},{"role":"myrole","index":5}]} +{"id":"3","method":"nostr_get_public_key","params":[{"role":"myrole","index":5}]} ``` → `2005 index_out_of_range` (5 is outside 0-3). ```json -{"id":"4","method":"nostr_get_public_key","params":[{},{"role":"unknown"}]} +{"id":"4","method":"nostr_get_public_key","params":[{"role":"unknown"}]} ``` → `1002 unknown_role` (name not registered). +For fixed-path roles (no range/set), clients omit the `index` field: + +```json +{"id":"5","method":"nostr_get_public_key","params":[{"role":"fixedrole"}]} +``` +→ derives the single fixed path. + #### Path whitelist (`--allow-index`) -The `--allow-index` flag (and the wizard's whitelist prompt) accepts both integer `nostr_index` tokens and path-template tokens. A `role_path` request is auto-registered and derived on demand if it matches a whitelisted template; otherwise it returns `2003 path_not_allowed`. +The `--allow-index` flag accepts both integer `nostr_index` tokens and path-template tokens. A `role_path` request is auto-registered and derived on demand if it matches a whitelisted template; otherwise it returns `2003 path_not_allowed`. + +**Note**: When named path-roles are defined in the wizard, the path whitelist prompt is skipped — the roles themselves define the allowed paths. The `--allow-index` flag can still be used for additional raw `role_path` access. ``` nsigner --allow-index "m/44'/1237'/0-3/1/0" @@ -541,6 +571,7 @@ Allowed syntax (comma-separated): - `0-3` / `0,1,3` — integer `nostr_index` values (backward compatible) - `m/44'/1237'/0-3/0/0` — NIP-06 paths X=0..3 - `m/44'/1237'/0-3/1/0` — custom paths X=0..3, change=1 +- `m/44'/1237'/1+34+54/1/0` — set of specific indices (1, 34, 54) - `m/44'/1237'/0-3/0/0,m/44'/1237'/0-3/1/0` — multiple templates ### 4.7 Pre-approval diff --git a/src/main.c b/src/main.c index a89141e..1933eb2 100644 --- a/src/main.c +++ b/src/main.c @@ -800,8 +800,8 @@ int socket_name_random(char *out, size_t out_len); /* Version information (auto-updated by build/version tooling) */ #define NSIGNER_VERSION_MAJOR 0 #define NSIGNER_VERSION_MINOR 1 -#define NSIGNER_VERSION_PATCH 13 -#define NSIGNER_VERSION "v0.1.13" +#define NSIGNER_VERSION_PATCH 14 +#define NSIGNER_VERSION "v0.1.14" /* NSIGNER_HEADERLESS_DECLS_END */