commit ba8d92e530c5576d6c2ad3ca0ec43a92a16fbe7e
parent fab7ed497fd658df947cd8794fac9b62e80ebb4c
Author: triesap <tyson@radroots.org>
Date: Mon, 13 Apr 2026 15:17:08 +0000
sdk: demote raw public trade requests
Diffstat:
3 files changed, 215 insertions(+), 33 deletions(-)
diff --git a/crates/sdk/src/client.rs b/crates/sdk/src/client.rs
@@ -1270,6 +1270,196 @@ impl RadrootsSdkClient {
}
#[cfg(feature = "radrootsd-client")]
+#[derive(Clone, PartialEq, Eq)]
+pub struct SdkRadrootsdPublicTradeMessage {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest,
+}
+
+#[cfg(feature = "radrootsd-client")]
+impl SdkRadrootsdPublicTradeMessage {
+ pub fn order_response(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeOrderResponse,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::order_response(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn order_revision(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ listing_event: RadrootsNostrEventPtr,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeOrderRevision,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::order_revision(
+ route,
+ listing_event,
+ chain,
+ payload,
+ )?,
+ })
+ }
+
+ pub fn order_revision_accept(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeOrderRevisionResponse,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::order_revision_accept(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn order_revision_decline(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeOrderRevisionResponse,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::order_revision_decline(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn question(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeQuestion,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::question(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn answer(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeAnswer,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::answer(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn discount_request(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ listing_event: RadrootsNostrEventPtr,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeDiscountRequest,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::discount_request(
+ route,
+ listing_event,
+ chain,
+ payload,
+ )?,
+ })
+ }
+
+ pub fn discount_offer(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ listing_event: RadrootsNostrEventPtr,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeDiscountOffer,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::discount_offer(
+ route,
+ listing_event,
+ chain,
+ payload,
+ )?,
+ })
+ }
+
+ pub fn discount_accept(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeDiscountDecision,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::discount_accept(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn discount_decline(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeDiscountDecision,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::discount_decline(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn cancel(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeListingCancel,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::cancel(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn fulfillment_update(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeFulfillmentUpdate,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::fulfillment_update(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub fn receipt(
+ route: &radrootsd::SdkRadrootsdPublicTradeRoute,
+ chain: &radrootsd::SdkRadrootsdTradeChain,
+ payload: trade::RadrootsTradeReceipt,
+ ) -> Result<Self, radrootsd::SdkRadrootsdPublicTradePublishValidationError> {
+ Ok(Self {
+ request: radrootsd::SdkRadrootsdPublicTradePublishRequest::receipt(
+ route, chain, payload,
+ )?,
+ })
+ }
+
+ pub(crate) fn as_request(&self) -> &radrootsd::SdkRadrootsdPublicTradePublishRequest {
+ &self.request
+ }
+}
+
+#[cfg(feature = "radrootsd-client")]
+impl fmt::Debug for SdkRadrootsdPublicTradeMessage {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("SdkRadrootsdPublicTradeMessage")
+ .field("request", &self.request)
+ .finish()
+ }
+}
+
+#[cfg(feature = "radrootsd-client")]
#[derive(Debug, Clone, Copy)]
pub struct RadrootsdClient<'a> {
client: &'a RadrootsSdkClient,
@@ -1727,11 +1917,11 @@ impl<'a> TradeClient<'a> {
#[cfg(feature = "radrootsd-client")]
pub async fn publish_public_message_via_radrootsd(
&self,
- request: &radrootsd::SdkRadrootsdPublicTradePublishRequest,
+ message: &SdkRadrootsdPublicTradeMessage,
session: &SdkRadrootsdSignerSessionHandle,
) -> Result<SdkPublishReceipt, SdkPublishError> {
self.publish_public_message_via_radrootsd_with_options(
- request,
+ message,
&SdkRadrootsdPublicTradePublishOptions::from_signer_session(session),
)
.await
@@ -1740,15 +1930,12 @@ impl<'a> TradeClient<'a> {
#[cfg(feature = "radrootsd-client")]
pub async fn publish_public_message_via_radrootsd_with_options(
&self,
- request: &radrootsd::SdkRadrootsdPublicTradePublishRequest,
+ message: &SdkRadrootsdPublicTradeMessage,
options: &SdkRadrootsdPublicTradePublishOptions,
) -> Result<SdkPublishReceipt, SdkPublishError> {
- request
- .validate_for_publish()
- .map_err(|err| SdkPublishError::Encode(err.to_string()))?;
self.client
.publish_public_trade_via_radrootsd(
- request,
+ message.as_request(),
options.session(),
options.idempotency_key(),
)
diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs
@@ -28,10 +28,10 @@ pub mod trade;
#[cfg(feature = "radrootsd-client")]
pub use crate::adapters::radrootsd::{
SdkRadrootsdBridgeDeliveryPolicy, SdkRadrootsdBridgeJobStatus,
- SdkRadrootsdBridgeRelayPublishResult, SdkRadrootsdPublicTradePublishRequest,
- SdkRadrootsdPublicTradePublishValidationError, SdkRadrootsdPublicTradeRoute,
- SdkRadrootsdSignerAuthority, SdkRadrootsdSignerSessionConnectRequest,
- SdkRadrootsdSignerSessionMode, SdkRadrootsdSignerSessionRole, SdkRadrootsdTradeChain,
+ SdkRadrootsdBridgeRelayPublishResult, SdkRadrootsdPublicTradePublishValidationError,
+ SdkRadrootsdPublicTradeRoute, SdkRadrootsdSignerAuthority,
+ SdkRadrootsdSignerSessionConnectRequest, SdkRadrootsdSignerSessionMode,
+ SdkRadrootsdSignerSessionRole, SdkRadrootsdTradeChain,
};
pub use crate::client::{
FarmClient, ListingClient, ProfileClient, RadrootsSdkClient, SdkPublishError,
@@ -43,10 +43,11 @@ pub use crate::client::{
RadrootsdBridgeClient, RadrootsdClient, RadrootsdSignerSessionClient, SdkRadrootsdBridgeError,
SdkRadrootsdBridgeJobRef, SdkRadrootsdBridgeJobView, SdkRadrootsdBridgeStatus,
SdkRadrootsdListingPublishOptions, SdkRadrootsdOrderRequestPublishOptions,
- SdkRadrootsdPublicTradePublishOptions, SdkRadrootsdSessionError,
- SdkRadrootsdSignerSessionAuthorizeResult, SdkRadrootsdSignerSessionCloseResult,
- SdkRadrootsdSignerSessionHandle, SdkRadrootsdSignerSessionRef,
- SdkRadrootsdSignerSessionRequireAuthResult, SdkRadrootsdSignerSessionView,
+ SdkRadrootsdPublicTradeMessage, SdkRadrootsdPublicTradePublishOptions,
+ SdkRadrootsdSessionError, SdkRadrootsdSignerSessionAuthorizeResult,
+ SdkRadrootsdSignerSessionCloseResult, SdkRadrootsdSignerSessionHandle,
+ SdkRadrootsdSignerSessionRef, SdkRadrootsdSignerSessionRequireAuthResult,
+ SdkRadrootsdSignerSessionView,
};
pub use crate::config::{
NetworkConfig, RADROOTS_SDK_LOCAL_RADROOTSD_ENDPOINT, RADROOTS_SDK_LOCAL_RELAY_URL,
diff --git a/crates/sdk/tests/radrootsd.rs b/crates/sdk/tests/radrootsd.rs
@@ -25,10 +25,11 @@ use radroots_sdk::{
RadrootsdConfig, SdkConfigError, SdkEnvironment, SdkPublishError,
SdkRadrootsdBridgeDeliveryPolicy, SdkRadrootsdBridgeError, SdkRadrootsdBridgeJobStatus,
SdkRadrootsdListingPublishOptions, SdkRadrootsdOrderRequestPublishOptions,
- SdkRadrootsdPublicTradePublishOptions, SdkRadrootsdPublicTradePublishValidationError,
- SdkRadrootsdPublicTradeRoute, SdkRadrootsdPublishReceipt, SdkRadrootsdSessionError,
- SdkRadrootsdSignerSessionHandle, SdkRadrootsdSignerSessionRole, SdkRadrootsdSignerSessionView,
- SdkRadrootsdTradeChain, SdkTransportMode, SdkTransportReceipt, SignerConfig,
+ SdkRadrootsdPublicTradeMessage, SdkRadrootsdPublicTradePublishOptions,
+ SdkRadrootsdPublicTradePublishValidationError, SdkRadrootsdPublicTradeRoute,
+ SdkRadrootsdPublishReceipt, SdkRadrootsdSessionError, SdkRadrootsdSignerSessionHandle,
+ SdkRadrootsdSignerSessionRole, SdkRadrootsdSignerSessionView, SdkRadrootsdTradeChain,
+ SdkTransportMode, SdkTransportReceipt, SignerConfig,
};
use serde_json::{Value, json};
use std::collections::VecDeque;
@@ -391,8 +392,8 @@ fn sample_trade_order() -> RadrootsTradeOrder {
}
}
-fn sample_public_trade_request() -> SdkRadrootsdPublicTradePublishRequest {
- SdkRadrootsdPublicTradePublishRequest::order_response(
+fn sample_public_trade_message() -> SdkRadrootsdPublicTradeMessage {
+ SdkRadrootsdPublicTradeMessage::order_response(
&sample_public_trade_route(),
&sample_trade_chain(),
RadrootsTradeOrderResponse {
@@ -1433,7 +1434,7 @@ async fn radrootsd_trade_public_message_publish_accepts_typed_request() -> TestR
let handle = connected_bunker_session_handle("session-response-1").await?;
let client = radrootsd_test_client(server.endpoint())?;
- let request = sample_public_trade_request();
+ let request = sample_public_trade_message();
let options = SdkRadrootsdPublicTradePublishOptions::from_signer_session(&handle)
.with_idempotency_key("idem-response-1");
@@ -1467,10 +1468,8 @@ async fn radrootsd_trade_public_message_publish_accepts_typed_request() -> TestR
Ok(())
}
-#[tokio::test]
-async fn radrootsd_trade_public_message_publish_rejects_order_request_payload() -> TestResult<()> {
- let client = radrootsd_test_client("https://rpc.radroots.org/jsonrpc")?;
- let handle = connected_bunker_session_handle("session-order-request").await?;
+#[test]
+fn public_trade_request_validation_rejects_order_request_payload() {
let request = SdkRadrootsdPublicTradePublishRequest::new(
sample_trade_order().listing_addr.clone(),
"order-1",
@@ -1478,21 +1477,16 @@ async fn radrootsd_trade_public_message_publish_rejects_order_request_payload()
RadrootsTradeMessagePayload::OrderRequest(sample_trade_order()),
);
- let error = client
- .trade()
- .publish_public_message_via_radrootsd(&request, &handle)
- .await
+ let error = request
+ .validate_for_publish()
.expect_err("order request payload should use the dedicated trade order request path");
- assert!(matches!(error, SdkPublishError::Encode(_)));
assert!(
error
.to_string()
.contains("trade.publish_order_request_via_radrootsd"),
"unexpected error: {error}"
);
-
- Ok(())
}
#[test]