commit 4f6a1033b2e7a79ebb136fb752f6a9eda0ff2605
parent af1ebd63d35c374c1ee97e7a32fe45063b6dde5e
Author: triesap <tyson@radroots.org>
Date: Fri, 31 Jul 2026 18:34:05 +0000
nostr-connect: stabilize request and response envelopes
- translate frozen signing drafts into the package-owned unsigned-event payload
- consume signed-event wrappers without exposing the upstream Nostr representation
- update remote-signer fixtures for the bounded request and response contract
- preserve SDK signing validation across the breaking NIP-46 envelope cutover
Diffstat:
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/crates/sdk/src/signer_provider.rs b/crates/sdk/src/signer_provider.rs
@@ -15,7 +15,7 @@ use radroots_nostr_connect::prelude::{
RadrootsNostrConnectClientTransport, RadrootsNostrConnectClientTransportFuture,
RadrootsNostrConnectError, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission,
RadrootsNostrConnectPermissions, RadrootsNostrConnectRequest, RadrootsNostrConnectResponse,
- execute_request_with_transport,
+ UnsignedEvent as ConnectUnsignedEvent, execute_request_with_transport,
};
use radroots_signing::{
Actor, SignReceipt, SignRequest, Signer,
@@ -617,6 +617,8 @@ fn sign_event_request_from_frozen_draft(
tags: Tags::from_list(tags),
content: draft.content().to_owned(),
};
+ let unsigned_event = ConnectUnsignedEvent::from_json(&unsigned_event.as_json())
+ .map_err(|error| nip46_sign_event_protocol_error(error.to_string()))?;
Ok(RadrootsNostrConnectRequest::SignEvent(unsigned_event))
}
diff --git a/crates/sdk/tests/unit/signer_provider_tests.rs b/crates/sdk/tests/unit/signer_provider_tests.rs
@@ -11,6 +11,7 @@ use radroots_nostr::{event::Event as RadrootsNostrEvent, signing::LocalSigner};
use radroots_nostr_connect::prelude::{
RADROOTS_NOSTR_CONNECT_RPC_KIND, RadrootsNostrConnectClientTarget, RadrootsNostrConnectError,
RadrootsNostrConnectRequest, RadrootsNostrConnectRequestMessage, RadrootsNostrConnectResponse,
+ SignedEvent as ConnectSignedEvent,
};
use radroots_signing::actor::ActorSource;
use std::collections::VecDeque;
@@ -31,6 +32,10 @@ fn user_keys() -> RadrootsNostrKeys {
USER_KEYS.clone()
}
+fn connect_signed_event(event: RadrootsNostrEvent) -> ConnectSignedEvent {
+ ConnectSignedEvent::from_json(&event.as_json()).expect("connect signed event")
+}
+
fn user_pubkey() -> &'static str {
USER_PUBLIC_KEY.as_str()
}
@@ -569,7 +574,7 @@ async fn myc_nip46_provider_signs_and_validates_remote_event() {
let transport = Arc::new(MockNip46Transport::new(
remote_keys.clone(),
vec![MockNip46Response::Respond(
- RadrootsNostrConnectResponse::SignedEvent(signed_event),
+ RadrootsNostrConnectResponse::SignedEvent(connect_signed_event(signed_event)),
)],
));
let target = RadrootsNostrConnectClientTarget::new(
@@ -612,6 +617,8 @@ async fn myc_nip46_provider_signs_and_validates_remote_event() {
RadrootsNostrConnectRequest::SignEvent(unsigned_event) => unsigned_event,
other => panic!("unexpected NIP-46 request: {other:?}"),
};
+ let sign_event_request: nostr::UnsignedEvent =
+ serde_json::from_str(&sign_event_request.as_json()).expect("unsigned event payload");
let request_tags = sign_event_request
.tags
.clone()
@@ -728,7 +735,7 @@ async fn myc_nip46_provider_returns_completion_progress_errors_after_remote_sign
let signed = sign_frozen_draft(&user_keys, &draft).expect("signed");
let signed_event = RadrootsNostrEvent::from_json(signed.raw_json()).expect("event");
let (signer, transport) = myc_signer_with_responses(vec![MockNip46Response::Respond(
- RadrootsNostrConnectResponse::SignedEvent(signed_event),
+ RadrootsNostrConnectResponse::SignedEvent(connect_signed_event(signed_event)),
)]);
let actor = actor();
let mut observed = Vec::new();
@@ -1016,7 +1023,7 @@ async fn myc_nip46_provider_rejects_returned_event_drift() {
let transport = Arc::new(MockNip46Transport::new(
remote_keys.clone(),
vec![MockNip46Response::Respond(
- RadrootsNostrConnectResponse::SignedEvent(signed_event),
+ RadrootsNostrConnectResponse::SignedEvent(connect_signed_event(signed_event)),
)],
));
let target = RadrootsNostrConnectClientTarget::new(remote_keys.public_key(), Vec::new());