v0.0.18 - Fix sign-event JSON escaping and variable-path role key caching (per-path re-derivation)
This commit is contained in:
Generated
+1
-1
@@ -2207,7 +2207,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signer"
|
||||
version = "0.0.17"
|
||||
version = "0.0.18"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chacha20poly1305",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "signer"
|
||||
version = "0.0.17"
|
||||
version = "0.0.18"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Attended Nostr signing daemon — Rust port of n_signer"
|
||||
|
||||
+16
-4
@@ -359,9 +359,16 @@ fn handle_nostr_verb(
|
||||
|
||||
// Ensure key is derived. For variable-path roles, use the concrete
|
||||
// path supplied by the client; for fixed-path roles, use the stored
|
||||
// template.
|
||||
if !role.derived {
|
||||
let has_variable = role.has_variable_path();
|
||||
// template. Variable-path roles are re-derived whenever the requested
|
||||
// path differs from the currently-derived one (the cache is per-path,
|
||||
// not per-role).
|
||||
let has_variable = role.has_variable_path();
|
||||
let needs_derive = if has_variable && sel.has_role_path {
|
||||
role.derived_path.as_deref() != Some(sel.role_path.as_str())
|
||||
} else {
|
||||
!role.derived
|
||||
};
|
||||
if needs_derive {
|
||||
let result = if has_variable && sel.has_role_path {
|
||||
ctx.key_store
|
||||
.derive_one_with_path(ctx.role_table, ctx.mnemonic, role_index, &sel.role_path)
|
||||
@@ -414,7 +421,12 @@ fn handle_nostr_verb(
|
||||
None => return make_error_response(id, RpcError::INVALID_PARAMS),
|
||||
};
|
||||
match ctx.key_store.sign_event(role_index, event_json) {
|
||||
Ok(signed) => make_success_response(id, &format!("\"{}\"", signed)),
|
||||
// The signed event is itself JSON; serialize it as a proper
|
||||
// JSON string value so embedded quotes are escaped.
|
||||
Ok(signed) => {
|
||||
let wrapped = serde_json::to_string(&signed).unwrap_or_else(|_| "\"\"".into());
|
||||
make_success_response(id, &wrapped)
|
||||
}
|
||||
Err(_) => make_error_response(id, RpcError::INVALID_PARAMS),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,10 +133,12 @@ impl KeyStore {
|
||||
|
||||
role.derived = false;
|
||||
role.pubkey_hex.clear();
|
||||
role.derived_path = None;
|
||||
|
||||
let dk = derive_for_role(concrete_path, role, phrase)?;
|
||||
role.pubkey_hex = dk.pubkey_hex.clone();
|
||||
role.derived = true;
|
||||
role.derived_path = Some(concrete_path.to_string());
|
||||
|
||||
if self.keys.len() <= role_index {
|
||||
self.keys.resize_with(role_index + 1, || None);
|
||||
|
||||
+1
-1
@@ -31,4 +31,4 @@ pub mod error;
|
||||
pub use error::SignerError;
|
||||
|
||||
/// Version string (matches C NSIGNER_VERSION).
|
||||
pub const VERSION: &str = "v0.0.17";
|
||||
pub const VERSION: &str = "v0.0.18";
|
||||
|
||||
@@ -137,6 +137,8 @@ pub struct RoleEntry {
|
||||
pub pubkey_hex: String,
|
||||
/// 1 if pubkey_hex has been populated.
|
||||
pub derived: bool,
|
||||
/// The concrete path the key was last derived for (variable-path roles).
|
||||
pub derived_path: Option<String>,
|
||||
/// Inclusive lower bound for %d; -1 = fixed path (no variable).
|
||||
pub path_range_lo: i32,
|
||||
/// Inclusive upper bound; == path_range_lo for single.
|
||||
@@ -162,6 +164,7 @@ impl Default for RoleEntry {
|
||||
role_path: String::new(),
|
||||
pubkey_hex: String::new(),
|
||||
derived: false,
|
||||
derived_path: None,
|
||||
path_range_lo: -1,
|
||||
path_range_hi: -1,
|
||||
path_default_index: -1,
|
||||
|
||||
Reference in New Issue
Block a user