commit 6624524c834a20482e5aed7153c9f727f40a0c00 parent 4267774b0f66efc51920512bb6a7671d33f4a82f Author: triesap <tyson@radroots.org> Date: Wed, 8 Jul 2026 01:01:38 +0000 sdk: remove proxy relay bridge - remove the radrootsd proxy relay-trait adapter and relay receipt conversion helpers - delete the configured-profile target policy and route callers through the active transport profile - update SDK runtime tests, source-boundary guards, and README wording for the typed transport path - verify SDK and downstream CLI transport lanes through extbuild Diffstat:
18 files changed, 141 insertions(+), 538 deletions(-)
diff --git a/crates/sdk/README b/crates/sdk/README @@ -9,7 +9,7 @@ The SDK v1 product runtime is centered on `RadrootsClient::builder()`, profile, and no production network publishing. Directory storage is opt-in and creates `event_store.sqlite` and `outbox.sqlite` in the selected directory. Configured Nostr relay URLs live inside `TransportProfile::Nostr` or the Nostr side of `TransportProfile::Hybrid`, and product -enqueue requests choose them through `TargetPolicy::UseConfiguredProfile`. +enqueue requests choose the active profile through `TargetPolicy::use_transport_profile()`. When `signer-adapters` is enabled, `RadrootsClient::builder()` accepts a configured `RadrootsSdkSignerProvider`. The production signing modes are `local_key` and `myc_nip46`. Product diff --git a/crates/sdk/src/adapters/radrootsd.rs b/crates/sdk/src/adapters/radrootsd.rs @@ -2,19 +2,10 @@ use core::fmt; use core::time::Duration; use radroots_events::draft::RadrootsSignedNostrEvent; -use radroots_transport::{ - RadrootsTransportKind, RadrootsTransportSatisfactionPolicy, RadrootsTransportTarget, -}; -use radroots_transport_nostr::{ - RadrootsRelayOutcome, RadrootsRelayOutcomeKind, RadrootsRelayPublishAdapter, - RadrootsRelayPublishReceipt, RadrootsRelayPublishRelayReceipt, RadrootsRelayPublishRequest, - RadrootsRelayTransportError, -}; use radroots_transport_publish_protocol::{ METHOD_EVENT, SignedNostrEventWire, TransportPublishDeliveryPolicy, - TransportPublishEventRequest, TransportPublishEventResponse, TransportPublishOutcomeKind, - TransportPublishProtocolError, TransportPublishTarget, TransportPublishTargetOutcome, - TransportPublishTargetPolicy, + TransportPublishEventRequest, TransportPublishEventResponse, TransportPublishProtocolError, + TransportPublishTarget, TransportPublishTargetOutcome, TransportPublishTargetPolicy, }; use reqwest::header::{AUTHORIZATION, CONTENT_TYPE, HeaderMap, HeaderValue}; use serde::{Deserialize, Serialize, de::DeserializeOwned}; @@ -107,47 +98,6 @@ impl RadrootsdProxyPublishAdapter { } } -impl RadrootsRelayPublishAdapter for RadrootsdProxyPublishAdapter { - fn publish<'a>( - &'a self, - request: RadrootsRelayPublishRequest, - ) -> futures::future::BoxFuture< - 'a, - Result<Vec<RadrootsRelayPublishRelayReceipt>, RadrootsRelayTransportError>, - > { - Box::pin(async move { - let targets = request - .targets - .relay_strings() - .into_iter() - .map(|relay| RadrootsTransportTarget::new(RadrootsTransportKind::Nostr, relay)) - .collect::<Result<Vec<_>, _>>()?; - let request = RadrootsdProxyPublishRequest { - delivery_policy: delivery_policy_from_relay_request( - targets.len(), - &request.satisfaction_policy, - )?, - signed_event: request.signed_event, - target_policy: TransportPublishTargetPolicy::explicit_targets( - targets - .iter() - .map(transport_publish_target) - .collect::<Result<Vec<_>, _>>()?, - ), - idempotency_key: None, - timeout_ms: self.config.request_timeout_ms, - }; - let response = self - .publish_signed_event(request) - .await - .map_err(|error| RadrootsRelayTransportError::Transport(error.to_string()))?; - let receipt = proxy_relay_receipt_from_response(response) - .map_err(|error| RadrootsRelayTransportError::Transport(error.to_string()))?; - Ok(receipt.relays) - }) - } -} - #[derive(Clone, Debug, PartialEq, Eq)] pub struct RadrootsdProxyPublishRequest { pub signed_event: RadrootsSignedNostrEvent, @@ -414,109 +364,6 @@ fn validate_explicit_response_targets( Ok(()) } -fn transport_publish_target( - target: &RadrootsTransportTarget, -) -> Result<TransportPublishTarget, RadrootsRelayTransportError> { - if target.kind != RadrootsTransportKind::Nostr { - return Err(RadrootsRelayTransportError::Transport(format!( - "radrootsd proxy relay adapter is Nostr-only and cannot publish {} targets", - target.kind.canonical_label() - ))); - } - Ok(TransportPublishTarget { - transport_kind: target.kind.canonical_label(), - endpoint_uri: target.uri.as_str().to_owned(), - preview_behavior: None, - }) -} - -fn delivery_policy_from_relay_request( - target_count: usize, - satisfaction_policy: &RadrootsTransportSatisfactionPolicy, -) -> Result<TransportPublishDeliveryPolicy, RadrootsRelayTransportError> { - let required = satisfaction_policy.required_target_count(target_count)?; - let delivery_policy = if required >= target_count { - TransportPublishDeliveryPolicy::All - } else if required <= 1 { - TransportPublishDeliveryPolicy::Any - } else { - TransportPublishDeliveryPolicy::Quorum { quorum: required } - }; - Ok(delivery_policy) -} - -fn proxy_relay_receipt_from_response( - response: TransportPublishEventResponse, -) -> Result<RadrootsRelayPublishReceipt, RadrootsdError> { - response - .job - .validate() - .map_err(RadrootsdError::from_protocol)?; - let quorum = response - .job - .delivery_policy - .required_target_count(response.job.target_count); - let relays = response - .job - .targets - .into_iter() - .filter(|target| target.transport_kind == "nostr") - .map(relay_receipt_from_target_outcome) - .collect::<Vec<_>>(); - let attempted_count = relays.iter().filter(|relay| relay.attempted).count(); - Ok(RadrootsRelayPublishReceipt { - event_id: response.job.event_id, - attempted_count, - accepted_count: response.job.acknowledged_count, - retryable_count: response.job.retryable_count, - terminal_count: response.job.terminal_count, - quorum, - quorum_met: response.job.delivery_satisfied, - relays, - }) -} - -fn relay_receipt_from_target_outcome( - target: TransportPublishTargetOutcome, -) -> RadrootsRelayPublishRelayReceipt { - RadrootsRelayPublishRelayReceipt { - relay_url: target.endpoint_uri, - attempted: target.attempted, - outcome: RadrootsRelayOutcome { - kind: relay_outcome_kind(target.outcome_kind), - message: target.message, - }, - } -} - -fn relay_outcome_kind(kind: TransportPublishOutcomeKind) -> RadrootsRelayOutcomeKind { - match kind { - TransportPublishOutcomeKind::Accepted => RadrootsRelayOutcomeKind::Accepted, - TransportPublishOutcomeKind::DuplicateAccepted => { - RadrootsRelayOutcomeKind::DuplicateAccepted - } - TransportPublishOutcomeKind::Blocked => RadrootsRelayOutcomeKind::Blocked, - TransportPublishOutcomeKind::RateLimited => RadrootsRelayOutcomeKind::RateLimited, - TransportPublishOutcomeKind::Invalid => RadrootsRelayOutcomeKind::Invalid, - TransportPublishOutcomeKind::PowRequired => RadrootsRelayOutcomeKind::PowRequired, - TransportPublishOutcomeKind::Restricted => RadrootsRelayOutcomeKind::Restricted, - TransportPublishOutcomeKind::AuthRequired => RadrootsRelayOutcomeKind::AuthRequired, - TransportPublishOutcomeKind::Muted => RadrootsRelayOutcomeKind::Muted, - TransportPublishOutcomeKind::Unsupported => RadrootsRelayOutcomeKind::Unsupported, - TransportPublishOutcomeKind::PaymentRequired => RadrootsRelayOutcomeKind::PaymentRequired, - TransportPublishOutcomeKind::Error => RadrootsRelayOutcomeKind::Error, - TransportPublishOutcomeKind::Timeout => RadrootsRelayOutcomeKind::Timeout, - TransportPublishOutcomeKind::ConnectionFailed => RadrootsRelayOutcomeKind::ConnectionFailed, - TransportPublishOutcomeKind::TargetRejected => RadrootsRelayOutcomeKind::RelayUrlRejected, - TransportPublishOutcomeKind::SkippedAlreadyAccepted => { - RadrootsRelayOutcomeKind::SkippedAlreadyAccepted - } - TransportPublishOutcomeKind::DeferredUntilImplemented - | TransportPublishOutcomeKind::PreviewUnavailable - | TransportPublishOutcomeKind::Unknown => RadrootsRelayOutcomeKind::Unknown, - } -} - #[cfg(test)] #[path = "../../tests/unit/adapters_radrootsd_tests.rs"] mod tests; diff --git a/crates/sdk/src/transport.rs b/crates/sdk/src/transport.rs @@ -67,16 +67,11 @@ impl NostrRelayUrlPolicy { #[derive(Clone, Debug, PartialEq, Eq)] #[non_exhaustive] pub enum TargetPolicy { - UseConfiguredProfile, Explicit(TargetSet), UseTransportProfile, } impl TargetPolicy { - pub fn configured_profile() -> Self { - Self::UseConfiguredProfile - } - pub fn explicit(targets: TargetSet) -> Self { Self::Explicit(targets) } @@ -108,11 +103,6 @@ impl serde::Serialize for TargetPolicy { S: serde::Serializer, { match self { - Self::UseConfiguredProfile => { - let mut state = serializer.serialize_struct("TargetPolicy", 1)?; - state.serialize_field("kind", "use_configured_profile")?; - state.end() - } Self::Explicit(targets) => { let mut state = serializer.serialize_struct("TargetPolicy", 3)?; state.serialize_field("kind", "explicit")?; @@ -204,22 +194,6 @@ impl TargetSet { self.targets.is_empty() } - pub(crate) fn from_normalized_nostr_relays( - relays: Vec<String>, - ) -> Result<Self, RadrootsSdkError> { - let mut targets = Vec::new(); - let mut seen = BTreeSet::new(); - for relay in relays { - if seen.insert(relay.clone()) { - targets.push(RadrootsTransportTarget::new( - RadrootsTransportKind::Nostr, - relay, - )?); - } - } - Self::from_transport_targets(targets) - } - fn from_transport_targets( targets: Vec<RadrootsTransportTarget>, ) -> Result<Self, RadrootsSdkError> { diff --git a/crates/sdk/src/workflow_runtime.rs b/crates/sdk/src/workflow_runtime.rs @@ -165,16 +165,6 @@ fn resolved_delivery_plan( satisfaction_policy, RadrootsOutboxReticulumPreviewBehavior::RejectDeliveryAttempts, ), - TargetPolicy::UseConfiguredProfile => { - let target_policy = - TargetSet::from_normalized_nostr_relays(sdk.configured_nostr_relay_urls())?; - delivery_plan_from_target_set( - "configured_profile", - target_policy, - satisfaction_policy, - RadrootsOutboxReticulumPreviewBehavior::RejectDeliveryAttempts, - ) - } TargetPolicy::UseTransportProfile => { let transport_profile = sdk.transport_profile(); let target_set = transport_profile.target_set()?.ok_or_else(|| { diff --git a/crates/sdk/tests/dvm_runtime.rs b/crates/sdk/tests/dvm_runtime.rs @@ -234,7 +234,7 @@ async fn dvm_configured_enqueue_reports_prepare_and_target_errors_without_mutati deterministic_event_id("request-event"), deterministic_event_id("decision-event"), inventory_bins(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ); let error = sdk .dvm() @@ -414,7 +414,7 @@ async fn dvm_trade_transition_proof_request_reports_prepare_and_target_errors_wi deterministic_event_id("request-event"), deterministic_event_id("decision-event"), inventory_bins(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ); let error = sdk .dvm() diff --git a/crates/sdk/tests/farms_runtime.rs b/crates/sdk/tests/farms_runtime.rs @@ -609,7 +609,7 @@ async fn farm_enqueue_publish_stores_event_and_queues_signed_outbox_without_prof let request = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_B_D_TAG, "North Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("farm-idem-b") .expect("idempotency key"); @@ -675,7 +675,7 @@ async fn farm_enqueue_publish_returns_sanitized_signer_errors_before_mutation() let request = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_C_D_TAG, "North Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ); let error = sdk .farms() @@ -721,7 +721,7 @@ async fn farm_enqueue_publish_derives_order_independent_idempotency_key() { let first = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_D_D_TAG, "North Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY_B, RELAY, RELAY], NostrRelayUrlPolicy::Public) .expect("first transport targets"); @@ -775,7 +775,7 @@ async fn farm_enqueue_publish_pushes_queued_event_with_mock_relay_sync() { let enqueue_request = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_D_D_TAG, "Sync Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY], NostrRelayUrlPolicy::Public) .expect("transport targets"); @@ -832,7 +832,7 @@ async fn farm_enqueue_publish_reports_preflight_idempotency_conflict_without_mut let first = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_E_D_TAG, "North Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("farm-idem-e") .expect("idempotency key"); @@ -867,7 +867,7 @@ async fn farm_enqueue_publish_reports_preflight_idempotency_conflict_without_mut let second = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_F_D_TAG, "Changed Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("farm-idem-e") .expect("idempotency key"); @@ -941,7 +941,7 @@ async fn farm_runtime_dtos_serialize_deterministically() { let enqueue_request = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_B_D_TAG, "Queued Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY, RELAY_B], NostrRelayUrlPolicy::Public) .expect("relay targets") @@ -1003,7 +1003,7 @@ async fn farm_runtime_dtos_serialize_deterministically() { let try_key_request = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_C_D_TAG, "Queued Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("farm-serialized-try-key") .expect("try idempotency key"); diff --git a/crates/sdk/tests/listings_runtime.rs b/crates/sdk/tests/listings_runtime.rs @@ -241,7 +241,7 @@ async fn enqueue_publish_stores_event_and_queues_signed_outbox_without_publish() let request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_B_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("idem-b") .expect("idempotency key"); @@ -293,24 +293,24 @@ async fn enqueue_publish_stores_event_and_queues_signed_outbox_without_publish() } #[tokio::test] -async fn enqueue_publish_use_configured_profile_rejects_empty_transport_targets() { +async fn enqueue_publish_use_transport_profile_rejects_empty_transport_targets() { let (_tempdir, sdk) = directory_sdk_with_relays(&[]).await; let request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_A_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ); let error = sdk .listings() .enqueue_publish_with_explicit_signer(request, &FixtureSigner::new(SELLER)) .await - .expect_err("empty configured profile"); + .expect_err("empty transport profile"); assert!(matches!( error, RadrootsSdkError::EmptyTransportTargets { operation } - if operation == "sdk transport target set" + if operation == "publish transport profile" )); } @@ -330,7 +330,7 @@ async fn prepare_then_enqueue_prepared_uses_same_event_id() { .enqueue_prepared_publish_with_explicit_signer( &actor, prepared.clone(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), None, &FixtureSigner::new(SELLER), ) @@ -369,7 +369,7 @@ async fn enqueue_receipt_debug_omits_signed_event_payload_material() { let request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_A_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("debug-secret-idempotency") .expect("idempotency key"); @@ -428,7 +428,7 @@ async fn listing_runtime_dtos_serialize_deterministically() { let enqueue_request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_B_D_TAG, "Queued Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY, RELAY_B], NostrRelayUrlPolicy::Public) .expect("relay targets") @@ -469,7 +469,7 @@ async fn listing_runtime_dtos_serialize_deterministically() { let try_key_request = ListingEnqueuePublishRequest::from_document( actor(), RadrootsListingDraftDocumentV1::new(listing(LISTING_C_D_TAG, "Queued Coffee")), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("listing-serialized-try-key") .expect("try idempotency key"); @@ -506,7 +506,7 @@ async fn enqueue_publish_convenience_matches_prepare_plus_enqueue_prepared() { .enqueue_prepared_publish_with_explicit_signer( &prepared_actor, prepared_plan, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), None, &FixtureSigner::new(SELLER), ) @@ -517,7 +517,7 @@ async fn enqueue_publish_convenience_matches_prepare_plus_enqueue_prepared() { let convenience_request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_H_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ); let convenience_receipt = convenience_sdk .listings() @@ -543,7 +543,7 @@ async fn enqueue_prepared_publish_returns_structured_actor_errors() { .enqueue_prepared_publish_with_explicit_signer( &non_seller_actor(), prepared, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), None, &FixtureSigner::new(SELLER), ) @@ -569,7 +569,7 @@ async fn enqueue_prepared_publish_returns_sanitized_signer_errors() { .enqueue_prepared_publish_with_explicit_signer( &actor, prepared, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), None, &FixtureSigner::new(OTHER), ) @@ -593,7 +593,7 @@ async fn explicit_historical_created_at_does_not_backdate_observed_at_ms() { let request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_K_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .with_created_at(created_at); @@ -639,7 +639,7 @@ async fn enqueue_publish_returns_sanitized_signer_errors() { let request = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_C_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ); let error = sdk .listings() @@ -662,7 +662,7 @@ async fn enqueue_publish_reports_preflight_idempotency_conflict_without_mutation let first = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_D_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("idem-d") .expect("idempotency key"); @@ -697,7 +697,7 @@ async fn enqueue_publish_reports_preflight_idempotency_conflict_without_mutation let second = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_E_D_TAG, "Changed"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("idem-d") .expect("idempotency key"); @@ -741,7 +741,7 @@ async fn enqueue_publish_derives_order_independent_idempotency_key() { let first = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_F_D_TAG, "Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY_B, RELAY, RELAY], NostrRelayUrlPolicy::Public) .expect("first transport targets"); diff --git a/crates/sdk/tests/market_runtime.rs b/crates/sdk/tests/market_runtime.rs @@ -150,7 +150,7 @@ async fn market_search_refreshes_local_projection_and_reads_fts() { let publish = ListingEnqueuePublishRequest::new( seller_actor(), listing("Blueberries"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY], NostrRelayUrlPolicy::Public) .expect("target relays"); diff --git a/crates/sdk/tests/orders_runtime.rs b/crates/sdk/tests/orders_runtime.rs @@ -849,7 +849,7 @@ async fn order_submit_enqueue_stores_event_queues_outbox_and_status_sees_request buyer_actor(), listing_event_ptr(), order, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3332,7 +3332,7 @@ async fn order_submit_enqueue_returns_sanitized_signer_errors_before_mutation() buyer_actor(), listing_event_ptr(), order_request("order-submit-wrong-signer"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3382,7 +3382,7 @@ async fn order_submit_enqueue_derives_order_independent_idempotency_key() { buyer_actor(), listing_event_ptr(), order_request("order-submit-idempotent"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3469,7 +3469,7 @@ async fn order_submit_enqueue_pushes_queued_event_with_mock_relay_sync() { buyer_actor(), listing_event_ptr(), order_request("order-submit-sync"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3533,7 +3533,7 @@ async fn order_submit_enqueue_reports_partial_local_mutation_after_outbox_confli buyer_actor(), listing_event_ptr(), order_request("order-submit-conflict-a"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3550,7 +3550,7 @@ async fn order_submit_enqueue_reports_partial_local_mutation_after_outbox_confli buyer_actor(), listing_event_ptr(), order_request("order-submit-conflict-b"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3642,7 +3642,7 @@ async fn order_submit_runtime_dtos_serialize_deterministically() { buyer_actor(), listing_event_ptr(), order_request("order-submit-serialized-enqueue"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -3692,7 +3692,7 @@ async fn order_submit_runtime_dtos_serialize_deterministically() { buyer_actor(), listing_event_ptr(), order_request("order-submit-try-idempotency"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -4663,7 +4663,7 @@ async fn order_decision_runtime_dtos_serialize_deterministically() { seller_actor(), request_event_ptr(&request_event), order_decision("order-decision-serialized-enqueue"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -4713,7 +4713,7 @@ async fn order_decision_runtime_dtos_serialize_deterministically() { seller_actor(), request_event_ptr(&request_event), order_decision("order-decision-try-idempotency"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -4866,7 +4866,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() { root_event.clone(), previous_event.clone(), proposal.clone(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -4910,7 +4910,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() { root_event.clone(), previous_event.clone(), proposal.clone(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -4953,7 +4953,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() { root_event.clone(), previous_event.clone(), revision_decision, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -4982,7 +4982,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() { &previous_event_id, RadrootsOrderRevisionOutcome::Accepted, ), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5014,7 +5014,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() { root_event.clone(), previous_event.clone(), cancellation, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5043,7 +5043,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() { root_event.clone(), previous_event.clone(), order_cancellation("order-revision-dto"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5085,7 +5085,7 @@ async fn order_decision_enqueue_accept_stores_event_queues_outbox_and_updates_st seller_actor(), request_event_ptr(&request_event), order_decision("order-decision-accept"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5192,7 +5192,7 @@ async fn order_decision_enqueue_decline_stores_event_and_status_sees_declined() seller_actor(), request_event_ptr(&request_event), decision, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5236,7 +5236,7 @@ async fn order_decision_enqueue_rejects_missing_request_evidence_before_mutation seller_actor(), missing_request, order_decision("order-decision-missing-request"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5284,7 +5284,7 @@ async fn order_decision_enqueue_returns_sanitized_signer_errors_before_decision_ seller_actor(), request_event_ptr(&request_event), order_decision("order-decision-wrong-signer"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5339,7 +5339,7 @@ async fn order_decision_enqueue_rejects_existing_decision_state_before_mutation( seller_actor(), request_event_ptr(&request_event), decline, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5549,7 +5549,7 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif request_event_ptr(&request_event), request_event_ptr(&request_event), proposal, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5592,7 +5592,7 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif seller_actor(), request_event_ptr(&request_event), order_decision("order-lifecycle-pending-revision"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5620,7 +5620,7 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif request_event_ptr(&request_event), order_event_ptr(&proposal_receipt.signed_event_id), blocked_proposal, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5667,7 +5667,7 @@ async fn order_declined_revision_finalizes_declined_negotiation() { request_event_ptr(&request_event), request_event_ptr(&request_event), proposal.clone(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5692,7 +5692,7 @@ async fn order_declined_revision_finalizes_declined_negotiation() { request_event_ptr(&request_event), order_event_ptr(&proposal_receipt.signed_event_id), declined_revision, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5742,7 +5742,7 @@ async fn order_declined_revision_finalizes_declined_negotiation() { request_event_ptr(&request_event), order_event_ptr(&proposal_receipt.signed_event_id), second_decision, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5826,7 +5826,7 @@ async fn order_cancel_lifecycle_enqueue_updates_status() { request_event_ptr(&request_event), request_event_ptr(&request_event), order_cancellation("order-lifecycle-cancel"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5882,7 +5882,7 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() { &request_event_id, &request_event_id, ), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5913,7 +5913,7 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() { seller_actor(), request_event_ptr(&request_event), order_decision("order-lifecycle-invalid"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5940,7 +5940,7 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() { request_event_ptr(&request_event), order_event_ptr(&decision_receipt.signed_event_id), revision_without_proposal, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) @@ -5963,7 +5963,7 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() { request_event_ptr(&request_event), order_event_ptr(&decision_receipt.signed_event_id), order_cancellation("order-lifecycle-invalid"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), PublishMode::EnqueueOnly, SatisfactionPolicy::NoWait, ) diff --git a/crates/sdk/tests/source_boundary.rs b/crates/sdk/tests/source_boundary.rs @@ -1359,12 +1359,13 @@ fn sdk_proxy_surfaces_reject_removed_daemon_publish_proxy_identifiers() { let adapter_source = read_source(manifest_dir.join("src/adapters/radrootsd.rs").as_path()); assert!( - adapter_source.contains("target.kind != RadrootsTransportKind::Nostr"), - "src/adapters/radrootsd.rs must keep the relay proxy adapter Nostr-only" + !adapter_source + .contains("impl RadrootsRelayPublishAdapter for RadrootsdProxyPublishAdapter"), + "src/adapters/radrootsd.rs must not implement relay publish traits for RadrootsdProxyPublishAdapter" ); assert!( - adapter_source.contains("radrootsd proxy relay adapter is Nostr-only"), - "src/adapters/radrootsd.rs must return a typed Nostr-only proxy adapter error" + !adapter_source.contains("proxy_relay_receipt_from_response"), + "src/adapters/radrootsd.rs must not convert typed transport publish jobs into relay receipts" ); assert!( !adapter_source.contains("TransportPublishPreviewBehavior::RejectDeliveryAttempts"), @@ -1405,6 +1406,44 @@ fn sdk_proxy_surfaces_reject_removed_daemon_publish_proxy_identifiers() { } #[test] +fn sdk_transport_policy_sources_reject_configured_profile_and_proxy_relay_bridge() { + let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + for relative_path in [ + "src", + "tests", + "examples", + "packages/events-bindings/src", + "packages/events-codec-js/src", + ] { + let root = manifest_dir.join(relative_path); + if !root.exists() { + continue; + } + for path in rust_source_files(root.as_path()) { + if path.file_name().and_then(|file_name| file_name.to_str()) + == Some("source_boundary.rs") + { + continue; + } + let source = read_source(path.as_path()); + for forbidden in [ + "UseConfiguredProfile", + "use_configured_profile", + "configured_profile()", + "impl RadrootsRelayPublishAdapter for RadrootsdProxyPublishAdapter", + "proxy_relay_receipt_from_response", + ] { + assert!( + !source.contains(forbidden), + "{} must not reintroduce removed transport policy or proxy relay bridge surface `{forbidden}`", + path.display() + ); + } + } + } +} + +#[test] fn sdk_transport_sources_keep_reticulum_preview_push_boundary() { let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); diff --git a/crates/sdk/tests/sync_runtime.rs b/crates/sdk/tests/sync_runtime.rs @@ -564,7 +564,7 @@ async fn enqueue_listing_with_policy( ListingEnqueuePublishRequest::new( actor(), listing(d_tag, title), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets(relays, url_policy) .expect("relay targets"), @@ -2271,7 +2271,7 @@ async fn push_outbox_with_adapter_scopes_duplicate_endpoint_sibling_plans() { ListingEnqueuePublishRequest::new( actor(), listing(LISTING_A_D_TAG, "Duplicate Plan Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY_A], NostrRelayUrlPolicy::Public) .expect("first targets") @@ -2557,7 +2557,7 @@ fn enqueue_publish_rejects_nonlocal_ws_relay_targets() { let error = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_C_D_TAG, "Nonlocal Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([NONLOCAL_WS_RELAY], NostrRelayUrlPolicy::Localhost) .expect_err("nonlocal ws relay target"); @@ -2567,7 +2567,7 @@ fn enqueue_publish_rejects_nonlocal_ws_relay_targets() { let error = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_C_D_TAG, "Private LAN Coffee"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([PRIVATE_LAN_WS_RELAY], NostrRelayUrlPolicy::Localhost) .expect_err("private LAN ws relay target"); diff --git a/crates/sdk/tests/unit/adapters_radrootsd_tests.rs b/crates/sdk/tests/unit/adapters_radrootsd_tests.rs @@ -1,8 +1,5 @@ use super::*; use radroots_transport::RADROOTS_RETICULUM_PREVIEW_ENDPOINT_URI; -use radroots_transport_nostr::{ - RadrootsRelayPublishRequest, RadrootsRelayTargetSet, RadrootsRelayUrlPolicy, -}; use radroots_transport_publish_protocol::{ NostrPublishTargetSourcePolicy, TransportPublishDeliveryPolicy, TransportPublishEventRequest, TransportPublishEventResponse, TransportPublishJobStatus, TransportPublishJobView, @@ -441,102 +438,6 @@ fn decode_jsonrpc_response_validates_envelope_and_errors() { )); } -#[test] -fn daemon_outcomes_map_to_relay_transport_receipts() { - let payment = proxy_relay_receipt_from_response(TransportPublishEventResponse { - deduplicated: false, - job: job(TransportPublishOutcomeKind::PaymentRequired), - }) - .expect("payment receipt"); - assert_eq!( - payment.relays[0].outcome.kind, - RadrootsRelayOutcomeKind::PaymentRequired - ); - assert_eq!(payment.terminal_count, 1); - - let skipped = proxy_relay_receipt_from_response(TransportPublishEventResponse { - deduplicated: true, - job: job(TransportPublishOutcomeKind::SkippedAlreadyAccepted), - }) - .expect("skipped receipt"); - assert_eq!( - skipped.relays[0].outcome.kind, - RadrootsRelayOutcomeKind::SkippedAlreadyAccepted - ); - assert!(skipped.quorum_met); - - let cases = [ - ( - TransportPublishOutcomeKind::Accepted, - RadrootsRelayOutcomeKind::Accepted, - ), - ( - TransportPublishOutcomeKind::DuplicateAccepted, - RadrootsRelayOutcomeKind::DuplicateAccepted, - ), - ( - TransportPublishOutcomeKind::Blocked, - RadrootsRelayOutcomeKind::Blocked, - ), - ( - TransportPublishOutcomeKind::RateLimited, - RadrootsRelayOutcomeKind::RateLimited, - ), - ( - TransportPublishOutcomeKind::Invalid, - RadrootsRelayOutcomeKind::Invalid, - ), - ( - TransportPublishOutcomeKind::PowRequired, - RadrootsRelayOutcomeKind::PowRequired, - ), - ( - TransportPublishOutcomeKind::Restricted, - RadrootsRelayOutcomeKind::Restricted, - ), - ( - TransportPublishOutcomeKind::AuthRequired, - RadrootsRelayOutcomeKind::AuthRequired, - ), - ( - TransportPublishOutcomeKind::Muted, - RadrootsRelayOutcomeKind::Muted, - ), - ( - TransportPublishOutcomeKind::Unsupported, - RadrootsRelayOutcomeKind::Unsupported, - ), - ( - TransportPublishOutcomeKind::Error, - RadrootsRelayOutcomeKind::Error, - ), - ( - TransportPublishOutcomeKind::Timeout, - RadrootsRelayOutcomeKind::Timeout, - ), - ( - TransportPublishOutcomeKind::ConnectionFailed, - RadrootsRelayOutcomeKind::ConnectionFailed, - ), - ( - TransportPublishOutcomeKind::TargetRejected, - RadrootsRelayOutcomeKind::RelayUrlRejected, - ), - ( - TransportPublishOutcomeKind::Unknown, - RadrootsRelayOutcomeKind::Unknown, - ), - ]; - for (proxy_kind, relay_kind) in cases { - let receipt = proxy_relay_receipt_from_response(TransportPublishEventResponse { - deduplicated: false, - job: job(proxy_kind), - }) - .expect("receipt"); - assert_eq!(receipt.relays[0].outcome.kind, relay_kind); - } -} - #[tokio::test] async fn publish_event_posts_transport_publish_jsonrpc() { let (endpoint, handle) = spawn_http_server("200 OK", publish_response_json().as_str()); @@ -837,120 +738,6 @@ async fn publish_event_empty_http_error_reports_empty_body() { } #[tokio::test] -async fn relay_publish_adapter_derives_delivery_policy_and_timeout() { - for (target_count, satisfaction_policy, expected_policy) in [ - ( - 2, - radroots_transport::RadrootsTransportSatisfactionPolicy::all_accepted(), - TransportPublishDeliveryPolicy::All, - ), - ( - 2, - radroots_transport::RadrootsTransportSatisfactionPolicy::any_accepted(), - TransportPublishDeliveryPolicy::Any, - ), - ( - 3, - radroots_transport::RadrootsTransportSatisfactionPolicy::quorum_accepted(2), - TransportPublishDeliveryPolicy::Quorum { quorum: 2 }, - ), - ] { - let relays = (0..target_count) - .map(|index| format!("wss://relay-{index}.example.com")) - .collect::<Vec<_>>(); - let response_body = explicit_nostr_response_json(relays.clone(), expected_policy.clone()); - let (endpoint, handle) = spawn_http_server("200 OK", response_body.as_str()); - let adapter = RadrootsdProxyPublishAdapter::new( - RadrootsdProxyConfig::new(endpoint).with_request_timeout_ms(4_000), - ); - let targets = - RadrootsRelayTargetSet::new(&relays, RadrootsRelayUrlPolicy::Public).expect("targets"); - - let receipts = adapter - .publish( - RadrootsRelayPublishRequest::new(signed_event(), targets, 10) - .with_satisfaction_policy(satisfaction_policy), - ) - .await - .expect("adapter publish"); - - assert_eq!(receipts[0].outcome.kind, RadrootsRelayOutcomeKind::Accepted); - let recorded = handle.join().expect("server thread"); - let body: serde_json::Value = - serde_json::from_str(recorded.body.as_str()).expect("request body"); - assert_eq!(body["params"]["timeout_ms"], 4_000); - assert_eq!( - serde_json::from_value::<TransportPublishDeliveryPolicy>( - body["params"]["delivery_policy"].clone() - ) - .expect("delivery policy"), - expected_policy - ); - } -} - -#[tokio::test] -async fn relay_publish_adapter_maps_proxy_errors_to_transport_errors() { - let adapter = RadrootsdProxyPublishAdapter::new( - RadrootsdProxyConfig::new("http://127.0.0.1:9/rpc").with_timeout(Duration::from_millis(50)), - ); - let targets = RadrootsRelayTargetSet::new( - &["wss://relay.example.com".to_owned()], - RadrootsRelayUrlPolicy::Public, - ) - .expect("targets"); - - let error = adapter - .publish(RadrootsRelayPublishRequest::new( - signed_event(), - targets, - 1_700_000_000_000, - )) - .await - .expect_err("transport error"); - - assert!(matches!( - error, - radroots_transport_nostr::RadrootsRelayTransportError::Transport(message) - if message.contains("radrootsd") - )); -} - -#[test] -fn relay_proxy_target_conversion_rejects_reticulum_targets_before_behavior_loss() { - let target = radroots_transport::RadrootsTransportTarget::new( - radroots_transport::RadrootsTransportKind::Reticulum, - RADROOTS_RETICULUM_PREVIEW_ENDPOINT_URI, - ) - .expect("Reticulum target"); - - let error = transport_publish_target(&target).expect_err("Reticulum rejected"); - - assert!(matches!( - error, - radroots_transport_nostr::RadrootsRelayTransportError::Transport(message) - if message.contains("Nostr-only") && message.contains("reticulum") - )); -} - -#[test] -fn relay_proxy_target_conversion_rejects_proxy_targets_before_daemon_explicit_target() { - let target = radroots_transport::RadrootsTransportTarget::new( - radroots_transport::RadrootsTransportKind::Proxy, - "http://127.0.0.1:8080/rpc", - ) - .expect("proxy target"); - - let error = transport_publish_target(&target).expect_err("proxy rejected"); - - assert!(matches!( - error, - radroots_transport_nostr::RadrootsRelayTransportError::Transport(message) - if message.contains("Nostr-only") && message.contains("proxy") - )); -} - -#[tokio::test] async fn publish_signed_event_rejects_invalid_protocol_requests_before_http() { let adapter = RadrootsdProxyPublishAdapter::new(RadrootsdProxyConfig::new("http://127.0.0.1:9/rpc")); @@ -1025,36 +812,6 @@ async fn publish_signed_event_rejects_invalid_protocol_requests_before_http() { } } -#[test] -fn proxy_relay_receipt_from_response_rejects_invalid_daemon_job_contracts() { - let mut empty_job_id = job(TransportPublishOutcomeKind::Accepted); - empty_job_id.job_id = " ".to_owned(); - let mut invalid_event_id = job(TransportPublishOutcomeKind::Accepted); - invalid_event_id.event_id = "not-an-event-id".to_owned(); - let mut invalid_pubkey = job(TransportPublishOutcomeKind::Accepted); - invalid_pubkey.pubkey = "not-a-pubkey".to_owned(); - let mut invalid_kind = job(TransportPublishOutcomeKind::Accepted); - invalid_kind.event_kind = 70_000; - let mut invalid_quorum = job(TransportPublishOutcomeKind::Accepted); - invalid_quorum.delivery_policy = TransportPublishDeliveryPolicy::Quorum { quorum: 0 }; - - for job in [ - empty_job_id, - invalid_event_id, - invalid_pubkey, - invalid_kind, - invalid_quorum, - ] { - assert!(matches!( - proxy_relay_receipt_from_response(TransportPublishEventResponse { - deduplicated: false, - job, - }), - Err(RadrootsdError::InvalidRequest(_)) - )); - } -} - #[tokio::test] async fn adapter_rejects_invalid_request_before_transport() { let adapter = diff --git a/crates/sdk/tests/unit/dvm_runtime_tests.rs b/crates/sdk/tests/unit/dvm_runtime_tests.rs @@ -230,7 +230,7 @@ fn enqueue_request_builders_and_ingest_request_builders_are_deterministic() { let idempotency_len = idempotency.as_str().len(); let request = DvmTradeTransitionProofEnqueueRequest::from_prepare( prepare.clone(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY], NostrRelayUrlPolicy::Public) .expect("relays") @@ -254,7 +254,7 @@ fn enqueue_request_builders_and_ingest_request_builders_are_deterministic() { event_id('2'), event_id('3'), inventory_bins(), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("dvm-proof-request-2") .expect("idempotency") @@ -267,7 +267,7 @@ fn enqueue_request_builders_and_ingest_request_builders_are_deterministic() { assert!(matches!( DvmTradeTransitionProofEnqueueRequest::from_prepare( prepare, - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets(["ws://relay.example.com"], NostrRelayUrlPolicy::Public), Err(RadrootsSdkError::InvalidRelayUrl { .. }) @@ -275,7 +275,7 @@ fn enqueue_request_builders_and_ingest_request_builders_are_deterministic() { assert!(matches!( DvmTradeTransitionProofEnqueueRequest::from_prepare( proof_request(service_actor()), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key(""), Err(RadrootsSdkError::InvalidRequest { .. }) diff --git a/crates/sdk/tests/unit/farms_runtime_tests.rs b/crates/sdk/tests/unit/farms_runtime_tests.rs @@ -167,7 +167,7 @@ fn farm_runtime_request_builders_and_serializers_cover_success_paths() { let enqueue = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_B_D_TAG, "Queued Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY_A, RELAY_B], NostrRelayUrlPolicy::Public) .expect("relay targets") @@ -182,7 +182,7 @@ fn farm_runtime_request_builders_and_serializers_cover_success_paths() { let try_key = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_C_D_TAG, "Try Key Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("farm-unit-try-key") .expect("try key"); @@ -357,7 +357,7 @@ fn farm_request_builders_reject_invalid_options_and_timestamp_bounds() { let invalid_relays = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_A_D_TAG, "Invalid Relay Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets(["http://relay.radroots.test"], NostrRelayUrlPolicy::Public); assert!(invalid_relays.is_err()); @@ -365,7 +365,7 @@ fn farm_request_builders_reject_invalid_options_and_timestamp_bounds() { let invalid_key = FarmEnqueuePublishRequest::new( farmer_actor(), farm(FARM_B_D_TAG, "Invalid Key Farm"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key(""); assert!(invalid_key.is_err()); diff --git a/crates/sdk/tests/unit/listings_runtime_tests.rs b/crates/sdk/tests/unit/listings_runtime_tests.rs @@ -104,7 +104,7 @@ fn listing_runtime_request_builders_and_serializers_cover_success_paths() { let enqueue = ListingEnqueuePublishRequest::from_document( actor(), RadrootsListingDraftDocumentV1::new(listing(LISTING_B_D_TAG, "Queued Greens")), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_nostr_targets([RELAY_A, RELAY_B], NostrRelayUrlPolicy::Public) .expect("relay targets") @@ -119,7 +119,7 @@ fn listing_runtime_request_builders_and_serializers_cover_success_paths() { let try_key = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_C_D_TAG, "Try Key Greens"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key("listing-unit-try-key") .expect("try key"); @@ -134,7 +134,7 @@ fn listing_request_builders_reject_invalid_options_and_timestamp_bounds() { let invalid_key = ListingEnqueuePublishRequest::new( actor(), listing(LISTING_A_D_TAG, "Invalid Key Greens"), - TargetPolicy::UseConfiguredProfile, + TargetPolicy::use_transport_profile(), ) .try_with_idempotency_key(""); assert!(invalid_key.is_err()); diff --git a/crates/sdk/tests/unit/orders_runtime_tests.rs b/crates/sdk/tests/unit/orders_runtime_tests.rs @@ -2075,7 +2075,7 @@ fn order_enqueue_request_mutators_reject_invalid_relays_and_idempotency_keys() { RadrootsOrderRevisionOutcome::Accepted, ); let cancellation_payload = cancellation_payload(); - let policy = TargetPolicy::UseConfiguredProfile; + let policy = TargetPolicy::use_transport_profile(); assert_error_display( TradeSubmitEnqueueRequest::new( @@ -4029,7 +4029,7 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths() reason: "not workable".to_owned(), }, ); - let policy = TargetPolicy::UseConfiguredProfile; + let policy = TargetPolicy::use_transport_profile(); let submit_prepare = TradeSubmitPrepareRequest::new(buyer_actor(), root_event.clone(), order_request_payload()) diff --git a/crates/sdk/tests/unit/transport_tests.rs b/crates/sdk/tests/unit/transport_tests.rs @@ -78,14 +78,7 @@ fn relay_authority_host(authority: &str) -> Option<String> { } #[test] -fn use_configured_policy_serializes_as_kind_only() { - let policy = TargetPolicy::UseConfiguredProfile; - assert_eq!( - serde_json::to_value(&policy).expect("json"), - serde_json::json!({ "kind": "use_configured_profile" }) - ); - assert_struct_serialize_error_paths(&policy, 1); - +fn transport_profile_policy_serializes_as_kind_only() { let transport_profile_policy = TargetPolicy::use_transport_profile(); assert_eq!( serde_json::to_value(&transport_profile_policy).expect("json"), @@ -102,11 +95,14 @@ fn target_set_accessors_and_configured_relays_cover_empty_and_dedupe_paths() { .is_empty() ); - let targets = TargetSet::from_normalized_nostr_relays(vec![ - "wss://relay-a.example.com".to_owned(), - "wss://relay-a.example.com".to_owned(), - "wss://relay-b.example.com".to_owned(), - ]) + let targets = TargetSet::new( + [ + "wss://relay-a.example.com", + "wss://relay-a.example.com", + "wss://relay-b.example.com", + ], + NostrRelayUrlPolicy::Public, + ) .expect("targets"); assert_eq!(targets.len(), 2); @@ -261,7 +257,7 @@ fn explicit_target_sets_reject_mixed_proxy_delegate_targets() { #[test] fn normalized_relays_reject_empty_and_over_limit_sets() { assert!(matches!( - TargetSet::from_normalized_nostr_relays(Vec::new()), + TargetSet::new(Vec::<String>::new(), NostrRelayUrlPolicy::Public), Err(RadrootsSdkError::EmptyTransportTargets { .. }) )); @@ -269,7 +265,7 @@ fn normalized_relays_reject_empty_and_over_limit_sets() { .map(|index| format!("wss://relay-{index}.example.com")) .collect::<Vec<_>>(); assert!(matches!( - TargetSet::from_normalized_nostr_relays(too_many), + TargetSet::new(too_many, NostrRelayUrlPolicy::Public), Err(RadrootsSdkError::TransportTargetLimitExceeded { actual, .. }) if actual == SDK_TRANSPORT_TARGET_MAX_COUNT + 1 )); diff --git a/crates/sdk/tests/unit/workflow_runtime_tests.rs b/crates/sdk/tests/unit/workflow_runtime_tests.rs @@ -170,7 +170,7 @@ async fn enqueue_signed_workflow_stores_signed_event_and_reports_idempotency_con operation_kind: "workflow.test.v1", actor: &actor, frozen_draft: &first_draft, - target_policy: TargetPolicy::UseConfiguredProfile, + target_policy: TargetPolicy::use_transport_profile(), satisfaction_policy: SatisfactionPolicy::AllTargets, idempotency_key: Some(idempotency_key.clone()), }, @@ -211,7 +211,7 @@ async fn enqueue_signed_workflow_stores_signed_event_and_reports_idempotency_con operation_kind: "workflow.test.v1", actor: &actor, frozen_draft: &second_draft, - target_policy: TargetPolicy::UseConfiguredProfile, + target_policy: TargetPolicy::use_transport_profile(), satisfaction_policy: SatisfactionPolicy::AllTargets, idempotency_key: Some(idempotency_key), }, @@ -274,7 +274,7 @@ async fn enqueue_configured_signed_workflow_uses_sdk_signer_provider() { operation_kind: "workflow.test.v1", actor: &actor, frozen_draft: &draft, - target_policy: TargetPolicy::UseConfiguredProfile, + target_policy: TargetPolicy::use_transport_profile(), satisfaction_policy: SatisfactionPolicy::AllTargets, idempotency_key: None, }, @@ -309,7 +309,7 @@ async fn enqueue_signed_workflow_reports_outbox_preflight_failure_without_mutati operation_kind: "workflow.test.v1", actor: &actor, frozen_draft: &draft, - target_policy: TargetPolicy::UseConfiguredProfile, + target_policy: TargetPolicy::use_transport_profile(), satisfaction_policy: SatisfactionPolicy::AllTargets, idempotency_key: None, }; @@ -345,7 +345,7 @@ async fn enqueue_signed_workflow_reports_store_failures() { operation_kind: "workflow.test.v1", actor: &actor, frozen_draft: &draft, - target_policy: TargetPolicy::UseConfiguredProfile, + target_policy: TargetPolicy::use_transport_profile(), satisfaction_policy: SatisfactionPolicy::AllTargets, idempotency_key: None, }; @@ -375,7 +375,7 @@ async fn enqueue_signed_workflow_reports_clock_failures() { operation_kind: "workflow.test.v1", actor: &actor, frozen_draft: &draft, - target_policy: TargetPolicy::UseConfiguredProfile, + target_policy: TargetPolicy::use_transport_profile(), satisfaction_policy: SatisfactionPolicy::AllTargets, idempotency_key: None, };