diff --git a/nostr_core/NSIGNER_INTEGRATION.md b/nostr_core/NSIGNER_INTEGRATION.md index d33f43f6..366aea30 100644 --- a/nostr_core/NSIGNER_INTEGRATION.md +++ b/nostr_core/NSIGNER_INTEGRATION.md @@ -116,9 +116,10 @@ int nostr_signer_nsigner_set_auth(nostr_signer_t* signer, * together for nostr_* verbs; set the role via the constructor and the path * here. */ int nostr_signer_nsigner_set_role_path(nostr_signer_t* signer, const char* role_path); -/* Compatibility shim: expands NIP-06 index N into role="main" + - * role_path="m/44'/1237'/N'/0/0" and stores N as the derive index. */ -int nostr_signer_nsigner_set_nostr_index(nostr_signer_t* signer, int nostr_index); +/* Set the algorithm derivation index used by the derive verb + * (nostr_signer_derive_hmac). The derive verb is algorithm-based and + * requires an explicit index (no default). Pass a negative value to clear. */ +int nostr_signer_nsigner_set_derive_index(nostr_signer_t* signer, int index); #endif ``` @@ -136,20 +137,14 @@ field is rejected by n_signer with `2008 role_required` / `2009 path_required`. The bare `{"nostr_index":N}` selector is **removed** on the n_signer side (error `2006 nostr_index_deprecated`); this library never emits it. -Two ways to set the selector: - -1. **`nostr_signer_nsigner_set_role_path(signer, path)`** — explicit. Pass the - role name to the constructor and the full path here. This is the canonical - path for new code. -2. **`nostr_signer_nsigner_set_nostr_index(signer, N)`** — convenience. Expands - `N` into `role="main"` + `role_path="m/44'/1237'/N'/0/0"` and also stores `N` - as the algorithm `index` used by `nostr_signer_derive_hmac`. The signer must - have a `main` role whose template matches the expanded path. +Set the selector with **`nostr_signer_nsigner_set_role_path(signer, path)`** — +pass the role name to the constructor and the full path here. This is the only +way to select a key for `nostr_*` verbs. For the algorithm-based `derive` verb (used by `nostr_signer_derive_hmac`), the backend emits `{"algorithm":"secp256k1","index":N}`. The index comes from the -last `set_nostr_index` call; if unset, the request is sent without `index` and -n_signer rejects it with `missing_index`. +last `nostr_signer_nsigner_set_derive_index` call; if unset, the request is +sent without `index` and n_signer rejects it with `missing_index`. ### 2.2 Transport constructors + framed I/O + discovery (`nostr_core/nsigner_transport.h`) diff --git a/nostr_core/nostr_signer.c b/nostr_core/nostr_signer.c index 0c320192..9b77b6ec 100644 --- a/nostr_core/nostr_signer.c +++ b/nostr_core/nostr_signer.c @@ -549,10 +549,8 @@ static int signer_remote_derive_hmac(nostr_signer_t* signer, /* Build the options object with algorithm:"secp256k1" and the index. * The derive verb is algorithm-based and requires an explicit index - * (no default). The index is set via nostr_signer_nsigner_set_nostr_index - * (which stores it in derive_index) or directly via a future - * set_derive_index helper. Without an index the signer rejects the - * request with missing_index. */ + * (no default). The index is set via nostr_signer_nsigner_set_derive_index. + * Without an index the signer rejects the request with missing_index. */ opts = cJSON_CreateObject(); if (opts == NULL) { cJSON_Delete(params); @@ -1576,7 +1574,7 @@ int nostr_signer_nsigner_set_role_path(nostr_signer_t* signer, const char* role_ return NOSTR_SUCCESS; } -int nostr_signer_nsigner_set_nostr_index(nostr_signer_t* signer, int nostr_index) { +int nostr_signer_nsigner_set_derive_index(nostr_signer_t* signer, int index) { if (signer == NULL) { return NOSTR_ERROR_INVALID_INPUT; } @@ -1585,30 +1583,11 @@ int nostr_signer_nsigner_set_nostr_index(nostr_signer_t* signer, int nostr_index return NOSTR_ERROR_INVALID_INPUT; } - if (nostr_index < 0) { - /* Clear the selector */ - signer->u.remote.has_role_path = 0; - signer->u.remote.role_path[0] = '\0'; + if (index < 0) { signer->u.remote.has_derive_index = 0; signer->u.remote.derive_index = -1; } else { - /* Expand the NIP-06 index into role="main" + the full derivation path. - * n_signer no longer accepts a bare {"nostr_index":N}; it requires - * {"role":"main","role_path":"m/44'/1237'/N'/0/0"}. We also store N as - * the algorithm derive index so nostr_signer_derive_hmac works. */ - const char* main_role = "main"; - size_t rlen = strlen(main_role); - if (rlen >= sizeof(signer->u.remote.role)) { - return NOSTR_ERROR_INVALID_INPUT; - } - memcpy(signer->u.remote.role, main_role, rlen); - signer->u.remote.role[rlen] = '\0'; - - snprintf(signer->u.remote.role_path, sizeof(signer->u.remote.role_path), - "m/44'/1237'/%d'/0/0", nostr_index); - signer->u.remote.has_role_path = 1; - - signer->u.remote.derive_index = nostr_index; + signer->u.remote.derive_index = index; signer->u.remote.has_derive_index = 1; } diff --git a/nostr_core/nostr_signer.h b/nostr_core/nostr_signer.h index d575fab3..1a6be506 100644 --- a/nostr_core/nostr_signer.h +++ b/nostr_core/nostr_signer.h @@ -173,15 +173,12 @@ int nostr_signer_nsigner_set_auth(nostr_signer_t* signer, */ int nostr_signer_nsigner_set_role_path(nostr_signer_t* signer, const char* role_path); /* - * Compatibility shim: expands the NIP-06 index N into role="main" and - * role_path="m/44'/1237'/N'/0/0" and stores N as the algorithm derive index. - * n_signer no longer accepts a bare {"nostr_index":N} selector, so this is - * the supported way to select a key by NIP-06 account index. The signer must - * have a "main" role registered whose template matches the expanded path. - * Pass a negative value to clear the selector. Returns NOSTR_SUCCESS or an - * error code. + * Set the algorithm derivation index used by the derive verb + * (nostr_signer_derive_hmac). The derive verb is algorithm-based and + * requires an explicit index (no default). Pass a negative value to clear. + * Returns NOSTR_SUCCESS or an error code. */ -int nostr_signer_nsigner_set_nostr_index(nostr_signer_t* signer, int nostr_index); +int nostr_signer_nsigner_set_derive_index(nostr_signer_t* signer, int index); #endif #ifdef __cplusplus diff --git a/plans/n_signer_selector_rewrite.md b/plans/n_signer_selector_rewrite.md index 8618c00f..117cf0a7 100644 --- a/plans/n_signer_selector_rewrite.md +++ b/plans/n_signer_selector_rewrite.md @@ -21,8 +21,10 @@ alone is rejected (`2008 role_required` / `2009 path_required`); a bare ### `nostr_core/nostr_signer.h` - Documented the new `nostr_signer_nsigner_set_role_path` setter. -- Repurposed `nostr_signer_nsigner_set_nostr_index` as a compatibility shim - that expands N into `role="main"` + `role_path="m/44'/1237'/N'/0/0"`. +- Added `nostr_signer_nsigner_set_derive_index` for the derive verb's + algorithm index. +- **Removed** `nostr_signer_nsigner_set_nostr_index` (the compatibility shim). + Callers must now use `set_role_path` explicitly. ### `nostr_core/nostr_signer.c` - Replaced the `remote` struct fields `nostr_index`/`has_nostr_index` with @@ -33,10 +35,10 @@ alone is rejected (`2008 role_required` / `2009 path_required`); a bare - Updated all three call sites (`get_public_key`, `sign_event`, `encrypt_decrypt`) to the new signature. - Rewrote `signer_remote_derive_hmac` to emit `{"algorithm":"secp256k1", - "index":N}` using `derive_index` (set by the `set_nostr_index` shim). + "index":N}` using `derive_index` (set by `set_derive_index`). - Added `nostr_signer_nsigner_set_role_path`. -- Rewrote `nostr_signer_nsigner_set_nostr_index` to expand the NIP-06 - template instead of storing a bare index. +- Added `nostr_signer_nsigner_set_derive_index`. +- **Removed** `nostr_signer_nsigner_set_nostr_index` (the compatibility shim). - Added `` for `snprintf`. - `nostr_signer_free` now also zeroes `role_path`. @@ -55,17 +57,17 @@ alone is rejected (`2008 role_required` / `2009 path_required`); a bare - `make` builds clean. - `nsigner_client_test` passes (mock transport round-trip with the new selector). -- `grep -rn 'nostr_index' nostr_core/nostr_signer.c` returns no bare-selector - emission (only the compatibility-shim function name and its doc comment). +- `grep -rn 'nostr_index' nostr_core/nostr_signer.c` returns no matches + (the shim is removed). ## Downstream consumers still needing updates -These repos link `nostr_core_lib` and call `nostr_signer_nsigner_*`; the -`set_nostr_index` shim keeps them functional, but their UIs still expose only -an "index" input and should be updated to collect role + path explicitly: +These repos link `nostr_core_lib` and call `nostr_signer_nsigner_*`. The +`set_nostr_index` shim is **removed** — they must be updated to use +`set_role_path` explicitly: - `sovereign_browser` — `src/login_dialog.c`, `src/agent_login.c`, - `src/key_store.c` (uses `set_nostr_index`; works via shim, UI needs role+path). + `src/key_store.c` (uses `set_nostr_index`; must switch to `set_role_path`). - `nostr_terminal` — has its own hand-rolled `nsigner_client.c` that still emits `{"nostr_index":N}` directly (NOT via this lib); must be rewritten independently. diff --git a/plans/nsigner_integration_plan.md b/plans/nsigner_integration_plan.md index 1acbcb79..46d1507e 100644 --- a/plans/nsigner_integration_plan.md +++ b/plans/nsigner_integration_plan.md @@ -15,9 +15,9 @@ > **Selector update:** n_signer removed the bare `nostr_index` selector and > `index`-on-nostr-verbs. The only accepted selector for `nostr_*` verbs is now > `{"role":"","role_path":""}` sent together. This library -> emits both fields; `nostr_signer_nsigner_set_nostr_index` is retained as a -> compatibility shim that expands N into `role="main"` + -> `role_path="m/44'/1237'/N'/0/0"`. See `NSIGNER_INTEGRATION.md` §2.1.1. +> emits both fields. The `nostr_signer_nsigner_set_nostr_index` compatibility +> shim was removed; callers must use `nostr_signer_nsigner_set_role_path` +> explicitly. See `NSIGNER_INTEGRATION.md` §2.1.1. > > This plan originally described pulling the **caller-side** signer-integration glue out of per-project implementations and into `nostr_core_lib`, > so any project that already links the library can sign **locally**, via a **running