commit 105dea109a2356188dce16ecdebb3864e798f3f8
parent ff48c3eff6888f7e0aa677bd63ac33714c88ddfd
Author: triesap <tyson@radroots.org>
Date: Sat, 1 Aug 2026 07:15:00 +0000
sdk: quarantine NIP-46 transition surface
- Store the canonical Nostr Connect transport behind the SDK signer boundary.
- Add final client-based constructors and keep only hidden CLI transition adapters.
- Update examples and tests to exercise the final package-owned state machine.
- Verify package checks, tests, clippy, architecture policy, and source boundaries.
Diffstat:
4 files changed, 235 insertions(+), 150 deletions(-)
diff --git a/crates/sdk/examples/sdk_v1_myc_nip46_signer_setup.rs b/crates/sdk/examples/sdk_v1_myc_nip46_signer_setup.rs
@@ -1,36 +1,31 @@
use nostr::Keys as RadrootsNostrKeys;
use radroots_event::envelope::kind::KIND_TRADE_PROPOSAL;
-use radroots_nostr::event::Event as RadrootsNostrEvent;
use radroots_nostr_connect::{
- Error as NostrConnectError, client::Target, uri::RelayUrl as ConnectRelayUrl,
+ client::{CancellationToken, Client, ClientEvent, Receive, Target, Transport, TransportFuture},
+ uri::RelayUrl as ConnectRelayUrl,
};
use radroots_sdk::{
- RadrootsClient, RadrootsSdkMycNip46Signer, RadrootsSdkNip46ClientKey,
- RadrootsSdkNip46Transport, RadrootsSdkNip46TransportFuture, RadrootsSdkSignerMode,
- RadrootsSdkSignerProvider, radroots_sdk_myc_nip46_product_permission_strings,
+ RadrootsClient, RadrootsSdkMycNip46Signer, RadrootsSdkSignerMode, RadrootsSdkSignerProvider,
+ radroots_sdk_myc_nip46_product_permission_strings,
};
-use std::sync::Arc;
struct ExampleNip46Transport;
-impl RadrootsSdkNip46Transport for ExampleNip46Transport {
- fn publish_request_event<'a>(
- &'a self,
- _event: RadrootsNostrEvent,
- ) -> RadrootsSdkNip46TransportFuture<'a, ()> {
+impl Transport for ExampleNip46Transport {
+ fn publish<'a>(&'a mut self, _event: ClientEvent) -> TransportFuture<'a, ()> {
Box::pin(async { Ok(()) })
}
- fn next_response_event<'a>(
- &'a self,
- ) -> RadrootsSdkNip46TransportFuture<'a, RadrootsNostrEvent> {
- Box::pin(async { Err(NostrConnectError::RequestTimedOut) })
+ fn receive<'a>(
+ &'a mut self,
+ _cancellation: &'a CancellationToken,
+ ) -> TransportFuture<'a, Receive> {
+ Box::pin(async { Ok(Receive::TimedOut) })
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
- let client_key = RadrootsSdkNip46ClientKey::generate();
let remote_signer_keys = RadrootsNostrKeys::generate();
let user_keys = RadrootsNostrKeys::generate();
let remote_signer_public_key =
@@ -39,11 +34,11 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
remote_signer_public_key,
vec![ConnectRelayUrl::parse("wss://relay.example.com")?],
)?;
- let signer = RadrootsSdkMycNip46Signer::new(
- client_key,
- target,
+ let client = Client::generate(target)?;
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ client,
user_keys.public_key().to_hex(),
- Arc::new(ExampleNip46Transport),
+ ExampleNip46Transport,
)?;
let sdk = RadrootsClient::builder()
.signer_provider(RadrootsSdkSignerProvider::MycNip46(Box::new(signer)))
diff --git a/crates/sdk/src/signer_provider.rs b/crates/sdk/src/signer_provider.rs
@@ -25,10 +25,10 @@ use radroots_signing::{
};
use std::sync::Arc;
use std::time::Duration;
+use tokio::sync::Mutex as AsyncMutex;
use tokio::time::timeout;
use uuid::Uuid;
-pub type RadrootsSdkNip46TransportFuture<'a, T> = TransportFuture<'a, T>;
pub type RadrootsSdkLocalSignerCapability = dyn Signer;
pub const RADROOTS_SDK_MYC_NIP46_PRODUCT_SIGN_EVENT_KINDS: [u32; 7] = [
@@ -42,32 +42,14 @@ pub const RADROOTS_SDK_MYC_NIP46_PRODUCT_SIGN_EVENT_KINDS: [u32; 7] = [
];
pub const RADROOTS_SDK_MYC_NIP46_DEFAULT_REQUEST_TIMEOUT_MS: u64 = 30_000;
-/// Opaque client key used only to authenticate and encrypt one NIP-46 session.
-///
-/// The key is single-owner, cannot be serialized, and never exposes its
-/// secret representation. Generate it explicitly and move it into
-/// [`RadrootsSdkMycNip46Signer::new`].
-///
-/// ```compile_fail
-/// use radroots_sdk::RadrootsSdkNip46ClientKey;
-///
-/// let key = RadrootsSdkNip46ClientKey::generate();
-/// let _duplicate = key.clone();
-/// ```
-///
-/// ```compile_fail
-/// use radroots_sdk::RadrootsSdkNip46ClientKey;
-///
-/// let key = RadrootsSdkNip46ClientKey::generate();
-/// let _json = serde_json::to_string(&key)?;
-/// # Ok::<(), serde_json::Error>(())
-/// ```
+/// Private key transition surface retained through CLI migration Step 271; removed in Step 313.
+#[doc(hidden)]
pub struct RadrootsSdkNip46ClientKey {
keys: RadrootsNostrKeys,
}
+#[doc(hidden)]
impl RadrootsSdkNip46ClientKey {
- /// Generates fresh client key material for one NIP-46 signer session.
#[must_use]
pub fn generate() -> Self {
Self {
@@ -89,6 +71,21 @@ impl fmt::Debug for RadrootsSdkNip46ClientKey {
}
}
+#[doc(hidden)]
+pub type RadrootsSdkNip46TransportFuture<'a, T> = TransportFuture<'a, T>;
+
+/// Private relay-event transition surface retained through CLI migration Step 271; removed in Step 313.
+#[doc(hidden)]
+pub trait RadrootsSdkNip46Transport: Send + Sync {
+ fn publish_request_event<'a>(
+ &'a self,
+ event: RadrootsNostrEvent,
+ ) -> RadrootsSdkNip46TransportFuture<'a, ()>;
+
+ fn next_response_event<'a>(&'a self)
+ -> RadrootsSdkNip46TransportFuture<'a, RadrootsNostrEvent>;
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
@@ -340,16 +337,6 @@ impl RadrootsSdkLocalKeySigner {
}
}
-pub trait RadrootsSdkNip46Transport: Send + Sync {
- fn publish_request_event<'a>(
- &'a self,
- event: RadrootsNostrEvent,
- ) -> RadrootsSdkNip46TransportFuture<'a, ()>;
-
- fn next_response_event<'a>(&'a self)
- -> RadrootsSdkNip46TransportFuture<'a, RadrootsNostrEvent>;
-}
-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct RadrootsSdkMycNip46RequestPolicy {
request_timeout: Duration,
@@ -385,12 +372,13 @@ impl Default for RadrootsSdkMycNip46RequestPolicy {
pub struct RadrootsSdkMycNip46Signer {
client: Arc<Client>,
user_pubkey: PublicKey,
- transport: Arc<dyn RadrootsSdkNip46Transport>,
+ transport: Arc<AsyncMutex<Box<dyn Transport>>>,
request_policy: RadrootsSdkMycNip46RequestPolicy,
request_id_generator: Arc<dyn RadrootsSdkMycNip46RequestIdGenerator>,
}
impl RadrootsSdkMycNip46Signer {
+ #[doc(hidden)]
pub fn new(
client_key: RadrootsSdkNip46ClientKey,
target: Target,
@@ -406,6 +394,7 @@ impl RadrootsSdkMycNip46Signer {
)
}
+ #[doc(hidden)]
pub fn new_with_request_policy(
client_key: RadrootsSdkNip46ClientKey,
target: Target,
@@ -413,9 +402,44 @@ impl RadrootsSdkMycNip46Signer {
transport: Arc<dyn RadrootsSdkNip46Transport>,
request_policy: RadrootsSdkMycNip46RequestPolicy,
) -> Result<Self, RadrootsSdkError> {
+ let client_secret = client_key.into_keys().secret_key().to_secret_hex();
+ let client = Client::from_secret(client_secret.as_str(), target)
+ .map_err(sdk_error_from_nip46_error)?;
+ Self::from_client_with_request_policy(
+ client,
+ user_pubkey,
+ RadrootsSdkNip46RelayEventTransport { transport },
+ request_policy,
+ )
+ }
+
+ pub fn from_client<T>(
+ client: Client,
+ user_pubkey: impl AsRef<str>,
+ transport: T,
+ ) -> Result<Self, RadrootsSdkError>
+ where
+ T: Transport + 'static,
+ {
+ Self::from_client_with_request_policy(
+ client,
+ user_pubkey,
+ transport,
+ RadrootsSdkMycNip46RequestPolicy::default(),
+ )
+ }
+
+ pub fn from_client_with_request_policy<T>(
+ client: Client,
+ user_pubkey: impl AsRef<str>,
+ transport: T,
+ request_policy: RadrootsSdkMycNip46RequestPolicy,
+ ) -> Result<Self, RadrootsSdkError>
+ where
+ T: Transport + 'static,
+ {
Self::new_with_request_id_generator(
- client_key,
- target,
+ client,
user_pubkey,
transport,
request_policy,
@@ -423,18 +447,17 @@ impl RadrootsSdkMycNip46Signer {
)
}
- fn new_with_request_id_generator(
- client_key: RadrootsSdkNip46ClientKey,
- target: Target,
+ fn new_with_request_id_generator<T>(
+ client: Client,
user_pubkey: impl AsRef<str>,
- transport: Arc<dyn RadrootsSdkNip46Transport>,
+ transport: T,
request_policy: RadrootsSdkMycNip46RequestPolicy,
request_id_generator: Arc<dyn RadrootsSdkMycNip46RequestIdGenerator>,
- ) -> Result<Self, RadrootsSdkError> {
+ ) -> Result<Self, RadrootsSdkError>
+ where
+ T: Transport + 'static,
+ {
RadrootsSdkMycNip46RequestPolicy::new(request_policy.request_timeout())?;
- let client_secret = client_key.into_keys().secret_key().to_secret_hex();
- let client = Client::from_secret(client_secret.as_str(), target)
- .map_err(sdk_error_from_nip46_error)?;
let user_pubkey = PublicKey::from_hex(user_pubkey.as_ref()).map_err(|error| {
RadrootsSdkError::InvalidRequest {
message: format!("myc_nip46 user pubkey is invalid: {error}"),
@@ -443,7 +466,7 @@ impl RadrootsSdkMycNip46Signer {
Ok(Self {
client: Arc::new(client),
user_pubkey,
- transport,
+ transport: Arc::new(AsyncMutex::new(Box::new(transport))),
request_policy,
request_id_generator,
})
@@ -498,8 +521,9 @@ impl RadrootsSdkMycNip46Signer {
let sign_event_request = sign_event_request_from_frozen_draft(sign_request.draft())?;
let request_id =
RequestId::parse(self.next_request_id()).map_err(sdk_error_from_nip46_error)?;
- let mut adapter = RadrootsSdkNip46TransportAdapter {
- transport: self.transport.as_ref(),
+ let mut transport = self.transport.lock().await;
+ let mut adapter = RadrootsSdkNip46TimeoutTransport {
+ transport: transport.as_mut(),
request_timeout: self.request_policy.request_timeout(),
};
let mut progress_error = None;
@@ -598,12 +622,16 @@ pub fn radroots_sdk_myc_nip46_product_permission_strings() -> Vec<String> {
.collect()
}
-struct RadrootsSdkNip46TransportAdapter<'a> {
- transport: &'a dyn RadrootsSdkNip46Transport,
+struct RadrootsSdkNip46TimeoutTransport<'a> {
+ transport: &'a mut dyn Transport,
request_timeout: Duration,
}
-impl Transport for RadrootsSdkNip46TransportAdapter<'_> {
+struct RadrootsSdkNip46RelayEventTransport {
+ transport: Arc<dyn RadrootsSdkNip46Transport>,
+}
+
+impl Transport for RadrootsSdkNip46RelayEventTransport {
fn publish<'a>(&'a mut self, event: ClientEvent) -> TransportFuture<'a, ()> {
let event = match RadrootsNostrEvent::from_json(event.as_json()) {
Ok(event) => event,
@@ -626,14 +654,37 @@ impl Transport for RadrootsSdkNip46TransportAdapter<'_> {
return Box::pin(async { Ok(Receive::Cancelled) });
}
let next = self.transport.next_response_event();
+ Box::pin(async move {
+ let event = next.await?;
+ if cancellation.is_cancelled() {
+ return Ok(Receive::Cancelled);
+ }
+ ClientEvent::from_json(event.as_json().as_str()).map(Receive::event)
+ })
+ }
+}
+
+impl Transport for RadrootsSdkNip46TimeoutTransport<'_> {
+ fn publish<'a>(&'a mut self, event: ClientEvent) -> TransportFuture<'a, ()> {
+ self.transport.publish(event)
+ }
+
+ fn receive<'a>(
+ &'a mut self,
+ cancellation: &'a CancellationToken,
+ ) -> TransportFuture<'a, Receive> {
+ if cancellation.is_cancelled() {
+ return Box::pin(async { Ok(Receive::Cancelled) });
+ }
+ let next = self.transport.receive(cancellation);
let request_timeout = self.request_timeout;
Box::pin(async move {
match timeout(request_timeout, next).await {
- Ok(Ok(event)) => {
+ Ok(Ok(receive)) => {
if cancellation.is_cancelled() {
return Ok(Receive::Cancelled);
}
- ClientEvent::from_json(event.as_json().as_str()).map(Receive::event)
+ Ok(receive)
}
Ok(Err(error)) => Err(error),
Err(_) => Ok(Receive::TimedOut),
diff --git a/crates/sdk/tests/source_boundary.rs b/crates/sdk/tests/source_boundary.rs
@@ -285,7 +285,6 @@ fn signer_transition_surface_is_private_hidden_and_scheduled_for_removal() {
fn signer_consumers_use_the_final_nostr_connect_state_machine() {
let manifest = manifest_dir();
for relative in [
- "src/signer_provider.rs",
"src/adapters/signer.rs",
"examples/sdk_v1_myc_nip46_signer_setup.rs",
] {
@@ -298,6 +297,8 @@ fn signer_consumers_use_the_final_nostr_connect_state_machine() {
"RadrootsNostrConnectRequest",
"RadrootsNostrConnectResponse",
"RADROOTS_NOSTR_CONNECT_",
+ "RadrootsSdkNip46ClientKey",
+ "RadrootsSdkNip46Transport",
] {
assert!(
!source.contains(retired),
@@ -307,6 +308,19 @@ fn signer_consumers_use_the_final_nostr_connect_state_machine() {
}
let provider = read_source(&manifest.join("src/signer_provider.rs"));
- assert!(provider.contains("impl Transport for RadrootsSdkNip46TransportAdapter"));
+ assert!(provider.contains("transport: Arc<AsyncMutex<Box<dyn Transport>>>"));
+ assert!(provider.contains("impl Transport for RadrootsSdkNip46TimeoutTransport"));
assert!(provider.contains(".client\n .execute("));
+ assert!(provider.contains("pub fn from_client<T>("));
+ assert!(provider.contains("CLI migration Step 271; removed in Step 313"));
+ for shim in [
+ "pub struct RadrootsSdkNip46ClientKey",
+ "pub type RadrootsSdkNip46TransportFuture",
+ "pub trait RadrootsSdkNip46Transport",
+ ] {
+ let position = provider
+ .find(shim)
+ .unwrap_or_else(|| panic!("missing compatibility shim `{shim}`"));
+ assert!(provider[..position].ends_with("#[doc(hidden)]\n"));
+ }
}
diff --git a/crates/sdk/tests/unit/signer_provider_tests.rs b/crates/sdk/tests/unit/signer_provider_tests.rs
@@ -1,4 +1,5 @@
use super::*;
+use nostr::Keys as RadrootsNostrKeys;
use nostr::nips::nip44::{self, Version};
use nostr::{EventBuilder, JsonUtil, Kind, Tag};
use radroots_event::contract::AuthorRole;
@@ -65,16 +66,8 @@ fn nip46_target(remote_public_key: nostr::PublicKey, relays: Vec<nostr::RelayUrl
Target::try_new(remote_public_key, relays).expect("NIP-46 target")
}
-fn client_keys() -> RadrootsSdkNip46ClientKey {
- RadrootsSdkNip46ClientKey::generate()
-}
-
-#[test]
-fn nip46_client_key_debug_output_is_always_redacted() {
- assert_eq!(
- format!("{:?}", RadrootsSdkNip46ClientKey::generate()),
- "RadrootsSdkNip46ClientKey(\"[redacted]\")"
- );
+fn nip46_client(target: Target) -> Client {
+ Client::generate(target).expect("NIP-46 client")
}
fn actor() -> Actor {
@@ -173,17 +166,21 @@ fn myc_signer_with_responses(
remote_keys.public_key(),
vec![nostr::RelayUrl::parse("wss://relay.example.com").expect("relay")],
);
- let signer =
- RadrootsSdkMycNip46Signer::new(client_keys(), target, user_pubkey(), transport.clone())
- .expect("signer");
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ user_pubkey(),
+ transport.as_ref().clone(),
+ )
+ .expect("signer");
(signer, transport)
}
+#[derive(Clone)]
struct MockNip46Transport {
remote_keys: RadrootsNostrKeys,
- responses: Mutex<VecDeque<MockNip46Response>>,
- published: Mutex<Vec<RadrootsNostrEvent>>,
- inbound: Mutex<VecDeque<RadrootsNostrEvent>>,
+ responses: Arc<Mutex<VecDeque<MockNip46Response>>>,
+ published: Arc<Mutex<Vec<RadrootsNostrEvent>>>,
+ inbound: Arc<Mutex<VecDeque<RadrootsNostrEvent>>>,
}
enum MockNip46Response {
@@ -194,9 +191,9 @@ impl MockNip46Transport {
fn new(remote_keys: RadrootsNostrKeys, responses: Vec<MockNip46Response>) -> Self {
Self {
remote_keys,
- responses: Mutex::new(responses.into()),
- published: Mutex::new(Vec::new()),
- inbound: Mutex::new(VecDeque::new()),
+ responses: Arc::new(Mutex::new(responses.into())),
+ published: Arc::new(Mutex::new(Vec::new())),
+ inbound: Arc::new(Mutex::new(VecDeque::new())),
}
}
@@ -221,11 +218,18 @@ fn request_message_from_event(
serde_json::from_str(payload.as_str()).expect("request message")
}
-impl RadrootsSdkNip46Transport for MockNip46Transport {
- fn publish_request_event<'a>(
- &'a self,
- event: RadrootsNostrEvent,
- ) -> RadrootsSdkNip46TransportFuture<'a, ()> {
+impl Transport for MockNip46Transport {
+ fn publish<'a>(&'a mut self, event: ClientEvent) -> TransportFuture<'a, ()> {
+ let event = match RadrootsNostrEvent::from_json(event.as_json()) {
+ Ok(event) => event,
+ Err(error) => {
+ return Box::pin(async move {
+ Err(NostrConnectError::Transport {
+ reason: format!("invalid test NIP-46 publication: {error}"),
+ })
+ });
+ }
+ };
self.published.lock().expect("published lock").push(event);
let response = self.responses.lock().expect("responses lock").pop_front();
if let Some(MockNip46Response::Respond(response)) = response {
@@ -246,41 +250,48 @@ impl RadrootsSdkNip46Transport for MockNip46Transport {
Box::pin(async { Ok(()) })
}
- fn next_response_event<'a>(
- &'a self,
- ) -> RadrootsSdkNip46TransportFuture<'a, RadrootsNostrEvent> {
+ fn receive<'a>(
+ &'a mut self,
+ cancellation: &'a CancellationToken,
+ ) -> TransportFuture<'a, Receive> {
+ if cancellation.is_cancelled() {
+ return Box::pin(async { Ok(Receive::Cancelled) });
+ }
let next = self.inbound.lock().expect("inbound lock").pop_front();
- Box::pin(async move { next.ok_or(NostrConnectError::RequestTimedOut) })
+ Box::pin(async move {
+ match next {
+ Some(event) => ClientEvent::from_json(event.as_json().as_str()).map(Receive::event),
+ None => Err(NostrConnectError::RequestTimedOut),
+ }
+ })
}
}
+#[derive(Clone)]
struct HangingNip46Transport {
- published: Mutex<Vec<RadrootsNostrEvent>>,
+ published: Arc<Mutex<Vec<RadrootsNostrEvent>>>,
}
impl HangingNip46Transport {
fn new() -> Self {
Self {
- published: Mutex::new(Vec::new()),
+ published: Arc::new(Mutex::new(Vec::new())),
}
}
}
-impl RadrootsSdkNip46Transport for HangingNip46Transport {
- fn publish_request_event<'a>(
- &'a self,
- event: RadrootsNostrEvent,
- ) -> RadrootsSdkNip46TransportFuture<'a, ()> {
+impl Transport for HangingNip46Transport {
+ fn publish<'a>(&'a mut self, event: ClientEvent) -> TransportFuture<'a, ()> {
+ let event = RadrootsNostrEvent::from_json(event.as_json()).expect("valid client event");
self.published.lock().expect("published lock").push(event);
Box::pin(async { Ok(()) })
}
- fn next_response_event<'a>(
- &'a self,
- ) -> RadrootsSdkNip46TransportFuture<'a, RadrootsNostrEvent> {
- Box::pin(future::pending::<
- Result<RadrootsNostrEvent, NostrConnectError>,
- >())
+ fn receive<'a>(
+ &'a mut self,
+ _cancellation: &'a CancellationToken,
+ ) -> TransportFuture<'a, Receive> {
+ Box::pin(future::pending::<Result<Receive, NostrConnectError>>())
}
}
@@ -422,9 +433,12 @@ fn signer_provider_reports_myc_status_capability_and_constructor_errors() {
];
let target = nip46_target(remote_keys.public_key(), relays);
let transport = Arc::new(MockNip46Transport::new(remote_keys.clone(), Vec::new()));
- let signer =
- RadrootsSdkMycNip46Signer::new(client_keys(), target, user_pubkey(), transport.clone())
- .expect("signer");
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ user_pubkey(),
+ transport.as_ref().clone(),
+ )
+ .expect("signer");
let provider = RadrootsSdkSignerProvider::MycNip46(Box::new(signer));
assert_eq!(provider.mode(), RadrootsSdkSignerMode::MycNip46);
@@ -454,11 +468,14 @@ fn signer_provider_reports_myc_status_capability_and_constructor_errors() {
);
let target = nip46_target(remote_keys.public_key(), Vec::new());
- let error =
- match RadrootsSdkMycNip46Signer::new(client_keys(), target, "not-a-pubkey", transport) {
- Ok(_) => panic!("expected invalid pubkey"),
- Err(error) => error,
- };
+ let error = match RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ "not-a-pubkey",
+ transport.as_ref().clone(),
+ ) {
+ Ok(_) => panic!("expected invalid pubkey"),
+ Err(error) => error,
+ };
assert!(matches!(
error,
RadrootsSdkError::InvalidRequest { ref message }
@@ -536,8 +553,9 @@ fn nip46_private_helpers_map_identity_adapter_and_response_edges() {
async fn nip46_transport_adapter_delegates_publish_and_response_poll() {
let transport = Arc::new(MockNip46Transport::new(remote_keys(), Vec::new()));
let event = sign_event(&user_keys(), &frozen_draft());
- let mut adapter = RadrootsSdkNip46TransportAdapter {
- transport: transport.as_ref(),
+ let mut canonical_transport = transport.as_ref().clone();
+ let mut adapter = RadrootsSdkNip46TimeoutTransport {
+ transport: &mut canonical_transport,
request_timeout: Duration::from_millis(10),
};
@@ -577,7 +595,6 @@ fn myc_nip46_product_permissions_cover_sdk_write_event_kinds() {
#[tokio::test]
async fn myc_nip46_provider_signs_and_validates_remote_event() {
- let client_keys = client_keys();
let remote_keys = remote_keys();
let user_keys = user_keys();
let draft = frozen_draft();
@@ -593,9 +610,12 @@ async fn myc_nip46_provider_signs_and_validates_remote_event() {
remote_keys.public_key(),
vec![nostr::RelayUrl::parse("wss://relay.example.com").expect("relay")],
);
- let signer =
- RadrootsSdkMycNip46Signer::new(client_keys, target, user_pubkey(), transport.clone())
- .expect("signer");
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ user_pubkey(),
+ transport.as_ref().clone(),
+ )
+ .expect("signer");
let provider = RadrootsSdkSignerProvider::MycNip46(Box::new(signer));
assert_eq!(
provider.capability().nip46_permissions,
@@ -721,11 +741,10 @@ async fn myc_nip46_provider_reports_preflight_and_progress_sink_edges() {
let remote_keys = remote_keys();
let mismatch_transport = Arc::new(MockNip46Transport::new(remote_keys.clone(), Vec::new()));
let mismatch_target = nip46_target(remote_keys.public_key(), Vec::new());
- let mismatch_signer = RadrootsSdkMycNip46Signer::new(
- client_keys(),
- mismatch_target,
+ let mismatch_signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(mismatch_target),
remote_keys.public_key().to_hex(),
- mismatch_transport.clone(),
+ mismatch_transport.as_ref().clone(),
)
.expect("mismatch signer");
let signer_error = mismatch_signer
@@ -794,7 +813,6 @@ async fn myc_nip46_provider_returns_completion_progress_errors_after_remote_sign
#[tokio::test]
async fn myc_nip46_provider_reports_auth_challenge_progress_and_timeout() {
- let client_keys = client_keys();
let remote_keys = remote_keys();
let transport = Arc::new(MockNip46Transport::new(
remote_keys.clone(),
@@ -803,8 +821,12 @@ async fn myc_nip46_provider_reports_auth_challenge_progress_and_timeout() {
))],
));
let target = nip46_target(remote_keys.public_key(), Vec::new());
- let signer = RadrootsSdkMycNip46Signer::new(client_keys, target, user_pubkey(), transport)
- .expect("signer");
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ user_pubkey(),
+ transport.as_ref().clone(),
+ )
+ .expect("signer");
let mut progress = Vec::new();
let draft = frozen_draft();
let actor = actor();
@@ -841,7 +863,6 @@ async fn myc_nip46_provider_reports_auth_challenge_progress_and_timeout() {
#[tokio::test]
async fn myc_nip46_provider_returns_progress_sink_errors_from_auth_challenge() {
- let client_keys = client_keys();
let remote_keys = remote_keys();
let transport = Arc::new(MockNip46Transport::new(
remote_keys.clone(),
@@ -850,8 +871,12 @@ async fn myc_nip46_provider_returns_progress_sink_errors_from_auth_challenge() {
))],
));
let target = nip46_target(remote_keys.public_key(), Vec::new());
- let signer = RadrootsSdkMycNip46Signer::new(client_keys, target, user_pubkey(), transport)
- .expect("signer");
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ user_pubkey(),
+ transport.as_ref().clone(),
+ )
+ .expect("signer");
let draft = frozen_draft();
let actor = actor();
let mut observed = Vec::new();
@@ -899,11 +924,10 @@ async fn myc_nip46_provider_rejects_zero_timeout_policy() {
let target = nip46_target(remote_keys().public_key(), Vec::new());
let transport = Arc::new(MockNip46Transport::new(remote_keys(), Vec::new()));
- let constructor_error = match RadrootsSdkMycNip46Signer::new_with_request_policy(
- client_keys(),
- target,
+ let constructor_error = match RadrootsSdkMycNip46Signer::from_client_with_request_policy(
+ nip46_client(target),
user_pubkey(),
- transport,
+ transport.as_ref().clone(),
RadrootsSdkMycNip46RequestPolicy {
request_timeout: Duration::ZERO,
},
@@ -920,16 +944,14 @@ async fn myc_nip46_provider_rejects_zero_timeout_policy() {
#[tokio::test]
async fn myc_nip46_provider_times_out_hanging_transport() {
- let client_keys = client_keys();
let remote_keys = remote_keys();
let target = nip46_target(remote_keys.public_key(), Vec::new());
let transport = Arc::new(HangingNip46Transport::new());
let policy = RadrootsSdkMycNip46RequestPolicy::new(Duration::from_millis(5)).expect("policy");
- let signer = RadrootsSdkMycNip46Signer::new_with_request_policy(
- client_keys,
- target,
+ let signer = RadrootsSdkMycNip46Signer::from_client_with_request_policy(
+ nip46_client(target),
user_pubkey(),
- transport,
+ transport.as_ref().clone(),
policy,
)
.expect("signer");
@@ -1028,7 +1050,6 @@ async fn myc_nip46_provider_rejects_returned_event_drift() {
];
for (drift_kind, signing_keys, drifted_draft) in cases {
- let client_keys = client_keys();
let remote_keys = remote_keys();
let signed_event = sign_event(&signing_keys, &drifted_draft);
let transport = Arc::new(MockNip46Transport::new(
@@ -1038,8 +1059,12 @@ async fn myc_nip46_provider_rejects_returned_event_drift() {
))],
));
let target = nip46_target(remote_keys.public_key(), Vec::new());
- let signer = RadrootsSdkMycNip46Signer::new(client_keys, target, user_pubkey(), transport)
- .expect("signer");
+ let signer = RadrootsSdkMycNip46Signer::from_client(
+ nip46_client(target),
+ user_pubkey(),
+ transport.as_ref().clone(),
+ )
+ .expect("signer");
let actor = actor();
let error = signer