commit 22fa4753f3a5ea0578870720945ea4b378ffbf3c
parent 514d65efbc7f26bd80e723de617db558b8cb972d
Author: triesap <tyson@radroots.org>
Date: Sun, 19 Jul 2026 20:01:03 +0000
nip46: enforce checked protocol event signing
- migrate signer-authored responses to the opaque generic event boundary
- preserve caller-supplied sign_event as a distinct interoperability path
- reject invalid inputs and mismatched or unverifiable external signer results
- refresh the locked library graph and cover tampered custody responses
Diffstat:
15 files changed, 352 insertions(+), 76 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1884,6 +1884,7 @@ dependencies = [
"mediatype",
"serde",
"sha2",
+ "unicode-general-category",
"url",
]
@@ -1907,6 +1908,7 @@ dependencies = [
"serde",
"serde_json",
"sha2",
+ "unicode-general-category",
"url",
]
@@ -1914,6 +1916,7 @@ dependencies = [
name = "radroots_event_codec"
version = "1.0.0-alpha.1"
dependencies = [
+ "radroots_blossom",
"radroots_core",
"radroots_event",
]
@@ -3004,6 +3007,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
+name = "unicode-general-category"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b993bddc193ae5bd0d623b49ec06ac3e9312875fdae725a975c51db1cc1677f"
+
+[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/README b/README
@@ -23,6 +23,13 @@ connect is approved.
Myc rejects invalid signatures, wrong recipient tags, empty request IDs,
malformed ciphertext, and duplicate event delivery before dispatch. Runtime
state and audit output do not log client private keys or raw connection URIs.
+Signer-authored protocol responses use the checked generic-event boundary from
+`radroots_nostr`. External custody commands receive canonical unsigned-event
+JSON only after typed-authoring policy succeeds, and Myc accepts their result
+only when the author and event id match the exact request and the complete
+NIP-01 event verifies. Caller-supplied NIP-46 `sign_event` payloads remain a
+separate low-level interoperability boundary and receive the same exact-result
+integrity checks without acquiring a typed product-authoring claim.
Use the repository-owned Nix lanes for validation:
diff --git a/src/app/runtime.rs b/src/app/runtime.rs
@@ -1311,7 +1311,7 @@ mod tests {
use nostr::PublicKey;
use radroots_identity::RadrootsIdentity;
- use radroots_nostr::prelude::{RadrootsNostrEventBuilder, RadrootsNostrKind};
+ use radroots_nostr::prelude::{RadrootsNostrGenericEventBuilder, RadrootsNostrKind};
use radroots_nostr_signer::prelude::{
RadrootsNostrFileSignerStore, RadrootsNostrSignerApprovalRequirement,
RadrootsNostrSignerAuthState, RadrootsNostrSignerConnectionDraft,
@@ -1885,8 +1885,8 @@ mod tests {
let event = runtime
.signer_identity()
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), "recovery"),
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(RadrootsNostrKind::Custom(24133), "recovery"),
"recovery test",
)
.expect("sign event");
@@ -1997,8 +1997,11 @@ mod tests {
.expect("begin workflow");
let event = runtime
.signer_identity()
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), "queued-recovery"),
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
+ RadrootsNostrKind::Custom(24133),
+ "queued-recovery",
+ ),
"queued recovery test",
)
.expect("sign event");
diff --git a/src/control.rs b/src/control.rs
@@ -169,7 +169,7 @@ pub async fn accept_client_uri(
)?;
let event = match runtime
.signer_identity()
- .sign_event_builder(event, "connect accept response")
+ .sign_protocol_event_builder(event, "connect accept response")
{
Ok(event) => event,
Err(error) => {
@@ -428,7 +428,7 @@ async fn replay_authorized_request(
})?;
let event = match runtime
.signer_identity()
- .sign_event_builder(event, "authorized auth replay response")
+ .sign_protocol_event_builder(event, "authorized auth replay response")
{
Ok(event) => event,
Err(error) => {
diff --git a/src/custody.rs b/src/custody.rs
@@ -9,7 +9,8 @@ use nostr::nips::nip44::Version;
use nostr::nips::{nip04, nip44};
use radroots_identity::{RadrootsIdentity, RadrootsIdentityId, RadrootsIdentityPublic};
use radroots_nostr::prelude::{
- RadrootsNostrClient, RadrootsNostrEvent, RadrootsNostrEventBuilder, RadrootsNostrPublicKey,
+ RadrootsNostrClient, RadrootsNostrEvent, RadrootsNostrExternalSigningRequest,
+ RadrootsNostrGenericEventBuilder, RadrootsNostrPublicKey,
};
use radroots_nostr_accounts::prelude::{
RadrootsNostrAccountRecord, RadrootsNostrAccountStatus, RadrootsNostrAccountsManager,
@@ -209,18 +210,38 @@ enum MycExternalCommandOperation {
Nip44Decrypt,
}
-#[derive(Debug, Clone, Serialize, Deserialize)]
-struct MycExternalCommandRequest {
+#[derive(Serialize)]
+#[serde(untagged)]
+enum MycExternalCommandUnsignedEvent<'a> {
+ CallerSupplied(&'a nostr::UnsignedEvent),
+ CheckedProtocol(&'a RadrootsNostrExternalSigningRequest),
+}
+
+#[derive(Serialize)]
+struct MycExternalCommandRequest<'a> {
version: u8,
operation: MycExternalCommandOperation,
#[serde(default, skip_serializing_if = "Option::is_none")]
- unsigned_event: Option<nostr::UnsignedEvent>,
+ unsigned_event: Option<MycExternalCommandUnsignedEvent<'a>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
public_key_hex: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
content: Option<String>,
}
+#[cfg(test)]
+#[derive(Debug, Clone, Deserialize)]
+struct MycExternalCommandRequestWire {
+ version: u8,
+ operation: MycExternalCommandOperation,
+ #[serde(default)]
+ unsigned_event: Option<nostr::UnsignedEvent>,
+ #[serde(default)]
+ public_key_hex: Option<String>,
+ #[serde(default)]
+ content: Option<String>,
+}
+
#[derive(Debug, Clone, Serialize, Deserialize)]
struct MycExternalCommandResponse {
#[serde(default)]
@@ -308,9 +329,9 @@ impl MycExternalCommandExecutor for MycProcessCommandExecutor {
trait MycIdentityOperations: Send + Sync {
fn nostr_client(&self) -> RadrootsNostrClient;
fn nostr_client_owned(&self) -> RadrootsNostrClient;
- fn sign_event_builder(
+ fn sign_protocol_event_builder(
&self,
- builder: RadrootsNostrEventBuilder,
+ builder: RadrootsNostrGenericEventBuilder,
operation: &str,
) -> Result<RadrootsNostrEvent, MycError>;
fn sign_unsigned_event(
@@ -361,9 +382,9 @@ impl MycIdentityOperations for MycLoadedIdentityOperations {
RadrootsNostrClient::from_identity_owned((*self.identity).clone())
}
- fn sign_event_builder(
+ fn sign_protocol_event_builder(
&self,
- builder: RadrootsNostrEventBuilder,
+ builder: RadrootsNostrGenericEventBuilder,
operation: &str,
) -> Result<RadrootsNostrEvent, MycError> {
builder
@@ -431,7 +452,6 @@ struct MycExternalCommandIdentityOperations {
role: String,
command_path: PathBuf,
timeout: Duration,
- public_identity: RadrootsIdentityPublic,
public_key: RadrootsNostrPublicKey,
executor: Arc<dyn MycExternalCommandExecutor>,
}
@@ -441,7 +461,6 @@ impl MycExternalCommandIdentityOperations {
role: String,
command_path: PathBuf,
timeout: Duration,
- public_identity: RadrootsIdentityPublic,
public_key: RadrootsNostrPublicKey,
executor: Arc<dyn MycExternalCommandExecutor>,
) -> Self {
@@ -449,7 +468,6 @@ impl MycExternalCommandIdentityOperations {
role,
command_path,
timeout,
- public_identity,
public_key,
executor,
}
@@ -457,7 +475,7 @@ impl MycExternalCommandIdentityOperations {
fn execute(
&self,
- request: &MycExternalCommandRequest,
+ request: &MycExternalCommandRequest<'_>,
) -> Result<MycExternalCommandResponse, MycError> {
let request_json = serde_json::to_vec(request)?;
let output = self
@@ -522,24 +540,46 @@ impl MycIdentityOperations for MycExternalCommandIdentityOperations {
self.nostr_client()
}
- fn sign_event_builder(
+ fn sign_protocol_event_builder(
&self,
- builder: RadrootsNostrEventBuilder,
+ builder: RadrootsNostrGenericEventBuilder,
operation: &str,
) -> Result<RadrootsNostrEvent, MycError> {
- let unsigned_event = builder.build(self.public_key);
- self.sign_unsigned_event(unsigned_event, operation)
+ let request = builder.into_external_signing_request(self.public_key)?;
+ let response = self.execute(&MycExternalCommandRequest {
+ version: 1,
+ operation: MycExternalCommandOperation::SignEvent,
+ unsigned_event: Some(MycExternalCommandUnsignedEvent::CheckedProtocol(&request)),
+ public_key_hex: None,
+ content: None,
+ })?;
+ let event = response.event.ok_or_else(|| {
+ MycError::InvalidOperation(format!(
+ "external signer command did not return a signed event for {operation}"
+ ))
+ })?;
+ request.complete(event).map_err(Into::into)
}
fn sign_unsigned_event(
&self,
- unsigned_event: nostr::UnsignedEvent,
+ mut unsigned_event: nostr::UnsignedEvent,
operation: &str,
) -> Result<nostr::Event, MycError> {
+ if unsigned_event.pubkey != self.public_key || unsigned_event.verify_id().is_err() {
+ return Err(MycError::CustodyExternalCommandUnsignedEventInvalid {
+ role: self.role.clone(),
+ path: self.command_path.clone(),
+ operation: operation.to_owned(),
+ });
+ }
+ let expected_event_id = unsigned_event.id();
let response = self.execute(&MycExternalCommandRequest {
version: 1,
operation: MycExternalCommandOperation::SignEvent,
- unsigned_event: Some(unsigned_event),
+ unsigned_event: Some(MycExternalCommandUnsignedEvent::CallerSupplied(
+ &unsigned_event,
+ )),
public_key_hex: None,
content: None,
})?;
@@ -548,13 +588,20 @@ impl MycIdentityOperations for MycExternalCommandIdentityOperations {
"external signer command did not return a signed event for {operation}"
))
})?;
- if event.pubkey != self.public_key {
- return Err(MycError::InvalidOperation(format!(
- "external signer command returned a signed {operation} event for `{}` instead of `{}`",
- event.pubkey.to_hex(),
- self.public_identity.public_key_hex
- )));
+ if event.pubkey != self.public_key || event.id != expected_event_id {
+ return Err(MycError::CustodyExternalCommandSignedEventMismatch {
+ role: self.role.clone(),
+ path: self.command_path.clone(),
+ operation: operation.to_owned(),
+ });
}
+ event
+ .verify()
+ .map_err(|_| MycError::CustodyExternalCommandSignedEventInvalid {
+ role: self.role.clone(),
+ path: self.command_path.clone(),
+ operation: operation.to_owned(),
+ })?;
Ok(event)
}
@@ -824,7 +871,6 @@ impl MycIdentityProvider {
self.role.clone(),
command_path.clone(),
*timeout,
- public_identity,
public_key,
executor.clone(),
)),
@@ -1551,12 +1597,13 @@ impl MycActiveIdentity {
self.operations.nostr_client_owned()
}
- pub fn sign_event_builder(
+ pub fn sign_protocol_event_builder(
&self,
- builder: RadrootsNostrEventBuilder,
+ builder: RadrootsNostrGenericEventBuilder,
operation: &str,
) -> Result<RadrootsNostrEvent, MycError> {
- self.operations.sign_event_builder(builder, operation)
+ self.operations
+ .sign_protocol_event_builder(builder, operation)
}
pub fn sign_unsigned_event(
@@ -1724,7 +1771,7 @@ mod tests {
#[derive(Debug)]
struct FakeExternalCommandExecutor {
identity: RadrootsIdentity,
- requests: Mutex<Vec<MycExternalCommandRequest>>,
+ requests: Mutex<Vec<MycExternalCommandRequestWire>>,
}
impl FakeExternalCommandExecutor {
@@ -1743,8 +1790,9 @@ mod tests {
request_json: &[u8],
_timeout: Duration,
) -> Result<MycExternalCommandOutput, MycExternalCommandExecuteError> {
- let request: MycExternalCommandRequest =
+ let request: MycExternalCommandRequestWire =
serde_json::from_slice(request_json).expect("request");
+ assert_eq!(request.version, 1);
self.requests
.lock()
.expect("requests lock")
@@ -2134,8 +2182,11 @@ mod tests {
)
.expect("peer identity");
let signed_event = active
- .sign_event_builder(
- RadrootsNostrEventBuilder::text_note("hello from external command"),
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
+ nostr::Kind::Custom(24_133),
+ "hello from external command",
+ ),
"test event",
)
.expect("signed event");
@@ -2186,6 +2237,188 @@ mod tests {
assert!(operations.contains(&MycExternalCommandOperation::SignEvent));
assert!(operations.contains(&MycExternalCommandOperation::Nip04Encrypt));
assert!(operations.contains(&MycExternalCommandOperation::Nip44Encrypt));
+
+ let requests = executor.requests.lock().expect("requests lock");
+ let signing_request = requests
+ .iter()
+ .find(|request| request.operation == MycExternalCommandOperation::SignEvent)
+ .and_then(|request| request.unsigned_event.as_ref())
+ .expect("serialized unsigned event");
+ assert!(signing_request.id.is_some());
+ signing_request.verify_id().expect("canonical event id");
+ assert_eq!(signing_request.kind, nostr::Kind::Custom(24_133));
+ }
+
+ #[derive(Debug)]
+ struct StaticSigningResponseExecutor {
+ event: RadrootsNostrEvent,
+ }
+
+ impl MycExternalCommandExecutor for StaticSigningResponseExecutor {
+ fn execute(
+ &self,
+ _command_path: &Path,
+ request_json: &[u8],
+ _timeout: Duration,
+ ) -> Result<MycExternalCommandOutput, MycExternalCommandExecuteError> {
+ let request: MycExternalCommandRequestWire =
+ serde_json::from_slice(request_json).expect("request");
+ assert_eq!(request.version, 1);
+ assert_eq!(request.operation, MycExternalCommandOperation::SignEvent);
+ assert!(request.unsigned_event.is_some());
+ Ok(MycExternalCommandOutput {
+ success: true,
+ status: Some(0),
+ stdout: serde_json::to_vec(&MycExternalCommandResponse {
+ identity: None,
+ event: Some(self.event.clone()),
+ content: None,
+ error: None,
+ })
+ .expect("response"),
+ stderr: Vec::new(),
+ })
+ }
+ }
+
+ fn external_operations_with_event(
+ identity: &RadrootsIdentity,
+ event: RadrootsNostrEvent,
+ ) -> MycExternalCommandIdentityOperations {
+ MycExternalCommandIdentityOperations::new(
+ "user".to_owned(),
+ PathBuf::from("/tmp/user-helper"),
+ Duration::from_secs(10),
+ identity.public_key(),
+ Arc::new(StaticSigningResponseExecutor { event }),
+ )
+ }
+
+ fn caller_unsigned_event(identity: &RadrootsIdentity, content: &str) -> nostr::UnsignedEvent {
+ nostr::UnsignedEvent::new(
+ identity.public_key(),
+ nostr::Timestamp::from_secs(1_234),
+ nostr::Kind::Custom(30_001),
+ [],
+ content,
+ )
+ }
+
+ #[test]
+ fn external_command_rejects_invalid_caller_unsigned_events_before_execution() {
+ let identity = RadrootsIdentity::from_secret_key_str(
+ "1111111111111111111111111111111111111111111111111111111111111111",
+ )
+ .expect("identity");
+ let valid_event = caller_unsigned_event(&identity, "valid")
+ .sign_with_keys(identity.keys())
+ .expect("event");
+ let operations = external_operations_with_event(&identity, valid_event);
+
+ let other_identity = RadrootsIdentity::from_secret_key_str(
+ "2222222222222222222222222222222222222222222222222222222222222222",
+ )
+ .expect("other identity");
+ let wrong_author = caller_unsigned_event(&other_identity, "wrong author");
+ assert!(matches!(
+ operations.sign_unsigned_event(wrong_author, "caller event"),
+ Err(MycError::CustodyExternalCommandUnsignedEventInvalid { .. })
+ ));
+
+ let mut invalid_id = caller_unsigned_event(&identity, "invalid id");
+ invalid_id.id = Some(nostr::EventId::all_zeros());
+ assert!(matches!(
+ operations.sign_unsigned_event(invalid_id, "caller event"),
+ Err(MycError::CustodyExternalCommandUnsignedEventInvalid { .. })
+ ));
+ }
+
+ #[test]
+ fn external_command_accepts_only_the_exact_valid_caller_event() {
+ let identity = RadrootsIdentity::from_secret_key_str(
+ "1111111111111111111111111111111111111111111111111111111111111111",
+ )
+ .expect("identity");
+ let unsigned_event = caller_unsigned_event(&identity, "expected");
+ let valid_event = unsigned_event
+ .clone()
+ .sign_with_keys(identity.keys())
+ .expect("event");
+ let accepted = external_operations_with_event(&identity, valid_event.clone())
+ .sign_unsigned_event(unsigned_event.clone(), "caller event")
+ .expect("accepted event");
+ assert_eq!(accepted, valid_event);
+
+ let wrong_event = caller_unsigned_event(&identity, "different")
+ .sign_with_keys(identity.keys())
+ .expect("different event");
+ assert!(matches!(
+ external_operations_with_event(&identity, wrong_event)
+ .sign_unsigned_event(unsigned_event.clone(), "caller event"),
+ Err(MycError::CustodyExternalCommandSignedEventMismatch { .. })
+ ));
+
+ let other_identity = RadrootsIdentity::from_secret_key_str(
+ "2222222222222222222222222222222222222222222222222222222222222222",
+ )
+ .expect("other identity");
+ let wrong_author = caller_unsigned_event(&other_identity, "expected")
+ .sign_with_keys(other_identity.keys())
+ .expect("wrong author event");
+ assert!(matches!(
+ external_operations_with_event(&identity, wrong_author)
+ .sign_unsigned_event(unsigned_event.clone(), "caller event"),
+ Err(MycError::CustodyExternalCommandSignedEventMismatch { .. })
+ ));
+
+ let mut tampered_content = valid_event.clone();
+ tampered_content.content.push_str(" tampered");
+ assert!(matches!(
+ external_operations_with_event(&identity, tampered_content)
+ .sign_unsigned_event(unsigned_event.clone(), "caller event"),
+ Err(MycError::CustodyExternalCommandSignedEventInvalid { .. })
+ ));
+
+ let mut invalid_signature = valid_event;
+ invalid_signature.sig = caller_unsigned_event(&identity, "signature source")
+ .sign_with_keys(identity.keys())
+ .expect("signature source")
+ .sig;
+ assert!(matches!(
+ external_operations_with_event(&identity, invalid_signature)
+ .sign_unsigned_event(unsigned_event, "caller event"),
+ Err(MycError::CustodyExternalCommandSignedEventInvalid { .. })
+ ));
+ }
+
+ #[test]
+ fn external_command_protocol_signing_uses_checked_library_completion() {
+ let identity = RadrootsIdentity::from_secret_key_str(
+ "1111111111111111111111111111111111111111111111111111111111111111",
+ )
+ .expect("identity");
+ let wrong_event = RadrootsNostrGenericEventBuilder::new(
+ nostr::Kind::Custom(24_133),
+ "different response",
+ )
+ .sign_with_keys(identity.keys())
+ .expect("different event");
+ let error = external_operations_with_event(&identity, wrong_event)
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
+ nostr::Kind::Custom(24_133),
+ "expected response",
+ ),
+ "protocol response",
+ )
+ .expect_err("different event");
+
+ assert!(matches!(
+ error,
+ MycError::Nostr(
+ radroots_nostr::prelude::RadrootsNostrError::ExternalSigningEventIdMismatch { .. }
+ )
+ ));
}
#[tokio::test]
@@ -2258,15 +2491,14 @@ mod tests {
"signer".to_owned(),
PathBuf::from("/tmp/signer-helper"),
Duration::from_secs(11),
- public_identity,
public_key,
Arc::new(TimeoutExternalCommandExecutor),
)),
);
let err = active
- .sign_event_builder(
- RadrootsNostrEventBuilder::text_note("timeout"),
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(nostr::Kind::Custom(24_133), "timeout"),
"timeout event",
)
.expect_err("timeout");
diff --git a/src/discovery.rs b/src/discovery.rs
@@ -455,7 +455,7 @@ impl MycDiscoveryContext {
pub fn build_signed_handler_event(&self) -> Result<RadrootsNostrEvent, MycError> {
let builder = radroots_nostr_build_application_handler_event(&self.build_handler_spec())?;
self.app_identity
- .sign_event_builder(builder, "NIP-89 application handler")
+ .sign_protocol_event_builder(builder, "NIP-89 application handler")
}
pub fn write_bundle(
diff --git a/src/error.rs b/src/error.rs
@@ -242,6 +242,30 @@ pub enum MycError {
path: PathBuf,
message: String,
},
+ #[error(
+ "external custody command rejected invalid unsigned event for {role} identity at {path} while signing {operation}"
+ )]
+ CustodyExternalCommandUnsignedEventInvalid {
+ role: String,
+ path: PathBuf,
+ operation: String,
+ },
+ #[error(
+ "external custody command returned a different signed event for {role} identity at {path} while signing {operation}"
+ )]
+ CustodyExternalCommandSignedEventMismatch {
+ role: String,
+ path: PathBuf,
+ operation: String,
+ },
+ #[error(
+ "external custody command returned an invalid signed event for {role} identity at {path} while signing {operation}"
+ )]
+ CustodyExternalCommandSignedEventInvalid {
+ role: String,
+ path: PathBuf,
+ operation: String,
+ },
#[error(transparent)]
Identity(#[from] IdentityError),
#[error(transparent)]
diff --git a/src/outbox.rs b/src/outbox.rs
@@ -249,7 +249,7 @@ pub(crate) fn now_unix_secs() -> u64 {
#[cfg(test)]
mod tests {
use radroots_identity::RadrootsIdentity;
- use radroots_nostr::prelude::{RadrootsNostrEventBuilder, RadrootsNostrKind};
+ use radroots_nostr::prelude::{RadrootsNostrGenericEventBuilder, RadrootsNostrKind};
use radroots_nostr_signer::prelude::{
RadrootsNostrSignerConnectionId, RadrootsNostrSignerWorkflowId,
};
@@ -264,7 +264,7 @@ mod tests {
"1111111111111111111111111111111111111111111111111111111111111111",
)
.expect("identity");
- RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), "hello")
+ RadrootsNostrGenericEventBuilder::new(RadrootsNostrKind::Custom(24133), "hello")
.sign_with_keys(identity.keys())
.expect("sign event")
}
diff --git a/src/outbox_sqlite.rs b/src/outbox_sqlite.rs
@@ -495,7 +495,7 @@ fn usize_from_i64(path: &Path, value: i64, field: &str) -> Result<usize, MycErro
#[cfg(test)]
mod tests {
use radroots_identity::RadrootsIdentity;
- use radroots_nostr::prelude::{RadrootsNostrEventBuilder, RadrootsNostrKind};
+ use radroots_nostr::prelude::{RadrootsNostrGenericEventBuilder, RadrootsNostrKind};
use radroots_nostr_signer::prelude::{
RadrootsNostrSignerConnectionId, RadrootsNostrSignerWorkflowId,
};
@@ -512,9 +512,10 @@ mod tests {
"1111111111111111111111111111111111111111111111111111111111111111",
)
.expect("identity");
- let event = RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), "hello")
- .sign_with_keys(identity.keys())
- .expect("sign event");
+ let event =
+ RadrootsNostrGenericEventBuilder::new(RadrootsNostrKind::Custom(24133), "hello")
+ .sign_with_keys(identity.keys())
+ .expect("sign event");
MycDeliveryOutboxRecord::new(
MycDeliveryOutboxKind::AuthReplayPublish,
event,
diff --git a/src/persistence.rs b/src/persistence.rs
@@ -1455,7 +1455,7 @@ mod tests {
use nostr::PublicKey;
use radroots_identity::RadrootsIdentity;
use radroots_nostr::prelude::{
- RadrootsNostrEvent, RadrootsNostrEventBuilder, RadrootsNostrKind,
+ RadrootsNostrEvent, RadrootsNostrGenericEventBuilder, RadrootsNostrKind,
};
use radroots_nostr_signer::prelude::{
RADROOTS_NOSTR_SIGNER_STORE_VERSION, RadrootsNostrFileSignerStore,
@@ -1500,7 +1500,7 @@ mod tests {
}
fn signed_event(secret_key: &str) -> RadrootsNostrEvent {
- RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), "hello")
+ RadrootsNostrGenericEventBuilder::new(RadrootsNostrKind::Custom(24133), "hello")
.sign_with_keys(identity(secret_key).keys())
.expect("sign event")
}
diff --git a/src/transport.rs b/src/transport.rs
@@ -4,7 +4,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::time::Duration;
use radroots_nostr::prelude::{
- RadrootsNostrClient, RadrootsNostrEvent, RadrootsNostrEventBuilder, RadrootsNostrOutput,
+ RadrootsNostrClient, RadrootsNostrEvent, RadrootsNostrGenericEventBuilder, RadrootsNostrOutput,
RadrootsNostrRelayUrl,
};
use serde::Serialize;
@@ -122,7 +122,7 @@ impl MycNostrTransport {
relays: &[RadrootsNostrRelayUrl],
config: &MycTransportConfig,
operation: &str,
- event: RadrootsNostrEventBuilder,
+ event: RadrootsNostrGenericEventBuilder,
) -> Result<MycPublishOutcome, MycError> {
if relays.is_empty() {
return Err(MycError::InvalidOperation(
@@ -130,7 +130,7 @@ impl MycNostrTransport {
));
}
- let event = signer_identity.sign_event_builder(event, "publish")?;
+ let event = signer_identity.sign_protocol_event_builder(event, "publish")?;
Self::publish_event_once(signer_identity, relays, config, operation, &event).await
}
diff --git a/src/transport/nip46.rs b/src/transport/nip46.rs
@@ -233,7 +233,7 @@ impl MycNip46Handler {
client_public_key: RadrootsNostrPublicKey,
request_id: impl Into<String>,
response: RadrootsNostrConnectResponse,
- ) -> Result<radroots_nostr::prelude::RadrootsNostrEventBuilder, MycError> {
+ ) -> Result<radroots_nostr::prelude::RadrootsNostrGenericEventBuilder, MycError> {
self.handler
.build_response_event(client_public_key, request_id, response)
.map_err(Into::into)
@@ -453,7 +453,7 @@ impl MycNip46Service {
.handler
.signer
.signer_identity()
- .sign_event_builder(response_event, "NIP-46 response")
+ .sign_protocol_event_builder(response_event, "NIP-46 response")
{
Ok(event) => event,
Err(error) => {
@@ -1017,7 +1017,7 @@ mod tests {
.expect("response builder");
let response_event = runtime
.signer_identity()
- .sign_event_builder(response_builder, "test response")
+ .sign_protocol_event_builder(response_builder, "test response")
.expect("sign response");
let decrypted = nip44::decrypt(
client_keys().secret_key(),
diff --git a/tests/nip46_e2e.rs b/tests/nip46_e2e.rs
@@ -28,7 +28,7 @@ use nostr::{
};
use radroots_identity::RadrootsIdentity;
use radroots_nostr::prelude::{
- RadrootsNostrApplicationHandlerSpec, RadrootsNostrClient, RadrootsNostrEventBuilder,
+ RadrootsNostrApplicationHandlerSpec, RadrootsNostrClient, RadrootsNostrGenericEventBuilder,
RadrootsNostrKind, RadrootsNostrMetadata, RadrootsNostrRelayUrl, RadrootsNostrTag,
radroots_nostr_build_application_handler_event,
};
@@ -645,8 +645,8 @@ fn build_external_request_event(
fn build_signer_noise_event(signer_identity: &MycActiveIdentity, created_at_unix: u64) -> Event {
signer_identity
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND),
"non-nip44-signer-noise",
)
@@ -2109,8 +2109,8 @@ async fn published_logout_acknowledgement_is_finalized_without_republish_on_rest
)?;
let acknowledgement_event = runtime
.signer_identity()
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND),
"published logout acknowledgement fixture",
),
@@ -2418,8 +2418,8 @@ async fn external_nostr_client_recovers_connect_response_after_restart() -> Test
response_payload,
Version::V2,
)?;
- let response_event = runtime.signer_identity().sign_event_builder(
- RadrootsNostrEventBuilder::new(
+ let response_event = runtime.signer_identity().sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND),
response_ciphertext,
)
@@ -2536,8 +2536,8 @@ async fn startup_recovery_republishes_queued_listener_connect_secret_job() -> Te
let workflow = manager.begin_connect_secret_publish_finalization(&connection.connection_id)?;
let event = runtime
.signer_identity()
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND),
"startup-recovery",
),
@@ -2635,8 +2635,8 @@ async fn startup_recovery_republishes_queued_connect_accept_job() -> TestResult<
let workflow = manager.begin_connect_secret_publish_finalization(&connection.connection_id)?;
let event = runtime
.signer_identity()
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND),
"startup-recovery-connect-accept",
),
@@ -2740,8 +2740,8 @@ async fn startup_recovery_republishes_queued_auth_replay_job() -> TestResult<()>
let workflow = manager.begin_auth_replay_publish_finalization(&connection.connection_id)?;
let event = runtime
.signer_identity()
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(
RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND),
"startup-recovery-auth-replay",
),
diff --git a/tests/operability_cli.rs b/tests/operability_cli.rs
@@ -8,7 +8,7 @@ use myc::{
MycOperationAuditRecord, MycRuntime,
};
use radroots_identity::RadrootsIdentity;
-use radroots_nostr::prelude::{RadrootsNostrEventBuilder, RadrootsNostrKind};
+use radroots_nostr::prelude::{RadrootsNostrGenericEventBuilder, RadrootsNostrKind};
use serde_json::{Value, json};
fn write_test_identity(path: &Path, secret_key: &str) {
@@ -55,8 +55,8 @@ MYC_TRANSPORT_CONNECT_TIMEOUT_SECS=1\n",
fn signed_event(identity: &MycActiveIdentity) -> nostr::Event {
identity
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), "operability"),
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(RadrootsNostrKind::Custom(24133), "operability"),
"operability test event",
)
.expect("sign event")
diff --git a/tests/operability_e2e.rs b/tests/operability_e2e.rs
@@ -10,7 +10,7 @@ use myc::{
};
use radroots_identity::RadrootsIdentity;
use radroots_nostr::prelude::{
- RadrootsNostrEventBuilder, RadrootsNostrKind, RadrootsNostrRelayUrl,
+ RadrootsNostrGenericEventBuilder, RadrootsNostrKind, RadrootsNostrRelayUrl,
};
use radroots_nostr_signer::prelude::{
RadrootsNostrSignerApprovalRequirement, RadrootsNostrSignerConnectionDraft,
@@ -123,8 +123,8 @@ fn write_test_identity(path: &Path, secret_key: &str) {
fn signed_delivery_event(identity: &MycActiveIdentity, content: &str) -> nostr::Event {
identity
- .sign_event_builder(
- RadrootsNostrEventBuilder::new(RadrootsNostrKind::Custom(24133), content),
+ .sign_protocol_event_builder(
+ RadrootsNostrGenericEventBuilder::new(RadrootsNostrKind::Custom(24133), content),
"operability delivery test event",
)
.expect("sign event")