commit e668f030fc29584004b8df8215b3f16ffdf6d613
parent ef9d0ba73e74d6eb98c18153ac8fc1b3338c9d53
Author: triesap <tyson@radroots.org>
Date: Tue, 30 Jun 2026 03:04:09 +0000
sdk: adopt trade product facade
Diffstat:
22 files changed, 2177 insertions(+), 938 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -2119,7 +2119,6 @@ dependencies = [
"radroots_replica_db_schema",
"radroots_replica_sync",
"radroots_runtime_paths",
- "radroots_sp1_guest_trade",
"radroots_sql_core",
"radroots_trade",
"reqwest",
@@ -2171,16 +2170,6 @@ name = "radroots_secret_vault"
version = "0.1.0-alpha.2"
[[package]]
-name = "radroots_sp1_guest_trade"
-version = "0.1.0-alpha.2"
-dependencies = [
- "serde",
- "serde_json",
- "sha2",
- "thiserror 1.0.69",
-]
-
-[[package]]
name = "radroots_sql_core"
version = "0.1.0-alpha.2"
dependencies = [
diff --git a/crates/sdk/Cargo.toml b/crates/sdk/Cargo.toml
@@ -62,7 +62,6 @@ runtime = [
"dep:radroots_outbox",
"dep:radroots_relay_transport",
"dep:radroots_runtime_paths",
- "dep:radroots_sp1_guest_trade",
"dep:sha2",
"dep:sqlx",
"dep:uuid",
@@ -116,7 +115,6 @@ radroots_outbox = { workspace = true, optional = true, default-features = false
radroots_publish_proxy_protocol = { workspace = true, optional = true, default-features = false }
radroots_relay_transport = { workspace = true, optional = true, default-features = false }
radroots_runtime_paths = { workspace = true, optional = true, default-features = false }
-radroots_sp1_guest_trade = { workspace = true, optional = true }
radroots_trade = { workspace = true, default-features = false }
radroots_identity = { workspace = true, optional = true, default-features = false }
radroots_nostr = { workspace = true, optional = true, default-features = false }
diff --git a/crates/sdk/examples/runtime_local.rs b/crates/sdk/examples/runtime_local.rs
@@ -11,9 +11,9 @@ use radroots_sdk::protocol::listing::{
RadrootsListing, RadrootsListingBin, RadrootsListingProduct,
};
use radroots_sdk::{
- ListingPreparePublishRequest, OrderStatusRequest, PushOutboxRequest, RadrootsClient,
- RadrootsSdkError, RadrootsSdkLocalKeySigner, RadrootsSdkSignerProvider, RadrootsSdkTimestamp,
- SdkIdempotencyKey, SdkRelayTargetPolicy, SdkRelayUrlPolicy,
+ ListingPreparePublishRequest, PushOutboxRequest, RadrootsClient, RadrootsSdkError,
+ RadrootsSdkLocalKeySigner, RadrootsSdkSignerProvider, RadrootsSdkTimestamp, SdkIdempotencyKey,
+ SdkRelayTargetPolicy, SdkRelayUrlPolicy, TradeStatusRequest,
};
const RELAY: &str = "wss://relay.example.com";
@@ -50,7 +50,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.await;
let order_status = sdk
.trades()
- .status(OrderStatusRequest::parse("example-order-1")?)
+ .status(TradeStatusRequest::parse("example-order-1")?)
.await?;
assert_eq!(
diff --git a/crates/sdk/examples/sdk_v1_local_enqueue_and_mock_sync.rs b/crates/sdk/examples/sdk_v1_local_enqueue_and_mock_sync.rs
@@ -12,9 +12,9 @@ use radroots_sdk::protocol::listing::{
RadrootsListing, RadrootsListingBin, RadrootsListingProduct,
};
use radroots_sdk::{
- ListingPreparePublishRequest, OrderStatusRequest, PushOutboxRequest, RadrootsClient,
- RadrootsSdkLocalKeySigner, RadrootsSdkSignerProvider, RadrootsSdkTimestamp, SdkIdempotencyKey,
- SdkRelayTargetPolicy, SdkRelayTargetSet, SdkRelayUrlPolicy,
+ ListingPreparePublishRequest, PushOutboxRequest, RadrootsClient, RadrootsSdkLocalKeySigner,
+ RadrootsSdkSignerProvider, RadrootsSdkTimestamp, SdkIdempotencyKey, SdkRelayTargetPolicy,
+ SdkRelayTargetSet, SdkRelayUrlPolicy, TradeStatusRequest,
};
const LOCAL_RELAY: &str = "ws://localhost:7777";
@@ -55,7 +55,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.await?;
let order_status = sdk
.trades()
- .status(OrderStatusRequest::parse("example-order-1")?)
+ .status(TradeStatusRequest::parse("example-order-1")?)
.await?;
println!("queued listing event: {}", enqueue.signed_event_id.as_str());
diff --git a/crates/sdk/src/dvm_runtime.rs b/crates/sdk/src/dvm_runtime.rs
@@ -23,11 +23,7 @@ use radroots_events::{
#[cfg(feature = "runtime")]
use radroots_events_codec::wire::{WireEventParts, canonicalize_tags, to_frozen_draft};
#[cfg(feature = "runtime")]
-use radroots_sp1_guest_trade::{
- RADROOTS_SP1_TRADE_ORDER_ACCEPTANCE_PROOF_TARGET, RADROOTS_SP1_TRADE_PROTOCOL_VERSION,
- RADROOTS_SP1_TRADE_REDUCER_PROGRAM_HASH, RADROOTS_SP1_TRADE_WITNESS_VERSION,
- RadrootsSp1TradeInventoryBinWitness,
-};
+use radroots_trade::dvm::RadrootsTradeInventoryBinWitnessDto;
#[cfg(feature = "runtime")]
use radroots_trade::validation_receipt::{
RadrootsValidationReceiptExpectedBinding, RadrootsValidationReceiptProofSystem,
@@ -36,6 +32,16 @@ use radroots_trade::validation_receipt::{
};
#[cfg(feature = "runtime")]
+const RADROOTS_TRADE_TRANSITION_WITNESS_VERSION: u32 = 1;
+#[cfg(feature = "runtime")]
+const RADROOTS_TRADE_TRANSITION_PROTOCOL_VERSION: &str = "radroots.trade.v1";
+#[cfg(feature = "runtime")]
+const RADROOTS_TRADE_TRANSITION_REDUCER_PROGRAM_HASH: &str =
+ "0x3d8f7f463904d71f2d0d14b1551450756697e51c7b658e10c6d5c20a7bc61f08";
+#[cfg(feature = "runtime")]
+const RADROOTS_TRADE_TRANSITION_PROOF_TARGET: &str = "trade.order_acceptance.v1";
+
+#[cfg(feature = "runtime")]
pub const DVM_TRADE_TRANSITION_PROOF_REQUEST_CONTRACT_ID: &str =
"radroots.trade.transition_proof.request.v1";
#[cfg(feature = "runtime")]
@@ -43,9 +49,6 @@ pub const DVM_TRADE_TRANSITION_PROOF_REQUEST_OPERATION_KIND: &str =
"dvm.trade_transition_proof.request.v1";
#[cfg(feature = "runtime")]
-pub type SdkDvmInventoryBinWitness = RadrootsSp1TradeInventoryBinWitness;
-
-#[cfg(feature = "runtime")]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
@@ -96,7 +99,7 @@ pub struct DvmTradeTransitionProofPrepareRequest {
pub listing_event_id: RadrootsEventId,
pub request_event_id: RadrootsEventId,
pub decision_event_id: RadrootsEventId,
- pub inventory_bins: Vec<SdkDvmInventoryBinWitness>,
+ pub inventory_bins: Vec<RadrootsTradeInventoryBinWitnessDto>,
pub inventory_sequence: u128,
pub previous_state_root: Option<String>,
pub proof_mode: DvmProofMode,
@@ -114,7 +117,7 @@ impl DvmTradeTransitionProofPrepareRequest {
listing_event_id: RadrootsEventId,
request_event_id: RadrootsEventId,
decision_event_id: RadrootsEventId,
- inventory_bins: Vec<SdkDvmInventoryBinWitness>,
+ inventory_bins: Vec<RadrootsTradeInventoryBinWitnessDto>,
) -> Self {
Self {
actor,
@@ -183,7 +186,7 @@ impl DvmTradeTransitionProofEnqueueRequest {
listing_event_id: RadrootsEventId,
request_event_id: RadrootsEventId,
decision_event_id: RadrootsEventId,
- inventory_bins: Vec<SdkDvmInventoryBinWitness>,
+ inventory_bins: Vec<RadrootsTradeInventoryBinWitnessDto>,
target_relays: SdkRelayTargetPolicy,
) -> Self {
Self::from_prepare(
@@ -276,7 +279,7 @@ pub struct DvmTradeTransitionProofRequestPayload {
pub listing_event_id: String,
pub request_event_id: String,
pub decision_event_id: String,
- pub inventory_bins: Vec<SdkDvmInventoryBinWitness>,
+ pub inventory_bins: Vec<RadrootsTradeInventoryBinWitnessDto>,
pub inventory_sequence: u128,
pub previous_state_root: Option<String>,
pub proof_mode: DvmProofMode,
@@ -530,8 +533,8 @@ fn dvm_trade_transition_proof_plan(
validate_inventory_bins(&request.inventory_bins)?;
validate_sp1_identity(&request)?;
let payload = DvmTradeTransitionProofRequestPayload {
- witness_version: RADROOTS_SP1_TRADE_WITNESS_VERSION,
- proof_target: RADROOTS_SP1_TRADE_ORDER_ACCEPTANCE_PROOF_TARGET.to_owned(),
+ witness_version: RADROOTS_TRADE_TRANSITION_WITNESS_VERSION,
+ proof_target: RADROOTS_TRADE_TRANSITION_PROOF_TARGET.to_owned(),
listing_event_id: request.listing_event_id.as_str().to_owned(),
request_event_id: request.request_event_id.as_str().to_owned(),
decision_event_id: request.decision_event_id.as_str().to_owned(),
@@ -539,8 +542,8 @@ fn dvm_trade_transition_proof_plan(
inventory_sequence: request.inventory_sequence,
previous_state_root: request.previous_state_root.clone(),
proof_mode: request.proof_mode,
- reducer_program_hash: RADROOTS_SP1_TRADE_REDUCER_PROGRAM_HASH.to_owned(),
- radroots_protocol_version: RADROOTS_SP1_TRADE_PROTOCOL_VERSION.to_owned(),
+ reducer_program_hash: RADROOTS_TRADE_TRANSITION_REDUCER_PROGRAM_HASH.to_owned(),
+ radroots_protocol_version: RADROOTS_TRADE_TRANSITION_PROTOCOL_VERSION.to_owned(),
sp1_program_hash: request.sp1_program_hash.clone(),
sp1_verifying_key_hash: request.sp1_verifying_key_hash.clone(),
};
@@ -552,19 +555,19 @@ fn dvm_trade_transition_proof_plan(
"i".to_owned(),
request.listing_event_id.as_str().to_owned(),
"event".to_owned(),
- "listing".to_owned(),
+ "radroots:listing_event".to_owned(),
],
vec![
"i".to_owned(),
request.request_event_id.as_str().to_owned(),
"event".to_owned(),
- "order_request".to_owned(),
+ "radroots:order_request_event".to_owned(),
],
vec![
"i".to_owned(),
request.decision_event_id.as_str().to_owned(),
"event".to_owned(),
- "order_decision".to_owned(),
+ "radroots:order_decision_event".to_owned(),
],
];
canonicalize_tags(&mut tags);
@@ -599,7 +602,7 @@ fn dvm_trade_transition_proof_plan(
#[cfg(feature = "runtime")]
fn validate_inventory_bins(
- inventory_bins: &[SdkDvmInventoryBinWitness],
+ inventory_bins: &[RadrootsTradeInventoryBinWitnessDto],
) -> Result<(), RadrootsSdkError> {
if inventory_bins.is_empty() {
return Err(RadrootsSdkError::InvalidRequest {
@@ -607,7 +610,7 @@ fn validate_inventory_bins(
});
}
for bin in inventory_bins {
- if bin.bin_id.trim().is_empty() {
+ if bin.bin_id.as_str().trim().is_empty() {
return Err(RadrootsSdkError::InvalidRequest {
message: "DVM proof request inventory bin id cannot be empty".to_owned(),
});
@@ -616,7 +619,7 @@ fn validate_inventory_bins(
return Err(RadrootsSdkError::InvalidRequest {
message: format!(
"DVM proof request inventory bin `{}` previous_reserved exceeds listing_capacity",
- bin.bin_id
+ bin.bin_id.as_str()
),
});
}
diff --git a/crates/sdk/src/error.rs b/crates/sdk/src/error.rs
@@ -138,12 +138,12 @@ pub enum RadrootsSdkError {
existing_digest_prefix: String,
new_digest_prefix: String,
},
- OrderStatusLimitInvalid {
+ TradeStatusLimitInvalid {
limit: u32,
min: u32,
max: u32,
},
- InvalidOrderId {
+ InvalidTradeId {
value: String,
message: String,
},
@@ -208,8 +208,8 @@ impl RadrootsSdkError {
Self::RelayTargetLimitExceeded { .. } => "relay_target_limit_exceeded",
Self::InvalidRelayUrl { .. } => "invalid_relay_url",
Self::IdempotencyConflict { .. } => "idempotency_conflict",
- Self::OrderStatusLimitInvalid { .. } => "order_status_limit_invalid",
- Self::InvalidOrderId { .. } => "invalid_order_id",
+ Self::TradeStatusLimitInvalid { .. } => "trade_status_limit_invalid",
+ Self::InvalidTradeId { .. } => "invalid_trade_id",
Self::ProductSyncUnsupported { .. } => "product_sync_unsupported",
Self::ProductSyncRelaySetupFailure { .. } => "product_sync_relay_setup_failure",
Self::Authority { .. } => "authority",
@@ -261,8 +261,8 @@ impl RadrootsSdkError {
| Self::RelayTargetLimitExceeded { .. }
| Self::InvalidRelayUrl { .. } => RadrootsSdkErrorClass::Configuration,
Self::IdempotencyConflict { .. }
- | Self::OrderStatusLimitInvalid { .. }
- | Self::InvalidOrderId { .. }
+ | Self::TradeStatusLimitInvalid { .. }
+ | Self::InvalidTradeId { .. }
| Self::SignerProtocol { .. }
| Self::SignerAuthChallengePending { .. }
| Self::InvalidRequest { .. }
@@ -348,8 +348,8 @@ impl RadrootsSdkError {
Self::PartialLocalMutation(error) => vec![error.recovery],
Self::ClockBeforeUnixEpoch
| Self::TimestampOutOfRange { .. }
- | Self::OrderStatusLimitInvalid { .. }
- | Self::InvalidOrderId { .. }
+ | Self::TradeStatusLimitInvalid { .. }
+ | Self::InvalidTradeId { .. }
| Self::SignerProtocol { .. }
| Self::InvalidRequest { .. }
| Self::ListingDraft { .. }
@@ -405,10 +405,10 @@ impl RadrootsSdkError {
"existing_digest_prefix": existing_digest_prefix,
"new_digest_prefix": new_digest_prefix
}),
- Self::OrderStatusLimitInvalid { limit, min, max } => {
+ Self::TradeStatusLimitInvalid { limit, min, max } => {
json!({ "limit": limit, "min": min, "max": max })
}
- Self::InvalidOrderId { value, message } => {
+ Self::InvalidTradeId { value, message } => {
json!({ "value": value, "message": message })
}
Self::ProductSyncUnsupported {
@@ -491,12 +491,12 @@ impl RadrootsSdkError {
}
}
- pub(crate) fn order_status_limit_invalid(limit: u32, min: u32, max: u32) -> Self {
- Self::OrderStatusLimitInvalid { limit, min, max }
+ pub(crate) fn trade_status_limit_invalid(limit: u32, min: u32, max: u32) -> Self {
+ Self::TradeStatusLimitInvalid { limit, min, max }
}
- pub(crate) fn invalid_order_id(value: impl Into<String>, message: impl Into<String>) -> Self {
- Self::InvalidOrderId {
+ pub(crate) fn invalid_trade_id(value: impl Into<String>, message: impl Into<String>) -> Self {
+ Self::InvalidTradeId {
value: value.into(),
message: message.into(),
}
@@ -583,11 +583,11 @@ impl fmt::Display for RadrootsSdkError {
f,
"sdk idempotency conflict for {operation_kind}: expected_pubkey_prefix={expected_pubkey_prefix}, existing_digest_prefix={existing_digest_prefix}, new_digest_prefix={new_digest_prefix}"
),
- Self::OrderStatusLimitInvalid { limit, min, max } => write!(
+ Self::TradeStatusLimitInvalid { limit, min, max } => write!(
f,
"sdk order status limit invalid: limit={limit}, min={min}, max={max}"
),
- Self::InvalidOrderId { value, message } => {
+ Self::InvalidTradeId { value, message } => {
write!(f, "sdk invalid order id `{value}`: {message}")
}
Self::ProductSyncUnsupported {
diff --git a/crates/sdk/src/idempotency.rs b/crates/sdk/src/idempotency.rs
@@ -1,5 +1,6 @@
use crate::RadrootsSdkError;
use core::fmt;
+use radroots_events::ids::{RadrootsEventId, RadrootsPublicKey};
use serde::ser::SerializeStruct;
use sha2::{Digest, Sha256};
@@ -88,6 +89,32 @@ struct SdkIdempotencyDerivationInput<'a> {
target_relays: &'a [String],
}
+#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
+pub struct SdkTradeIdempotencyRecord {
+ pub idempotency_key: SdkIdempotencyKey,
+ pub operation_kind: String,
+ pub actor_pubkey: RadrootsPublicKey,
+ pub digest: String,
+ pub canonical_payload_hash: String,
+ pub expected_event_id: RadrootsEventId,
+ pub outbox_operation_id: i64,
+}
+
+impl SdkTradeIdempotencyRecord {
+ pub fn matches_payload(&self, canonical_payload_hash: &str) -> bool {
+ self.canonical_payload_hash == canonical_payload_hash
+ }
+
+ pub fn conflict_error(&self, new_digest: impl Into<String>) -> RadrootsSdkError {
+ RadrootsSdkError::IdempotencyConflict {
+ operation_kind: self.operation_kind.clone(),
+ expected_pubkey_prefix: self.actor_pubkey.as_str().chars().take(12).collect(),
+ existing_digest_prefix: self.digest.chars().take(12).collect(),
+ new_digest_prefix: new_digest.into().chars().take(12).collect(),
+ }
+ }
+}
+
fn invalid_request(message: impl Into<String>) -> RadrootsSdkError {
RadrootsSdkError::InvalidRequest {
message: message.into(),
diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs
@@ -35,6 +35,8 @@ mod order;
#[cfg(feature = "runtime")]
mod orders_runtime;
#[cfg(feature = "runtime")]
+mod privacy;
+#[cfg(feature = "runtime")]
mod private_store;
#[cfg(feature = "runtime")]
mod product_clients;
@@ -49,6 +51,8 @@ mod signer_provider;
#[cfg(feature = "runtime")]
mod sync_runtime;
#[cfg(feature = "runtime")]
+mod trade_storage;
+#[cfg(feature = "runtime")]
mod workflow_runtime;
#[cfg(feature = "runtime")]
@@ -58,7 +62,7 @@ pub use crate::dvm_runtime::{
DvmTradeTransitionProofEnqueueRequest, DvmTradeTransitionProofPlan,
DvmTradeTransitionProofPrepareRequest, DvmTradeTransitionProofReceipt,
DvmTradeTransitionProofRequestPayload, DvmValidationReceiptIngestReceipt,
- DvmValidationReceiptIngestRequest, SdkDvmInventoryBinWitness,
+ DvmValidationReceiptIngestRequest,
};
#[cfg(feature = "runtime")]
pub use crate::error::{
@@ -85,7 +89,9 @@ pub use crate::geonames::{
RadrootsGeoNamesConfig,
};
#[cfg(feature = "runtime")]
-pub use crate::idempotency::{SDK_IDEMPOTENCY_KEY_MAX_LEN, SdkIdempotencyKey};
+pub use crate::idempotency::{
+ SDK_IDEMPOTENCY_KEY_MAX_LEN, SdkIdempotencyKey, SdkTradeIdempotencyRecord,
+};
#[cfg(feature = "runtime")]
pub use crate::listings_runtime::{
LISTING_PUBLISH_OPERATION_KIND, ListingEnqueuePublishRequest, ListingEnqueueReceipt,
@@ -98,30 +104,38 @@ pub use crate::market_runtime::{
};
#[cfg(feature = "runtime")]
pub use crate::orders_runtime::{
- ORDER_CANCELLATION_OPERATION_KIND, ORDER_DECISION_OPERATION_KIND,
- ORDER_REVISION_DECISION_OPERATION_KIND, ORDER_REVISION_PROPOSAL_OPERATION_KIND,
- ORDER_STATUS_DEFAULT_LIMIT, ORDER_STATUS_MAX_LIMIT, ORDER_SUBMIT_OPERATION_KIND,
- OrderCancellationEnqueueRequest, OrderCancellationPlan, OrderCancellationPrepareRequest,
- OrderCancellationReceipt, OrderDecisionEnqueueRequest, OrderDecisionPlan,
- OrderDecisionPrepareRequest, OrderDecisionReceipt, OrderEvidenceIngestReceipt,
- OrderEvidenceIngestRequest, OrderRequestEvidenceIngestReceipt,
- OrderRequestEvidenceIngestRequest, OrderRevisionDecisionEnqueueRequest,
- OrderRevisionDecisionPlan, OrderRevisionDecisionPrepareRequest, OrderRevisionDecisionReceipt,
- OrderRevisionProposalEnqueueRequest, OrderRevisionProposalPlan,
- OrderRevisionProposalPrepareRequest, OrderRevisionProposalReceipt, OrderStatusEligibility,
- OrderStatusEvidenceSummary, OrderStatusKind, OrderStatusNextActionKind, OrderStatusReceipt,
- OrderStatusRequest, OrderSubmitEnqueueRequest, OrderSubmitPlan, OrderSubmitPrepareRequest,
- OrderSubmitReceipt, OrderWorkflowEnqueueReceipt, OrderWorkflowIdempotencyReceipt,
- OrderWorkflowKind, OrderWorkflowPlan, OrderWorkflowRetryAdvice, SdkOrderStatusIssue,
- SdkOrderStatusIssueKind, SdkOrderStatusSource,
+ SdkTradeStatusIssue, SdkTradeStatusIssueKind, SdkTradeStatusSource,
+ TRADE_CANCELLATION_OPERATION_KIND, TRADE_DECISION_OPERATION_KIND,
+ TRADE_REVISION_DECISION_OPERATION_KIND, TRADE_REVISION_PROPOSAL_OPERATION_KIND,
+ TRADE_STATUS_DEFAULT_LIMIT, TRADE_STATUS_MAX_LIMIT, TRADE_SUBMIT_OPERATION_KIND,
+ TradeCancellationEnqueueRequest, TradeCancellationPlan, TradeCancellationPrepareRequest,
+ TradeCancellationReceipt, TradeDecisionEnqueueRequest, TradeDecisionPlan,
+ TradeDecisionPrepareRequest, TradeDecisionReceipt, TradeEvidenceIngestReceipt,
+ TradeEvidenceIngestRequest, TradeRequestEvidenceIngestReceipt,
+ TradeRequestEvidenceIngestRequest, TradeRevisionDecisionEnqueueRequest,
+ TradeRevisionDecisionPlan, TradeRevisionDecisionPrepareRequest, TradeRevisionDecisionReceipt,
+ TradeRevisionProposalEnqueueRequest, TradeRevisionProposalPlan,
+ TradeRevisionProposalPrepareRequest, TradeRevisionProposalReceipt,
+ TradeStatusAmbiguityCandidate, TradeStatusEligibility, TradeStatusEvidenceSummary,
+ TradeStatusKind, TradeStatusNextActionKind, TradeStatusReceipt, TradeStatusRequest,
+ TradeSubmitEnqueueRequest, TradeSubmitPlan, TradeSubmitPrepareRequest, TradeSubmitReceipt,
+ TradeWorkflowEnqueueReceipt, TradeWorkflowIdempotencyReceipt, TradeWorkflowKind,
+ TradeWorkflowPlan, TradeWorkflowRetryAdvice,
+};
+#[cfg(feature = "runtime")]
+pub use crate::privacy::{
+ PrivacyPreflightReceipt, PrivacyPreflightStatus, ProductSensitivityField,
};
#[cfg(feature = "runtime")]
pub use crate::product_clients::{
- DvmClient, FarmsClient, GeoNamesClient, ListingsClient, MarketClient, SyncClient, TradesClient,
+ DvmClient, FarmsClient, GeoNamesClient, ListingsClient, MarketClient, SyncClient,
+ TradeBuyerClient, TradeResyncClient, TradeSellerClient, TradeStatusClient,
+ TradeValidationClient, TradesClient,
};
#[cfg(feature = "runtime")]
pub use crate::relay_targets::{
- SDK_RELAY_TARGET_MAX_COUNT, SdkRelayTargetPolicy, SdkRelayTargetSet, SdkRelayUrlPolicy,
+ AckPolicy, PublishMode, RelayResolutionPolicy, SDK_RELAY_TARGET_MAX_COUNT,
+ SdkRelayTargetPolicy, SdkRelayTargetSet, SdkRelayUrlPolicy,
};
#[cfg(feature = "runtime")]
pub use crate::runtime::{
@@ -153,3 +167,10 @@ pub use crate::sync_runtime::{
SyncProjectionRefreshRequest, SyncRelayTargetSummary, SyncStatusReceipt, SyncStatusRequest,
SyncStatusSource,
};
+#[cfg(feature = "runtime")]
+pub use crate::trade_storage::{
+ SDK_TRADE_PROJECTION_CACHE_VERSION, SdkTradeProjectionCache, SdkTradeProjectionCacheKey,
+ SdkTradeProjectionCacheRecord,
+};
+#[cfg(feature = "runtime")]
+pub use radroots_trade::dvm::RadrootsTradeInventoryBinWitnessDto;
diff --git a/crates/sdk/src/orders_runtime.rs b/crates/sdk/src/orders_runtime.rs
@@ -2,8 +2,9 @@
use crate::workflow_runtime::enqueue_configured_signed_workflow;
#[cfg(feature = "runtime")]
use crate::{
- RadrootsSdkError, RadrootsSdkRecoveryAction, RadrootsSdkTimestamp, SdkIdempotencyKey,
- SdkMutationState, SdkRelayTargetPolicy, SdkRelayUrlPolicy, TradesClient, order,
+ AckPolicy, PublishMode, RadrootsSdkError, RadrootsSdkRecoveryAction, RadrootsSdkTimestamp,
+ RelayResolutionPolicy, SdkIdempotencyKey, SdkMutationState, SdkRelayUrlPolicy, TradesClient,
+ order,
workflow_runtime::{SdkWorkflowEnqueueRequest, enqueue_signed_workflow},
};
#[cfg(feature = "runtime")]
@@ -33,47 +34,50 @@ use radroots_events_codec::order::{
#[cfg(feature = "runtime")]
use radroots_events_codec::wire::{WireEventParts, to_frozen_draft};
#[cfg(feature = "runtime")]
+use radroots_trade::identity::{RadrootsTradeLocator, RadrootsTradeLocatorCandidate};
+#[cfg(feature = "runtime")]
use radroots_trade::order::{
RadrootsOrderCanonicalizationError, RadrootsOrderIssue, RadrootsOrderProjection,
RadrootsOrderProjectionQueryResult, RadrootsOrderStoreQueryError,
+ RadrootsTradeLocatorProjectionQueryResult, RadrootsTradeLocatorProjectionResolution,
canonicalize_order_decision_for_signer, canonicalize_order_request_for_signer,
- order_projection_query_for_order_id,
+ order_projection_query_for_order_id, order_projection_query_for_trade_locator,
};
#[cfg(feature = "runtime")]
use radroots_trade::workflow::RadrootsTradeWorkflowState;
#[cfg(feature = "runtime")]
use serde::ser::SerializeStruct;
#[cfg(feature = "runtime")]
-pub const ORDER_STATUS_DEFAULT_LIMIT: u32 = 500;
+pub const TRADE_STATUS_DEFAULT_LIMIT: u32 = 500;
#[cfg(feature = "runtime")]
-pub const ORDER_STATUS_MAX_LIMIT: u32 = 1_000;
+pub const TRADE_STATUS_MAX_LIMIT: u32 = 1_000;
#[cfg(feature = "runtime")]
-pub const ORDER_SUBMIT_OPERATION_KIND: &str = "order.submit.v1";
+pub const TRADE_SUBMIT_OPERATION_KIND: &str = "trade.submit.v1";
#[cfg(feature = "runtime")]
-pub const ORDER_DECISION_OPERATION_KIND: &str = "order.decision.v1";
+pub const TRADE_DECISION_OPERATION_KIND: &str = "trade.decision.v1";
#[cfg(feature = "runtime")]
-pub const ORDER_REVISION_PROPOSAL_OPERATION_KIND: &str = "order.revision.proposal.v1";
+pub const TRADE_REVISION_PROPOSAL_OPERATION_KIND: &str = "trade.revision.proposal.v1";
#[cfg(feature = "runtime")]
-pub const ORDER_REVISION_DECISION_OPERATION_KIND: &str = "order.revision.decision.v1";
+pub const TRADE_REVISION_DECISION_OPERATION_KIND: &str = "trade.revision.decision.v1";
#[cfg(feature = "runtime")]
-pub const ORDER_CANCELLATION_OPERATION_KIND: &str = "order.cancellation.v1";
+pub const TRADE_CANCELLATION_OPERATION_KIND: &str = "trade.cancellation.v1";
#[cfg(feature = "runtime")]
-const ORDER_REQUEST_CONTRACT_ID: &str = "radroots.order.request.v1";
+const TRADE_SUBMIT_CONTRACT_ID: &str = "radroots.order.request.v1";
#[cfg(feature = "runtime")]
-const ORDER_DECISION_CONTRACT_ID: &str = "radroots.order.decision.v1";
+const TRADE_DECISION_CONTRACT_ID: &str = "radroots.order.decision.v1";
#[cfg(feature = "runtime")]
-const ORDER_REVISION_PROPOSAL_CONTRACT_ID: &str = "radroots.order.revision_proposal.v1";
+const TRADE_REVISION_PROPOSAL_CONTRACT_ID: &str = "radroots.order.revision_proposal.v1";
#[cfg(feature = "runtime")]
-const ORDER_REVISION_DECISION_CONTRACT_ID: &str = "radroots.order.revision_decision.v1";
+const TRADE_REVISION_DECISION_CONTRACT_ID: &str = "radroots.order.revision_decision.v1";
#[cfg(feature = "runtime")]
-const ORDER_CANCELLATION_CONTRACT_ID: &str = "radroots.order.cancellation.v1";
+const TRADE_CANCELLATION_CONTRACT_ID: &str = "radroots.order.cancellation.v1";
#[cfg(feature = "runtime")]
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
-pub enum OrderWorkflowKind {
+pub enum TradeWorkflowKind {
Submit,
Decision,
RevisionProposal,
@@ -82,32 +86,32 @@ pub enum OrderWorkflowKind {
}
#[cfg(feature = "runtime")]
-impl OrderWorkflowKind {
+impl TradeWorkflowKind {
pub fn operation_kind(self) -> &'static str {
match self {
- Self::Submit => ORDER_SUBMIT_OPERATION_KIND,
- Self::Decision => ORDER_DECISION_OPERATION_KIND,
- Self::RevisionProposal => ORDER_REVISION_PROPOSAL_OPERATION_KIND,
- Self::RevisionDecision => ORDER_REVISION_DECISION_OPERATION_KIND,
- Self::Cancellation => ORDER_CANCELLATION_OPERATION_KIND,
+ Self::Submit => TRADE_SUBMIT_OPERATION_KIND,
+ Self::Decision => TRADE_DECISION_OPERATION_KIND,
+ Self::RevisionProposal => TRADE_REVISION_PROPOSAL_OPERATION_KIND,
+ Self::RevisionDecision => TRADE_REVISION_DECISION_OPERATION_KIND,
+ Self::Cancellation => TRADE_CANCELLATION_OPERATION_KIND,
}
}
pub fn contract_id(self) -> &'static str {
match self {
- Self::Submit => ORDER_REQUEST_CONTRACT_ID,
- Self::Decision => ORDER_DECISION_CONTRACT_ID,
- Self::RevisionProposal => ORDER_REVISION_PROPOSAL_CONTRACT_ID,
- Self::RevisionDecision => ORDER_REVISION_DECISION_CONTRACT_ID,
- Self::Cancellation => ORDER_CANCELLATION_CONTRACT_ID,
+ Self::Submit => TRADE_SUBMIT_CONTRACT_ID,
+ Self::Decision => TRADE_DECISION_CONTRACT_ID,
+ Self::RevisionProposal => TRADE_REVISION_PROPOSAL_CONTRACT_ID,
+ Self::RevisionDecision => TRADE_REVISION_DECISION_CONTRACT_ID,
+ Self::Cancellation => TRADE_CANCELLATION_CONTRACT_ID,
}
}
}
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderWorkflowPlan {
- pub kind: OrderWorkflowKind,
+pub struct TradeWorkflowPlan {
+ pub kind: TradeWorkflowKind,
pub operation_kind: &'static str,
pub contract_id: &'static str,
pub expected_event_id: RadrootsEventId,
@@ -116,8 +120,8 @@ pub struct OrderWorkflowPlan {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderWorkflowEnqueueReceipt {
- pub kind: OrderWorkflowKind,
+pub struct TradeWorkflowEnqueueReceipt {
+ pub kind: TradeWorkflowKind,
pub operation_kind: &'static str,
pub expected_event_id: RadrootsEventId,
pub signed_event_id: RadrootsEventId,
@@ -126,13 +130,13 @@ pub struct OrderWorkflowEnqueueReceipt {
pub outbox_event_id: i64,
pub state: SdkMutationState,
pub idempotency_digest_prefix: Option<String>,
- pub idempotency: OrderWorkflowIdempotencyReceipt,
- pub retry: OrderWorkflowRetryAdvice,
+ pub idempotency: TradeWorkflowIdempotencyReceipt,
+ pub retry: TradeWorkflowRetryAdvice,
}
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderWorkflowIdempotencyReceipt {
+pub struct TradeWorkflowIdempotencyReceipt {
pub digest_prefix: Option<String>,
pub replayed_existing_operation: bool,
pub safe_to_retry_with_same_idempotency_key: bool,
@@ -140,7 +144,7 @@ pub struct OrderWorkflowIdempotencyReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderWorkflowRetryAdvice {
+pub struct TradeWorkflowRetryAdvice {
pub retryable_after_error: bool,
pub safe_to_retry_enqueue_with_same_idempotency_key: bool,
pub recovery_actions: Vec<RadrootsSdkRecoveryAction>,
@@ -149,7 +153,7 @@ pub struct OrderWorkflowRetryAdvice {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderSubmitPrepareRequest {
+pub struct TradeSubmitPrepareRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub listing_event: RadrootsNostrEventPtr,
@@ -158,7 +162,7 @@ pub struct OrderSubmitPrepareRequest {
}
#[cfg(feature = "runtime")]
-impl OrderSubmitPrepareRequest {
+impl TradeSubmitPrepareRequest {
pub fn new(
actor: RadrootsActorContext,
listing_event: RadrootsNostrEventPtr,
@@ -181,29 +185,35 @@ impl OrderSubmitPrepareRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderSubmitEnqueueRequest {
+pub struct TradeSubmitEnqueueRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub listing_event: RadrootsNostrEventPtr,
pub order: RadrootsOrderRequest,
- pub target_relays: SdkRelayTargetPolicy,
+ pub target_relays: RelayResolutionPolicy,
+ pub publish_mode: PublishMode,
+ pub ack_policy: AckPolicy,
pub idempotency_key: Option<SdkIdempotencyKey>,
pub created_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderSubmitEnqueueRequest {
+impl TradeSubmitEnqueueRequest {
pub fn new(
actor: RadrootsActorContext,
listing_event: RadrootsNostrEventPtr,
order: RadrootsOrderRequest,
- target_relays: SdkRelayTargetPolicy,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
) -> Self {
Self {
actor,
listing_event,
order,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key: None,
created_at: None,
}
@@ -218,7 +228,7 @@ impl OrderSubmitEnqueueRequest {
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
- self.target_relays = SdkRelayTargetPolicy::try_explicit(target_relays, policy)?;
+ self.target_relays = RelayResolutionPolicy::try_explicit(target_relays, policy)?;
Ok(self)
}
@@ -243,8 +253,8 @@ impl OrderSubmitEnqueueRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderSubmitPlan {
- pub workflow: OrderWorkflowPlan,
+pub struct TradeSubmitPlan {
+ pub workflow: TradeWorkflowPlan,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub listing_event_id: RadrootsEventId,
@@ -255,8 +265,8 @@ pub struct OrderSubmitPlan {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderSubmitReceipt {
- pub workflow: OrderWorkflowEnqueueReceipt,
+pub struct TradeSubmitReceipt {
+ pub workflow: TradeWorkflowEnqueueReceipt,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub listing_event_id: RadrootsEventId,
@@ -272,13 +282,13 @@ pub struct OrderSubmitReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderRequestEvidenceIngestRequest {
+pub struct TradeRequestEvidenceIngestRequest {
pub event: RadrootsNostrEvent,
pub observed_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderRequestEvidenceIngestRequest {
+impl TradeRequestEvidenceIngestRequest {
pub fn new(event: RadrootsNostrEvent) -> Self {
Self {
event,
@@ -294,7 +304,7 @@ impl OrderRequestEvidenceIngestRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderRequestEvidenceIngestReceipt {
+pub struct TradeRequestEvidenceIngestReceipt {
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -307,13 +317,13 @@ pub struct OrderRequestEvidenceIngestReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderEvidenceIngestRequest {
+pub struct TradeEvidenceIngestRequest {
pub event: RadrootsNostrEvent,
pub observed_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderEvidenceIngestRequest {
+impl TradeEvidenceIngestRequest {
pub fn new(event: RadrootsNostrEvent) -> Self {
Self {
event,
@@ -329,7 +339,7 @@ impl OrderEvidenceIngestRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderEvidenceIngestReceipt {
+pub struct TradeEvidenceIngestReceipt {
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub event_id: RadrootsEventId,
@@ -341,7 +351,7 @@ pub struct OrderEvidenceIngestReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderDecisionPrepareRequest {
+pub struct TradeDecisionPrepareRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub request_event: RadrootsNostrEventPtr,
@@ -350,7 +360,7 @@ pub struct OrderDecisionPrepareRequest {
}
#[cfg(feature = "runtime")]
-impl OrderDecisionPrepareRequest {
+impl TradeDecisionPrepareRequest {
pub fn new(
actor: RadrootsActorContext,
request_event: RadrootsNostrEventPtr,
@@ -373,29 +383,35 @@ impl OrderDecisionPrepareRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderDecisionEnqueueRequest {
+pub struct TradeDecisionEnqueueRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub request_event: RadrootsNostrEventPtr,
pub decision: RadrootsOrderDecision,
- pub target_relays: SdkRelayTargetPolicy,
+ pub target_relays: RelayResolutionPolicy,
+ pub publish_mode: PublishMode,
+ pub ack_policy: AckPolicy,
pub idempotency_key: Option<SdkIdempotencyKey>,
pub created_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderDecisionEnqueueRequest {
+impl TradeDecisionEnqueueRequest {
pub fn new(
actor: RadrootsActorContext,
request_event: RadrootsNostrEventPtr,
decision: RadrootsOrderDecision,
- target_relays: SdkRelayTargetPolicy,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
) -> Self {
Self {
actor,
request_event,
decision,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key: None,
created_at: None,
}
@@ -410,7 +426,7 @@ impl OrderDecisionEnqueueRequest {
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
- self.target_relays = SdkRelayTargetPolicy::try_explicit(target_relays, policy)?;
+ self.target_relays = RelayResolutionPolicy::try_explicit(target_relays, policy)?;
Ok(self)
}
@@ -435,8 +451,8 @@ impl OrderDecisionEnqueueRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderDecisionPlan {
- pub workflow: OrderWorkflowPlan,
+pub struct TradeDecisionPlan {
+ pub workflow: TradeWorkflowPlan,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -449,8 +465,8 @@ pub struct OrderDecisionPlan {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderDecisionReceipt {
- pub workflow: OrderWorkflowEnqueueReceipt,
+pub struct TradeDecisionReceipt {
+ pub workflow: TradeWorkflowEnqueueReceipt,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -468,7 +484,7 @@ pub struct OrderDecisionReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderRevisionProposalPrepareRequest {
+pub struct TradeRevisionProposalPrepareRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub root_event: RadrootsNostrEventPtr,
@@ -478,7 +494,7 @@ pub struct OrderRevisionProposalPrepareRequest {
}
#[cfg(feature = "runtime")]
-impl OrderRevisionProposalPrepareRequest {
+impl TradeRevisionProposalPrepareRequest {
pub fn new(
actor: RadrootsActorContext,
root_event: RadrootsNostrEventPtr,
@@ -503,25 +519,29 @@ impl OrderRevisionProposalPrepareRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderRevisionProposalEnqueueRequest {
+pub struct TradeRevisionProposalEnqueueRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub root_event: RadrootsNostrEventPtr,
pub previous_event: RadrootsNostrEventPtr,
pub proposal: RadrootsOrderRevisionProposal,
- pub target_relays: SdkRelayTargetPolicy,
+ pub target_relays: RelayResolutionPolicy,
+ pub publish_mode: PublishMode,
+ pub ack_policy: AckPolicy,
pub idempotency_key: Option<SdkIdempotencyKey>,
pub created_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderRevisionProposalEnqueueRequest {
+impl TradeRevisionProposalEnqueueRequest {
pub fn new(
actor: RadrootsActorContext,
root_event: RadrootsNostrEventPtr,
previous_event: RadrootsNostrEventPtr,
proposal: RadrootsOrderRevisionProposal,
- target_relays: SdkRelayTargetPolicy,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
) -> Self {
Self {
actor,
@@ -529,6 +549,8 @@ impl OrderRevisionProposalEnqueueRequest {
previous_event,
proposal,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key: None,
created_at: None,
}
@@ -543,7 +565,7 @@ impl OrderRevisionProposalEnqueueRequest {
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
- self.target_relays = SdkRelayTargetPolicy::try_explicit(target_relays, policy)?;
+ self.target_relays = RelayResolutionPolicy::try_explicit(target_relays, policy)?;
Ok(self)
}
@@ -568,8 +590,8 @@ impl OrderRevisionProposalEnqueueRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderRevisionProposalPlan {
- pub workflow: OrderWorkflowPlan,
+pub struct TradeRevisionProposalPlan {
+ pub workflow: TradeWorkflowPlan,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -583,8 +605,8 @@ pub struct OrderRevisionProposalPlan {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderRevisionProposalReceipt {
- pub workflow: OrderWorkflowEnqueueReceipt,
+pub struct TradeRevisionProposalReceipt {
+ pub workflow: TradeWorkflowEnqueueReceipt,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -603,7 +625,7 @@ pub struct OrderRevisionProposalReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderRevisionDecisionPrepareRequest {
+pub struct TradeRevisionDecisionPrepareRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub root_event: RadrootsNostrEventPtr,
@@ -613,7 +635,7 @@ pub struct OrderRevisionDecisionPrepareRequest {
}
#[cfg(feature = "runtime")]
-impl OrderRevisionDecisionPrepareRequest {
+impl TradeRevisionDecisionPrepareRequest {
pub fn new(
actor: RadrootsActorContext,
root_event: RadrootsNostrEventPtr,
@@ -638,25 +660,29 @@ impl OrderRevisionDecisionPrepareRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderRevisionDecisionEnqueueRequest {
+pub struct TradeRevisionDecisionEnqueueRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub root_event: RadrootsNostrEventPtr,
pub previous_event: RadrootsNostrEventPtr,
pub decision: RadrootsOrderRevisionDecision,
- pub target_relays: SdkRelayTargetPolicy,
+ pub target_relays: RelayResolutionPolicy,
+ pub publish_mode: PublishMode,
+ pub ack_policy: AckPolicy,
pub idempotency_key: Option<SdkIdempotencyKey>,
pub created_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderRevisionDecisionEnqueueRequest {
+impl TradeRevisionDecisionEnqueueRequest {
pub fn new(
actor: RadrootsActorContext,
root_event: RadrootsNostrEventPtr,
previous_event: RadrootsNostrEventPtr,
decision: RadrootsOrderRevisionDecision,
- target_relays: SdkRelayTargetPolicy,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
) -> Self {
Self {
actor,
@@ -664,6 +690,8 @@ impl OrderRevisionDecisionEnqueueRequest {
previous_event,
decision,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key: None,
created_at: None,
}
@@ -678,7 +706,7 @@ impl OrderRevisionDecisionEnqueueRequest {
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
- self.target_relays = SdkRelayTargetPolicy::try_explicit(target_relays, policy)?;
+ self.target_relays = RelayResolutionPolicy::try_explicit(target_relays, policy)?;
Ok(self)
}
@@ -703,8 +731,8 @@ impl OrderRevisionDecisionEnqueueRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderRevisionDecisionPlan {
- pub workflow: OrderWorkflowPlan,
+pub struct TradeRevisionDecisionPlan {
+ pub workflow: TradeWorkflowPlan,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -718,8 +746,8 @@ pub struct OrderRevisionDecisionPlan {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderRevisionDecisionReceipt {
- pub workflow: OrderWorkflowEnqueueReceipt,
+pub struct TradeRevisionDecisionReceipt {
+ pub workflow: TradeWorkflowEnqueueReceipt,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -738,7 +766,7 @@ pub struct OrderRevisionDecisionReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderCancellationPrepareRequest {
+pub struct TradeCancellationPrepareRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub root_event: RadrootsNostrEventPtr,
@@ -748,7 +776,7 @@ pub struct OrderCancellationPrepareRequest {
}
#[cfg(feature = "runtime")]
-impl OrderCancellationPrepareRequest {
+impl TradeCancellationPrepareRequest {
pub fn new(
actor: RadrootsActorContext,
root_event: RadrootsNostrEventPtr,
@@ -773,25 +801,29 @@ impl OrderCancellationPrepareRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderCancellationEnqueueRequest {
+pub struct TradeCancellationEnqueueRequest {
#[serde(serialize_with = "crate::actor_json::serialize_actor_context")]
pub actor: RadrootsActorContext,
pub root_event: RadrootsNostrEventPtr,
pub previous_event: RadrootsNostrEventPtr,
pub cancellation: RadrootsOrderCancellation,
- pub target_relays: SdkRelayTargetPolicy,
+ pub target_relays: RelayResolutionPolicy,
+ pub publish_mode: PublishMode,
+ pub ack_policy: AckPolicy,
pub idempotency_key: Option<SdkIdempotencyKey>,
pub created_at: Option<RadrootsSdkTimestamp>,
}
#[cfg(feature = "runtime")]
-impl OrderCancellationEnqueueRequest {
+impl TradeCancellationEnqueueRequest {
pub fn new(
actor: RadrootsActorContext,
root_event: RadrootsNostrEventPtr,
previous_event: RadrootsNostrEventPtr,
cancellation: RadrootsOrderCancellation,
- target_relays: SdkRelayTargetPolicy,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
) -> Self {
Self {
actor,
@@ -799,6 +831,8 @@ impl OrderCancellationEnqueueRequest {
previous_event,
cancellation,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key: None,
created_at: None,
}
@@ -813,7 +847,7 @@ impl OrderCancellationEnqueueRequest {
I: IntoIterator<Item = S>,
S: AsRef<str>,
{
- self.target_relays = SdkRelayTargetPolicy::try_explicit(target_relays, policy)?;
+ self.target_relays = RelayResolutionPolicy::try_explicit(target_relays, policy)?;
Ok(self)
}
@@ -838,8 +872,8 @@ impl OrderCancellationEnqueueRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderCancellationPlan {
- pub workflow: OrderWorkflowPlan,
+pub struct TradeCancellationPlan {
+ pub workflow: TradeWorkflowPlan,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -853,8 +887,8 @@ pub struct OrderCancellationPlan {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderCancellationReceipt {
- pub workflow: OrderWorkflowEnqueueReceipt,
+pub struct TradeCancellationReceipt {
+ pub workflow: TradeWorkflowEnqueueReceipt,
pub order_id: RadrootsOrderId,
pub listing_addr: RadrootsListingAddress,
pub buyer_pubkey: RadrootsPublicKey,
@@ -873,24 +907,25 @@ pub struct OrderCancellationReceipt {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
#[non_exhaustive]
-pub struct OrderStatusRequest {
- pub order_id: RadrootsOrderId,
+pub struct TradeStatusRequest {
+ pub locator: RadrootsTradeLocator,
pub limit: u32,
}
#[cfg(feature = "runtime")]
-impl OrderStatusRequest {
- pub fn new(order_id: RadrootsOrderId) -> Self {
+impl TradeStatusRequest {
+ pub fn new(locator: RadrootsTradeLocator) -> Self {
Self {
- order_id,
- limit: ORDER_STATUS_DEFAULT_LIMIT,
+ locator,
+ limit: TRADE_STATUS_DEFAULT_LIMIT,
}
}
pub fn parse(order_id: &str) -> Result<Self, RadrootsSdkError> {
RadrootsOrderId::parse(order_id)
+ .map(RadrootsTradeLocator::from_order_id)
.map(Self::new)
- .map_err(|error| RadrootsSdkError::invalid_order_id(order_id, error.to_string()))
+ .map_err(|error| RadrootsSdkError::invalid_trade_id(order_id, error.to_string()))
}
pub fn with_limit(mut self, limit: u32) -> Self {
@@ -899,11 +934,11 @@ impl OrderStatusRequest {
}
fn validate(&self) -> Result<(), RadrootsSdkError> {
- if self.limit == 0 || self.limit > ORDER_STATUS_MAX_LIMIT {
- return Err(RadrootsSdkError::order_status_limit_invalid(
+ if self.limit == 0 || self.limit > TRADE_STATUS_MAX_LIMIT {
+ return Err(RadrootsSdkError::trade_status_limit_invalid(
self.limit,
1,
- ORDER_STATUS_MAX_LIMIT,
+ TRADE_STATUS_MAX_LIMIT,
));
}
Ok(())
@@ -912,21 +947,24 @@ impl OrderStatusRequest {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderStatusReceipt {
+pub struct TradeStatusReceipt {
+ pub locator: RadrootsTradeLocator,
pub order_id: RadrootsOrderId,
- pub source: SdkOrderStatusSource,
+ pub root_event_id: Option<RadrootsEventId>,
+ pub ambiguity_candidates: Vec<TradeStatusAmbiguityCandidate>,
+ pub source: SdkTradeStatusSource,
pub found: bool,
pub event_count: usize,
pub limit_applied: u32,
- pub status: OrderStatusKind,
+ pub status: TradeStatusKind,
pub lifecycle_terminal: bool,
pub listing_addr: Option<RadrootsListingAddress>,
pub buyer_pubkey: Option<RadrootsPublicKey>,
pub seller_pubkey: Option<RadrootsPublicKey>,
pub economics: Option<RadrootsOrderEconomics>,
- pub evidence: OrderStatusEvidenceSummary,
- pub eligibility: OrderStatusEligibility,
- pub next_action: OrderStatusNextActionKind,
+ pub evidence: TradeStatusEvidenceSummary,
+ pub eligibility: TradeStatusEligibility,
+ pub next_action: TradeStatusNextActionKind,
pub event_ids: Vec<RadrootsEventId>,
pub request_event_id: Option<RadrootsEventId>,
pub decision_event_id: Option<RadrootsEventId>,
@@ -935,12 +973,18 @@ pub struct OrderStatusReceipt {
pub pending_revision_event_id: Option<RadrootsEventId>,
pub cancellation_event_id: Option<RadrootsEventId>,
pub last_event_id: Option<RadrootsEventId>,
- pub issues: Vec<SdkOrderStatusIssue>,
+ pub issues: Vec<SdkTradeStatusIssue>,
}
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderStatusEvidenceSummary {
+pub struct TradeStatusAmbiguityCandidate {
+ pub locator: RadrootsTradeLocator,
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
+pub struct TradeStatusEvidenceSummary {
pub event_count: usize,
pub limit_applied: u32,
pub has_request: bool,
@@ -953,7 +997,7 @@ pub struct OrderStatusEvidenceSummary {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
-pub struct OrderStatusEligibility {
+pub struct TradeStatusEligibility {
pub can_decide: bool,
pub can_propose_revision: bool,
pub can_decide_revision: bool,
@@ -964,7 +1008,7 @@ pub struct OrderStatusEligibility {
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
-pub enum OrderStatusNextActionKind {
+pub enum TradeStatusNextActionKind {
NoLocalOrder,
InspectEvidenceIssues,
AwaitSellerDecision,
@@ -977,7 +1021,7 @@ pub enum OrderStatusNextActionKind {
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
-pub enum SdkOrderStatusSource {
+pub enum SdkTradeStatusSource {
LocalEventStore,
}
@@ -985,8 +1029,9 @@ pub enum SdkOrderStatusSource {
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
-pub enum OrderStatusKind {
+pub enum TradeStatusKind {
Missing,
+ Ambiguous,
Requested,
RevisionProposed,
AgreedPendingRhi,
@@ -998,18 +1043,18 @@ pub enum OrderStatusKind {
#[cfg(feature = "runtime")]
#[derive(Clone, Debug, PartialEq, Eq)]
-pub struct SdkOrderStatusIssue {
- pub kind: SdkOrderStatusIssueKind,
+pub struct SdkTradeStatusIssue {
+ pub kind: SdkTradeStatusIssueKind,
pub event_ids: Vec<RadrootsEventId>,
}
#[cfg(feature = "runtime")]
-impl SdkOrderStatusIssue {
- fn new(kind: SdkOrderStatusIssueKind, event_ids: Vec<RadrootsEventId>) -> Self {
+impl SdkTradeStatusIssue {
+ fn new(kind: SdkTradeStatusIssueKind, event_ids: Vec<RadrootsEventId>) -> Self {
Self { kind, event_ids }
}
- fn single(kind: SdkOrderStatusIssueKind, event_id: RadrootsEventId) -> Self {
+ fn single(kind: SdkTradeStatusIssueKind, event_id: RadrootsEventId) -> Self {
Self::new(kind, vec![event_id])
}
@@ -1019,12 +1064,12 @@ impl SdkOrderStatusIssue {
}
#[cfg(feature = "runtime")]
-impl serde::Serialize for SdkOrderStatusIssue {
+impl serde::Serialize for SdkTradeStatusIssue {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
- let mut state = serializer.serialize_struct("SdkOrderStatusIssue", 3)?;
+ let mut state = serializer.serialize_struct("SdkTradeStatusIssue", 3)?;
state.serialize_field("code", &self.code())?;
state.serialize_field("kind", &self.kind)?;
state.serialize_field("event_ids", &self.event_ids)?;
@@ -1036,7 +1081,7 @@ impl serde::Serialize for SdkOrderStatusIssue {
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
-pub enum SdkOrderStatusIssueKind {
+pub enum SdkTradeStatusIssueKind {
MissingRequest,
MultipleRequests,
RequestPayloadInvalid,
@@ -1104,7 +1149,7 @@ pub enum SdkOrderStatusIssueKind {
}
#[cfg(feature = "runtime")]
-impl SdkOrderStatusIssueKind {
+impl SdkTradeStatusIssueKind {
pub fn code(self) -> String {
camel_to_snake(format!("{self:?}").as_str())
}
@@ -1114,8 +1159,8 @@ impl SdkOrderStatusIssueKind {
impl<'sdk> TradesClient<'sdk> {
pub async fn ingest_evidence(
&self,
- request: OrderEvidenceIngestRequest,
- ) -> Result<OrderEvidenceIngestReceipt, RadrootsSdkError> {
+ request: TradeEvidenceIngestRequest,
+ ) -> Result<TradeEvidenceIngestReceipt, RadrootsSdkError> {
let evidence = parse_order_evidence(&request.event)?;
let observed_at = self.resolved_created_at(request.observed_at)?;
let observed_at_ms = sdk_timestamp_ms(observed_at)?;
@@ -1127,7 +1172,7 @@ impl<'sdk> TradesClient<'sdk> {
.map_err(|error| RadrootsSdkError::EventStore {
message: error.to_string(),
})?;
- Ok(OrderEvidenceIngestReceipt {
+ Ok(TradeEvidenceIngestReceipt {
order_id: evidence.order_id,
listing_addr: evidence.listing_addr,
event_id: evidence.event_id,
@@ -1139,8 +1184,8 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn ingest_request_evidence(
&self,
- request: OrderRequestEvidenceIngestRequest,
- ) -> Result<OrderRequestEvidenceIngestReceipt, RadrootsSdkError> {
+ request: TradeRequestEvidenceIngestRequest,
+ ) -> Result<TradeRequestEvidenceIngestReceipt, RadrootsSdkError> {
let evidence = parse_order_request_evidence(&request.event)?;
let observed_at = self.resolved_created_at(request.observed_at)?;
let observed_at_ms = sdk_timestamp_ms(observed_at)?;
@@ -1152,7 +1197,7 @@ impl<'sdk> TradesClient<'sdk> {
.map_err(|error| RadrootsSdkError::EventStore {
message: error.to_string(),
})?;
- Ok(OrderRequestEvidenceIngestReceipt {
+ Ok(TradeRequestEvidenceIngestReceipt {
order_id: evidence.order_id,
listing_addr: evidence.listing_addr,
buyer_pubkey: evidence.buyer_pubkey,
@@ -1165,8 +1210,8 @@ impl<'sdk> TradesClient<'sdk> {
pub fn prepare_submit(
&self,
- request: OrderSubmitPrepareRequest,
- ) -> Result<OrderSubmitPlan, RadrootsSdkError> {
+ request: TradeSubmitPrepareRequest,
+ ) -> Result<TradeSubmitPlan, RadrootsSdkError> {
let created_at = self.resolved_created_at(request.created_at)?;
order_submit_plan(
&request.actor,
@@ -1179,41 +1224,54 @@ impl<'sdk> TradesClient<'sdk> {
#[cfg(feature = "signer-adapters")]
pub async fn enqueue_submit(
&self,
- request: OrderSubmitEnqueueRequest,
- ) -> Result<OrderSubmitReceipt, RadrootsSdkError> {
- let OrderSubmitEnqueueRequest {
+ request: TradeSubmitEnqueueRequest,
+ ) -> Result<TradeSubmitReceipt, RadrootsSdkError> {
+ let TradeSubmitEnqueueRequest {
actor,
listing_event,
order,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderSubmitPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeSubmitPrepareRequest {
actor: actor.clone(),
listing_event,
order,
created_at,
};
let plan = self.prepare_submit(prepare_request)?;
- self.enqueue_prepared_submit(&actor, plan, target_relays, idempotency_key)
- .await
+ self.enqueue_prepared_submit(
+ &actor,
+ plan,
+ target_relays,
+ publish_mode,
+ ack_policy,
+ idempotency_key,
+ )
+ .await
}
pub async fn enqueue_submit_with_explicit_signer(
&self,
- request: OrderSubmitEnqueueRequest,
+ request: TradeSubmitEnqueueRequest,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderSubmitReceipt, RadrootsSdkError> {
- let OrderSubmitEnqueueRequest {
+ ) -> Result<TradeSubmitReceipt, RadrootsSdkError> {
+ let TradeSubmitEnqueueRequest {
actor,
listing_event,
order,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderSubmitPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeSubmitPrepareRequest {
actor: actor.clone(),
listing_event,
order,
@@ -1224,6 +1282,8 @@ impl<'sdk> TradesClient<'sdk> {
&actor,
plan,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
signer,
)
@@ -1234,17 +1294,20 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_submit(
&self,
actor: &RadrootsActorContext,
- plan: OrderSubmitPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeSubmitPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
- ) -> Result<OrderSubmitReceipt, RadrootsSdkError> {
+ ) -> Result<TradeSubmitReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
let enqueue = enqueue_configured_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::Submit.operation_kind(),
+ operation_kind: TradeWorkflowKind::Submit.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
)
@@ -1255,18 +1318,21 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_submit_with_explicit_signer(
&self,
actor: &RadrootsActorContext,
- plan: OrderSubmitPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeSubmitPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderSubmitReceipt, RadrootsSdkError> {
+ ) -> Result<TradeSubmitReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
let enqueue = enqueue_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::Submit.operation_kind(),
+ operation_kind: TradeWorkflowKind::Submit.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
signer,
@@ -1277,8 +1343,8 @@ impl<'sdk> TradesClient<'sdk> {
pub fn prepare_decision(
&self,
- request: OrderDecisionPrepareRequest,
- ) -> Result<OrderDecisionPlan, RadrootsSdkError> {
+ request: TradeDecisionPrepareRequest,
+ ) -> Result<TradeDecisionPlan, RadrootsSdkError> {
let created_at = self.resolved_created_at(request.created_at)?;
order_decision_plan(
&request.actor,
@@ -1291,41 +1357,54 @@ impl<'sdk> TradesClient<'sdk> {
#[cfg(feature = "signer-adapters")]
pub async fn enqueue_decision(
&self,
- request: OrderDecisionEnqueueRequest,
- ) -> Result<OrderDecisionReceipt, RadrootsSdkError> {
- let OrderDecisionEnqueueRequest {
+ request: TradeDecisionEnqueueRequest,
+ ) -> Result<TradeDecisionReceipt, RadrootsSdkError> {
+ let TradeDecisionEnqueueRequest {
actor,
request_event,
decision,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderDecisionPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeDecisionPrepareRequest {
actor: actor.clone(),
request_event,
decision,
created_at,
};
let plan = self.prepare_decision(prepare_request)?;
- self.enqueue_prepared_decision(&actor, plan, target_relays, idempotency_key)
- .await
+ self.enqueue_prepared_decision(
+ &actor,
+ plan,
+ target_relays,
+ publish_mode,
+ ack_policy,
+ idempotency_key,
+ )
+ .await
}
pub async fn enqueue_decision_with_explicit_signer(
&self,
- request: OrderDecisionEnqueueRequest,
+ request: TradeDecisionEnqueueRequest,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderDecisionReceipt, RadrootsSdkError> {
- let OrderDecisionEnqueueRequest {
+ ) -> Result<TradeDecisionReceipt, RadrootsSdkError> {
+ let TradeDecisionEnqueueRequest {
actor,
request_event,
decision,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderDecisionPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeDecisionPrepareRequest {
actor: actor.clone(),
request_event,
decision,
@@ -1336,6 +1415,8 @@ impl<'sdk> TradesClient<'sdk> {
&actor,
plan,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
signer,
)
@@ -1346,10 +1427,13 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_decision(
&self,
actor: &RadrootsActorContext,
- plan: OrderDecisionPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeDecisionPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
- ) -> Result<OrderDecisionReceipt, RadrootsSdkError> {
+ ) -> Result<TradeDecisionReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1359,10 +1443,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_configured_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::Decision.operation_kind(),
+ operation_kind: TradeWorkflowKind::Decision.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
)
@@ -1373,11 +1457,14 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_decision_with_explicit_signer(
&self,
actor: &RadrootsActorContext,
- plan: OrderDecisionPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeDecisionPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderDecisionReceipt, RadrootsSdkError> {
+ ) -> Result<TradeDecisionReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1387,10 +1474,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::Decision.operation_kind(),
+ operation_kind: TradeWorkflowKind::Decision.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
signer,
@@ -1401,8 +1488,8 @@ impl<'sdk> TradesClient<'sdk> {
pub fn prepare_revision_proposal(
&self,
- request: OrderRevisionProposalPrepareRequest,
- ) -> Result<OrderRevisionProposalPlan, RadrootsSdkError> {
+ request: TradeRevisionProposalPrepareRequest,
+ ) -> Result<TradeRevisionProposalPlan, RadrootsSdkError> {
let created_at = self.resolved_created_at(request.created_at)?;
order_revision_proposal_plan(
&request.actor,
@@ -1416,18 +1503,21 @@ impl<'sdk> TradesClient<'sdk> {
#[cfg(feature = "signer-adapters")]
pub async fn enqueue_revision_proposal(
&self,
- request: OrderRevisionProposalEnqueueRequest,
- ) -> Result<OrderRevisionProposalReceipt, RadrootsSdkError> {
- let OrderRevisionProposalEnqueueRequest {
+ request: TradeRevisionProposalEnqueueRequest,
+ ) -> Result<TradeRevisionProposalReceipt, RadrootsSdkError> {
+ let TradeRevisionProposalEnqueueRequest {
actor,
root_event,
previous_event,
proposal,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderRevisionProposalPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeRevisionProposalPrepareRequest {
actor: actor.clone(),
root_event,
previous_event,
@@ -1435,25 +1525,35 @@ impl<'sdk> TradesClient<'sdk> {
created_at,
};
let plan = self.prepare_revision_proposal(prepare_request)?;
- self.enqueue_prepared_revision_proposal(&actor, plan, target_relays, idempotency_key)
- .await
+ self.enqueue_prepared_revision_proposal(
+ &actor,
+ plan,
+ target_relays,
+ publish_mode,
+ ack_policy,
+ idempotency_key,
+ )
+ .await
}
pub async fn enqueue_revision_proposal_with_explicit_signer(
&self,
- request: OrderRevisionProposalEnqueueRequest,
+ request: TradeRevisionProposalEnqueueRequest,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderRevisionProposalReceipt, RadrootsSdkError> {
- let OrderRevisionProposalEnqueueRequest {
+ ) -> Result<TradeRevisionProposalReceipt, RadrootsSdkError> {
+ let TradeRevisionProposalEnqueueRequest {
actor,
root_event,
previous_event,
proposal,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderRevisionProposalPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeRevisionProposalPrepareRequest {
actor: actor.clone(),
root_event,
previous_event,
@@ -1465,6 +1565,8 @@ impl<'sdk> TradesClient<'sdk> {
&actor,
plan,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
signer,
)
@@ -1475,10 +1577,13 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_revision_proposal(
&self,
actor: &RadrootsActorContext,
- plan: OrderRevisionProposalPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeRevisionProposalPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
- ) -> Result<OrderRevisionProposalReceipt, RadrootsSdkError> {
+ ) -> Result<TradeRevisionProposalReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1488,10 +1593,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_configured_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::RevisionProposal.operation_kind(),
+ operation_kind: TradeWorkflowKind::RevisionProposal.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
)
@@ -1502,11 +1607,14 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_revision_proposal_with_explicit_signer(
&self,
actor: &RadrootsActorContext,
- plan: OrderRevisionProposalPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeRevisionProposalPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderRevisionProposalReceipt, RadrootsSdkError> {
+ ) -> Result<TradeRevisionProposalReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1516,10 +1624,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::RevisionProposal.operation_kind(),
+ operation_kind: TradeWorkflowKind::RevisionProposal.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
signer,
@@ -1530,8 +1638,8 @@ impl<'sdk> TradesClient<'sdk> {
pub fn prepare_revision_decision(
&self,
- request: OrderRevisionDecisionPrepareRequest,
- ) -> Result<OrderRevisionDecisionPlan, RadrootsSdkError> {
+ request: TradeRevisionDecisionPrepareRequest,
+ ) -> Result<TradeRevisionDecisionPlan, RadrootsSdkError> {
let created_at = self.resolved_created_at(request.created_at)?;
order_revision_decision_plan(
&request.actor,
@@ -1545,18 +1653,21 @@ impl<'sdk> TradesClient<'sdk> {
#[cfg(feature = "signer-adapters")]
pub async fn enqueue_revision_decision(
&self,
- request: OrderRevisionDecisionEnqueueRequest,
- ) -> Result<OrderRevisionDecisionReceipt, RadrootsSdkError> {
- let OrderRevisionDecisionEnqueueRequest {
+ request: TradeRevisionDecisionEnqueueRequest,
+ ) -> Result<TradeRevisionDecisionReceipt, RadrootsSdkError> {
+ let TradeRevisionDecisionEnqueueRequest {
actor,
root_event,
previous_event,
decision,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderRevisionDecisionPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeRevisionDecisionPrepareRequest {
actor: actor.clone(),
root_event,
previous_event,
@@ -1564,25 +1675,35 @@ impl<'sdk> TradesClient<'sdk> {
created_at,
};
let plan = self.prepare_revision_decision(prepare_request)?;
- self.enqueue_prepared_revision_decision(&actor, plan, target_relays, idempotency_key)
- .await
+ self.enqueue_prepared_revision_decision(
+ &actor,
+ plan,
+ target_relays,
+ publish_mode,
+ ack_policy,
+ idempotency_key,
+ )
+ .await
}
pub async fn enqueue_revision_decision_with_explicit_signer(
&self,
- request: OrderRevisionDecisionEnqueueRequest,
+ request: TradeRevisionDecisionEnqueueRequest,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderRevisionDecisionReceipt, RadrootsSdkError> {
- let OrderRevisionDecisionEnqueueRequest {
+ ) -> Result<TradeRevisionDecisionReceipt, RadrootsSdkError> {
+ let TradeRevisionDecisionEnqueueRequest {
actor,
root_event,
previous_event,
decision,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderRevisionDecisionPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeRevisionDecisionPrepareRequest {
actor: actor.clone(),
root_event,
previous_event,
@@ -1594,6 +1715,8 @@ impl<'sdk> TradesClient<'sdk> {
&actor,
plan,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
signer,
)
@@ -1604,10 +1727,13 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_revision_decision(
&self,
actor: &RadrootsActorContext,
- plan: OrderRevisionDecisionPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeRevisionDecisionPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
- ) -> Result<OrderRevisionDecisionReceipt, RadrootsSdkError> {
+ ) -> Result<TradeRevisionDecisionReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1617,10 +1743,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_configured_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::RevisionDecision.operation_kind(),
+ operation_kind: TradeWorkflowKind::RevisionDecision.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
)
@@ -1631,11 +1757,14 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_revision_decision_with_explicit_signer(
&self,
actor: &RadrootsActorContext,
- plan: OrderRevisionDecisionPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeRevisionDecisionPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderRevisionDecisionReceipt, RadrootsSdkError> {
+ ) -> Result<TradeRevisionDecisionReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1645,10 +1774,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::RevisionDecision.operation_kind(),
+ operation_kind: TradeWorkflowKind::RevisionDecision.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
signer,
@@ -1659,8 +1788,8 @@ impl<'sdk> TradesClient<'sdk> {
pub fn prepare_cancellation(
&self,
- request: OrderCancellationPrepareRequest,
- ) -> Result<OrderCancellationPlan, RadrootsSdkError> {
+ request: TradeCancellationPrepareRequest,
+ ) -> Result<TradeCancellationPlan, RadrootsSdkError> {
let created_at = self.resolved_created_at(request.created_at)?;
order_cancellation_plan(
&request.actor,
@@ -1674,18 +1803,21 @@ impl<'sdk> TradesClient<'sdk> {
#[cfg(feature = "signer-adapters")]
pub async fn enqueue_cancellation(
&self,
- request: OrderCancellationEnqueueRequest,
- ) -> Result<OrderCancellationReceipt, RadrootsSdkError> {
- let OrderCancellationEnqueueRequest {
+ request: TradeCancellationEnqueueRequest,
+ ) -> Result<TradeCancellationReceipt, RadrootsSdkError> {
+ let TradeCancellationEnqueueRequest {
actor,
root_event,
previous_event,
cancellation,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderCancellationPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeCancellationPrepareRequest {
actor: actor.clone(),
root_event,
previous_event,
@@ -1693,25 +1825,35 @@ impl<'sdk> TradesClient<'sdk> {
created_at,
};
let plan = self.prepare_cancellation(prepare_request)?;
- self.enqueue_prepared_cancellation(&actor, plan, target_relays, idempotency_key)
- .await
+ self.enqueue_prepared_cancellation(
+ &actor,
+ plan,
+ target_relays,
+ publish_mode,
+ ack_policy,
+ idempotency_key,
+ )
+ .await
}
pub async fn enqueue_cancellation_with_explicit_signer(
&self,
- request: OrderCancellationEnqueueRequest,
+ request: TradeCancellationEnqueueRequest,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderCancellationReceipt, RadrootsSdkError> {
- let OrderCancellationEnqueueRequest {
+ ) -> Result<TradeCancellationReceipt, RadrootsSdkError> {
+ let TradeCancellationEnqueueRequest {
actor,
root_event,
previous_event,
cancellation,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
created_at,
} = request;
- let prepare_request = OrderCancellationPrepareRequest {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
+ let prepare_request = TradeCancellationPrepareRequest {
actor: actor.clone(),
root_event,
previous_event,
@@ -1723,6 +1865,8 @@ impl<'sdk> TradesClient<'sdk> {
&actor,
plan,
target_relays,
+ publish_mode,
+ ack_policy,
idempotency_key,
signer,
)
@@ -1733,10 +1877,13 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_cancellation(
&self,
actor: &RadrootsActorContext,
- plan: OrderCancellationPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeCancellationPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
- ) -> Result<OrderCancellationReceipt, RadrootsSdkError> {
+ ) -> Result<TradeCancellationReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1746,10 +1893,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_configured_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::Cancellation.operation_kind(),
+ operation_kind: TradeWorkflowKind::Cancellation.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
)
@@ -1760,11 +1907,14 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn enqueue_prepared_cancellation_with_explicit_signer(
&self,
actor: &RadrootsActorContext,
- plan: OrderCancellationPlan,
- target_relays: SdkRelayTargetPolicy,
+ plan: TradeCancellationPlan,
+ target_relays: RelayResolutionPolicy,
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
idempotency_key: Option<SdkIdempotencyKey>,
signer: &dyn RadrootsEventSigner,
- ) -> Result<OrderCancellationReceipt, RadrootsSdkError> {
+ ) -> Result<TradeCancellationReceipt, RadrootsSdkError> {
+ validate_trade_enqueue_policy(publish_mode, ack_policy)?;
if !self
.prepared_order_event_exists(&plan.expected_event_id)
.await?
@@ -1774,10 +1924,10 @@ impl<'sdk> TradesClient<'sdk> {
let enqueue = enqueue_signed_workflow(
self.sdk,
SdkWorkflowEnqueueRequest {
- operation_kind: OrderWorkflowKind::Cancellation.operation_kind(),
+ operation_kind: TradeWorkflowKind::Cancellation.operation_kind(),
actor,
frozen_draft: &plan.frozen_draft,
- target_relays,
+ target_relays: target_relays.workflow_target_policy(),
idempotency_key,
},
signer,
@@ -1788,17 +1938,20 @@ impl<'sdk> TradesClient<'sdk> {
pub async fn status(
&self,
- request: OrderStatusRequest,
- ) -> Result<OrderStatusReceipt, RadrootsSdkError> {
+ request: TradeStatusRequest,
+ ) -> Result<TradeStatusReceipt, RadrootsSdkError> {
request.validate()?;
- let query_result = order_projection_query_for_order_id(
+ let query_result = order_projection_query_for_trade_locator(
&self.sdk._event_store,
- &request.order_id,
+ &request.locator,
request.limit,
)
.await
.map_err(projection_error)?;
- Ok(OrderStatusReceipt::from_query_result(query_result))
+ Ok(TradeStatusReceipt::from_locator_query_result(
+ request.locator,
+ query_result,
+ ))
}
fn resolved_created_at(
@@ -1813,7 +1966,7 @@ impl<'sdk> TradesClient<'sdk> {
async fn require_decision_preflight(
&self,
- plan: &OrderDecisionPlan,
+ plan: &TradeDecisionPlan,
) -> Result<(), RadrootsSdkError> {
let query_result = self.query_order_projection(&plan.order_id).await?;
require_decision_request_evidence(plan, &query_result.projection)
@@ -1821,7 +1974,7 @@ impl<'sdk> TradesClient<'sdk> {
async fn require_revision_proposal_preflight(
&self,
- plan: &OrderRevisionProposalPlan,
+ plan: &TradeRevisionProposalPlan,
) -> Result<(), RadrootsSdkError> {
let query_result = self.query_order_projection(&plan.order_id).await?;
require_revision_proposal_state(plan, &query_result.projection)
@@ -1829,7 +1982,7 @@ impl<'sdk> TradesClient<'sdk> {
async fn require_revision_decision_preflight(
&self,
- plan: &OrderRevisionDecisionPlan,
+ plan: &TradeRevisionDecisionPlan,
) -> Result<(), RadrootsSdkError> {
let query_result = self.query_order_projection(&plan.order_id).await?;
require_revision_decision_state(plan, &query_result.projection)
@@ -1837,7 +1990,7 @@ impl<'sdk> TradesClient<'sdk> {
async fn require_cancellation_preflight(
&self,
- plan: &OrderCancellationPlan,
+ plan: &TradeCancellationPlan,
) -> Result<(), RadrootsSdkError> {
let query_result = self.query_order_projection(&plan.order_id).await?;
require_cancellation_state(plan, &query_result.projection)
@@ -1850,7 +2003,7 @@ impl<'sdk> TradesClient<'sdk> {
order_projection_query_for_order_id(
&self.sdk._event_store,
order_id,
- ORDER_STATUS_MAX_LIMIT,
+ TRADE_STATUS_MAX_LIMIT,
)
.await
.map_err(projection_error)
@@ -1872,6 +2025,31 @@ impl<'sdk> TradesClient<'sdk> {
}
#[cfg(feature = "runtime")]
+fn validate_trade_enqueue_policy(
+ publish_mode: PublishMode,
+ ack_policy: AckPolicy,
+) -> Result<(), RadrootsSdkError> {
+ if publish_mode == PublishMode::DryRun {
+ return Err(RadrootsSdkError::InvalidRequest {
+ message: "trade dry-run publish mode must use a prepare request".to_owned(),
+ });
+ }
+ if publish_mode == PublishMode::EnqueueOnly && ack_policy != AckPolicy::NoWait {
+ return Err(RadrootsSdkError::InvalidRequest {
+ message: "trade enqueue-only publish mode only supports no-wait acknowledgement"
+ .to_owned(),
+ });
+ }
+ if publish_mode == PublishMode::EnqueueAndPublish {
+ return Err(RadrootsSdkError::InvalidRequest {
+ message: "trade enqueue-and-publish mode requires publish receipt orchestration"
+ .to_owned(),
+ });
+ }
+ Ok(())
+}
+
+#[cfg(feature = "runtime")]
struct ParsedOrderEvidence {
order_id: RadrootsOrderId,
listing_addr: RadrootsListingAddress,
@@ -1945,23 +2123,65 @@ fn order_evidence_parse_error(
}
#[cfg(feature = "runtime")]
-impl OrderStatusReceipt {
- fn from_query_result(query_result: RadrootsOrderProjectionQueryResult) -> Self {
- let projection = query_result.projection;
+impl TradeStatusReceipt {
+ fn from_locator_query_result(
+ locator: RadrootsTradeLocator,
+ query_result: RadrootsTradeLocatorProjectionQueryResult,
+ ) -> Self {
+ match query_result.resolution {
+ RadrootsTradeLocatorProjectionResolution::Projected {
+ locator,
+ projection,
+ } => Self::from_projection(
+ locator.clone(),
+ locator.root_event_id,
+ Vec::new(),
+ projection,
+ query_result.event_count,
+ query_result.limit_applied,
+ query_result.event_ids,
+ ),
+ RadrootsTradeLocatorProjectionResolution::Ambiguous { candidates, .. } => {
+ Self::ambiguous(
+ locator,
+ candidates,
+ query_result.event_count,
+ query_result.limit_applied,
+ query_result.event_ids,
+ )
+ }
+ RadrootsTradeLocatorProjectionResolution::Missing { .. } => Self::missing(
+ locator,
+ query_result.event_count,
+ query_result.limit_applied,
+ query_result.event_ids,
+ ),
+ }
+ }
+
+ fn from_projection(
+ locator: RadrootsTradeLocator,
+ root_event_id: Option<RadrootsEventId>,
+ ambiguity_candidates: Vec<TradeStatusAmbiguityCandidate>,
+ projection: RadrootsOrderProjection,
+ event_count: usize,
+ limit_applied: u32,
+ event_ids: Vec<RadrootsEventId>,
+ ) -> Self {
let found = projection.status != RadrootsTradeWorkflowState::Missing;
- let evidence = OrderStatusEvidenceSummary::from_projection(
- &projection,
- query_result.event_count,
- query_result.limit_applied,
- );
- let eligibility = OrderStatusEligibility::from_projection(&projection);
- let next_action = OrderStatusNextActionKind::from_projection(&projection, &eligibility);
+ let evidence =
+ TradeStatusEvidenceSummary::from_projection(&projection, event_count, limit_applied);
+ let eligibility = TradeStatusEligibility::from_projection(&projection);
+ let next_action = TradeStatusNextActionKind::from_projection(&projection, &eligibility);
Self {
+ locator,
order_id: projection.order_id,
- source: SdkOrderStatusSource::LocalEventStore,
+ root_event_id,
+ ambiguity_candidates,
+ source: SdkTradeStatusSource::LocalEventStore,
found,
- event_count: query_result.event_count,
- limit_applied: query_result.limit_applied,
+ event_count,
+ limit_applied,
status: projection.status.into(),
lifecycle_terminal: projection.lifecycle_terminal,
listing_addr: projection.listing_addr,
@@ -1971,7 +2191,7 @@ impl OrderStatusReceipt {
evidence,
eligibility,
next_action,
- event_ids: query_result.event_ids,
+ event_ids,
request_event_id: projection.request_event_id,
decision_event_id: projection.decision_event_id,
agreement_event_id: projection.agreement_event_id,
@@ -1982,10 +2202,65 @@ impl OrderStatusReceipt {
issues: projection.issues.into_iter().map(Into::into).collect(),
}
}
+
+ fn missing(
+ locator: RadrootsTradeLocator,
+ event_count: usize,
+ limit_applied: u32,
+ event_ids: Vec<RadrootsEventId>,
+ ) -> Self {
+ Self::from_projection(
+ locator.clone(),
+ locator.root_event_id.clone(),
+ Vec::new(),
+ RadrootsOrderProjection {
+ order_id: locator.order_id().clone(),
+ status: RadrootsTradeWorkflowState::Missing,
+ request_event_id: None,
+ decision_event_id: None,
+ cancellation_event_id: None,
+ validation_receipt_event_id: None,
+ lifecycle_terminal: false,
+ economics: None,
+ agreement_event_id: None,
+ pending_revision_event_id: None,
+ pending_inventory_reservations: Vec::new(),
+ committed_inventory_reservations: Vec::new(),
+ listing_addr: locator.listing_addr.clone(),
+ buyer_pubkey: locator.buyer_pubkey.clone(),
+ seller_pubkey: locator.seller_pubkey.clone(),
+ last_event_id: None,
+ issues: Vec::new(),
+ },
+ event_count,
+ limit_applied,
+ event_ids,
+ )
+ }
+
+ fn ambiguous(
+ locator: RadrootsTradeLocator,
+ candidates: Vec<RadrootsTradeLocatorCandidate>,
+ event_count: usize,
+ limit_applied: u32,
+ event_ids: Vec<RadrootsEventId>,
+ ) -> Self {
+ let ambiguity_candidates = candidates
+ .into_iter()
+ .map(|candidate| TradeStatusAmbiguityCandidate {
+ locator: candidate.locator(),
+ })
+ .collect::<Vec<_>>();
+ let mut receipt = Self::missing(locator, event_count, limit_applied, event_ids);
+ receipt.status = TradeStatusKind::Ambiguous;
+ receipt.next_action = TradeStatusNextActionKind::InspectEvidenceIssues;
+ receipt.ambiguity_candidates = ambiguity_candidates;
+ receipt
+ }
}
#[cfg(feature = "runtime")]
-impl OrderStatusEvidenceSummary {
+impl TradeStatusEvidenceSummary {
fn from_projection(
projection: &RadrootsOrderProjection,
event_count: usize,
@@ -2005,7 +2280,7 @@ impl OrderStatusEvidenceSummary {
}
#[cfg(feature = "runtime")]
-impl OrderStatusEligibility {
+impl TradeStatusEligibility {
fn from_projection(projection: &RadrootsOrderProjection) -> Self {
let clean = projection.issues.is_empty();
let open = clean && !projection.lifecycle_terminal;
@@ -2026,10 +2301,10 @@ impl OrderStatusEligibility {
}
#[cfg(feature = "runtime")]
-impl OrderStatusNextActionKind {
+impl TradeStatusNextActionKind {
fn from_projection(
projection: &RadrootsOrderProjection,
- eligibility: &OrderStatusEligibility,
+ eligibility: &TradeStatusEligibility,
) -> Self {
if projection.status == RadrootsTradeWorkflowState::Missing {
return Self::NoLocalOrder;
@@ -2060,8 +2335,8 @@ fn order_submit_plan(
listing_event: RadrootsNostrEventPtr,
order_request: RadrootsOrderRequest,
created_at: RadrootsSdkTimestamp,
-) -> Result<OrderSubmitPlan, RadrootsSdkError> {
- require_buyer_actor(actor, "order.prepare_submit")?;
+) -> Result<TradeSubmitPlan, RadrootsSdkError> {
+ require_buyer_actor(actor, "trade.prepare_submit")?;
let listing_event_id = listing_event_id(&listing_event)?;
let order_request =
canonicalize_order_request_for_signer(order_request, actor.pubkey().as_str())
@@ -2077,16 +2352,16 @@ fn order_submit_plan(
})?;
let frozen_draft = to_frozen_draft(
draft.into_wire_parts(),
- ORDER_REQUEST_CONTRACT_ID,
+ TRADE_SUBMIT_CONTRACT_ID,
order_request.buyer_pubkey.as_str(),
created_at_nostr,
)
.expect("validated order submit draft freezes");
let expected_event_id = RadrootsEventId::parse(frozen_draft.expected_event_id.as_str())
.expect("frozen order submit draft produces a valid event id");
- Ok(OrderSubmitPlan {
+ Ok(TradeSubmitPlan {
workflow: order_workflow_plan(
- OrderWorkflowKind::Submit,
+ TradeWorkflowKind::Submit,
expected_event_id.clone(),
created_at,
),
@@ -2105,12 +2380,12 @@ fn order_decision_plan(
request_event: RadrootsNostrEventPtr,
decision: RadrootsOrderDecision,
created_at: RadrootsSdkTimestamp,
-) -> Result<OrderDecisionPlan, RadrootsSdkError> {
- require_seller_actor(actor, "order.prepare_decision")?;
+) -> Result<TradeDecisionPlan, RadrootsSdkError> {
+ require_seller_actor(actor, "trade.prepare_decision")?;
let request_event_id = request_event_id(&request_event)?;
if decision.seller_pubkey.as_str() != actor.pubkey().as_str() {
return Err(RadrootsSdkError::UnauthorizedActor {
- operation: "order.prepare_decision".to_owned(),
+ operation: "trade.prepare_decision".to_owned(),
reason: "actor pubkey must match order seller_pubkey".to_owned(),
});
}
@@ -2127,16 +2402,16 @@ fn order_decision_plan(
.expect("validated order decision draft encodes");
let frozen_draft = to_frozen_draft(
draft.into_wire_parts(),
- ORDER_DECISION_CONTRACT_ID,
+ TRADE_DECISION_CONTRACT_ID,
decision.seller_pubkey.as_str(),
created_at_nostr,
)
.expect("validated order decision draft freezes");
let expected_event_id = RadrootsEventId::parse(frozen_draft.expected_event_id.as_str())
.expect("frozen order decision draft produces a valid event id");
- Ok(OrderDecisionPlan {
+ Ok(TradeDecisionPlan {
workflow: order_workflow_plan(
- OrderWorkflowKind::Decision,
+ TradeWorkflowKind::Decision,
expected_event_id.clone(),
created_at,
),
@@ -2158,13 +2433,13 @@ fn order_revision_proposal_plan(
previous_event: RadrootsNostrEventPtr,
proposal: RadrootsOrderRevisionProposal,
created_at: RadrootsSdkTimestamp,
-) -> Result<OrderRevisionProposalPlan, RadrootsSdkError> {
- require_seller_actor(actor, "order.prepare_revision_proposal")?;
+) -> Result<TradeRevisionProposalPlan, RadrootsSdkError> {
+ require_seller_actor(actor, "trade.prepare_revision_proposal")?;
let root_event_id = order_reference_event_id(&root_event, "root")?;
let previous_event_id = order_reference_event_id(&previous_event, "previous")?;
if proposal.seller_pubkey.as_str() != actor.pubkey().as_str() {
return Err(RadrootsSdkError::UnauthorizedActor {
- operation: "order.prepare_revision_proposal".to_owned(),
+ operation: "trade.prepare_revision_proposal".to_owned(),
reason: "actor pubkey must match order seller_pubkey".to_owned(),
});
}
@@ -2186,14 +2461,14 @@ fn order_revision_proposal_plan(
.expect("validated order revision proposal draft encodes");
let (frozen_draft, expected_event_id) = freeze_order_workflow_draft(
draft.into_wire_parts(),
- ORDER_REVISION_PROPOSAL_CONTRACT_ID,
+ TRADE_REVISION_PROPOSAL_CONTRACT_ID,
seller_pubkey.as_str(),
created_at_nostr,
"order revision proposal",
);
- Ok(OrderRevisionProposalPlan {
+ Ok(TradeRevisionProposalPlan {
workflow: order_workflow_plan(
- OrderWorkflowKind::RevisionProposal,
+ TradeWorkflowKind::RevisionProposal,
expected_event_id.clone(),
created_at,
),
@@ -2216,13 +2491,13 @@ fn order_revision_decision_plan(
previous_event: RadrootsNostrEventPtr,
decision: RadrootsOrderRevisionDecision,
created_at: RadrootsSdkTimestamp,
-) -> Result<OrderRevisionDecisionPlan, RadrootsSdkError> {
- require_buyer_actor(actor, "order.prepare_revision_decision")?;
+) -> Result<TradeRevisionDecisionPlan, RadrootsSdkError> {
+ require_buyer_actor(actor, "trade.prepare_revision_decision")?;
let root_event_id = order_reference_event_id(&root_event, "root")?;
let previous_event_id = order_reference_event_id(&previous_event, "previous")?;
if decision.buyer_pubkey.as_str() != actor.pubkey().as_str() {
return Err(RadrootsSdkError::UnauthorizedActor {
- operation: "order.prepare_revision_decision".to_owned(),
+ operation: "trade.prepare_revision_decision".to_owned(),
reason: "actor pubkey must match order buyer_pubkey".to_owned(),
});
}
@@ -2244,14 +2519,14 @@ fn order_revision_decision_plan(
.expect("validated order revision decision draft encodes");
let (frozen_draft, expected_event_id) = freeze_order_workflow_draft(
draft.into_wire_parts(),
- ORDER_REVISION_DECISION_CONTRACT_ID,
+ TRADE_REVISION_DECISION_CONTRACT_ID,
buyer_pubkey.as_str(),
created_at_nostr,
"order revision decision",
);
- Ok(OrderRevisionDecisionPlan {
+ Ok(TradeRevisionDecisionPlan {
workflow: order_workflow_plan(
- OrderWorkflowKind::RevisionDecision,
+ TradeWorkflowKind::RevisionDecision,
expected_event_id.clone(),
created_at,
),
@@ -2274,13 +2549,13 @@ fn order_cancellation_plan(
previous_event: RadrootsNostrEventPtr,
cancellation: RadrootsOrderCancellation,
created_at: RadrootsSdkTimestamp,
-) -> Result<OrderCancellationPlan, RadrootsSdkError> {
- require_buyer_actor(actor, "order.prepare_cancellation")?;
+) -> Result<TradeCancellationPlan, RadrootsSdkError> {
+ require_buyer_actor(actor, "trade.prepare_cancellation")?;
let root_event_id = order_reference_event_id(&root_event, "root")?;
let previous_event_id = order_reference_event_id(&previous_event, "previous")?;
if cancellation.buyer_pubkey.as_str() != actor.pubkey().as_str() {
return Err(RadrootsSdkError::UnauthorizedActor {
- operation: "order.prepare_cancellation".to_owned(),
+ operation: "trade.prepare_cancellation".to_owned(),
reason: "actor pubkey must match order buyer_pubkey".to_owned(),
});
}
@@ -2295,14 +2570,14 @@ fn order_cancellation_plan(
.expect("validated order cancellation draft encodes");
let (frozen_draft, expected_event_id) = freeze_order_workflow_draft(
draft.into_wire_parts(),
- ORDER_CANCELLATION_CONTRACT_ID,
+ TRADE_CANCELLATION_CONTRACT_ID,
buyer_pubkey.as_str(),
created_at_nostr,
"order cancellation",
);
- Ok(OrderCancellationPlan {
+ Ok(TradeCancellationPlan {
workflow: order_workflow_plan(
- OrderWorkflowKind::Cancellation,
+ TradeWorkflowKind::Cancellation,
expected_event_id.clone(),
created_at,
),
@@ -2320,11 +2595,11 @@ fn order_cancellation_plan(
#[cfg(feature = "runtime")]
fn order_workflow_plan(
- kind: OrderWorkflowKind,
+ kind: TradeWorkflowKind,
expected_event_id: RadrootsEventId,
created_at: RadrootsSdkTimestamp,
-) -> OrderWorkflowPlan {
- OrderWorkflowPlan {
+) -> TradeWorkflowPlan {
+ TradeWorkflowPlan {
kind,
operation_kind: kind.operation_kind(),
contract_id: kind.contract_id(),
@@ -2335,12 +2610,12 @@ fn order_workflow_plan(
#[cfg(feature = "runtime")]
fn order_submit_receipt(
- plan: OrderSubmitPlan,
+ plan: TradeSubmitPlan,
enqueue: crate::workflow_runtime::SdkWorkflowEnqueueReceipt,
-) -> OrderSubmitReceipt {
- OrderSubmitReceipt {
+) -> TradeSubmitReceipt {
+ TradeSubmitReceipt {
workflow: order_workflow_enqueue_receipt(
- OrderWorkflowKind::Submit,
+ TradeWorkflowKind::Submit,
plan.expected_event_id.clone(),
&enqueue,
),
@@ -2359,12 +2634,12 @@ fn order_submit_receipt(
#[cfg(feature = "runtime")]
fn order_decision_receipt(
- plan: OrderDecisionPlan,
+ plan: TradeDecisionPlan,
enqueue: crate::workflow_runtime::SdkWorkflowEnqueueReceipt,
-) -> OrderDecisionReceipt {
- OrderDecisionReceipt {
+) -> TradeDecisionReceipt {
+ TradeDecisionReceipt {
workflow: order_workflow_enqueue_receipt(
- OrderWorkflowKind::Decision,
+ TradeWorkflowKind::Decision,
plan.expected_event_id.clone(),
&enqueue,
),
@@ -2385,12 +2660,12 @@ fn order_decision_receipt(
#[cfg(feature = "runtime")]
fn order_revision_proposal_receipt(
- plan: OrderRevisionProposalPlan,
+ plan: TradeRevisionProposalPlan,
enqueue: crate::workflow_runtime::SdkWorkflowEnqueueReceipt,
-) -> OrderRevisionProposalReceipt {
- OrderRevisionProposalReceipt {
+) -> TradeRevisionProposalReceipt {
+ TradeRevisionProposalReceipt {
workflow: order_workflow_enqueue_receipt(
- OrderWorkflowKind::RevisionProposal,
+ TradeWorkflowKind::RevisionProposal,
plan.expected_event_id.clone(),
&enqueue,
),
@@ -2412,12 +2687,12 @@ fn order_revision_proposal_receipt(
#[cfg(feature = "runtime")]
fn order_revision_decision_receipt(
- plan: OrderRevisionDecisionPlan,
+ plan: TradeRevisionDecisionPlan,
enqueue: crate::workflow_runtime::SdkWorkflowEnqueueReceipt,
-) -> OrderRevisionDecisionReceipt {
- OrderRevisionDecisionReceipt {
+) -> TradeRevisionDecisionReceipt {
+ TradeRevisionDecisionReceipt {
workflow: order_workflow_enqueue_receipt(
- OrderWorkflowKind::RevisionDecision,
+ TradeWorkflowKind::RevisionDecision,
plan.expected_event_id.clone(),
&enqueue,
),
@@ -2439,12 +2714,12 @@ fn order_revision_decision_receipt(
#[cfg(feature = "runtime")]
fn order_cancellation_receipt(
- plan: OrderCancellationPlan,
+ plan: TradeCancellationPlan,
enqueue: crate::workflow_runtime::SdkWorkflowEnqueueReceipt,
-) -> OrderCancellationReceipt {
- OrderCancellationReceipt {
+) -> TradeCancellationReceipt {
+ TradeCancellationReceipt {
workflow: order_workflow_enqueue_receipt(
- OrderWorkflowKind::Cancellation,
+ TradeWorkflowKind::Cancellation,
plan.expected_event_id.clone(),
&enqueue,
),
@@ -2466,15 +2741,15 @@ fn order_cancellation_receipt(
#[cfg(feature = "runtime")]
fn order_workflow_enqueue_receipt(
- kind: OrderWorkflowKind,
+ kind: TradeWorkflowKind,
expected_event_id: RadrootsEventId,
enqueue: &crate::workflow_runtime::SdkWorkflowEnqueueReceipt,
-) -> OrderWorkflowEnqueueReceipt {
+) -> TradeWorkflowEnqueueReceipt {
let state = SdkMutationState::from(enqueue.state);
let digest_prefix = Some(enqueue.idempotency_digest_prefix.clone());
let safe_retry_same_key = true;
let replayed_existing_operation = state == SdkMutationState::AlreadyQueued;
- OrderWorkflowEnqueueReceipt {
+ TradeWorkflowEnqueueReceipt {
kind,
operation_kind: kind.operation_kind(),
expected_event_id,
@@ -2484,12 +2759,12 @@ fn order_workflow_enqueue_receipt(
outbox_event_id: enqueue.outbox_event_id,
state,
idempotency_digest_prefix: digest_prefix.clone(),
- idempotency: OrderWorkflowIdempotencyReceipt {
+ idempotency: TradeWorkflowIdempotencyReceipt {
digest_prefix,
replayed_existing_operation,
safe_to_retry_with_same_idempotency_key: safe_retry_same_key,
},
- retry: OrderWorkflowRetryAdvice {
+ retry: TradeWorkflowRetryAdvice {
retryable_after_error: false,
safe_to_retry_enqueue_with_same_idempotency_key: safe_retry_same_key,
recovery_actions: Vec::new(),
@@ -2568,7 +2843,7 @@ impl OrderPayloadValidate for RadrootsOrderCancellation {
}
#[cfg(feature = "runtime")]
-struct OrderRequestEvidence {
+struct TradeRequestEvidence {
order_id: RadrootsOrderId,
listing_addr: RadrootsListingAddress,
buyer_pubkey: RadrootsPublicKey,
@@ -2579,7 +2854,7 @@ struct OrderRequestEvidence {
#[cfg(feature = "runtime")]
fn parse_order_request_evidence(
event: &RadrootsNostrEvent,
-) -> Result<OrderRequestEvidence, RadrootsSdkError> {
+) -> Result<TradeRequestEvidence, RadrootsSdkError> {
let request_event_id = RadrootsEventId::parse(event.id.as_str()).map_err(|error| {
RadrootsSdkError::InvalidRequest {
message: format!("order request evidence event id is invalid: {error}"),
@@ -2590,7 +2865,7 @@ fn parse_order_request_evidence(
message: format!("order request evidence decode failed: {error}"),
})?;
let payload = envelope.payload;
- Ok(OrderRequestEvidence {
+ Ok(TradeRequestEvidence {
order_id: payload.order_id,
listing_addr: payload.listing_addr,
buyer_pubkey: payload.buyer_pubkey,
@@ -2610,7 +2885,7 @@ fn sdk_timestamp_ms(timestamp: RadrootsSdkTimestamp) -> Result<i64, RadrootsSdkE
#[cfg(feature = "runtime")]
fn require_decision_request_evidence(
- plan: &OrderDecisionPlan,
+ plan: &TradeDecisionPlan,
projection: &RadrootsOrderProjection,
) -> Result<(), RadrootsSdkError> {
let Some(request_event_id) = &projection.request_event_id else {
@@ -2692,7 +2967,7 @@ struct OrderLifecycleReferences<'a> {
#[cfg(feature = "runtime")]
fn require_revision_proposal_state(
- plan: &OrderRevisionProposalPlan,
+ plan: &TradeRevisionProposalPlan,
projection: &RadrootsOrderProjection,
) -> Result<(), RadrootsSdkError> {
let refs = OrderLifecycleReferences {
@@ -2713,7 +2988,7 @@ fn require_revision_proposal_state(
#[cfg(feature = "runtime")]
fn require_revision_decision_state(
- plan: &OrderRevisionDecisionPlan,
+ plan: &TradeRevisionDecisionPlan,
projection: &RadrootsOrderProjection,
) -> Result<(), RadrootsSdkError> {
let refs = OrderLifecycleReferences {
@@ -2738,7 +3013,7 @@ fn require_revision_decision_state(
#[cfg(feature = "runtime")]
fn require_cancellation_state(
- plan: &OrderCancellationPlan,
+ plan: &TradeCancellationPlan,
projection: &RadrootsOrderProjection,
) -> Result<(), RadrootsSdkError> {
let refs = OrderLifecycleReferences {
@@ -3052,7 +3327,7 @@ fn order_canonicalization_error(error: RadrootsOrderCanonicalizationError) -> Ra
match error {
RadrootsOrderCanonicalizationError::InvalidBuyerSigner => {
RadrootsSdkError::UnauthorizedActor {
- operation: "order.prepare_submit".to_owned(),
+ operation: "trade.prepare_submit".to_owned(),
reason: "actor pubkey must match order buyer_pubkey".to_owned(),
}
}
@@ -3072,7 +3347,7 @@ fn order_decision_canonicalization_error(
}
#[cfg(feature = "runtime")]
-impl From<RadrootsTradeWorkflowState> for OrderStatusKind {
+impl From<RadrootsTradeWorkflowState> for TradeStatusKind {
fn from(status: RadrootsTradeWorkflowState) -> Self {
match status {
RadrootsTradeWorkflowState::Missing => Self::Missing,
@@ -3088,250 +3363,250 @@ impl From<RadrootsTradeWorkflowState> for OrderStatusKind {
}
#[cfg(feature = "runtime")]
-impl From<RadrootsOrderIssue> for SdkOrderStatusIssue {
+impl From<RadrootsOrderIssue> for SdkTradeStatusIssue {
fn from(issue: RadrootsOrderIssue) -> Self {
match issue {
RadrootsOrderIssue::MissingRequest => {
- Self::new(SdkOrderStatusIssueKind::MissingRequest, Vec::new())
+ Self::new(SdkTradeStatusIssueKind::MissingRequest, Vec::new())
}
RadrootsOrderIssue::MultipleRequests { event_ids } => {
- Self::new(SdkOrderStatusIssueKind::MultipleRequests, event_ids)
+ Self::new(SdkTradeStatusIssueKind::MultipleRequests, event_ids)
}
RadrootsOrderIssue::RequestPayloadInvalid { event_id } => {
- Self::single(SdkOrderStatusIssueKind::RequestPayloadInvalid, event_id)
+ Self::single(SdkTradeStatusIssueKind::RequestPayloadInvalid, event_id)
}
RadrootsOrderIssue::RequestOrderIdMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::RequestOrderIdMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::RequestOrderIdMismatch, event_id)
}
RadrootsOrderIssue::RequestAuthorMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::RequestAuthorMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::RequestAuthorMismatch, event_id)
}
RadrootsOrderIssue::RequestListingAddressInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::RequestListingAddressInvalid,
+ SdkTradeStatusIssueKind::RequestListingAddressInvalid,
event_id,
),
RadrootsOrderIssue::RequestSellerListingMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RequestSellerListingMismatch,
+ SdkTradeStatusIssueKind::RequestSellerListingMismatch,
event_id,
),
RadrootsOrderIssue::DecisionPayloadInvalid { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionPayloadInvalid, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionPayloadInvalid, event_id)
}
RadrootsOrderIssue::DecisionOrderIdMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionOrderIdMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionOrderIdMismatch, event_id)
}
RadrootsOrderIssue::DecisionAuthorMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionAuthorMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionAuthorMismatch, event_id)
}
RadrootsOrderIssue::DecisionCounterpartyMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::DecisionCounterpartyMismatch,
+ SdkTradeStatusIssueKind::DecisionCounterpartyMismatch,
event_id,
),
RadrootsOrderIssue::DecisionBuyerMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionBuyerMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionBuyerMismatch, event_id)
}
RadrootsOrderIssue::DecisionSellerMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionSellerMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionSellerMismatch, event_id)
}
RadrootsOrderIssue::DecisionListingAddressInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::DecisionListingAddressInvalid,
+ SdkTradeStatusIssueKind::DecisionListingAddressInvalid,
event_id,
),
RadrootsOrderIssue::DecisionListingMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionListingMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionListingMismatch, event_id)
}
RadrootsOrderIssue::DecisionRootMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionRootMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionRootMismatch, event_id)
}
RadrootsOrderIssue::DecisionPreviousMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionPreviousMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionPreviousMismatch, event_id)
}
RadrootsOrderIssue::DecisionMissingInventoryCommitments { event_id } => Self::single(
- SdkOrderStatusIssueKind::DecisionMissingInventoryCommitments,
+ SdkTradeStatusIssueKind::DecisionMissingInventoryCommitments,
event_id,
),
RadrootsOrderIssue::DecisionInventoryCommitmentMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::DecisionInventoryCommitmentMismatch,
+ SdkTradeStatusIssueKind::DecisionInventoryCommitmentMismatch,
event_id,
),
RadrootsOrderIssue::DecisionMissingReason { event_id } => {
- Self::single(SdkOrderStatusIssueKind::DecisionMissingReason, event_id)
+ Self::single(SdkTradeStatusIssueKind::DecisionMissingReason, event_id)
}
RadrootsOrderIssue::ConflictingDecisions { event_ids } => {
- Self::new(SdkOrderStatusIssueKind::ConflictingDecisions, event_ids)
+ Self::new(SdkTradeStatusIssueKind::ConflictingDecisions, event_ids)
}
RadrootsOrderIssue::RevisionProposalPayloadInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalPayloadInvalid,
+ SdkTradeStatusIssueKind::RevisionProposalPayloadInvalid,
event_id,
),
RadrootsOrderIssue::RevisionProposalOrderIdMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalOrderIdMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalOrderIdMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalAuthorMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalAuthorMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalAuthorMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalCounterpartyMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalCounterpartyMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalCounterpartyMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalBuyerMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalBuyerMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalBuyerMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalSellerMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalSellerMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalSellerMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalListingAddressInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalListingAddressInvalid,
+ SdkTradeStatusIssueKind::RevisionProposalListingAddressInvalid,
event_id,
),
RadrootsOrderIssue::RevisionProposalListingMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalListingMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalListingMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalRootMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalRootMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalRootMismatch,
event_id,
),
RadrootsOrderIssue::RevisionProposalPreviousMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionProposalPreviousMismatch,
+ SdkTradeStatusIssueKind::RevisionProposalPreviousMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionWithoutProposal { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionWithoutProposal,
+ SdkTradeStatusIssueKind::RevisionDecisionWithoutProposal,
event_id,
),
RadrootsOrderIssue::RevisionDecisionPayloadInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionPayloadInvalid,
+ SdkTradeStatusIssueKind::RevisionDecisionPayloadInvalid,
event_id,
),
RadrootsOrderIssue::RevisionDecisionOrderIdMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionOrderIdMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionOrderIdMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionAuthorMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionAuthorMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionAuthorMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionCounterpartyMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionCounterpartyMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionCounterpartyMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionBuyerMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionBuyerMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionBuyerMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionSellerMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionSellerMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionSellerMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionListingAddressInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionListingAddressInvalid,
+ SdkTradeStatusIssueKind::RevisionDecisionListingAddressInvalid,
event_id,
),
RadrootsOrderIssue::RevisionDecisionListingMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionListingMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionListingMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionRootMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionRootMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionRootMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionPreviousMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionPreviousMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionPreviousMismatch,
event_id,
),
RadrootsOrderIssue::RevisionDecisionRevisionIdMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::RevisionDecisionRevisionIdMismatch,
+ SdkTradeStatusIssueKind::RevisionDecisionRevisionIdMismatch,
event_id,
),
RadrootsOrderIssue::CancellationWithoutCancellableOrder { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationWithoutCancellableOrder,
+ SdkTradeStatusIssueKind::CancellationWithoutCancellableOrder,
event_id,
),
RadrootsOrderIssue::CancellationPayloadInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationPayloadInvalid,
+ SdkTradeStatusIssueKind::CancellationPayloadInvalid,
event_id,
),
RadrootsOrderIssue::CancellationOrderIdMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationOrderIdMismatch,
+ SdkTradeStatusIssueKind::CancellationOrderIdMismatch,
event_id,
),
RadrootsOrderIssue::CancellationAuthorMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationAuthorMismatch,
+ SdkTradeStatusIssueKind::CancellationAuthorMismatch,
event_id,
),
RadrootsOrderIssue::CancellationCounterpartyMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationCounterpartyMismatch,
+ SdkTradeStatusIssueKind::CancellationCounterpartyMismatch,
event_id,
),
RadrootsOrderIssue::CancellationBuyerMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::CancellationBuyerMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::CancellationBuyerMismatch, event_id)
}
RadrootsOrderIssue::CancellationSellerMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationSellerMismatch,
+ SdkTradeStatusIssueKind::CancellationSellerMismatch,
event_id,
),
RadrootsOrderIssue::CancellationListingAddressInvalid { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationListingAddressInvalid,
+ SdkTradeStatusIssueKind::CancellationListingAddressInvalid,
event_id,
),
RadrootsOrderIssue::CancellationListingMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationListingMismatch,
+ SdkTradeStatusIssueKind::CancellationListingMismatch,
event_id,
),
RadrootsOrderIssue::CancellationRootMismatch { event_id } => {
- Self::single(SdkOrderStatusIssueKind::CancellationRootMismatch, event_id)
+ Self::single(SdkTradeStatusIssueKind::CancellationRootMismatch, event_id)
}
RadrootsOrderIssue::CancellationPreviousMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::CancellationPreviousMismatch,
+ SdkTradeStatusIssueKind::CancellationPreviousMismatch,
event_id,
),
RadrootsOrderIssue::ForkedLifecycle { event_ids } => {
- Self::new(SdkOrderStatusIssueKind::ForkedLifecycle, event_ids)
+ Self::new(SdkTradeStatusIssueKind::ForkedLifecycle, event_ids)
}
RadrootsOrderIssue::ValidationReceiptWithoutPendingAgreement { event_id } => {
Self::single(
- SdkOrderStatusIssueKind::ValidationReceiptWithoutPendingAgreement,
+ SdkTradeStatusIssueKind::ValidationReceiptWithoutPendingAgreement,
event_id,
)
}
RadrootsOrderIssue::ValidationReceiptOrderIdMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::ValidationReceiptOrderIdMismatch,
+ SdkTradeStatusIssueKind::ValidationReceiptOrderIdMismatch,
event_id,
),
RadrootsOrderIssue::ValidationReceiptTypeMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::ValidationReceiptTypeMismatch,
+ SdkTradeStatusIssueKind::ValidationReceiptTypeMismatch,
event_id,
),
RadrootsOrderIssue::ValidationReceiptRootMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::ValidationReceiptRootMismatch,
+ SdkTradeStatusIssueKind::ValidationReceiptRootMismatch,
event_id,
),
RadrootsOrderIssue::ValidationReceiptTargetMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::ValidationReceiptTargetMismatch,
+ SdkTradeStatusIssueKind::ValidationReceiptTargetMismatch,
event_id,
),
RadrootsOrderIssue::ValidationReceiptListingMismatch { event_id } => Self::single(
- SdkOrderStatusIssueKind::ValidationReceiptListingMismatch,
+ SdkTradeStatusIssueKind::ValidationReceiptListingMismatch,
event_id,
),
RadrootsOrderIssue::ConflictingValidationReceipts { event_ids } => Self::new(
- SdkOrderStatusIssueKind::ConflictingValidationReceipts,
+ SdkTradeStatusIssueKind::ConflictingValidationReceipts,
event_ids,
),
RadrootsOrderIssue::DeterministicValidationFailure { event_id, .. } => Self::single(
- SdkOrderStatusIssueKind::DeterministicValidationFailure,
+ SdkTradeStatusIssueKind::DeterministicValidationFailure,
event_id,
),
RadrootsOrderIssue::StaleListingEvent {
expected_event_id,
current_event_id,
} => Self::new(
- SdkOrderStatusIssueKind::StaleListingEvent,
+ SdkTradeStatusIssueKind::StaleListingEvent,
vec![expected_event_id, current_event_id],
),
}
diff --git a/crates/sdk/src/privacy.rs b/crates/sdk/src/privacy.rs
@@ -0,0 +1,86 @@
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
+#[serde(rename_all = "snake_case")]
+#[non_exhaustive]
+pub enum ProductSensitivityField {
+ ExactLocation,
+ SensitiveFulfillmentDetails,
+ PublicButSensitiveNotes,
+ ProtocolMinimizedInventoryFields,
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
+#[serde(rename_all = "snake_case")]
+#[non_exhaustive]
+pub enum PrivacyPreflightStatus {
+ Ok,
+ ExplicitConfirmationRequired,
+ ForbiddenPublicFields,
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
+pub struct PrivacyPreflightReceipt {
+ pub status: PrivacyPreflightStatus,
+ pub fields: Vec<ProductSensitivityField>,
+}
+
+#[cfg(feature = "runtime")]
+impl PrivacyPreflightReceipt {
+ pub fn evaluate<I>(fields: I) -> Self
+ where
+ I: IntoIterator<Item = ProductSensitivityField>,
+ {
+ let mut fields = fields.into_iter().collect::<Vec<_>>();
+ fields.sort();
+ fields.dedup();
+ let status = if fields.iter().any(|field| {
+ matches!(
+ field,
+ ProductSensitivityField::ExactLocation
+ | ProductSensitivityField::SensitiveFulfillmentDetails
+ )
+ }) {
+ PrivacyPreflightStatus::ForbiddenPublicFields
+ } else if fields
+ .iter()
+ .any(|field| matches!(field, ProductSensitivityField::PublicButSensitiveNotes))
+ {
+ PrivacyPreflightStatus::ExplicitConfirmationRequired
+ } else {
+ PrivacyPreflightStatus::Ok
+ };
+ Self { status, fields }
+ }
+}
+
+#[cfg(test)]
+#[cfg(feature = "runtime")]
+mod tests {
+ use super::{PrivacyPreflightReceipt, PrivacyPreflightStatus, ProductSensitivityField};
+
+ #[test]
+ fn privacy_preflight_classifies_public_sensitivity() {
+ let ok = PrivacyPreflightReceipt::evaluate([
+ ProductSensitivityField::ProtocolMinimizedInventoryFields,
+ ]);
+ assert_eq!(ok.status, PrivacyPreflightStatus::Ok);
+
+ let confirm =
+ PrivacyPreflightReceipt::evaluate([ProductSensitivityField::PublicButSensitiveNotes]);
+ assert_eq!(
+ confirm.status,
+ PrivacyPreflightStatus::ExplicitConfirmationRequired
+ );
+
+ let forbidden = PrivacyPreflightReceipt::evaluate([
+ ProductSensitivityField::ExactLocation,
+ ProductSensitivityField::SensitiveFulfillmentDetails,
+ ]);
+ assert_eq!(
+ forbidden.status,
+ PrivacyPreflightStatus::ForbiddenPublicFields
+ );
+ }
+}
diff --git a/crates/sdk/src/product_clients.rs b/crates/sdk/src/product_clients.rs
@@ -64,6 +64,91 @@ impl<'client> TradesClient<'client> {
pub(crate) fn new(sdk: &'client RadrootsClient) -> Self {
Self { sdk }
}
+
+ pub fn buyer(&self) -> TradeBuyerClient<'client> {
+ TradeBuyerClient { sdk: self.sdk }
+ }
+
+ pub fn seller(&self) -> TradeSellerClient<'client> {
+ TradeSellerClient { sdk: self.sdk }
+ }
+
+ pub fn validation(&self) -> TradeValidationClient<'client> {
+ TradeValidationClient { sdk: self.sdk }
+ }
+
+ pub fn status_client(&self) -> TradeStatusClient<'client> {
+ TradeStatusClient { sdk: self.sdk }
+ }
+
+ pub fn resync(&self) -> TradeResyncClient<'client> {
+ TradeResyncClient { sdk: self.sdk }
+ }
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy)]
+pub struct TradeBuyerClient<'client> {
+ pub(crate) sdk: &'client RadrootsClient,
+}
+
+#[cfg(feature = "runtime")]
+impl<'client> TradeBuyerClient<'client> {
+ pub fn root(&self) -> &'client RadrootsClient {
+ self.sdk
+ }
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy)]
+pub struct TradeSellerClient<'client> {
+ pub(crate) sdk: &'client RadrootsClient,
+}
+
+#[cfg(feature = "runtime")]
+impl<'client> TradeSellerClient<'client> {
+ pub fn root(&self) -> &'client RadrootsClient {
+ self.sdk
+ }
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy)]
+pub struct TradeValidationClient<'client> {
+ pub(crate) sdk: &'client RadrootsClient,
+}
+
+#[cfg(feature = "runtime")]
+impl<'client> TradeValidationClient<'client> {
+ pub fn root(&self) -> &'client RadrootsClient {
+ self.sdk
+ }
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy)]
+pub struct TradeStatusClient<'client> {
+ pub(crate) sdk: &'client RadrootsClient,
+}
+
+#[cfg(feature = "runtime")]
+impl<'client> TradeStatusClient<'client> {
+ pub fn root(&self) -> &'client RadrootsClient {
+ self.sdk
+ }
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Copy)]
+pub struct TradeResyncClient<'client> {
+ pub(crate) sdk: &'client RadrootsClient,
+}
+
+#[cfg(feature = "runtime")]
+impl<'client> TradeResyncClient<'client> {
+ pub fn root(&self) -> &'client RadrootsClient {
+ self.sdk
+ }
}
#[cfg(feature = "runtime")]
diff --git a/crates/sdk/src/relay_targets.rs b/crates/sdk/src/relay_targets.rs
@@ -8,6 +8,93 @@ pub const SDK_RELAY_TARGET_MAX_COUNT: usize = 20;
#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
+pub enum PublishMode {
+ DryRun,
+ EnqueueOnly,
+ EnqueueAndPublish,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
+#[serde(rename_all = "snake_case")]
+#[non_exhaustive]
+pub enum AckPolicy {
+ NoWait,
+ AtLeastOneRelay,
+ AllRelays,
+ Quorum { required: u16 },
+}
+
+impl AckPolicy {
+ pub fn quorum(required: u16) -> Result<Self, RadrootsSdkError> {
+ if required == 0 {
+ return Err(RadrootsSdkError::InvalidRequest {
+ message: "ack policy quorum must require at least one relay".to_owned(),
+ });
+ }
+ Ok(Self::Quorum { required })
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum RelayResolutionPolicy {
+ ConfiguredRelays,
+ Explicit(SdkRelayTargetSet),
+}
+
+impl RelayResolutionPolicy {
+ pub fn configured_relays() -> Self {
+ Self::ConfiguredRelays
+ }
+
+ pub fn explicit(targets: SdkRelayTargetSet) -> Self {
+ Self::Explicit(targets)
+ }
+
+ pub fn try_explicit<I, S>(
+ relays: I,
+ url_policy: SdkRelayUrlPolicy,
+ ) -> Result<Self, RadrootsSdkError>
+ where
+ I: IntoIterator<Item = S>,
+ S: AsRef<str>,
+ {
+ Ok(Self::Explicit(SdkRelayTargetSet::new(relays, url_policy)?))
+ }
+
+ pub(crate) fn workflow_target_policy(self) -> SdkRelayTargetPolicy {
+ match self {
+ Self::ConfiguredRelays => SdkRelayTargetPolicy::UseConfiguredRelays,
+ Self::Explicit(targets) => SdkRelayTargetPolicy::Explicit(targets),
+ }
+ }
+}
+
+impl serde::Serialize for RelayResolutionPolicy {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ match self {
+ Self::ConfiguredRelays => {
+ let mut state = serializer.serialize_struct("RelayResolutionPolicy", 1)?;
+ state.serialize_field("kind", "configured_relays")?;
+ state.end()
+ }
+ Self::Explicit(targets) => {
+ let mut state = serializer.serialize_struct("RelayResolutionPolicy", 3)?;
+ state.serialize_field("kind", "explicit")?;
+ state.serialize_field("relays", targets.relays())?;
+ state.serialize_field("canonical_relays", targets.canonical_relays())?;
+ state.end()
+ }
+ }
+ }
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize)]
+#[serde(rename_all = "snake_case")]
+#[non_exhaustive]
pub enum SdkRelayUrlPolicy {
Public,
Localhost,
diff --git a/crates/sdk/src/trade_storage.rs b/crates/sdk/src/trade_storage.rs
@@ -0,0 +1,152 @@
+#[cfg(feature = "runtime")]
+use std::collections::BTreeMap;
+
+#[cfg(feature = "runtime")]
+use radroots_events::ids::{RadrootsEventId, RadrootsOrderId};
+#[cfg(feature = "runtime")]
+use radroots_trade::{
+ identity::{RadrootsTradeId, RadrootsTradeLocator, RadrootsTradeLocatorCandidate},
+ workflow::RadrootsTradeWorkflowState,
+};
+
+#[cfg(feature = "runtime")]
+pub const SDK_TRADE_PROJECTION_CACHE_VERSION: u32 = 1;
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
+pub struct SdkTradeProjectionCacheKey {
+ pub order_id: RadrootsOrderId,
+ pub root_event_id: RadrootsEventId,
+ pub projection_version: u32,
+}
+
+#[cfg(feature = "runtime")]
+impl SdkTradeProjectionCacheKey {
+ pub fn new(order_id: RadrootsOrderId, root_event_id: RadrootsEventId) -> Self {
+ Self {
+ order_id,
+ root_event_id,
+ projection_version: SDK_TRADE_PROJECTION_CACHE_VERSION,
+ }
+ }
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize)]
+pub struct SdkTradeProjectionCacheRecord {
+ pub key: SdkTradeProjectionCacheKey,
+ pub locator: RadrootsTradeLocator,
+ pub status: RadrootsTradeWorkflowState,
+ pub updated_at_ms: i64,
+}
+
+#[cfg(feature = "runtime")]
+#[derive(Clone, Debug, Default, PartialEq, Eq)]
+pub struct SdkTradeProjectionCache {
+ records: BTreeMap<SdkTradeProjectionCacheKey, SdkTradeProjectionCacheRecord>,
+}
+
+#[cfg(feature = "runtime")]
+impl SdkTradeProjectionCache {
+ pub fn upsert(&mut self, record: SdkTradeProjectionCacheRecord) {
+ self.records.insert(record.key.clone(), record);
+ }
+
+ pub fn get(&self, key: &SdkTradeProjectionCacheKey) -> Option<&SdkTradeProjectionCacheRecord> {
+ self.records.get(key)
+ }
+
+ pub fn ambiguity_candidates(
+ &self,
+ order_id: &RadrootsOrderId,
+ ) -> Vec<RadrootsTradeLocatorCandidate> {
+ self.records
+ .values()
+ .filter(|record| record.key.order_id == *order_id)
+ .filter_map(|record| {
+ Some(RadrootsTradeLocatorCandidate {
+ trade_id: RadrootsTradeId::from(record.key.order_id.clone()),
+ root_event_id: record.key.root_event_id.clone(),
+ listing_addr: record.locator.listing_addr.clone()?,
+ buyer_pubkey: record.locator.buyer_pubkey.clone()?,
+ seller_pubkey: record.locator.seller_pubkey.clone()?,
+ })
+ })
+ .collect()
+ }
+}
+
+#[cfg(test)]
+#[cfg(feature = "runtime")]
+mod tests {
+ use super::{
+ SDK_TRADE_PROJECTION_CACHE_VERSION, SdkTradeProjectionCache, SdkTradeProjectionCacheKey,
+ SdkTradeProjectionCacheRecord,
+ };
+ use radroots_events::ids::{
+ RadrootsEventId, RadrootsListingAddress, RadrootsOrderId, RadrootsPublicKey,
+ };
+ use radroots_events::kinds::KIND_LISTING;
+ use radroots_trade::{identity::RadrootsTradeLocator, workflow::RadrootsTradeWorkflowState};
+
+ const SELLER: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+ const BUYER: &str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
+
+ fn order_id() -> RadrootsOrderId {
+ RadrootsOrderId::parse("order-1").expect("order id")
+ }
+
+ fn event_id(raw: u8) -> RadrootsEventId {
+ RadrootsEventId::parse(format!("{raw:064x}")).expect("event id")
+ }
+
+ fn listing_addr() -> RadrootsListingAddress {
+ RadrootsListingAddress::parse(format!("{KIND_LISTING}:{SELLER}:AAAAAAAAAAAAAAAAAAAAAg"))
+ .expect("listing address")
+ }
+
+ fn locator(root: RadrootsEventId) -> RadrootsTradeLocator {
+ RadrootsTradeLocator::from_order_id(order_id())
+ .with_root_event_id(root)
+ .with_listing_addr(listing_addr())
+ .with_buyer_pubkey(RadrootsPublicKey::parse(BUYER).expect("buyer"))
+ .with_seller_pubkey(RadrootsPublicKey::parse(SELLER).expect("seller"))
+ }
+
+ #[test]
+ fn projection_cache_key_includes_root_and_version() {
+ let first = SdkTradeProjectionCacheKey::new(order_id(), event_id(1));
+ let second = SdkTradeProjectionCacheKey::new(order_id(), event_id(2));
+
+ assert_ne!(first, second);
+ assert_eq!(first.projection_version, SDK_TRADE_PROJECTION_CACHE_VERSION);
+ }
+
+ #[test]
+ fn projection_cache_returns_root_ambiguity_candidates() {
+ let mut cache = SdkTradeProjectionCache::default();
+ for root in [event_id(1), event_id(2)] {
+ let record = SdkTradeProjectionCacheRecord {
+ key: SdkTradeProjectionCacheKey::new(order_id(), root.clone()),
+ locator: locator(root),
+ status: RadrootsTradeWorkflowState::Requested,
+ updated_at_ms: 1,
+ };
+ cache.upsert(record);
+ }
+
+ let candidates = cache.ambiguity_candidates(&order_id());
+
+ assert_eq!(candidates.len(), 2);
+ assert!(
+ candidates
+ .iter()
+ .any(|candidate| candidate.root_event_id == event_id(1))
+ );
+ assert!(
+ candidates
+ .iter()
+ .any(|candidate| candidate.root_event_id == event_id(2))
+ );
+ }
+}
diff --git a/crates/sdk/tests/dvm_runtime.rs b/crates/sdk/tests/dvm_runtime.rs
@@ -11,7 +11,10 @@ use radroots_events::{
RadrootsNostrEvent,
contract::RadrootsActorRole,
draft::{RadrootsFrozenEventDraft, RadrootsSignedNostrEvent},
- ids::{RadrootsEventId, RadrootsListingAddress, RadrootsOrderId, RadrootsPublicKey},
+ ids::{
+ RadrootsEventId, RadrootsInventoryBinId, RadrootsListingAddress, RadrootsOrderId,
+ RadrootsPublicKey,
+ },
kinds::{KIND_LISTING, KIND_TRADE_TRANSITION_PROOF_REQUEST},
order::{
RadrootsOrderDecision, RadrootsOrderDecisionOutcome, RadrootsOrderEconomicItem,
@@ -27,10 +30,10 @@ use radroots_outbox::RadrootsOutbox;
use radroots_sdk::protocol::events::RadrootsNostrEventPtr;
use radroots_sdk::{
DVM_TRADE_TRANSITION_PROOF_REQUEST_OPERATION_KIND, DvmTradeTransitionProofEnqueueRequest,
- DvmTradeTransitionProofPrepareRequest, DvmValidationReceiptIngestRequest, OrderStatusKind,
- OrderStatusNextActionKind, OrderStatusRequest, RadrootsClient, RadrootsSdkError,
- RadrootsSdkStorageConfig, RadrootsSdkTimestamp, SdkDvmInventoryBinWitness, SdkMutationState,
- SdkRelayTargetPolicy, SdkRelayUrlPolicy,
+ DvmTradeTransitionProofPrepareRequest, DvmValidationReceiptIngestRequest, RadrootsClient,
+ RadrootsSdkError, RadrootsSdkStorageConfig, RadrootsSdkTimestamp,
+ RadrootsTradeInventoryBinWitnessDto, SdkMutationState, SdkRelayTargetPolicy, SdkRelayUrlPolicy,
+ TradeStatusKind, TradeStatusNextActionKind, TradeStatusRequest,
};
#[cfg(feature = "signer-adapters")]
use radroots_sdk::{RadrootsSdkLocalKeySigner, RadrootsSdkSignerProvider};
@@ -272,7 +275,7 @@ async fn dvm_validation_receipt_ingest_commits_pending_trade_status() {
.status(status_request("order-dvm-ingest"))
.await
.expect("pending status");
- assert_eq!(pending.status, OrderStatusKind::AgreedPendingRhi);
+ assert_eq!(pending.status, TradeStatusKind::AgreedPendingRhi);
assert!(pending.rhi_receipt_event_id.is_none());
let listing_event_id = deterministic_event_id("listing-event");
@@ -321,9 +324,9 @@ async fn dvm_validation_receipt_ingest_commits_pending_trade_status() {
.status(status_request("order-dvm-ingest"))
.await
.expect("committed status");
- assert_eq!(committed.status, OrderStatusKind::Committed);
+ assert_eq!(committed.status, TradeStatusKind::Committed);
assert!(committed.lifecycle_terminal);
- assert_eq!(committed.next_action, OrderStatusNextActionKind::Terminal);
+ assert_eq!(committed.next_action, TradeStatusNextActionKind::Terminal);
assert_eq!(
committed.rhi_receipt_event_id,
Some(receipt_event_id.clone())
@@ -648,9 +651,9 @@ fn explicit_relays() -> SdkRelayTargetPolicy {
SdkRelayTargetPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public).expect("relay targets")
}
-fn inventory_bins() -> Vec<SdkDvmInventoryBinWitness> {
- vec![SdkDvmInventoryBinWitness {
- bin_id: "bin-1".to_owned(),
+fn inventory_bins() -> Vec<RadrootsTradeInventoryBinWitnessDto> {
+ vec![RadrootsTradeInventoryBinWitnessDto {
+ bin_id: RadrootsInventoryBinId::parse("bin-1").expect("bin id"),
listing_capacity: 5,
previous_reserved: 1,
}]
@@ -660,8 +663,8 @@ fn order_id(raw: &str) -> RadrootsOrderId {
RadrootsOrderId::parse(raw).expect("order id")
}
-fn status_request(raw: &str) -> OrderStatusRequest {
- OrderStatusRequest::parse(raw).expect("status request")
+fn status_request(raw: &str) -> TradeStatusRequest {
+ TradeStatusRequest::parse(raw).expect("status request")
}
fn listing_address() -> RadrootsListingAddress {
diff --git a/crates/sdk/tests/orders_runtime.rs b/crates/sdk/tests/orders_runtime.rs
@@ -33,19 +33,19 @@ use radroots_sdk::protocol::order::{
};
use radroots_sdk::protocol::wire::WireEventParts;
use radroots_sdk::{
- ORDER_CANCELLATION_OPERATION_KIND, ORDER_DECISION_OPERATION_KIND,
- ORDER_REVISION_DECISION_OPERATION_KIND, ORDER_REVISION_PROPOSAL_OPERATION_KIND,
- ORDER_STATUS_DEFAULT_LIMIT, ORDER_STATUS_MAX_LIMIT, ORDER_SUBMIT_OPERATION_KIND,
- OrderCancellationEnqueueRequest, OrderCancellationPrepareRequest, OrderDecisionEnqueueRequest,
- OrderDecisionPrepareRequest, OrderEvidenceIngestRequest, OrderRequestEvidenceIngestRequest,
- OrderRevisionDecisionEnqueueRequest, OrderRevisionDecisionPrepareRequest,
- OrderRevisionProposalEnqueueRequest, OrderRevisionProposalPrepareRequest, OrderStatusKind,
- OrderStatusNextActionKind, OrderStatusRequest, OrderSubmitEnqueueRequest,
- OrderSubmitPrepareRequest, OrderWorkflowKind, PushOutboxEventState, PushOutboxRelayOutcomeKind,
- PushOutboxRequest, RadrootsClient, RadrootsSdkError, RadrootsSdkPartialLocalMutationFailure,
- RadrootsSdkRecoveryAction, RadrootsSdkTimestamp, SdkIdempotencyKey, SdkMutationState,
- SdkOrderStatusIssue, SdkOrderStatusIssueKind, SdkOrderStatusSource, SdkRelayTargetPolicy,
- SdkRelayTargetSet, SdkRelayUrlPolicy,
+ AckPolicy, PublishMode, PushOutboxEventState, PushOutboxRelayOutcomeKind, PushOutboxRequest,
+ RadrootsClient, RadrootsSdkError, RadrootsSdkPartialLocalMutationFailure,
+ RadrootsSdkRecoveryAction, RadrootsSdkTimestamp, RelayResolutionPolicy, SdkIdempotencyKey,
+ SdkMutationState, SdkRelayTargetSet, SdkRelayUrlPolicy, SdkTradeStatusIssue,
+ SdkTradeStatusIssueKind, SdkTradeStatusSource, TRADE_CANCELLATION_OPERATION_KIND,
+ TRADE_DECISION_OPERATION_KIND, TRADE_REVISION_DECISION_OPERATION_KIND,
+ TRADE_REVISION_PROPOSAL_OPERATION_KIND, TRADE_STATUS_DEFAULT_LIMIT, TRADE_STATUS_MAX_LIMIT,
+ TRADE_SUBMIT_OPERATION_KIND, TradeCancellationEnqueueRequest, TradeCancellationPrepareRequest,
+ TradeDecisionEnqueueRequest, TradeDecisionPrepareRequest, TradeEvidenceIngestRequest,
+ TradeRequestEvidenceIngestRequest, TradeRevisionDecisionEnqueueRequest,
+ TradeRevisionDecisionPrepareRequest, TradeRevisionProposalEnqueueRequest,
+ TradeRevisionProposalPrepareRequest, TradeStatusKind, TradeStatusNextActionKind,
+ TradeStatusRequest, TradeSubmitEnqueueRequest, TradeSubmitPrepareRequest, TradeWorkflowKind,
};
use radroots_trade::order::RadrootsOrderIssue;
use serde::Serialize;
@@ -390,8 +390,8 @@ fn order_id(raw: &str) -> RadrootsOrderId {
RadrootsOrderId::parse(raw).expect("order id")
}
-fn status_request(raw: &str) -> OrderStatusRequest {
- OrderStatusRequest::parse(raw).expect("order status request")
+fn status_request(raw: &str) -> TradeStatusRequest {
+ TradeStatusRequest::parse(raw).expect("order status request")
}
fn buyer_actor() -> RadrootsActorContext {
@@ -507,7 +507,7 @@ fn invalid_listing_event_ptr() -> RadrootsNostrEventPtr {
async fn order_submit_prepare_is_side_effect_free() {
let (_tempdir, sdk, store) = directory_sdk_and_store().await;
let listing_event = listing_event_ptr();
- let request = OrderSubmitPrepareRequest::new(
+ let request = TradeSubmitPrepareRequest::new(
buyer_actor(),
listing_event.clone(),
order_request("order-submit-prepare"),
@@ -559,7 +559,7 @@ async fn order_submit_prepare_is_side_effect_free() {
#[tokio::test]
async fn order_submit_prepare_rejects_missing_listing_evidence() {
let (_tempdir, sdk, _store) = directory_sdk_and_store().await;
- let request = OrderSubmitPrepareRequest::new(
+ let request = TradeSubmitPrepareRequest::new(
buyer_actor(),
invalid_listing_event_ptr(),
order_request("order-submit-missing-listing"),
@@ -579,7 +579,7 @@ async fn order_submit_prepare_rejects_invalid_actor_or_payload() {
let non_buyer = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
non_buyer_actor(),
listing_event_ptr(),
order_request("order-submit-non-buyer"),
@@ -592,7 +592,7 @@ async fn order_submit_prepare_rejects_invalid_actor_or_payload() {
let wrong_actor = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
other_buyer_actor(),
listing_event_ptr(),
order_request("order-submit-wrong-actor"),
@@ -607,7 +607,7 @@ async fn order_submit_prepare_rejects_invalid_actor_or_payload() {
seller_mismatch.seller_pubkey = OTHER_PUBLIC_KEY_HEX.parse().expect("seller pubkey");
let seller_error = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer_actor(),
listing_event_ptr(),
seller_mismatch,
@@ -622,7 +622,7 @@ async fn order_submit_prepare_rejects_invalid_actor_or_payload() {
empty_items.items.clear();
let empty_items_error = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer_actor(),
listing_event_ptr(),
empty_items,
@@ -637,7 +637,7 @@ async fn order_submit_prepare_rejects_invalid_actor_or_payload() {
empty_economics.economics.items.clear();
let empty_economics_error = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer_actor(),
listing_event_ptr(),
empty_economics,
@@ -655,16 +655,16 @@ async fn order_submit_enqueue_stores_event_queues_outbox_and_status_sees_request
let order = order_request("order-submit-enqueue");
let prepared = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer_actor(),
listing_event_ptr(),
order.clone(),
))
.expect("prepared");
- assert_eq!(prepared.workflow.kind, OrderWorkflowKind::Submit);
+ assert_eq!(prepared.workflow.kind, TradeWorkflowKind::Submit);
assert_eq!(
prepared.workflow.operation_kind,
- ORDER_SUBMIT_OPERATION_KIND
+ TRADE_SUBMIT_OPERATION_KIND
);
assert_eq!(prepared.workflow.contract_id, "radroots.order.request.v1");
assert_eq!(
@@ -672,11 +672,13 @@ async fn order_submit_enqueue_stores_event_queues_outbox_and_status_sees_request
prepared.expected_event_id
);
assert_eq!(prepared.workflow.created_at, prepared.created_at);
- let request = OrderSubmitEnqueueRequest::new(
+ let request = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays")
@@ -692,8 +694,8 @@ async fn order_submit_enqueue_stores_event_queues_outbox_and_status_sees_request
assert_eq!(receipt.order_id, prepared.order_id);
assert_eq!(receipt.listing_addr, prepared.listing_addr);
assert_eq!(receipt.listing_event_id, prepared.listing_event_id);
- assert_eq!(receipt.workflow.kind, OrderWorkflowKind::Submit);
- assert_eq!(receipt.workflow.operation_kind, ORDER_SUBMIT_OPERATION_KIND);
+ assert_eq!(receipt.workflow.kind, TradeWorkflowKind::Submit);
+ assert_eq!(receipt.workflow.operation_kind, TRADE_SUBMIT_OPERATION_KIND);
assert_eq!(
receipt.workflow.expected_event_id,
prepared.expected_event_id
@@ -775,7 +777,7 @@ async fn order_submit_enqueue_stores_event_queues_outbox_and_status_sees_request
.await
.expect("status");
assert!(status.found);
- assert_eq!(status.status, OrderStatusKind::Requested);
+ assert_eq!(status.status, TradeStatusKind::Requested);
assert_eq!(status.event_count, 1);
assert_eq!(
status
@@ -789,11 +791,13 @@ async fn order_submit_enqueue_stores_event_queues_outbox_and_status_sees_request
#[tokio::test]
async fn order_submit_enqueue_returns_sanitized_signer_errors_before_mutation() {
let (_tempdir, sdk, store) = directory_sdk_and_store().await;
- let request = OrderSubmitEnqueueRequest::new(
+ let request = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-wrong-signer"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays");
@@ -836,22 +840,26 @@ async fn order_submit_enqueue_returns_sanitized_signer_errors_before_mutation()
#[tokio::test]
async fn order_submit_enqueue_derives_order_independent_idempotency_key() {
let (_tempdir, sdk, _store) = directory_sdk_and_store().await;
- let first = OrderSubmitEnqueueRequest::new(
+ let first = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-idempotent"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY_B, RELAY, RELAY], SdkRelayUrlPolicy::Public)
.expect("first target relays");
- let second = OrderSubmitEnqueueRequest::new(
+ let second = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-idempotent"),
- SdkRelayTargetPolicy::explicit(
+ RelayResolutionPolicy::explicit(
SdkRelayTargetSet::new([RELAY, RELAY_B], SdkRelayUrlPolicy::Public)
.expect("second target relays"),
),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
);
let first_receipt = sdk
@@ -918,11 +926,13 @@ async fn order_submit_enqueue_derives_order_independent_idempotency_key() {
#[tokio::test]
async fn order_submit_enqueue_pushes_queued_event_with_mock_relay_sync() {
let (_tempdir, sdk, _store) = directory_sdk_and_store().await;
- let enqueue_request = OrderSubmitEnqueueRequest::new(
+ let enqueue_request = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-sync"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays");
@@ -979,11 +989,13 @@ async fn order_submit_enqueue_pushes_queued_event_with_mock_relay_sync() {
#[tokio::test]
async fn order_submit_enqueue_reports_partial_local_mutation_after_outbox_conflict() {
let (_tempdir, sdk, _store) = directory_sdk_and_store().await;
- let first = OrderSubmitEnqueueRequest::new(
+ let first = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-conflict-a"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("first target relays")
@@ -994,11 +1006,13 @@ async fn order_submit_enqueue_reports_partial_local_mutation_after_outbox_confli
.await
.expect("first enqueue");
- let second = OrderSubmitEnqueueRequest::new(
+ let second = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-conflict-b"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("second target relays")
@@ -1016,7 +1030,7 @@ async fn order_submit_enqueue_reports_partial_local_mutation_after_outbox_confli
if partial.stored
&& !partial.queued
&& partial.event_id.is_some()
- && partial.operation_kind == ORDER_SUBMIT_OPERATION_KIND
+ && partial.operation_kind == TRADE_SUBMIT_OPERATION_KIND
&& partial.idempotency_digest_prefix.is_some()
&& partial.failure == RadrootsSdkPartialLocalMutationFailure::OutboxIdempotencyConflict
&& partial.recovery == RadrootsSdkRecoveryAction::RetryOperationWithSameIdempotencyKey
@@ -1044,7 +1058,7 @@ async fn order_submit_enqueue_reports_partial_local_mutation_after_outbox_confli
async fn order_submit_runtime_dtos_serialize_deterministically() {
let (_tempdir, sdk, _store) = directory_sdk_and_store().await;
let created_at = RadrootsSdkTimestamp::from_unix_seconds(1_700_000_123);
- let prepare_request = OrderSubmitPrepareRequest::new(
+ let prepare_request = TradeSubmitPrepareRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-serialized"),
@@ -1083,11 +1097,13 @@ async fn order_submit_runtime_dtos_serialize_deterministically() {
assert_eq!(prepare_json["order"]["items"][0]["bin_count"], 2);
assert_eq!(prepare_json["created_at"], 1_700_000_123);
- let enqueue_request = OrderSubmitEnqueueRequest::new(
+ let enqueue_request = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-serialized-enqueue"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY, RELAY_B], SdkRelayUrlPolicy::Public)
.expect("relay targets")
@@ -1117,11 +1133,13 @@ async fn order_submit_runtime_dtos_serialize_deterministically() {
.contains("order-serialized-idempotency")
);
- let try_key_enqueue = OrderSubmitEnqueueRequest::new(
+ let try_key_enqueue = TradeSubmitEnqueueRequest::new(
buyer_actor(),
listing_event_ptr(),
order_request("order-submit-try-idempotency"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("order-submit-try-key")
.expect("try idempotency key");
@@ -1145,7 +1163,7 @@ async fn order_submit_runtime_dtos_serialize_deterministically() {
serde_json::json!({
"workflow": {
"kind": "submit",
- "operation_kind": ORDER_SUBMIT_OPERATION_KIND,
+ "operation_kind": TRADE_SUBMIT_OPERATION_KIND,
"expected_event_id": receipt.workflow.expected_event_id.as_str(),
"signed_event_id": receipt.workflow.signed_event_id.as_str(),
"local_event_seq": 1,
@@ -1350,7 +1368,7 @@ async fn order_request_evidence_ingest_stores_request_and_enables_decision_enque
let (_tempdir, sdk, store) = directory_sdk_and_store().await;
let request_event = signed_order_request_event("order-decision-ingested", 39);
let request_event_id = RadrootsEventId::parse(request_event.id.as_str()).expect("request id");
- let ingest_request = OrderRequestEvidenceIngestRequest::new(request_event.clone())
+ let ingest_request = TradeRequestEvidenceIngestRequest::new(request_event.clone())
.with_observed_at(RadrootsSdkTimestamp::from_unix_seconds(1_700_000_039));
let ingest_receipt = sdk
@@ -1370,7 +1388,7 @@ async fn order_request_evidence_ingest_stores_request_and_enables_decision_enque
let actor = seller_actor();
let plan = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
actor.clone(),
request_event_ptr(&request_event),
order_decision("order-decision-ingested"),
@@ -1381,8 +1399,10 @@ async fn order_request_evidence_ingest_stores_request_and_enables_decision_enque
.enqueue_prepared_decision_with_explicit_signer(
&actor,
plan,
- SdkRelayTargetPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
+ RelayResolutionPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays"),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&FixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -1392,7 +1412,7 @@ async fn order_request_evidence_ingest_stores_request_and_enables_decision_enque
assert_eq!(receipt.local_event_seq, 2);
let duplicate_receipt = sdk
.trades()
- .ingest_request_evidence(OrderRequestEvidenceIngestRequest::new(
+ .ingest_request_evidence(TradeRequestEvidenceIngestRequest::new(
request_event.clone(),
))
.await
@@ -1419,7 +1439,7 @@ async fn order_evidence_ingest_stores_lifecycle_evidence_for_projection() {
let request_receipt = sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(request_event.clone()))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(request_event.clone()))
.await
.expect("request evidence");
assert_eq!(request_receipt.order_id.as_str(), "order-evidence-ingest");
@@ -1429,7 +1449,7 @@ async fn order_evidence_ingest_stores_lifecycle_evidence_for_projection() {
let decision_receipt = sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(decision_event.clone()))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(decision_event.clone()))
.await
.expect("decision evidence");
assert_eq!(decision_receipt.order_id.as_str(), "order-evidence-ingest");
@@ -1439,7 +1459,7 @@ async fn order_evidence_ingest_stores_lifecycle_evidence_for_projection() {
let duplicate_receipt = sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(decision_event))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(decision_event))
.await
.expect("duplicate decision evidence");
assert_eq!(duplicate_receipt.local_event_seq, 2);
@@ -1458,7 +1478,7 @@ async fn order_evidence_ingest_stores_lifecycle_evidence_for_projection() {
.status(status_request("order-evidence-ingest"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::AgreedPendingRhi);
+ assert_eq!(status.status, TradeStatusKind::AgreedPendingRhi);
assert_eq!(status.event_count, 2);
assert_eq!(
status
@@ -1474,7 +1494,7 @@ async fn order_evidence_ingest_rejects_non_order_events() {
let (_tempdir, sdk, store) = directory_sdk_and_store().await;
let error = sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(signed_non_order_event(41)))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(signed_non_order_event(41)))
.await
.expect_err("non order event");
@@ -1497,7 +1517,7 @@ async fn order_request_evidence_ingest_rejects_non_request_events() {
let error = sdk
.trades()
- .ingest_request_evidence(OrderRequestEvidenceIngestRequest::new(decision_event))
+ .ingest_request_evidence(TradeRequestEvidenceIngestRequest::new(decision_event))
.await
.expect_err("non request event");
@@ -1520,7 +1540,7 @@ async fn order_decision_prepare_accept_and_decline_are_side_effect_free() {
id: request_event_id.as_str().to_owned(),
relays: Some(RELAY.to_owned()),
};
- let accepted_request = OrderDecisionPrepareRequest::new(
+ let accepted_request = TradeDecisionPrepareRequest::new(
seller_actor(),
request_event.clone(),
order_decision("order-decision-prepare-accept"),
@@ -1549,7 +1569,7 @@ async fn order_decision_prepare_accept_and_decline_are_side_effect_free() {
};
let declined = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller_actor(),
request_event,
declined_payload,
@@ -1592,7 +1612,7 @@ async fn order_decision_prepare_rejects_invalid_actor_evidence_and_payload() {
let non_seller = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
non_seller_actor(),
request_event.clone(),
order_decision("order-decision-non-seller"),
@@ -1605,7 +1625,7 @@ async fn order_decision_prepare_rejects_invalid_actor_evidence_and_payload() {
let wrong_actor = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
other_seller_actor(),
request_event.clone(),
order_decision("order-decision-wrong-seller"),
@@ -1618,7 +1638,7 @@ async fn order_decision_prepare_rejects_invalid_actor_evidence_and_payload() {
let invalid_evidence = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller_actor(),
RadrootsNostrEventPtr {
id: String::new(),
@@ -1638,7 +1658,7 @@ async fn order_decision_prepare_rejects_invalid_actor_evidence_and_payload() {
};
let commitment_error = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller_actor(),
request_event.clone(),
empty_commitments,
@@ -1655,7 +1675,7 @@ async fn order_decision_prepare_rejects_invalid_actor_evidence_and_payload() {
};
let reason_error = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller_actor(),
request_event,
missing_reason,
@@ -1672,7 +1692,7 @@ async fn order_decision_runtime_dtos_serialize_deterministically() {
let (_tempdir, sdk, store) = directory_sdk_and_store().await;
let created_at = RadrootsSdkTimestamp::from_unix_seconds(1_700_000_321);
let prepare_event_id = deterministic_event_id("order-decision-serialized-request");
- let prepare_request = OrderDecisionPrepareRequest::new(
+ let prepare_request = TradeDecisionPrepareRequest::new(
seller_actor(),
RadrootsNostrEventPtr {
id: prepare_event_id.as_str().to_owned(),
@@ -1715,11 +1735,13 @@ async fn order_decision_runtime_dtos_serialize_deterministically() {
.ingest_event(RadrootsEventIngest::new(request_event.clone(), 4_500))
.await
.expect("ingest request");
- let enqueue_request = OrderDecisionEnqueueRequest::new(
+ let enqueue_request = TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_decision("order-decision-serialized-enqueue"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY, RELAY_B], SdkRelayUrlPolicy::Public)
.expect("target relays")
@@ -1749,11 +1771,13 @@ async fn order_decision_runtime_dtos_serialize_deterministically() {
.contains("order-decision-serialized-idempotency")
);
- let try_key_enqueue = OrderDecisionEnqueueRequest::new(
+ let try_key_enqueue = TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_decision("order-decision-try-idempotency"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("order-decision-try-key")
.expect("try idempotency key");
@@ -1770,10 +1794,10 @@ async fn order_decision_runtime_dtos_serialize_deterministically() {
)
.await
.expect("enqueue");
- assert_eq!(receipt.workflow.kind, OrderWorkflowKind::Decision);
+ assert_eq!(receipt.workflow.kind, TradeWorkflowKind::Decision);
assert_eq!(
receipt.workflow.operation_kind,
- ORDER_DECISION_OPERATION_KIND
+ TRADE_DECISION_OPERATION_KIND
);
assert_eq!(
receipt.workflow.expected_event_id,
@@ -1806,7 +1830,7 @@ async fn order_decision_runtime_dtos_serialize_deterministically() {
serde_json::json!({
"workflow": {
"kind": "decision",
- "operation_kind": ORDER_DECISION_OPERATION_KIND,
+ "operation_kind": TRADE_DECISION_OPERATION_KIND,
"expected_event_id": receipt.workflow.expected_event_id.as_str(),
"signed_event_id": receipt.workflow.signed_event_id.as_str(),
"local_event_seq": 2,
@@ -1859,7 +1883,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
);
let cancellation = order_cancellation("order-revision-dto");
- let proposal_prepare = OrderRevisionProposalPrepareRequest::new(
+ let proposal_prepare = TradeRevisionProposalPrepareRequest::new(
seller_actor(),
root_event.clone(),
previous_event.clone(),
@@ -1891,12 +1915,14 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
);
assert_eq!(proposal_prepare_json["created_at"], 1_700_000_654);
- let proposal_enqueue = OrderRevisionProposalEnqueueRequest::new(
+ let proposal_enqueue = TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
root_event.clone(),
previous_event.clone(),
proposal.clone(),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY, RELAY_B], SdkRelayUrlPolicy::Public)
.expect("proposal relays")
@@ -1919,12 +1945,14 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
);
assert!(!proposal_enqueue_json.to_string().contains("proposal-dto"));
- let proposal_try_key = OrderRevisionProposalEnqueueRequest::new(
+ let proposal_try_key = TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
root_event.clone(),
previous_event.clone(),
proposal.clone(),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("order-revision-proposal-try")
.expect("proposal try key");
@@ -1933,7 +1961,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
serde_json::json!({ "value": "<redacted>", "len": 27 })
);
- let decision_prepare = OrderRevisionDecisionPrepareRequest::new(
+ let decision_prepare = TradeRevisionDecisionPrepareRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
@@ -1960,12 +1988,14 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
);
assert_eq!(decision_prepare_json["created_at"], 1_700_000_654);
- let decision_enqueue = OrderRevisionDecisionEnqueueRequest::new(
+ let decision_enqueue = TradeRevisionDecisionEnqueueRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
revision_decision,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY, RELAY_B], SdkRelayUrlPolicy::Public)
.expect("decision relays")
@@ -1983,7 +2013,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
assert_eq!(decision_enqueue_json["created_at"], 1_700_000_654);
assert!(!decision_enqueue_json.to_string().contains("decision-dto"));
- let decision_try_key = OrderRevisionDecisionEnqueueRequest::new(
+ let decision_try_key = TradeRevisionDecisionEnqueueRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
@@ -1992,7 +2022,9 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
&previous_event_id,
RadrootsOrderRevisionOutcome::Accepted,
),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("order-revision-decision-try")
.expect("decision try key");
@@ -2001,7 +2033,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
serde_json::json!({ "value": "<redacted>", "len": 27 })
);
- let cancellation_prepare = OrderCancellationPrepareRequest::new(
+ let cancellation_prepare = TradeCancellationPrepareRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
@@ -2017,12 +2049,14 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
);
assert_eq!(cancellation_prepare_json["created_at"], 1_700_000_654);
- let cancellation_enqueue = OrderCancellationEnqueueRequest::new(
+ let cancellation_enqueue = TradeCancellationEnqueueRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
cancellation,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY, RELAY_B], SdkRelayUrlPolicy::Public)
.expect("cancellation relays")
@@ -2044,12 +2078,14 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
.contains("cancellation-dto")
);
- let cancellation_try_key = OrderCancellationEnqueueRequest::new(
+ let cancellation_try_key = TradeCancellationEnqueueRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
order_cancellation("order-revision-dto"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("order-cancellation-try")
.expect("cancellation try key");
@@ -2060,7 +2096,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
let event = signed_order_request_event("order-evidence-dto", 77);
let request_evidence =
- OrderRequestEvidenceIngestRequest::new(event.clone()).with_observed_at(created_at);
+ TradeRequestEvidenceIngestRequest::new(event.clone()).with_observed_at(created_at);
let request_evidence_json =
serde_json::to_value(&request_evidence).expect("request evidence json");
assert_struct_serialize_error_paths(&request_evidence, 2);
@@ -2068,7 +2104,7 @@ async fn order_revision_and_cancellation_dtos_serialize_deterministically() {
assert_eq!(request_evidence_json["observed_at"], 1_700_000_654);
let order_evidence =
- OrderEvidenceIngestRequest::new(event.clone()).with_observed_at(created_at);
+ TradeEvidenceIngestRequest::new(event.clone()).with_observed_at(created_at);
let order_evidence_json = serde_json::to_value(&order_evidence).expect("order evidence json");
assert_struct_serialize_error_paths(&order_evidence, 2);
assert_eq!(order_evidence_json["event"]["id"], event.id.as_str());
@@ -2084,11 +2120,13 @@ async fn order_decision_enqueue_accept_stores_event_queues_outbox_and_updates_st
.ingest_event(RadrootsEventIngest::new(request_event.clone(), 4_000))
.await
.expect("ingest request");
- let request = OrderDecisionEnqueueRequest::new(
+ let request = TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_decision("order-decision-accept"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays")
@@ -2133,7 +2171,7 @@ async fn order_decision_enqueue_accept_stores_event_queues_outbox_and_updates_st
.await
.expect("outbox operation")
.expect("outbox operation");
- assert_eq!(operation.operation_kind, ORDER_DECISION_OPERATION_KIND);
+ assert_eq!(operation.operation_kind, TRADE_DECISION_OPERATION_KIND);
let outbox_event = outbox
.get_event(receipt.outbox_event_id)
.await
@@ -2149,7 +2187,7 @@ async fn order_decision_enqueue_accept_stores_event_queues_outbox_and_updates_st
.await
.expect("status");
assert!(status.found);
- assert_eq!(status.status, OrderStatusKind::AgreedPendingRhi);
+ assert_eq!(status.status, TradeStatusKind::AgreedPendingRhi);
assert_eq!(status.event_count, 2);
assert_eq!(
status
@@ -2188,11 +2226,13 @@ async fn order_decision_enqueue_decline_stores_event_and_status_sees_declined()
decision.decision = RadrootsOrderDecisionOutcome::Declined {
reason: " unavailable ".to_owned(),
};
- let request = OrderDecisionEnqueueRequest::new(
+ let request = TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
decision,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays");
@@ -2209,7 +2249,7 @@ async fn order_decision_enqueue_decline_stores_event_and_status_sees_declined()
.status(status_request("order-decision-decline"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::Declined);
+ assert_eq!(status.status, TradeStatusKind::Declined);
assert_eq!(
status
.decision_event_id
@@ -2229,11 +2269,13 @@ async fn order_decision_enqueue_rejects_missing_request_evidence_before_mutation
.to_owned(),
relays: Some(RELAY.to_owned()),
};
- let request = OrderDecisionEnqueueRequest::new(
+ let request = TradeDecisionEnqueueRequest::new(
seller_actor(),
missing_request,
order_decision("order-decision-missing-request"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays");
@@ -2274,11 +2316,13 @@ async fn order_decision_enqueue_returns_sanitized_signer_errors_before_decision_
.ingest_event(RadrootsEventIngest::new(request_event.clone(), 4_200))
.await
.expect("ingest request");
- let request = OrderDecisionEnqueueRequest::new(
+ let request = TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_decision("order-decision-wrong-signer"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays");
@@ -2326,11 +2370,13 @@ async fn order_decision_enqueue_rejects_existing_decision_state_before_mutation(
decline.decision = RadrootsOrderDecisionOutcome::Declined {
reason: "too late".to_owned(),
};
- let request = OrderDecisionEnqueueRequest::new(
+ let request = TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
decline,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("target relays");
@@ -2355,7 +2401,7 @@ async fn order_decision_enqueue_rejects_existing_decision_state_before_mutation(
.status(status_request("order-decision-conflict"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::AgreedPendingRhi);
+ assert_eq!(status.status, TradeStatusKind::AgreedPendingRhi);
assert_eq!(
status
.decision_event_id
@@ -2383,7 +2429,7 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
let proposal_actor = seller_actor();
let proposal_plan = sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
proposal_actor.clone(),
request_event_ptr(&request_event),
request_event_ptr(&request_event),
@@ -2395,8 +2441,10 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
.enqueue_prepared_revision_proposal_with_explicit_signer(
&proposal_actor,
proposal_plan,
- SdkRelayTargetPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
+ RelayResolutionPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
.expect("proposal target relays"),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
Some(
SdkIdempotencyKey::new("order-lifecycle-revision-proposal")
.expect("proposal idempotency"),
@@ -2411,7 +2459,7 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
);
assert_eq!(
outbox_operation_kind(&sdk, proposal_receipt.outbox_operation_id).await,
- ORDER_REVISION_PROPOSAL_OPERATION_KIND
+ TRADE_REVISION_PROPOSAL_OPERATION_KIND
);
let stored_proposal = store
.get_event(proposal_receipt.signed_event_id.as_str())
@@ -2432,7 +2480,7 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
let revision_decision_actor = buyer_actor();
let revision_decision_plan = sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
revision_decision_actor.clone(),
request_event_ptr(&request_event),
order_event_ptr(&proposal_receipt.signed_event_id),
@@ -2444,8 +2492,10 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
.enqueue_prepared_revision_decision_with_explicit_signer(
&revision_decision_actor,
revision_decision_plan,
- SdkRelayTargetPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
+ RelayResolutionPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
.expect("revision decision target relays"),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&FixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2453,7 +2503,7 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
.expect("enqueue revision decision");
assert_eq!(
outbox_operation_kind(&sdk, revision_decision_receipt.outbox_operation_id).await,
- ORDER_REVISION_DECISION_OPERATION_KIND
+ TRADE_REVISION_DECISION_OPERATION_KIND
);
assert_eq!(
store
@@ -2470,7 +2520,7 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
.status(status_request("order-lifecycle-agreement"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::AgreedPendingRhi);
+ assert_eq!(status.status, TradeStatusKind::AgreedPendingRhi);
assert_eq!(status.event_count, 3);
assert_eq!(
status
@@ -2495,7 +2545,7 @@ async fn order_revision_lifecycle_accepts_proposal_and_waits_for_rhi() {
assert!(!status.lifecycle_terminal);
assert_eq!(
status.next_action,
- OrderStatusNextActionKind::AwaitRhiValidation
+ TradeStatusNextActionKind::AwaitRhiValidation
);
assert!(status.evidence.has_request);
assert!(!status.evidence.has_decision);
@@ -2527,12 +2577,14 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif
let proposal_receipt = sdk
.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
request_event_ptr(&request_event),
proposal,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("proposal target relays"),
@@ -2546,7 +2598,7 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif
.status(status_request("order-lifecycle-pending-revision"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::RevisionProposed);
+ assert_eq!(status.status, TradeStatusKind::RevisionProposed);
assert_eq!(status.event_count, 2);
assert!(status.agreement_event_id.is_none());
assert_eq!(
@@ -2569,11 +2621,13 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif
let decision_error = sdk
.trades()
.enqueue_decision_with_explicit_signer(
- OrderDecisionEnqueueRequest::new(
+ TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_decision("order-lifecycle-pending-revision"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("decision target relays"),
@@ -2594,12 +2648,14 @@ async fn order_revision_proposal_status_exposes_pending_and_blocks_follow_on_lif
let proposal_error = sdk
.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_event_ptr(&proposal_receipt.signed_event_id),
blocked_proposal,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("blocked proposal target relays"),
@@ -2638,12 +2694,14 @@ async fn order_declined_revision_finalizes_declined_negotiation() {
let proposal_receipt = sdk
.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
request_event_ptr(&request_event),
proposal.clone(),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("proposal target relays"),
@@ -2661,12 +2719,14 @@ async fn order_declined_revision_finalizes_declined_negotiation() {
let declined_revision_receipt = sdk
.trades()
.enqueue_revision_decision_with_explicit_signer(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
buyer_actor(),
request_event_ptr(&request_event),
order_event_ptr(&proposal_receipt.signed_event_id),
declined_revision,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("declined revision target relays"),
@@ -2680,7 +2740,7 @@ async fn order_declined_revision_finalizes_declined_negotiation() {
.status(status_request("order-lifecycle-declined-revision"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::Declined);
+ assert_eq!(status.status, TradeStatusKind::Declined);
assert_eq!(status.event_count, 3);
assert!(status.agreement_event_id.is_none());
assert_eq!(
@@ -2695,7 +2755,7 @@ async fn order_declined_revision_finalizes_declined_negotiation() {
Some(declined_revision_receipt.signed_event_id.as_str())
);
assert!(status.lifecycle_terminal);
- assert_eq!(status.next_action, OrderStatusNextActionKind::Terminal);
+ assert_eq!(status.next_action, TradeStatusNextActionKind::Terminal);
assert!(!status.eligibility.can_decide);
assert!(!status.eligibility.can_propose_revision);
assert!(!status.eligibility.can_decide_revision);
@@ -2709,12 +2769,14 @@ async fn order_declined_revision_finalizes_declined_negotiation() {
let second_decision_error = sdk
.trades()
.enqueue_revision_decision_with_explicit_signer(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
buyer_actor(),
request_event_ptr(&request_event),
order_event_ptr(&proposal_receipt.signed_event_id),
second_decision,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("second decision target relays"),
@@ -2748,7 +2810,7 @@ async fn order_cancel_lifecycle_enqueue_updates_status() {
let cancellation_actor = buyer_actor();
let cancellation_plan = sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
cancellation_actor.clone(),
request_event_ptr(&request_event),
request_event_ptr(&request_event),
@@ -2760,8 +2822,10 @@ async fn order_cancel_lifecycle_enqueue_updates_status() {
.enqueue_prepared_cancellation_with_explicit_signer(
&cancellation_actor,
cancellation_plan,
- SdkRelayTargetPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
+ RelayResolutionPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public)
.expect("cancellation target relays"),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
Some(
SdkIdempotencyKey::new("order-lifecycle-cancel").expect("cancellation idempotency"),
),
@@ -2774,7 +2838,7 @@ async fn order_cancel_lifecycle_enqueue_updates_status() {
assert_eq!(cancellation.previous_event_id, request_event_id);
assert_eq!(
outbox_operation_kind(&sdk, cancellation.outbox_operation_id).await,
- ORDER_CANCELLATION_OPERATION_KIND
+ TRADE_CANCELLATION_OPERATION_KIND
);
assert_eq!(
store
@@ -2788,12 +2852,14 @@ async fn order_cancel_lifecycle_enqueue_updates_status() {
let replay = sdk
.trades()
.enqueue_cancellation_with_explicit_signer(
- OrderCancellationEnqueueRequest::new(
+ TradeCancellationEnqueueRequest::new(
buyer_actor(),
request_event_ptr(&request_event),
request_event_ptr(&request_event),
order_cancellation("order-lifecycle-cancel"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("replay target relays")
@@ -2811,7 +2877,7 @@ async fn order_cancel_lifecycle_enqueue_updates_status() {
.status(status_request("order-lifecycle-cancel"))
.await
.expect("status");
- assert_eq!(status.status, OrderStatusKind::Cancelled);
+ assert_eq!(status.status, TradeStatusKind::Cancelled);
assert_eq!(
status
.cancellation_event_id
@@ -2820,7 +2886,7 @@ async fn order_cancel_lifecycle_enqueue_updates_status() {
Some(cancellation.signed_event_id.as_str())
);
assert!(status.lifecycle_terminal);
- assert_eq!(status.next_action, OrderStatusNextActionKind::Terminal);
+ assert_eq!(status.next_action, TradeStatusNextActionKind::Terminal);
assert!(status.evidence.has_request);
assert!(!status.evidence.has_decision);
assert!(status.evidence.has_cancellation);
@@ -2837,7 +2903,7 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() {
let missing = sdk
.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
request_event_ptr(&request_event),
@@ -2846,7 +2912,9 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() {
&request_event_id,
&request_event_id,
),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("missing target relays"),
@@ -2871,11 +2939,13 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() {
let decision_receipt = sdk
.trades()
.enqueue_decision_with_explicit_signer(
- OrderDecisionEnqueueRequest::new(
+ TradeDecisionEnqueueRequest::new(
seller_actor(),
request_event_ptr(&request_event),
order_decision("order-lifecycle-invalid"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("decision target relays"),
@@ -2895,12 +2965,14 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() {
let revision_error = sdk
.trades()
.enqueue_revision_decision_with_explicit_signer(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
buyer_actor(),
request_event_ptr(&request_event),
order_event_ptr(&decision_receipt.signed_event_id),
revision_without_proposal,
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("revision decision target relays"),
@@ -2916,12 +2988,14 @@ async fn order_lifecycle_enqueue_rejects_invalid_state_before_mutation() {
let cancellation_error = sdk
.trades()
.enqueue_cancellation_with_explicit_signer(
- OrderCancellationEnqueueRequest::new(
+ TradeCancellationEnqueueRequest::new(
buyer_actor(),
request_event_ptr(&request_event),
order_event_ptr(&decision_receipt.signed_event_id),
order_cancellation("order-lifecycle-invalid"),
- SdkRelayTargetPolicy::UseConfiguredRelays,
+ RelayResolutionPolicy::ConfiguredRelays,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays([RELAY], SdkRelayUrlPolicy::Public)
.expect("cancellation target relays"),
@@ -2948,24 +3022,24 @@ async fn order_status_returns_not_found_for_missing_local_order() {
let (_tempdir, sdk, _store) = directory_sdk_and_store().await;
let request = status_request("order-1");
- assert_eq!(request.limit, ORDER_STATUS_DEFAULT_LIMIT);
+ assert_eq!(request.limit, TRADE_STATUS_DEFAULT_LIMIT);
let receipt = sdk.trades().status(request).await.expect("status");
assert!(!receipt.found);
assert_eq!(receipt.order_id.as_str(), "order-1");
- assert_eq!(receipt.source, SdkOrderStatusSource::LocalEventStore);
+ assert_eq!(receipt.source, SdkTradeStatusSource::LocalEventStore);
assert_eq!(receipt.event_count, 0);
- assert_eq!(receipt.limit_applied, ORDER_STATUS_DEFAULT_LIMIT);
+ assert_eq!(receipt.limit_applied, TRADE_STATUS_DEFAULT_LIMIT);
assert!(receipt.event_ids.is_empty());
- assert_eq!(receipt.status, OrderStatusKind::Missing);
+ assert_eq!(receipt.status, TradeStatusKind::Missing);
assert!(receipt.listing_addr.is_none());
assert!(receipt.buyer_pubkey.is_none());
assert!(receipt.seller_pubkey.is_none());
assert!(receipt.economics.is_none());
- assert_eq!(receipt.next_action, OrderStatusNextActionKind::NoLocalOrder);
+ assert_eq!(receipt.next_action, TradeStatusNextActionKind::NoLocalOrder);
assert_eq!(receipt.evidence.event_count, 0);
- assert_eq!(receipt.evidence.limit_applied, ORDER_STATUS_DEFAULT_LIMIT);
+ assert_eq!(receipt.evidence.limit_applied, TRADE_STATUS_DEFAULT_LIMIT);
assert!(!receipt.evidence.has_request);
assert!(!receipt.evidence.has_issues);
assert!(!receipt.eligibility.can_decide);
@@ -2986,33 +3060,33 @@ async fn order_status_rejects_invalid_limits_before_querying() {
.expect_err("zero limit");
let too_large = sdk
.trades()
- .status(status_request("order-1").with_limit(ORDER_STATUS_MAX_LIMIT + 1))
+ .status(status_request("order-1").with_limit(TRADE_STATUS_MAX_LIMIT + 1))
.await
.expect_err("too large");
assert!(matches!(
zero,
- RadrootsSdkError::OrderStatusLimitInvalid {
+ RadrootsSdkError::TradeStatusLimitInvalid {
limit: 0,
min: 1,
- max: ORDER_STATUS_MAX_LIMIT
+ max: TRADE_STATUS_MAX_LIMIT
}
));
assert!(matches!(
too_large,
- RadrootsSdkError::OrderStatusLimitInvalid {
+ RadrootsSdkError::TradeStatusLimitInvalid {
limit,
min: 1,
- max: ORDER_STATUS_MAX_LIMIT
- } if limit == ORDER_STATUS_MAX_LIMIT + 1
+ max: TRADE_STATUS_MAX_LIMIT
+ } if limit == TRADE_STATUS_MAX_LIMIT + 1
));
}
#[test]
fn order_status_parse_rejects_invalid_order_ids() {
- let error = OrderStatusRequest::parse("bad order id").expect_err("invalid order id");
+ let error = TradeStatusRequest::parse("bad order id").expect_err("invalid order id");
- assert!(matches!(error, RadrootsSdkError::InvalidOrderId { .. }));
+ assert!(matches!(error, RadrootsSdkError::InvalidTradeId { .. }));
}
#[tokio::test]
@@ -3025,7 +3099,13 @@ async fn order_status_contract_dtos_serialize_deterministically() {
assert_eq!(
request_json,
serde_json::json!({
- "order_id": "order-1",
+ "locator": {
+ "trade_id": "order-1",
+ "root_event_id": null,
+ "listing_addr": null,
+ "buyer_pubkey": null,
+ "seller_pubkey": null
+ },
"limit": 25
})
);
@@ -3035,6 +3115,10 @@ async fn order_status_contract_dtos_serialize_deterministically() {
assert_eq!(receipt_json["source"], "local_event_store");
assert_eq!(receipt_json["status"], "missing");
+ assert_eq!(receipt_json["locator"], request_json["locator"]);
+ assert_eq!(receipt_json["order_id"], "order-1");
+ assert_eq!(receipt_json["root_event_id"], serde_json::Value::Null);
+ assert_eq!(receipt_json["ambiguity_candidates"], serde_json::json!([]));
assert_eq!(receipt_json["listing_addr"], serde_json::Value::Null);
assert_eq!(receipt_json["buyer_pubkey"], serde_json::Value::Null);
assert_eq!(receipt_json["seller_pubkey"], serde_json::Value::Null);
@@ -3052,8 +3136,8 @@ async fn order_status_contract_dtos_serialize_deterministically() {
assert_eq!(receipt_json["eligibility"]["can_propose_revision"], false);
assert_eq!(receipt_json["eligibility"]["can_decide_revision"], false);
- let issue = SdkOrderStatusIssue {
- kind: SdkOrderStatusIssueKind::DecisionPayloadInvalid,
+ let issue = SdkTradeStatusIssue {
+ kind: SdkTradeStatusIssueKind::DecisionPayloadInvalid,
event_ids: vec![deterministic_event_id("issue-event")],
};
assert_eq!(issue.code(), "decision_payload_invalid");
@@ -3077,7 +3161,7 @@ fn order_status_issue_mapping_preserves_kind_codes_and_event_ids() {
RadrootsOrderIssue::$variant {
event_id: event_id.clone(),
},
- SdkOrderStatusIssueKind::$kind,
+ SdkTradeStatusIssueKind::$kind,
$code,
vec![event_id],
)
@@ -3094,7 +3178,7 @@ fn order_status_issue_mapping_preserves_kind_codes_and_event_ids() {
RadrootsOrderIssue::$variant {
event_ids: event_ids.clone(),
},
- SdkOrderStatusIssueKind::$kind,
+ SdkTradeStatusIssueKind::$kind,
$code,
event_ids,
)
@@ -3104,7 +3188,7 @@ fn order_status_issue_mapping_preserves_kind_codes_and_event_ids() {
let cases = vec![
(
RadrootsOrderIssue::MissingRequest,
- SdkOrderStatusIssueKind::MissingRequest,
+ SdkTradeStatusIssueKind::MissingRequest,
"missing_request",
Vec::new(),
),
@@ -3412,7 +3496,7 @@ fn order_status_issue_mapping_preserves_kind_codes_and_event_ids() {
event_id: event_id.clone(),
reason: "fixture validation failed".to_owned(),
},
- SdkOrderStatusIssueKind::DeterministicValidationFailure,
+ SdkTradeStatusIssueKind::DeterministicValidationFailure,
"deterministic_validation_failure",
vec![event_id],
)
@@ -3425,7 +3509,7 @@ fn order_status_issue_mapping_preserves_kind_codes_and_event_ids() {
expected_event_id: expected_event_id.clone(),
current_event_id: current_event_id.clone(),
},
- SdkOrderStatusIssueKind::StaleListingEvent,
+ SdkTradeStatusIssueKind::StaleListingEvent,
"stale_listing_event",
vec![expected_event_id, current_event_id],
)
@@ -3433,7 +3517,7 @@ fn order_status_issue_mapping_preserves_kind_codes_and_event_ids() {
];
for (issue, expected_kind, expected_code, expected_event_ids) in cases {
- let sdk_issue = SdkOrderStatusIssue::from(issue);
+ let sdk_issue = SdkTradeStatusIssue::from(issue);
assert_eq!(sdk_issue.kind, expected_kind);
assert_eq!(sdk_issue.code(), expected_code);
@@ -3466,7 +3550,7 @@ async fn order_status_projects_local_request_and_decision_events() {
assert!(receipt.found);
assert_eq!(receipt.order_id.as_str(), "order-1");
- assert_eq!(receipt.source, SdkOrderStatusSource::LocalEventStore);
+ assert_eq!(receipt.source, SdkTradeStatusSource::LocalEventStore);
assert_eq!(receipt.event_count, 2);
assert_eq!(receipt.limit_applied, 1_000);
assert_eq!(
@@ -3477,7 +3561,7 @@ async fn order_status_projects_local_request_and_decision_events() {
.collect::<Vec<_>>(),
vec![request_event.id.as_str(), decision_event.id.as_str()]
);
- assert_eq!(receipt.status, OrderStatusKind::AgreedPendingRhi);
+ assert_eq!(receipt.status, TradeStatusKind::AgreedPendingRhi);
assert_eq!(
receipt
.request_event_id
@@ -3510,7 +3594,7 @@ async fn order_status_projects_local_request_and_decision_events() {
assert!(!receipt.lifecycle_terminal);
assert_eq!(
receipt.next_action,
- OrderStatusNextActionKind::AwaitRhiValidation
+ TradeStatusNextActionKind::AwaitRhiValidation
);
assert_eq!(receipt.evidence.event_count, 2);
assert!(receipt.evidence.has_request);
@@ -3545,7 +3629,7 @@ async fn order_status_reports_limited_local_results() {
.expect("status");
assert!(receipt.found);
- assert_eq!(receipt.status, OrderStatusKind::Requested);
+ assert_eq!(receipt.status, TradeStatusKind::Requested);
assert_eq!(receipt.event_count, 1);
assert_eq!(receipt.limit_applied, 1);
assert_eq!(
@@ -3572,7 +3656,7 @@ async fn order_status_reports_limited_local_results() {
}
#[tokio::test]
-async fn order_status_reports_typed_reducer_issues() {
+async fn order_status_reports_root_ambiguity_for_reused_trade_ids() {
let (_tempdir, sdk, store) = directory_sdk_and_store().await;
let first_request_event = signed_order_request_event("order-1", 27);
let second_request_event = signed_order_request_event("order-1", 28);
@@ -3593,8 +3677,8 @@ async fn order_status_reports_typed_reducer_issues() {
.await
.expect("status");
- assert!(receipt.found);
- assert_eq!(receipt.status, OrderStatusKind::Invalid);
+ assert!(!receipt.found);
+ assert_eq!(receipt.status, TradeStatusKind::Ambiguous);
assert_eq!(receipt.event_count, 2);
assert_eq!(
receipt
@@ -3607,17 +3691,21 @@ async fn order_status_reports_typed_reducer_issues() {
second_request_event.id.as_str()
]
);
- let issue = receipt
- .issues
+ assert!(receipt.issues.is_empty());
+ let candidate_roots = receipt
+ .ambiguity_candidates
.iter()
- .find(|issue| issue.kind == SdkOrderStatusIssueKind::MultipleRequests)
- .expect("multiple request issue");
+ .map(|candidate| {
+ candidate
+ .locator
+ .root_event_id
+ .as_ref()
+ .map(RadrootsEventId::as_str)
+ .expect("root event id")
+ })
+ .collect::<Vec<_>>();
assert_eq!(
- issue
- .event_ids
- .iter()
- .map(RadrootsEventId::as_str)
- .collect::<Vec<_>>(),
+ candidate_roots,
vec![
first_request_event.id.as_str(),
second_request_event.id.as_str()
diff --git a/crates/sdk/tests/runtime_foundation.rs b/crates/sdk/tests/runtime_foundation.rs
@@ -408,22 +408,22 @@ fn sdk_error_contract_methods_cover_all_variants() {
vec![RadrootsSdkRecoveryAction::RetryOperationWithSameIdempotencyKey],
),
(
- RadrootsSdkError::OrderStatusLimitInvalid {
+ RadrootsSdkError::TradeStatusLimitInvalid {
limit: 0,
min: 1,
max: 1000,
},
- "order_status_limit_invalid",
+ "trade_status_limit_invalid",
RadrootsSdkErrorClass::Request,
false,
vec![RadrootsSdkRecoveryAction::FixRequest],
),
(
- RadrootsSdkError::InvalidOrderId {
+ RadrootsSdkError::InvalidTradeId {
value: "bad".to_owned(),
message: "invalid".to_owned(),
},
- "invalid_order_id",
+ "invalid_trade_id",
RadrootsSdkErrorClass::Request,
false,
vec![RadrootsSdkRecoveryAction::FixRequest],
@@ -892,7 +892,7 @@ fn sdk_examples_stay_on_product_api_boundary() {
assert!(local_enqueue.contains("enqueue_prepared_publish"));
assert!(!local_enqueue.contains("enqueue_prepared_publish_with_explicit_signer"));
assert!(local_enqueue.contains("push_outbox_with_adapter"));
- assert!(local_enqueue.contains("OrderStatusRequest"));
+ assert!(local_enqueue.contains("TradeStatusRequest"));
let myc_setup = include_str!("../examples/sdk_v1_myc_nip46_signer_setup.rs");
assert!(myc_setup.contains("RadrootsSdkMycNip46Signer"));
diff --git a/crates/sdk/tests/source_boundary.rs b/crates/sdk/tests/source_boundary.rs
@@ -39,52 +39,53 @@ const FORBIDDEN_SDK_SOURCE_CONCEPTS: &[ForbiddenSdkConcept] = &[
},
];
-const REQUIRED_ORDER_RUNTIME_EXPORTS: &[&str] = &[
- "ORDER_CANCELLATION_OPERATION_KIND",
- "ORDER_DECISION_OPERATION_KIND",
- "ORDER_REVISION_DECISION_OPERATION_KIND",
- "ORDER_REVISION_PROPOSAL_OPERATION_KIND",
- "ORDER_STATUS_DEFAULT_LIMIT",
- "ORDER_STATUS_MAX_LIMIT",
- "ORDER_SUBMIT_OPERATION_KIND",
- "OrderCancellationEnqueueRequest",
- "OrderCancellationPlan",
- "OrderCancellationPrepareRequest",
- "OrderCancellationReceipt",
- "OrderDecisionEnqueueRequest",
- "OrderDecisionPlan",
- "OrderDecisionPrepareRequest",
- "OrderDecisionReceipt",
- "OrderEvidenceIngestReceipt",
- "OrderEvidenceIngestRequest",
- "OrderRequestEvidenceIngestReceipt",
- "OrderRequestEvidenceIngestRequest",
- "OrderRevisionDecisionEnqueueRequest",
- "OrderRevisionDecisionPlan",
- "OrderRevisionDecisionPrepareRequest",
- "OrderRevisionDecisionReceipt",
- "OrderRevisionProposalEnqueueRequest",
- "OrderRevisionProposalPlan",
- "OrderRevisionProposalPrepareRequest",
- "OrderRevisionProposalReceipt",
- "OrderStatusEligibility",
- "OrderStatusEvidenceSummary",
- "OrderStatusKind",
- "OrderStatusNextActionKind",
- "OrderStatusReceipt",
- "OrderStatusRequest",
- "OrderSubmitEnqueueRequest",
- "OrderSubmitPlan",
- "OrderSubmitPrepareRequest",
- "OrderSubmitReceipt",
- "OrderWorkflowEnqueueReceipt",
- "OrderWorkflowIdempotencyReceipt",
- "OrderWorkflowKind",
- "OrderWorkflowPlan",
- "OrderWorkflowRetryAdvice",
- "SdkOrderStatusIssue",
- "SdkOrderStatusIssueKind",
- "SdkOrderStatusSource",
+const REQUIRED_TRADE_RUNTIME_EXPORTS: &[&str] = &[
+ "TRADE_CANCELLATION_OPERATION_KIND",
+ "TRADE_DECISION_OPERATION_KIND",
+ "TRADE_REVISION_DECISION_OPERATION_KIND",
+ "TRADE_REVISION_PROPOSAL_OPERATION_KIND",
+ "TRADE_STATUS_DEFAULT_LIMIT",
+ "TRADE_STATUS_MAX_LIMIT",
+ "TRADE_SUBMIT_OPERATION_KIND",
+ "TradeCancellationEnqueueRequest",
+ "TradeCancellationPlan",
+ "TradeCancellationPrepareRequest",
+ "TradeCancellationReceipt",
+ "TradeDecisionEnqueueRequest",
+ "TradeDecisionPlan",
+ "TradeDecisionPrepareRequest",
+ "TradeDecisionReceipt",
+ "TradeEvidenceIngestReceipt",
+ "TradeEvidenceIngestRequest",
+ "TradeRequestEvidenceIngestReceipt",
+ "TradeRequestEvidenceIngestRequest",
+ "TradeRevisionDecisionEnqueueRequest",
+ "TradeRevisionDecisionPlan",
+ "TradeRevisionDecisionPrepareRequest",
+ "TradeRevisionDecisionReceipt",
+ "TradeRevisionProposalEnqueueRequest",
+ "TradeRevisionProposalPlan",
+ "TradeRevisionProposalPrepareRequest",
+ "TradeRevisionProposalReceipt",
+ "TradeStatusAmbiguityCandidate",
+ "TradeStatusEligibility",
+ "TradeStatusEvidenceSummary",
+ "TradeStatusKind",
+ "TradeStatusNextActionKind",
+ "TradeStatusReceipt",
+ "TradeStatusRequest",
+ "TradeSubmitEnqueueRequest",
+ "TradeSubmitPlan",
+ "TradeSubmitPrepareRequest",
+ "TradeSubmitReceipt",
+ "TradeWorkflowEnqueueReceipt",
+ "TradeWorkflowIdempotencyReceipt",
+ "TradeWorkflowKind",
+ "TradeWorkflowPlan",
+ "TradeWorkflowRetryAdvice",
+ "SdkTradeStatusIssue",
+ "SdkTradeStatusIssueKind",
+ "SdkTradeStatusSource",
];
const REQUIRED_DVM_RUNTIME_EXPORTS: &[&str] = &[
@@ -98,10 +99,24 @@ const REQUIRED_DVM_RUNTIME_EXPORTS: &[&str] = &[
"DvmTradeTransitionProofRequestPayload",
"DvmValidationReceiptIngestReceipt",
"DvmValidationReceiptIngestRequest",
- "SdkDvmInventoryBinWitness",
+ "RadrootsTradeInventoryBinWitnessDto",
+];
+
+const REQUIRED_TRADE_POLICY_EXPORTS: &[&str] = &[
+ "AckPolicy",
+ "PublishMode",
+ "RelayResolutionPolicy",
+ "SdkTradeIdempotencyRecord",
+ "PrivacyPreflightReceipt",
+ "PrivacyPreflightStatus",
+ "ProductSensitivityField",
+ "SDK_TRADE_PROJECTION_CACHE_VERSION",
+ "SdkTradeProjectionCache",
+ "SdkTradeProjectionCacheKey",
+ "SdkTradeProjectionCacheRecord",
];
-const REQUIRED_ORDERS_CLIENT_METHODS: &[&str] = &[
+const REQUIRED_TRADES_CLIENT_METHODS: &[&str] = &[
"pub async fn ingest_evidence(",
"pub async fn ingest_request_evidence(",
"pub fn prepare_submit(",
@@ -131,7 +146,7 @@ const REQUIRED_DVM_CLIENT_METHODS: &[&str] = &[
const REQUIRED_DVM_CLIENT_CONFIGURED_SIGNER_METHODS: &[&str] =
&["pub async fn enqueue_trade_transition_proof_request("];
-const REQUIRED_ORDERS_CLIENT_ADVANCED_SIGNER_METHODS: &[&str] = &[
+const REQUIRED_TRADES_CLIENT_ADVANCED_SIGNER_METHODS: &[&str] = &[
"pub async fn enqueue_submit_with_explicit_signer(",
"pub async fn enqueue_prepared_submit_with_explicit_signer(",
"pub async fn enqueue_decision_with_explicit_signer(",
@@ -176,6 +191,54 @@ const FORBIDDEN_ORDER_RUNTIME_PUBLIC_EXPORTS: &[&str] = &[
"ORDER_SETTLEMENT_DECISION_OPERATION_KIND",
];
+const FORBIDDEN_LEGACY_ORDER_PRODUCT_EXPORTS: &[&str] = &[
+ "ORDER_CANCELLATION_OPERATION_KIND",
+ "ORDER_DECISION_OPERATION_KIND",
+ "ORDER_REVISION_DECISION_OPERATION_KIND",
+ "ORDER_REVISION_PROPOSAL_OPERATION_KIND",
+ "ORDER_STATUS_DEFAULT_LIMIT",
+ "ORDER_STATUS_MAX_LIMIT",
+ "ORDER_SUBMIT_OPERATION_KIND",
+ "OrderCancellationEnqueueRequest",
+ "OrderCancellationPlan",
+ "OrderCancellationPrepareRequest",
+ "OrderCancellationReceipt",
+ "OrderDecisionEnqueueRequest",
+ "OrderDecisionPlan",
+ "OrderDecisionPrepareRequest",
+ "OrderDecisionReceipt",
+ "OrderEvidenceIngestReceipt",
+ "OrderEvidenceIngestRequest",
+ "OrderRequestEvidenceIngestReceipt",
+ "OrderRequestEvidenceIngestRequest",
+ "OrderRevisionDecisionEnqueueRequest",
+ "OrderRevisionDecisionPlan",
+ "OrderRevisionDecisionPrepareRequest",
+ "OrderRevisionDecisionReceipt",
+ "OrderRevisionProposalEnqueueRequest",
+ "OrderRevisionProposalPlan",
+ "OrderRevisionProposalPrepareRequest",
+ "OrderRevisionProposalReceipt",
+ "OrderStatusEligibility",
+ "OrderStatusEvidenceSummary",
+ "OrderStatusReceipt",
+ "OrderStatusRequest",
+ "OrderSubmitEnqueueRequest",
+ "OrderSubmitPlan",
+ "OrderSubmitPrepareRequest",
+ "OrderSubmitReceipt",
+ "OrderWorkflowEnqueueReceipt",
+ "OrderWorkflowIdempotencyReceipt",
+ "OrderWorkflowKind",
+ "OrderWorkflowPlan",
+ "OrderWorkflowRetryAdvice",
+ "SdkDvmInventoryBinWitness",
+ "SdkOrderStatusIssue",
+ "SdkOrderStatusIssueKind",
+ "SdkOrderStatusSource",
+ "TradeProtocolClient",
+];
+
const FORBIDDEN_ORDER_RUNTIME_METHODS: &[&str] = &[
"accept_settlement",
"checkout",
@@ -298,10 +361,24 @@ fn order_runtime_public_exports_are_explicit() {
"src/lib.rs must not wildcard-export the order runtime"
);
- for export in REQUIRED_ORDER_RUNTIME_EXPORTS {
+ for export in REQUIRED_TRADE_RUNTIME_EXPORTS {
+ assert!(
+ source.contains(export),
+ "src/lib.rs must explicitly expose trade SDK runtime export `{export}`"
+ );
+ }
+
+ for export in REQUIRED_TRADE_POLICY_EXPORTS {
assert!(
source.contains(export),
- "src/lib.rs must explicitly expose order SDK runtime export `{export}`"
+ "src/lib.rs must explicitly expose trade policy export `{export}`"
+ );
+ }
+
+ for forbidden in FORBIDDEN_LEGACY_ORDER_PRODUCT_EXPORTS {
+ assert!(
+ !source.contains(forbidden),
+ "src/lib.rs must not expose legacy order SDK product export `{forbidden}`"
);
}
}
@@ -352,14 +429,14 @@ fn orders_client_surface_is_inventory_guarded() {
"src/orders_runtime.rs must own TradesClient runtime methods"
);
- for method in REQUIRED_ORDERS_CLIENT_METHODS {
+ for method in REQUIRED_TRADES_CLIENT_METHODS {
assert!(
source.contains(method),
"TradesClient must expose inventory-guarded method `{method}`"
);
}
- for method in REQUIRED_ORDERS_CLIENT_ADVANCED_SIGNER_METHODS {
+ for method in REQUIRED_TRADES_CLIENT_ADVANCED_SIGNER_METHODS {
assert!(
source.contains(method),
"TradesClient must expose explicit-signer advanced method `{method}`"
@@ -427,6 +504,11 @@ fn product_clients_remain_thin_sdk_handles() {
"ListingsClient",
"MarketClient",
"SyncClient",
+ "TradeBuyerClient",
+ "TradeResyncClient",
+ "TradeSellerClient",
+ "TradeStatusClient",
+ "TradeValidationClient",
"TradesClient",
] {
assert!(
diff --git a/crates/sdk/tests/unit/dvm_runtime_tests.rs b/crates/sdk/tests/unit/dvm_runtime_tests.rs
@@ -1,7 +1,7 @@
use super::{
DvmProofMode, DvmTradeTransitionProofEnqueueRequest, DvmTradeTransitionProofPrepareRequest,
- DvmValidationReceiptIngestRequest, SdkDvmInventoryBinWitness, dvm_trade_transition_proof_plan,
- sdk_timestamp_ms,
+ DvmValidationReceiptIngestRequest, RadrootsTradeInventoryBinWitnessDto,
+ dvm_trade_transition_proof_plan, sdk_timestamp_ms,
};
use crate::{
RadrootsSdkError, RadrootsSdkTimestamp, SdkIdempotencyKey, SdkRelayTargetPolicy,
@@ -11,7 +11,7 @@ use radroots_authority::RadrootsActorContext;
use radroots_events::{
RadrootsNostrEvent,
contract::RadrootsActorRole,
- ids::{RadrootsEventId, RadrootsListingAddress, RadrootsPublicKey},
+ ids::{RadrootsEventId, RadrootsInventoryBinId, RadrootsListingAddress, RadrootsPublicKey},
kinds::KIND_TRADE_TRANSITION_PROOF_REQUEST,
};
use radroots_trade::validation_receipt::RadrootsValidationReceiptProofSystem;
@@ -60,15 +60,30 @@ fn trade_transition_proof_plan_builds_microstandard_wire_payload() {
);
assert_eq!(
plan.frozen_draft.tags[1],
- vec!["i", event_id('1').as_str(), "event", "listing"]
+ vec![
+ "i",
+ event_id('1').as_str(),
+ "event",
+ "radroots:listing_event"
+ ]
);
assert_eq!(
plan.frozen_draft.tags[2],
- vec!["i", event_id('2').as_str(), "event", "order_request"]
+ vec![
+ "i",
+ event_id('2').as_str(),
+ "event",
+ "radroots:order_request_event"
+ ]
);
assert_eq!(
plan.frozen_draft.tags[3],
- vec!["i", event_id('3').as_str(), "event", "order_decision"]
+ vec![
+ "i",
+ event_id('3').as_str(),
+ "event",
+ "radroots:order_decision_event"
+ ]
);
assert_eq!(plan.frozen_draft.tags[4], vec!["p", WORKER]);
}
@@ -110,8 +125,8 @@ fn trade_transition_proof_plan_rejects_inventory_and_sp1_identity_edges() {
event_id('1'),
event_id('2'),
event_id('3'),
- vec![SdkDvmInventoryBinWitness {
- bin_id: "bin-1".to_owned(),
+ vec![RadrootsTradeInventoryBinWitnessDto {
+ bin_id: RadrootsInventoryBinId::parse("bin-1").expect("bin id"),
listing_capacity: 2,
previous_reserved: 3,
}],
@@ -124,22 +139,11 @@ fn trade_transition_proof_plan_rejects_inventory_and_sp1_identity_edges() {
Err(RadrootsSdkError::InvalidRequest { .. })
));
- let empty_bin_id = DvmTradeTransitionProofPrepareRequest::new(
- service_actor(),
- worker_pubkey(),
- listing_addr(),
- event_id('1'),
- event_id('2'),
- event_id('3'),
- vec![SdkDvmInventoryBinWitness {
- bin_id: " ".to_owned(),
- listing_capacity: 2,
- previous_reserved: 1,
- }],
- );
+ let invalid_previous_state_root =
+ proof_request(service_actor()).with_previous_state_root("not-a-hash");
assert!(matches!(
dvm_trade_transition_proof_plan(
- empty_bin_id,
+ invalid_previous_state_root,
RadrootsSdkTimestamp::from_unix_seconds(1_700_000_000),
),
Err(RadrootsSdkError::InvalidRequest { .. })
@@ -344,17 +348,17 @@ fn proof_request(actor: RadrootsActorContext) -> DvmTradeTransitionProofPrepareR
event_id('1'),
event_id('2'),
event_id('3'),
- vec![SdkDvmInventoryBinWitness {
- bin_id: "bin-1".to_owned(),
+ vec![RadrootsTradeInventoryBinWitnessDto {
+ bin_id: RadrootsInventoryBinId::parse("bin-1").expect("bin id"),
listing_capacity: 5,
previous_reserved: 1,
}],
)
}
-fn inventory_bins() -> Vec<SdkDvmInventoryBinWitness> {
- vec![SdkDvmInventoryBinWitness {
- bin_id: "bin-1".to_owned(),
+fn inventory_bins() -> Vec<RadrootsTradeInventoryBinWitnessDto> {
+ vec![RadrootsTradeInventoryBinWitnessDto {
+ bin_id: RadrootsInventoryBinId::parse("bin-1").expect("bin id"),
listing_capacity: 5,
previous_reserved: 1,
}]
diff --git a/crates/sdk/tests/unit/error_tests.rs b/crates/sdk/tests/unit/error_tests.rs
@@ -354,8 +354,8 @@ fn sdk_error_contract_methods_cover_representative_classes_and_details() {
existing_digest_prefix: "existing".to_owned(),
new_digest_prefix: "new".to_owned(),
},
- RadrootsSdkError::order_status_limit_invalid(0, 1, 100),
- RadrootsSdkError::invalid_order_id("bad order", "bad id"),
+ RadrootsSdkError::trade_status_limit_invalid(0, 1, 100),
+ RadrootsSdkError::invalid_trade_id("bad order", "bad id"),
RadrootsSdkError::ProductSyncUnsupported {
operation: "sync.push_outbox",
required_feature: "relay-runtime",
diff --git a/crates/sdk/tests/unit/idempotency_tests.rs b/crates/sdk/tests/unit/idempotency_tests.rs
@@ -1,5 +1,6 @@
-use super::SdkIdempotencyKey;
+use super::{SdkIdempotencyKey, SdkTradeIdempotencyRecord};
use crate::RadrootsSdkError;
+use radroots_events::ids::{RadrootsEventId, RadrootsPublicKey};
#[path = "../support/serializer_failure.rs"]
mod serializer_failure;
@@ -49,3 +50,42 @@ fn idempotency_key_reports_serializer_failures() {
assert_struct_serialize_error_paths(&key, 2);
}
+
+#[test]
+fn trade_idempotency_record_binds_payload_and_reports_conflicts() {
+ let record = SdkTradeIdempotencyRecord {
+ idempotency_key: SdkIdempotencyKey::new("trade-idempotent").expect("key"),
+ operation_kind: "trade.submit.v1".to_owned(),
+ actor_pubkey: RadrootsPublicKey::parse(
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+ )
+ .expect("actor pubkey"),
+ digest: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb".to_owned(),
+ canonical_payload_hash: "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
+ .to_owned(),
+ expected_event_id: RadrootsEventId::parse(
+ "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
+ )
+ .expect("event id"),
+ outbox_operation_id: 42,
+ };
+
+ assert!(
+ record.matches_payload("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc")
+ );
+ assert!(
+ !record.matches_payload("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
+ );
+ assert!(matches!(
+ record.conflict_error("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
+ RadrootsSdkError::IdempotencyConflict {
+ ref operation_kind,
+ ref expected_pubkey_prefix,
+ ref existing_digest_prefix,
+ ref new_digest_prefix,
+ } if operation_kind == "trade.submit.v1"
+ && expected_pubkey_prefix == "aaaaaaaaaaaa"
+ && existing_digest_prefix == "bbbbbbbbbbbb"
+ && new_digest_prefix == "ffffffffffff"
+ ));
+}
diff --git a/crates/sdk/tests/unit/orders_runtime_tests.rs b/crates/sdk/tests/unit/orders_runtime_tests.rs
@@ -18,6 +18,7 @@ use radroots_nostr::prelude::{
RadrootsNostrKeys, RadrootsNostrSecretKey, radroots_nostr_sign_frozen_draft,
};
use radroots_trade::{
+ identity::RadrootsTradeLocator,
order::{RadrootsOrderEventDecodeError, RadrootsOrderIssue},
projection::RadrootsTradeProjectionError,
workflow::RadrootsTradeWorkflowState,
@@ -410,8 +411,8 @@ fn fixture_cancellation(raw_order_id: &str) -> RadrootsOrderCancellation {
}
}
-fn fixture_target_relays() -> SdkRelayTargetPolicy {
- SdkRelayTargetPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public).expect("target relays")
+fn fixture_target_relays() -> RelayResolutionPolicy {
+ RelayResolutionPolicy::try_explicit([RELAY], SdkRelayUrlPolicy::Public).expect("target relays")
}
async fn prepared_order_sdk() -> RadrootsClient {
@@ -439,11 +440,13 @@ async fn order_configured_local_signer_enqueues_submit_without_explicit_signer()
let receipt = sdk
.trades()
- .enqueue_submit(OrderSubmitEnqueueRequest::new(
+ .enqueue_submit(TradeSubmitEnqueueRequest::new(
fixture_buyer_actor(),
fixture_event_ptr('a'),
fixture_order_request("order-configured-local-1"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await
.expect("enqueue submit");
@@ -458,11 +461,13 @@ async fn order_configured_local_signer_enqueues_lifecycle_wrappers_without_expli
let decision_submit = enqueue_fixture_submit(&seller_sdk, "order-configured-decision").await;
let decision = seller_sdk
.trades()
- .enqueue_decision(OrderDecisionEnqueueRequest::new(
+ .enqueue_decision(TradeDecisionEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&decision_submit.signed_event_id),
fixture_order_decision("order-configured-decision"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await
.expect("configured decision");
@@ -477,12 +482,14 @@ async fn order_configured_local_signer_enqueues_lifecycle_wrappers_without_expli
);
let proposal = seller_sdk
.trades()
- .enqueue_revision_proposal(OrderRevisionProposalEnqueueRequest::new(
+ .enqueue_revision_proposal(TradeRevisionProposalEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
proposal_payload,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await
.expect("configured revision proposal");
@@ -500,12 +507,14 @@ async fn order_configured_local_signer_enqueues_lifecycle_wrappers_without_expli
let revision_proposal = buyer_sdk
.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_submit.signed_event_id),
revision_proposal_payload.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -517,12 +526,14 @@ async fn order_configured_local_signer_enqueues_lifecycle_wrappers_without_expli
);
let revision_decision = buyer_sdk
.trades()
- .enqueue_revision_decision(OrderRevisionDecisionEnqueueRequest::new(
+ .enqueue_revision_decision(TradeRevisionDecisionEnqueueRequest::new(
fixture_buyer_actor(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_proposal.signed_event_id),
revision_decision_payload,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await
.expect("configured revision decision");
@@ -539,12 +550,14 @@ async fn order_configured_local_signer_enqueues_lifecycle_wrappers_without_expli
let cancel_submit = enqueue_fixture_submit(&buyer_sdk, "order-configured-cancel").await;
let cancellation = buyer_sdk
.trades()
- .enqueue_cancellation(OrderCancellationEnqueueRequest::new(
+ .enqueue_cancellation(TradeCancellationEnqueueRequest::new(
fixture_buyer_actor(),
fixture_order_event_ptr(&cancel_submit.signed_event_id),
fixture_order_event_ptr(&cancel_submit.signed_event_id),
fixture_cancellation("order-configured-cancel"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await
.expect("configured cancellation");
@@ -556,11 +569,11 @@ async fn order_configured_local_signer_enqueues_lifecycle_wrappers_without_expli
assert_eq!(cancellation.state, SdkMutationState::StoredAndQueued);
}
-async fn enqueue_fixture_submit(sdk: &RadrootsClient, raw_order_id: &str) -> OrderSubmitReceipt {
+async fn enqueue_fixture_submit(sdk: &RadrootsClient, raw_order_id: &str) -> TradeSubmitReceipt {
let buyer = fixture_buyer_actor();
let plan = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer.clone(),
fixture_event_ptr('a'),
fixture_order_request(raw_order_id),
@@ -571,6 +584,8 @@ async fn enqueue_fixture_submit(sdk: &RadrootsClient, raw_order_id: &str) -> Ord
&buyer,
plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -603,13 +618,13 @@ fn request_event() -> RadrootsNostrEvent {
order::build_order_request_draft(&listing_event, &request)
.expect("request draft")
.into_wire_parts(),
- ORDER_REQUEST_CONTRACT_ID,
+ TRADE_SUBMIT_CONTRACT_ID,
&request.buyer_pubkey,
)
}
fn order_request_evidence_error(
- result: Result<OrderRequestEvidence, RadrootsSdkError>,
+ result: Result<TradeRequestEvidence, RadrootsSdkError>,
) -> RadrootsSdkError {
result.err().expect("expected order request evidence error")
}
@@ -662,7 +677,7 @@ fn workflow_plan_builders_cover_success_and_actor_mismatch_paths() {
created_at,
)
.expect("submit plan");
- assert_eq!(submit_plan.workflow.kind, OrderWorkflowKind::Submit);
+ assert_eq!(submit_plan.workflow.kind, TradeWorkflowKind::Submit);
assert_eq!(submit_plan.listing_event_id, listing_event_id);
let request_event = ptr(submit_plan.expected_event_id.as_str().to_owned());
@@ -673,7 +688,7 @@ fn workflow_plan_builders_cover_success_and_actor_mismatch_paths() {
created_at,
)
.expect("decision plan");
- assert_eq!(decision_plan.workflow.kind, OrderWorkflowKind::Decision);
+ assert_eq!(decision_plan.workflow.kind, TradeWorkflowKind::Decision);
let proposal = revision_proposal_payload(
&submit_plan.expected_event_id,
@@ -689,7 +704,7 @@ fn workflow_plan_builders_cover_success_and_actor_mismatch_paths() {
.expect("revision proposal plan");
assert_eq!(
proposal_plan.workflow.kind,
- OrderWorkflowKind::RevisionProposal
+ TradeWorkflowKind::RevisionProposal
);
let revision_decision = revision_decision_payload(
@@ -707,7 +722,7 @@ fn workflow_plan_builders_cover_success_and_actor_mismatch_paths() {
.expect("revision decision plan");
assert_eq!(
revision_decision_plan.workflow.kind,
- OrderWorkflowKind::RevisionDecision
+ TradeWorkflowKind::RevisionDecision
);
let cancellation_plan = order_cancellation_plan(
@@ -720,7 +735,7 @@ fn workflow_plan_builders_cover_success_and_actor_mismatch_paths() {
.expect("cancellation plan");
assert_eq!(
cancellation_plan.workflow.kind,
- OrderWorkflowKind::Cancellation
+ TradeWorkflowKind::Cancellation
);
let mut wrong_submit = order_request_payload();
@@ -986,7 +1001,7 @@ fn workflow_plan_builders_cover_success_and_actor_mismatch_paths() {
content: "{}".to_owned(),
tags: vec![vec!["p".to_owned(), pubkey('c').as_str().to_owned()]],
},
- ORDER_REQUEST_CONTRACT_ID,
+ TRADE_SUBMIT_CONTRACT_ID,
pubkey('c').as_str(),
1_700_000_000,
"order test",
@@ -1133,7 +1148,7 @@ fn order_evidence_parses_all_lifecycle_event_kinds() {
order::build_order_decision_draft(&root_event_id, &root_event_id, &decision)
.expect("decision draft")
.into_wire_parts(),
- ORDER_DECISION_CONTRACT_ID,
+ TRADE_DECISION_CONTRACT_ID,
&decision.seller_pubkey,
);
assert_eq!(
@@ -1150,7 +1165,7 @@ fn order_evidence_parses_all_lifecycle_event_kinds() {
order::build_order_revision_proposal_draft(&root_event_id, &decision_event_id, &proposal)
.expect("proposal draft")
.into_wire_parts(),
- ORDER_REVISION_PROPOSAL_CONTRACT_ID,
+ TRADE_REVISION_PROPOSAL_CONTRACT_ID,
&proposal.seller_pubkey,
);
assert_eq!(
@@ -1175,7 +1190,7 @@ fn order_evidence_parses_all_lifecycle_event_kinds() {
)
.expect("revision decision draft")
.into_wire_parts(),
- ORDER_REVISION_DECISION_CONTRACT_ID,
+ TRADE_REVISION_DECISION_CONTRACT_ID,
&revision_decision.buyer_pubkey,
);
assert_eq!(
@@ -1190,7 +1205,7 @@ fn order_evidence_parses_all_lifecycle_event_kinds() {
order::build_order_cancellation_draft(&root_event_id, &decision_event_id, &cancellation)
.expect("cancellation draft")
.into_wire_parts(),
- ORDER_CANCELLATION_CONTRACT_ID,
+ TRADE_CANCELLATION_CONTRACT_ID,
&cancellation.buyer_pubkey,
);
assert_eq!(
@@ -1232,7 +1247,7 @@ fn order_request_evidence_parses_and_rejects_malformed_envelopes() {
order::build_order_request_draft(&ptr(event_id('a').as_str().to_owned()), &request)
.expect("request draft")
.into_wire_parts(),
- ORDER_REQUEST_CONTRACT_ID,
+ TRADE_SUBMIT_CONTRACT_ID,
&pubkey('d'),
);
assert!(
@@ -1365,53 +1380,57 @@ fn order_status_next_action_covers_revision_and_fallback_terminal_paths() {
projection.status = RadrootsTradeWorkflowState::RevisionProposed;
projection.pending_revision_event_id = Some(previous_event_id.clone());
- let eligibility = OrderStatusEligibility::from_projection(&projection);
+ let eligibility = TradeStatusEligibility::from_projection(&projection);
assert!(eligibility.can_decide_revision);
assert_eq!(
- OrderStatusNextActionKind::from_projection(&projection, &eligibility),
- OrderStatusNextActionKind::DecideRevision
+ TradeStatusNextActionKind::from_projection(&projection, &eligibility),
+ TradeStatusNextActionKind::DecideRevision
);
- let receipt = OrderStatusReceipt::from_query_result(RadrootsOrderProjectionQueryResult {
- projection: projection.clone(),
- event_count: 2,
- limit_applied: 10,
- event_ids: vec![root_event_id.clone(), previous_event_id.clone()],
- });
+ let receipt = TradeStatusReceipt::from_projection(
+ RadrootsTradeLocator::from_order_id(order_id.clone())
+ .with_root_event_id(root_event_id.clone()),
+ Some(root_event_id.clone()),
+ Vec::new(),
+ projection.clone(),
+ 2,
+ 10,
+ vec![root_event_id.clone(), previous_event_id.clone()],
+ );
assert_eq!(
receipt.next_action,
- OrderStatusNextActionKind::DecideRevision
+ TradeStatusNextActionKind::DecideRevision
);
assert!(receipt.evidence.has_pending_revision);
projection.pending_revision_event_id = None;
projection.status = RadrootsTradeWorkflowState::Requested;
- let fallback = OrderStatusNextActionKind::from_projection(
+ let fallback = TradeStatusNextActionKind::from_projection(
&projection,
- &OrderStatusEligibility {
+ &TradeStatusEligibility {
can_decide: false,
can_propose_revision: true,
can_decide_revision: false,
can_cancel: true,
},
);
- assert_eq!(fallback, OrderStatusNextActionKind::Terminal);
+ assert_eq!(fallback, TradeStatusNextActionKind::Terminal);
projection.lifecycle_terminal = true;
- let terminal_eligibility = OrderStatusEligibility::from_projection(&projection);
+ let terminal_eligibility = TradeStatusEligibility::from_projection(&projection);
assert_eq!(
- OrderStatusNextActionKind::from_projection(&projection, &terminal_eligibility),
- OrderStatusNextActionKind::Terminal
+ TradeStatusNextActionKind::from_projection(&projection, &terminal_eligibility),
+ TradeStatusNextActionKind::Terminal
);
projection.lifecycle_terminal = false;
projection.issues = vec![RadrootsOrderIssue::ForkedLifecycle {
event_ids: vec![event_id('e')],
}];
- let issue_eligibility = OrderStatusEligibility::from_projection(&projection);
+ let issue_eligibility = TradeStatusEligibility::from_projection(&projection);
assert_eq!(
- OrderStatusNextActionKind::from_projection(&projection, &issue_eligibility),
- OrderStatusNextActionKind::InspectEvidenceIssues
+ TradeStatusNextActionKind::from_projection(&projection, &issue_eligibility),
+ TradeStatusNextActionKind::InspectEvidenceIssues
);
}
@@ -1427,7 +1446,7 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
RadrootsOrderIssue::$issue {
event_id: one.clone(),
},
- SdkOrderStatusIssueKind::$kind,
+ SdkTradeStatusIssueKind::$kind,
1,
)
};
@@ -1436,14 +1455,14 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
let cases = vec![
(
RadrootsOrderIssue::MissingRequest,
- SdkOrderStatusIssueKind::MissingRequest,
+ SdkTradeStatusIssueKind::MissingRequest,
0,
),
(
RadrootsOrderIssue::MultipleRequests {
event_ids: many.clone(),
},
- SdkOrderStatusIssueKind::MultipleRequests,
+ SdkTradeStatusIssueKind::MultipleRequests,
2,
),
single!(RequestPayloadInvalid, RequestPayloadInvalid),
@@ -1474,7 +1493,7 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
RadrootsOrderIssue::ConflictingDecisions {
event_ids: many.clone(),
},
- SdkOrderStatusIssueKind::ConflictingDecisions,
+ SdkTradeStatusIssueKind::ConflictingDecisions,
2,
),
single!(
@@ -1577,7 +1596,7 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
RadrootsOrderIssue::ForkedLifecycle {
event_ids: many.clone(),
},
- SdkOrderStatusIssueKind::ForkedLifecycle,
+ SdkTradeStatusIssueKind::ForkedLifecycle,
2,
),
single!(
@@ -1602,7 +1621,7 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
RadrootsOrderIssue::ConflictingValidationReceipts {
event_ids: many.clone(),
},
- SdkOrderStatusIssueKind::ConflictingValidationReceipts,
+ SdkTradeStatusIssueKind::ConflictingValidationReceipts,
2,
),
(
@@ -1610,7 +1629,7 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
event_id: one.clone(),
reason: "fixture validation failed".to_owned(),
},
- SdkOrderStatusIssueKind::DeterministicValidationFailure,
+ SdkTradeStatusIssueKind::DeterministicValidationFailure,
1,
),
(
@@ -1618,13 +1637,13 @@ fn order_issue_mapping_covers_every_trade_issue_variant() {
expected_event_id: one,
current_event_id: two,
},
- SdkOrderStatusIssueKind::StaleListingEvent,
+ SdkTradeStatusIssueKind::StaleListingEvent,
2,
),
];
for (issue, expected_kind, expected_event_count) in cases {
- let sdk_issue = SdkOrderStatusIssue::from(issue);
+ let sdk_issue = SdkTradeStatusIssue::from(issue);
assert_eq!(sdk_issue.kind, expected_kind);
assert_eq!(sdk_issue.event_ids.len(), expected_event_count);
assert_eq!(sdk_issue.code(), expected_kind.code());
@@ -2054,120 +2073,160 @@ fn order_enqueue_request_mutators_reject_invalid_relays_and_idempotency_keys() {
RadrootsOrderRevisionOutcome::Accepted,
);
let cancellation_payload = cancellation_payload();
- let policy = SdkRelayTargetPolicy::UseConfiguredRelays;
+ let policy = RelayResolutionPolicy::ConfiguredRelays;
assert_error_display(
- OrderSubmitEnqueueRequest::new(
+ TradeSubmitEnqueueRequest::new(
buyer.clone(),
listing_event.clone(),
submit_payload.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(Vec::<String>::new(), SdkRelayUrlPolicy::Public),
"target relays",
);
assert_error_display(
- OrderSubmitEnqueueRequest::new(
+ TradeSubmitEnqueueRequest::new(
buyer.clone(),
listing_event,
submit_payload,
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key(""),
"idempotency key",
);
assert_error_display(
- OrderDecisionEnqueueRequest::new(
+ TradeDecisionEnqueueRequest::new(
seller.clone(),
request_event.clone(),
decision_payload.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(Vec::<String>::new(), SdkRelayUrlPolicy::Public),
"target relays",
);
assert_error_display(
- OrderDecisionEnqueueRequest::new(
+ TradeDecisionEnqueueRequest::new(
seller.clone(),
request_event.clone(),
decision_payload,
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key(" leading"),
"idempotency key",
);
assert_error_display(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller.clone(),
request_event.clone(),
previous_event.clone(),
proposal_payload.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(Vec::<String>::new(), SdkRelayUrlPolicy::Public),
"target relays",
);
assert_error_display(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller.clone(),
request_event.clone(),
previous_event.clone(),
proposal_payload.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("trailing "),
"idempotency key",
);
assert_error_display(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
buyer.clone(),
request_event.clone(),
previous_event.clone(),
revision_decision_payload.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(Vec::<String>::new(), SdkRelayUrlPolicy::Public),
"target relays",
);
assert_error_display(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
buyer.clone(),
request_event.clone(),
previous_event.clone(),
revision_decision_payload,
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key("invalid\nkey"),
"idempotency key",
);
assert_error_display(
- OrderCancellationEnqueueRequest::new(
+ TradeCancellationEnqueueRequest::new(
buyer.clone(),
request_event.clone(),
previous_event.clone(),
cancellation_payload.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(Vec::<String>::new(), SdkRelayUrlPolicy::Public),
"target relays",
);
assert_error_display(
- OrderCancellationEnqueueRequest::new(
+ TradeCancellationEnqueueRequest::new(
buyer,
request_event,
previous_event,
cancellation_payload,
policy,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_idempotency_key(""),
"idempotency key",
);
}
+#[test]
+fn trade_enqueue_policy_rejects_publish_modes_without_matching_side_effects() {
+ assert!(matches!(
+ validate_trade_enqueue_policy(PublishMode::DryRun, AckPolicy::NoWait),
+ Err(RadrootsSdkError::InvalidRequest { ref message })
+ if message == "trade dry-run publish mode must use a prepare request"
+ ));
+ assert!(matches!(
+ validate_trade_enqueue_policy(PublishMode::EnqueueOnly, AckPolicy::AtLeastOneRelay),
+ Err(RadrootsSdkError::InvalidRequest { ref message })
+ if message == "trade enqueue-only publish mode only supports no-wait acknowledgement"
+ ));
+ assert!(matches!(
+ validate_trade_enqueue_policy(PublishMode::EnqueueAndPublish, AckPolicy::AtLeastOneRelay),
+ Err(RadrootsSdkError::InvalidRequest { ref message })
+ if message == "trade enqueue-and-publish mode requires publish receipt orchestration"
+ ));
+ assert!(validate_trade_enqueue_policy(PublishMode::EnqueueOnly, AckPolicy::NoWait).is_ok());
+}
+
#[tokio::test]
async fn orders_client_prepare_methods_resolve_request_created_at() {
let sdk = crate::RadrootsClient::builder()
@@ -2182,7 +2241,7 @@ async fn orders_client_prepare_methods_resolve_request_created_at() {
assert_eq!(
sdk.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer_actor(),
root_event.clone(),
order_request_payload(),
@@ -2194,7 +2253,7 @@ async fn orders_client_prepare_methods_resolve_request_created_at() {
assert_eq!(
sdk.trades()
.prepare_decision(
- OrderDecisionPrepareRequest::new(
+ TradeDecisionPrepareRequest::new(
seller_actor(),
root_event.clone(),
order_decision_payload(),
@@ -2210,7 +2269,7 @@ async fn orders_client_prepare_methods_resolve_request_created_at() {
assert_eq!(
sdk.trades()
.prepare_revision_proposal(
- OrderRevisionProposalPrepareRequest::new(
+ TradeRevisionProposalPrepareRequest::new(
seller_actor(),
root_event.clone(),
previous_event.clone(),
@@ -2225,7 +2284,7 @@ async fn orders_client_prepare_methods_resolve_request_created_at() {
assert_eq!(
sdk.trades()
.prepare_revision_decision(
- OrderRevisionDecisionPrepareRequest::new(
+ TradeRevisionDecisionPrepareRequest::new(
buyer_actor(),
root_event.clone(),
ptr(event_id('c').as_str().to_owned()),
@@ -2244,7 +2303,7 @@ async fn orders_client_prepare_methods_resolve_request_created_at() {
assert_eq!(
sdk.trades()
.prepare_cancellation(
- OrderCancellationPrepareRequest::new(
+ TradeCancellationPrepareRequest::new(
buyer_actor(),
root_event,
previous_event,
@@ -2264,12 +2323,12 @@ async fn prepared_submit_and_decision_enqueue_cover_source_attached_success_path
let submit = enqueue_fixture_submit(&sdk, "order-prepared-decision");
let submit = submit.await;
assert_eq!(submit.signed_event_id, submit.expected_event_id);
- assert_eq!(submit.workflow.kind, OrderWorkflowKind::Submit);
+ assert_eq!(submit.workflow.kind, TradeWorkflowKind::Submit);
let seller = fixture_seller_actor();
let decision_plan = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&submit.signed_event_id),
fixture_order_decision("order-prepared-decision"),
@@ -2281,6 +2340,8 @@ async fn prepared_submit_and_decision_enqueue_cover_source_attached_success_path
&seller,
decision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
Some(SdkIdempotencyKey::new("prepared-decision").expect("idempotency")),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2288,7 +2349,7 @@ async fn prepared_submit_and_decision_enqueue_cover_source_attached_success_path
.expect("enqueue decision");
assert_eq!(decision.signed_event_id, decision.expected_event_id);
- assert_eq!(decision.workflow.kind, OrderWorkflowKind::Decision);
+ assert_eq!(decision.workflow.kind, TradeWorkflowKind::Decision);
assert_eq!(decision.request_event_id, submit.signed_event_id);
}
@@ -2304,7 +2365,7 @@ async fn prepared_revision_lifecycle_enqueue_cover_source_attached_success_paths
);
let proposal_plan = sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&submit.signed_event_id),
fixture_order_event_ptr(&submit.signed_event_id),
@@ -2317,6 +2378,8 @@ async fn prepared_revision_lifecycle_enqueue_cover_source_attached_success_paths
&seller,
proposal_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
Some(SdkIdempotencyKey::new("prepared-proposal").expect("idempotency")),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2324,7 +2387,7 @@ async fn prepared_revision_lifecycle_enqueue_cover_source_attached_success_paths
.expect("enqueue proposal");
assert_eq!(proposal.signed_event_id, proposal.expected_event_id);
- assert_eq!(proposal.workflow.kind, OrderWorkflowKind::RevisionProposal);
+ assert_eq!(proposal.workflow.kind, TradeWorkflowKind::RevisionProposal);
assert_eq!(proposal.root_event_id, submit.signed_event_id);
assert_eq!(proposal.previous_event_id, submit.signed_event_id);
@@ -2332,7 +2395,7 @@ async fn prepared_revision_lifecycle_enqueue_cover_source_attached_success_paths
let revision_decision = fixture_revision_decision(&proposal_payload, &proposal.signed_event_id);
let revision_decision_plan = sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&submit.signed_event_id),
fixture_order_event_ptr(&proposal.signed_event_id),
@@ -2345,6 +2408,8 @@ async fn prepared_revision_lifecycle_enqueue_cover_source_attached_success_paths
&buyer,
revision_decision_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2352,7 +2417,7 @@ async fn prepared_revision_lifecycle_enqueue_cover_source_attached_success_paths
.expect("enqueue revision decision");
assert_eq!(revision.signed_event_id, revision.expected_event_id);
- assert_eq!(revision.workflow.kind, OrderWorkflowKind::RevisionDecision);
+ assert_eq!(revision.workflow.kind, TradeWorkflowKind::RevisionDecision);
assert_eq!(revision.root_event_id, submit.signed_event_id);
assert_eq!(revision.previous_event_id, proposal.signed_event_id);
}
@@ -2364,7 +2429,7 @@ async fn prepared_cancellation_enqueue_covers_source_attached_success_path() {
let buyer = fixture_buyer_actor();
let cancellation_plan = sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&submit.signed_event_id),
fixture_order_event_ptr(&submit.signed_event_id),
@@ -2377,6 +2442,8 @@ async fn prepared_cancellation_enqueue_covers_source_attached_success_path() {
&buyer,
cancellation_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
Some(SdkIdempotencyKey::new("prepared-cancellation").expect("idempotency")),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2384,7 +2451,7 @@ async fn prepared_cancellation_enqueue_covers_source_attached_success_path() {
.expect("enqueue cancellation");
assert_eq!(cancellation.signed_event_id, cancellation.expected_event_id);
- assert_eq!(cancellation.workflow.kind, OrderWorkflowKind::Cancellation);
+ assert_eq!(cancellation.workflow.kind, TradeWorkflowKind::Cancellation);
assert_eq!(cancellation.root_event_id, submit.signed_event_id);
assert_eq!(cancellation.previous_event_id, submit.signed_event_id);
}
@@ -2395,11 +2462,13 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let decision_submit = sdk
.trades()
.enqueue_submit_with_explicit_signer(
- OrderSubmitEnqueueRequest::new(
+ TradeSubmitEnqueueRequest::new(
fixture_buyer_actor(),
fixture_event_ptr('b'),
fixture_order_request("order-wrapper-decision"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2408,11 +2477,13 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let decision = sdk
.trades()
.enqueue_decision_with_explicit_signer(
- OrderDecisionEnqueueRequest::new(
+ TradeDecisionEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&decision_submit.signed_event_id),
fixture_order_decision("order-wrapper-decision"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2423,11 +2494,13 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let revision_submit = sdk
.trades()
.enqueue_submit_with_explicit_signer(
- OrderSubmitEnqueueRequest::new(
+ TradeSubmitEnqueueRequest::new(
fixture_buyer_actor(),
fixture_event_ptr('c'),
fixture_order_request("order-wrapper-revision"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2441,12 +2514,14 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let proposal = sdk
.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_submit.signed_event_id),
proposal_payload.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2455,12 +2530,14 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let revision = sdk
.trades()
.enqueue_revision_decision_with_explicit_signer(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
fixture_buyer_actor(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&proposal.signed_event_id),
fixture_revision_decision(&proposal_payload, &proposal.signed_event_id),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2471,11 +2548,13 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let cancellation_submit = sdk
.trades()
.enqueue_submit_with_explicit_signer(
- OrderSubmitEnqueueRequest::new(
+ TradeSubmitEnqueueRequest::new(
fixture_buyer_actor(),
fixture_event_ptr('d'),
fixture_order_request("order-wrapper-cancellation"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2484,12 +2563,14 @@ async fn convenience_order_enqueue_methods_cover_source_attached_wrappers() {
let cancellation = sdk
.trades()
.enqueue_cancellation_with_explicit_signer(
- OrderCancellationEnqueueRequest::new(
+ TradeCancellationEnqueueRequest::new(
fixture_buyer_actor(),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
fixture_cancellation("order-wrapper-cancellation"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2515,7 +2596,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
let decision_plan = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
root.clone(),
fixture_order_decision("order-preflight-errors"),
@@ -2527,6 +2608,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&seller,
decision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2539,7 +2622,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
let proposal_plan = sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
root.clone(),
previous.clone(),
@@ -2552,6 +2635,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&seller,
proposal_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2564,7 +2649,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
let revision_decision_plan = sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
root.clone(),
previous.clone(),
@@ -2577,6 +2662,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&buyer,
revision_decision_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2589,7 +2676,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
let cancellation_plan = sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
root,
previous,
@@ -2602,6 +2689,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&buyer,
cancellation_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2624,7 +2713,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
);
let closed_plan = closed_sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
closed_root.clone(),
fixture_order_decision("order-closed-preflight"),
@@ -2632,7 +2721,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
.expect("closed decision plan");
let closed_proposal_plan = closed_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
closed_root.clone(),
closed_previous.clone(),
@@ -2641,7 +2730,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
.expect("closed proposal plan");
let closed_revision_plan = closed_sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
closed_root.clone(),
closed_previous.clone(),
@@ -2650,7 +2739,7 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
.expect("closed revision decision plan");
let closed_cancellation_plan = closed_sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
closed_root,
closed_previous,
@@ -2664,6 +2753,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&seller,
closed_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2676,6 +2767,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&seller,
closed_proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -2691,6 +2784,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&buyer,
closed_revision_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2706,6 +2801,8 @@ async fn prepared_lifecycle_enqueues_report_missing_and_closed_preflight_errors(
&buyer,
closed_cancellation_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -2734,7 +2831,7 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
let seller_sdk = configured_order_sdk(SELLER_SECRET_KEY_HEX).await;
let decision_plan = seller_sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
root.clone(),
fixture_order_decision("order-configured-preflight"),
@@ -2742,7 +2839,14 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
.expect("decision plan");
let decision_missing = seller_sdk
.trades()
- .enqueue_prepared_decision(&seller, decision_plan, fixture_target_relays(), None)
+ .enqueue_prepared_decision(
+ &seller,
+ decision_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None,
+ )
.await
.expect_err("configured missing decision evidence");
assert!(matches!(
@@ -2752,7 +2856,7 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
let proposal_plan = seller_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
root.clone(),
previous.clone(),
@@ -2761,7 +2865,14 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
.expect("proposal plan");
let proposal_missing = seller_sdk
.trades()
- .enqueue_prepared_revision_proposal(&seller, proposal_plan, fixture_target_relays(), None)
+ .enqueue_prepared_revision_proposal(
+ &seller,
+ proposal_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None,
+ )
.await
.expect_err("configured missing proposal evidence");
assert!(matches!(
@@ -2772,7 +2883,7 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
let buyer_sdk = configured_order_sdk(BUYER_SECRET_KEY_HEX).await;
let revision_plan = buyer_sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
root.clone(),
previous.clone(),
@@ -2781,7 +2892,14 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
.expect("revision decision plan");
let revision_missing = buyer_sdk
.trades()
- .enqueue_prepared_revision_decision(&buyer, revision_plan, fixture_target_relays(), None)
+ .enqueue_prepared_revision_decision(
+ &buyer,
+ revision_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None,
+ )
.await
.expect_err("configured missing revision decision evidence");
assert!(matches!(
@@ -2791,7 +2909,7 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
let cancellation_plan = buyer_sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
root,
previous,
@@ -2800,7 +2918,14 @@ async fn configured_prepared_lifecycle_enqueues_run_preflight_guards() {
.expect("cancellation plan");
let cancellation_missing = buyer_sdk
.trades()
- .enqueue_prepared_cancellation(&buyer, cancellation_plan, fixture_target_relays(), None)
+ .enqueue_prepared_cancellation(
+ &buyer,
+ cancellation_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None,
+ )
.await
.expect_err("configured missing cancellation evidence");
assert!(matches!(
@@ -2826,7 +2951,7 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
let seller_sdk = configured_order_sdk(SELLER_SECRET_KEY_HEX).await;
let decision_plan = seller_sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
root.clone(),
fixture_order_decision("order-configured-existing-lookup"),
@@ -2834,7 +2959,7 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
.expect("decision plan");
let proposal_plan = seller_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
root.clone(),
previous.clone(),
@@ -2845,7 +2970,14 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
assert!(matches!(
seller_sdk
.trades()
- .enqueue_prepared_decision(&seller, decision_plan, fixture_target_relays(), None)
+ .enqueue_prepared_decision(
+ &seller,
+ decision_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None
+ )
.await,
Err(RadrootsSdkError::EventStore { .. })
));
@@ -2856,6 +2988,8 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
&seller,
proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
)
.await,
@@ -2865,7 +2999,7 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
let buyer_sdk = configured_order_sdk(BUYER_SECRET_KEY_HEX).await;
let revision_plan = buyer_sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
root.clone(),
previous.clone(),
@@ -2874,7 +3008,7 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
.expect("revision decision plan");
let cancellation_plan = buyer_sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
root,
previous,
@@ -2889,6 +3023,8 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
&buyer,
revision_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None
)
.await,
@@ -2897,7 +3033,14 @@ async fn configured_prepared_lifecycle_enqueues_report_existing_event_lookup_err
assert!(matches!(
buyer_sdk
.trades()
- .enqueue_prepared_cancellation(&buyer, cancellation_plan, fixture_target_relays(), None)
+ .enqueue_prepared_cancellation(
+ &buyer,
+ cancellation_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None
+ )
.await,
Err(RadrootsSdkError::EventStore { .. })
));
@@ -2918,11 +3061,13 @@ async fn configured_enqueue_wrappers_report_prepare_errors_before_signing() {
assert!(matches!(
buyer_sdk
.trades()
- .enqueue_submit(OrderSubmitEnqueueRequest::new(
+ .enqueue_submit(TradeSubmitEnqueueRequest::new(
fixture_seller_actor(),
fixture_event_ptr('a'),
fixture_order_request("order-configured-prepare-submit"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await,
Err(RadrootsSdkError::UnauthorizedActor { .. })
@@ -2930,11 +3075,13 @@ async fn configured_enqueue_wrappers_report_prepare_errors_before_signing() {
assert!(matches!(
seller_sdk
.trades()
- .enqueue_decision(OrderDecisionEnqueueRequest::new(
+ .enqueue_decision(TradeDecisionEnqueueRequest::new(
fixture_buyer_actor(),
fixture_event_ptr('a'),
fixture_order_decision("order-configured-prepare-decision"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await,
Err(RadrootsSdkError::UnauthorizedActor { .. })
@@ -2942,12 +3089,14 @@ async fn configured_enqueue_wrappers_report_prepare_errors_before_signing() {
assert!(matches!(
seller_sdk
.trades()
- .enqueue_revision_proposal(OrderRevisionProposalEnqueueRequest::new(
+ .enqueue_revision_proposal(TradeRevisionProposalEnqueueRequest::new(
fixture_buyer_actor(),
fixture_order_event_ptr(&root_event_id),
fixture_order_event_ptr(&previous_event_id),
proposal.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await,
Err(RadrootsSdkError::UnauthorizedActor { .. })
@@ -2955,12 +3104,14 @@ async fn configured_enqueue_wrappers_report_prepare_errors_before_signing() {
assert!(matches!(
buyer_sdk
.trades()
- .enqueue_revision_decision(OrderRevisionDecisionEnqueueRequest::new(
+ .enqueue_revision_decision(TradeRevisionDecisionEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&root_event_id),
fixture_order_event_ptr(&previous_event_id),
fixture_revision_decision(&proposal, &previous_event_id),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await,
Err(RadrootsSdkError::UnauthorizedActor { .. })
@@ -2968,12 +3119,14 @@ async fn configured_enqueue_wrappers_report_prepare_errors_before_signing() {
assert!(matches!(
buyer_sdk
.trades()
- .enqueue_cancellation(OrderCancellationEnqueueRequest::new(
+ .enqueue_cancellation(TradeCancellationEnqueueRequest::new(
fixture_seller_actor(),
fixture_order_event_ptr(&root_event_id),
fixture_order_event_ptr(&previous_event_id),
fixture_cancellation("order-configured-prepare-cancel"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
))
.await,
Err(RadrootsSdkError::UnauthorizedActor { .. })
@@ -2988,7 +3141,7 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
let submit_plan = sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer.clone(),
fixture_event_ptr('a'),
fixture_order_request("order-missing-configured-submit"),
@@ -2996,7 +3149,14 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
.expect("submit plan");
assert!(matches!(
sdk.trades()
- .enqueue_prepared_submit(&buyer, submit_plan, fixture_target_relays(), None)
+ .enqueue_prepared_submit(
+ &buyer,
+ submit_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None
+ )
.await,
Err(RadrootsSdkError::SignerUnavailable { .. })
));
@@ -3004,7 +3164,7 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
let decision_submit = enqueue_fixture_submit(&sdk, "order-missing-configured-decision").await;
let decision_plan = sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&decision_submit.signed_event_id),
fixture_order_decision("order-missing-configured-decision"),
@@ -3012,7 +3172,14 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
.expect("decision plan");
assert!(matches!(
sdk.trades()
- .enqueue_prepared_decision(&seller, decision_plan, fixture_target_relays(), None)
+ .enqueue_prepared_decision(
+ &seller,
+ decision_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None
+ )
.await,
Err(RadrootsSdkError::SignerUnavailable { .. })
));
@@ -3025,7 +3192,7 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
);
let proposal_plan = sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
@@ -3038,6 +3205,8 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
&seller,
proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None
)
.await,
@@ -3052,7 +3221,7 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
);
let revision_proposal_plan = sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_submit.signed_event_id),
@@ -3065,6 +3234,8 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
&seller,
revision_proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3072,7 +3243,7 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
.expect("revision proposal evidence");
let revision_plan = sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_proposal.signed_event_id),
@@ -3088,6 +3259,8 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
&buyer,
revision_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None
)
.await,
@@ -3097,7 +3270,7 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
let cancellation_submit = enqueue_fixture_submit(&sdk, "order-missing-configured-cancel").await;
let cancellation_plan = sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
@@ -3106,7 +3279,14 @@ async fn configured_prepared_methods_report_missing_configured_signer_after_pref
.expect("cancellation plan");
assert!(matches!(
sdk.trades()
- .enqueue_prepared_cancellation(&buyer, cancellation_plan, fixture_target_relays(), None)
+ .enqueue_prepared_cancellation(
+ &buyer,
+ cancellation_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None
+ )
.await,
Err(RadrootsSdkError::SignerUnavailable { .. })
));
@@ -3129,14 +3309,14 @@ async fn lifecycle_preflight_helpers_map_projection_query_failures() {
);
let decision_plan = client
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
root.clone(),
fixture_order_decision("order-preflight-query-failure"),
))
.expect("decision plan");
let proposal_plan = client
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller,
root.clone(),
previous.clone(),
@@ -3144,7 +3324,7 @@ async fn lifecycle_preflight_helpers_map_projection_query_failures() {
))
.expect("proposal plan");
let revision_plan = client
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
root.clone(),
previous.clone(),
@@ -3152,7 +3332,7 @@ async fn lifecycle_preflight_helpers_map_projection_query_failures() {
))
.expect("revision plan");
let cancellation_plan = client
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer,
root,
previous,
@@ -3198,7 +3378,7 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
);
let proposal_plan = proposal_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
@@ -3212,12 +3392,14 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
&seller,
proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
.await
.expect_err("closed outbox proposal");
- assert_partial_outbox_enqueue(proposal_error, ORDER_REVISION_PROPOSAL_OPERATION_KIND);
+ assert_partial_outbox_enqueue(proposal_error, TRADE_REVISION_PROPOSAL_OPERATION_KIND);
let revision_sdk = prepared_order_sdk().await;
let revision_submit =
@@ -3229,7 +3411,7 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
);
let proposal_plan = revision_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_submit.signed_event_id),
@@ -3242,6 +3424,8 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
&seller,
proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3250,7 +3434,7 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
let buyer = fixture_buyer_actor();
let revision_plan = revision_sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&proposal.signed_event_id),
@@ -3264,19 +3448,21 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
&buyer,
revision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
.await
.expect_err("closed outbox revision");
- assert_partial_outbox_enqueue(revision_error, ORDER_REVISION_DECISION_OPERATION_KIND);
+ assert_partial_outbox_enqueue(revision_error, TRADE_REVISION_DECISION_OPERATION_KIND);
let cancellation_sdk = prepared_order_sdk().await;
let cancellation_submit =
enqueue_fixture_submit(&cancellation_sdk, "order-closed-outbox-cancellation").await;
let cancellation_plan = cancellation_sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
@@ -3290,12 +3476,14 @@ async fn prepared_lifecycle_enqueues_report_closed_outbox_after_preflight() {
&buyer,
cancellation_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
.await
.expect_err("closed outbox cancellation");
- assert_partial_outbox_enqueue(cancellation_error, ORDER_CANCELLATION_OPERATION_KIND);
+ assert_partial_outbox_enqueue(cancellation_error, TRADE_CANCELLATION_OPERATION_KIND);
}
#[tokio::test]
@@ -3305,7 +3493,7 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
let seller = fixture_seller_actor();
let decision_plan = decision_sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&decision_submit.signed_event_id),
fixture_order_decision("order-existing-decision"),
@@ -3317,6 +3505,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
decision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3328,6 +3518,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
decision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3349,6 +3541,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
decision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
)
.await
@@ -3373,7 +3567,7 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
);
let proposal_plan = proposal_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
fixture_order_event_ptr(&proposal_submit.signed_event_id),
@@ -3386,6 +3580,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
proposal_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3397,6 +3593,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
proposal_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3418,6 +3616,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
proposal_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
)
.await
@@ -3442,7 +3642,7 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
);
let proposal_plan = revision_sdk
.trades()
- .prepare_revision_proposal(OrderRevisionProposalPrepareRequest::new(
+ .prepare_revision_proposal(TradeRevisionProposalPrepareRequest::new(
seller.clone(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&revision_submit.signed_event_id),
@@ -3455,6 +3655,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&seller,
proposal_plan,
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
)
@@ -3463,7 +3665,7 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
let buyer = fixture_buyer_actor();
let revision_plan = revision_sdk
.trades()
- .prepare_revision_decision(OrderRevisionDecisionPrepareRequest::new(
+ .prepare_revision_decision(TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&revision_submit.signed_event_id),
fixture_order_event_ptr(&proposal.signed_event_id),
@@ -3476,6 +3678,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&buyer,
revision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -3487,6 +3691,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&buyer,
revision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -3508,6 +3714,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&buyer,
revision_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
)
.await
@@ -3528,7 +3736,7 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
enqueue_fixture_submit(&cancellation_sdk, "order-existing-cancellation").await;
let cancellation_plan = cancellation_sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer.clone(),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
fixture_order_event_ptr(&cancellation_submit.signed_event_id),
@@ -3541,6 +3749,8 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
&buyer,
cancellation_plan.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
None,
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
)
@@ -3548,7 +3758,14 @@ async fn prepared_lifecycle_enqueues_skip_preflight_for_existing_events() {
.expect("enqueue cancellation");
let cancellation_repeat = cancellation_sdk
.trades()
- .enqueue_prepared_cancellation(&buyer, cancellation_plan, fixture_target_relays(), None)
+ .enqueue_prepared_cancellation(
+ &buyer,
+ cancellation_plan,
+ fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
+ None,
+ )
.await
.expect("configured cancellation replay");
assert_eq!(
@@ -3573,7 +3790,7 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.ingest_evidence(
- OrderEvidenceIngestRequest::new(request_event()).with_observed_at(out_of_range,)
+ TradeEvidenceIngestRequest::new(request_event()).with_observed_at(out_of_range,)
)
.await,
Err(RadrootsSdkError::TimestampOutOfRange { .. })
@@ -3581,7 +3798,7 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.ingest_request_evidence(
- OrderRequestEvidenceIngestRequest::new(request_event())
+ TradeRequestEvidenceIngestRequest::new(request_event())
.with_observed_at(out_of_range,),
)
.await,
@@ -3590,11 +3807,13 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.enqueue_submit_with_explicit_signer(
- OrderSubmitEnqueueRequest::new(
+ TradeSubmitEnqueueRequest::new(
buyer.clone(),
fixture_event_ptr('a'),
fixture_order_request("order-wrapper-submit-error"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.with_created_at(out_of_range),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
@@ -3605,11 +3824,13 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.enqueue_decision_with_explicit_signer(
- OrderDecisionEnqueueRequest::new(
+ TradeDecisionEnqueueRequest::new(
seller.clone(),
fixture_event_ptr('b'),
fixture_order_decision("order-wrapper-decision-error"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.with_created_at(out_of_range),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
@@ -3628,12 +3849,14 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.enqueue_revision_proposal_with_explicit_signer(
- OrderRevisionProposalEnqueueRequest::new(
+ TradeRevisionProposalEnqueueRequest::new(
seller.clone(),
ptr(root_event_id.as_str().to_owned()),
ptr(previous_event_id.as_str().to_owned()),
proposal_payload.clone(),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.with_created_at(out_of_range),
&OrderFixtureSigner::new(SELLER_SECRET_KEY_HEX),
@@ -3644,12 +3867,14 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.enqueue_revision_decision_with_explicit_signer(
- OrderRevisionDecisionEnqueueRequest::new(
+ TradeRevisionDecisionEnqueueRequest::new(
buyer.clone(),
ptr(root_event_id.as_str().to_owned()),
ptr(previous_event_id.as_str().to_owned()),
fixture_revision_decision(&proposal_payload, &previous_event_id),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.with_created_at(out_of_range),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
@@ -3660,12 +3885,14 @@ async fn order_ingest_and_enqueue_wrappers_report_prepare_timestamp_errors() {
assert!(matches!(
sdk.trades()
.enqueue_cancellation_with_explicit_signer(
- OrderCancellationEnqueueRequest::new(
+ TradeCancellationEnqueueRequest::new(
buyer,
ptr(root_event_id.as_str().to_owned()),
ptr(previous_event_id.as_str().to_owned()),
fixture_cancellation("order-wrapper-cancellation-error"),
fixture_target_relays(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.with_created_at(out_of_range),
&OrderFixtureSigner::new(BUYER_SECRET_KEY_HEX),
@@ -3691,21 +3918,21 @@ async fn order_default_timestamp_paths_report_clock_errors() {
assert!(matches!(
clock_error_sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(request_event()))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(request_event()))
.await,
Err(RadrootsSdkError::ClockBeforeUnixEpoch)
));
assert!(matches!(
clock_error_sdk
.trades()
- .ingest_request_evidence(OrderRequestEvidenceIngestRequest::new(request_event()))
+ .ingest_request_evidence(TradeRequestEvidenceIngestRequest::new(request_event()))
.await,
Err(RadrootsSdkError::ClockBeforeUnixEpoch)
));
assert!(matches!(
clock_error_sdk
.trades()
- .prepare_submit(OrderSubmitPrepareRequest::new(
+ .prepare_submit(TradeSubmitPrepareRequest::new(
buyer.clone(),
ptr(root_event_id.as_str().to_owned()),
order_request_payload(),
@@ -3715,7 +3942,7 @@ async fn order_default_timestamp_paths_report_clock_errors() {
assert!(matches!(
clock_error_sdk
.trades()
- .prepare_decision(OrderDecisionPrepareRequest::new(
+ .prepare_decision(TradeDecisionPrepareRequest::new(
seller.clone(),
ptr(root_event_id.as_str().to_owned()),
order_decision_payload(),
@@ -3724,7 +3951,7 @@ async fn order_default_timestamp_paths_report_clock_errors() {
));
assert!(matches!(
clock_error_sdk.trades().prepare_revision_proposal(
- OrderRevisionProposalPrepareRequest::new(
+ TradeRevisionProposalPrepareRequest::new(
seller,
ptr(root_event_id.as_str().to_owned()),
ptr(previous_event_id.as_str().to_owned()),
@@ -3735,7 +3962,7 @@ async fn order_default_timestamp_paths_report_clock_errors() {
));
assert!(matches!(
clock_error_sdk.trades().prepare_revision_decision(
- OrderRevisionDecisionPrepareRequest::new(
+ TradeRevisionDecisionPrepareRequest::new(
buyer.clone(),
ptr(root_event_id.as_str().to_owned()),
ptr(previous_event_id.as_str().to_owned()),
@@ -3751,7 +3978,7 @@ async fn order_default_timestamp_paths_report_clock_errors() {
assert!(matches!(
clock_error_sdk
.trades()
- .prepare_cancellation(OrderCancellationPrepareRequest::new(
+ .prepare_cancellation(TradeCancellationPrepareRequest::new(
buyer,
ptr(root_event_id.as_str().to_owned()),
ptr(previous_event_id.as_str().to_owned()),
@@ -3776,10 +4003,10 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
reason: "not workable".to_owned(),
},
);
- let policy = SdkRelayTargetPolicy::UseConfiguredRelays;
+ let policy = RelayResolutionPolicy::ConfiguredRelays;
let submit_prepare =
- OrderSubmitPrepareRequest::new(buyer_actor(), root_event.clone(), order_request_payload())
+ TradeSubmitPrepareRequest::new(buyer_actor(), root_event.clone(), order_request_payload())
.with_created_at(created_at);
assert_struct_serialize_error_paths(&submit_prepare, 4);
assert_eq!(
@@ -3787,11 +4014,13 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
1_700_000_321
);
- let submit_enqueue = OrderSubmitEnqueueRequest::new(
+ let submit_enqueue = TradeSubmitEnqueueRequest::new(
buyer_actor(),
root_event.clone(),
order_request_payload(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(["wss://relay-a.radroots.test"], SdkRelayUrlPolicy::Public)
.expect("submit relays")
@@ -3800,13 +4029,13 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
assert_struct_serialize_error_paths(&submit_enqueue, 6);
let request_ingest =
- OrderRequestEvidenceIngestRequest::new(request_event()).with_observed_at(created_at);
+ TradeRequestEvidenceIngestRequest::new(request_event()).with_observed_at(created_at);
assert_struct_serialize_error_paths(&request_ingest, 2);
let evidence_ingest =
- OrderEvidenceIngestRequest::new(request_event()).with_observed_at(created_at);
+ TradeEvidenceIngestRequest::new(request_event()).with_observed_at(created_at);
assert_struct_serialize_error_paths(&evidence_ingest, 2);
- let decision_prepare = OrderDecisionPrepareRequest::new(
+ let decision_prepare = TradeDecisionPrepareRequest::new(
seller_actor(),
root_event.clone(),
order_decision_payload(),
@@ -3814,11 +4043,13 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&decision_prepare, 4);
- let decision_enqueue = OrderDecisionEnqueueRequest::new(
+ let decision_enqueue = TradeDecisionEnqueueRequest::new(
seller_actor(),
root_event.clone(),
order_decision_payload(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(["wss://relay-b.radroots.test"], SdkRelayUrlPolicy::Public)
.expect("decision relays")
@@ -3826,7 +4057,7 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&decision_enqueue, 6);
- let proposal_prepare = OrderRevisionProposalPrepareRequest::new(
+ let proposal_prepare = TradeRevisionProposalPrepareRequest::new(
seller_actor(),
root_event.clone(),
previous_event.clone(),
@@ -3835,12 +4066,14 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&proposal_prepare, 5);
- let proposal_enqueue = OrderRevisionProposalEnqueueRequest::new(
+ let proposal_enqueue = TradeRevisionProposalEnqueueRequest::new(
seller_actor(),
root_event.clone(),
previous_event.clone(),
proposal.clone(),
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(["wss://relay-c.radroots.test"], SdkRelayUrlPolicy::Public)
.expect("proposal relays")
@@ -3848,7 +4081,7 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&proposal_enqueue, 7);
- let revision_decision_prepare = OrderRevisionDecisionPrepareRequest::new(
+ let revision_decision_prepare = TradeRevisionDecisionPrepareRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
@@ -3857,12 +4090,14 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&revision_decision_prepare, 5);
- let revision_decision_enqueue = OrderRevisionDecisionEnqueueRequest::new(
+ let revision_decision_enqueue = TradeRevisionDecisionEnqueueRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
revision_decision,
policy.clone(),
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(["wss://relay-d.radroots.test"], SdkRelayUrlPolicy::Public)
.expect("revision decision relays")
@@ -3870,7 +4105,7 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&revision_decision_enqueue, 7);
- let cancellation_prepare = OrderCancellationPrepareRequest::new(
+ let cancellation_prepare = TradeCancellationPrepareRequest::new(
buyer_actor(),
root_event.clone(),
previous_event.clone(),
@@ -3879,12 +4114,14 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&cancellation_prepare, 5);
- let cancellation_enqueue = OrderCancellationEnqueueRequest::new(
+ let cancellation_enqueue = TradeCancellationEnqueueRequest::new(
buyer_actor(),
root_event,
previous_event,
cancellation_payload(),
policy,
+ PublishMode::EnqueueOnly,
+ AckPolicy::NoWait,
)
.try_with_target_relays(["wss://relay-e.radroots.test"], SdkRelayUrlPolicy::Public)
.expect("cancellation relays")
@@ -3892,17 +4129,17 @@ fn order_runtime_request_builders_and_serializers_cover_source_attached_paths()
.with_created_at(created_at);
assert_struct_serialize_error_paths(&cancellation_enqueue, 7);
- let parsed_status = OrderStatusRequest::parse(order_id().as_str())
+ let parsed_status = TradeStatusRequest::parse(order_id().as_str())
.expect("status request")
- .with_limit(ORDER_STATUS_DEFAULT_LIMIT);
+ .with_limit(TRADE_STATUS_DEFAULT_LIMIT);
parsed_status.validate().expect("status validates");
assert_eq!(
serde_json::to_value(&parsed_status).expect("status json")["limit"],
- ORDER_STATUS_DEFAULT_LIMIT
+ TRADE_STATUS_DEFAULT_LIMIT
);
let issue =
- SdkOrderStatusIssue::single(SdkOrderStatusIssueKind::ForkedLifecycle, event_id('f'));
+ SdkTradeStatusIssue::single(SdkTradeStatusIssueKind::ForkedLifecycle, event_id('f'));
assert_eq!(issue.code(), "forked_lifecycle");
assert_struct_serialize_error_paths(&issue, 3);
}
@@ -3913,7 +4150,7 @@ async fn closed_event_store_errors_are_mapped_for_ingest_and_prepared_lookup() {
sdk._event_store.pool().close().await;
let ingest_error = sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(request_event()))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(request_event()))
.await
.expect_err("closed ingest evidence");
assert!(matches!(ingest_error, RadrootsSdkError::EventStore { .. }));
@@ -3922,7 +4159,7 @@ async fn closed_event_store_errors_are_mapped_for_ingest_and_prepared_lookup() {
sdk._event_store.pool().close().await;
let request_ingest_error = sdk
.trades()
- .ingest_request_evidence(OrderRequestEvidenceIngestRequest::new(request_event()))
+ .ingest_request_evidence(TradeRequestEvidenceIngestRequest::new(request_event()))
.await
.expect_err("closed request evidence ingest");
assert!(matches!(
@@ -3946,7 +4183,7 @@ async fn order_status_and_evidence_ingest_cover_source_attached_success_paths()
let request_event = request_event();
let request_receipt = sdk
.trades()
- .ingest_request_evidence(OrderRequestEvidenceIngestRequest::new(
+ .ingest_request_evidence(TradeRequestEvidenceIngestRequest::new(
request_event.clone(),
))
.await
@@ -3957,15 +4194,15 @@ async fn order_status_and_evidence_ingest_cover_source_attached_success_paths()
let submit = enqueue_fixture_submit(&sdk, "order-status-source-attached").await;
let status = sdk
.trades()
- .status(OrderStatusRequest::parse(submit.order_id.as_str()).expect("status request"))
+ .status(TradeStatusRequest::parse(submit.order_id.as_str()).expect("status request"))
.await
.expect("order status");
- assert_eq!(status.status, OrderStatusKind::Requested);
+ assert_eq!(status.status, TradeStatusKind::Requested);
assert!(status.evidence.has_request);
let duplicate_receipt = sdk
.trades()
- .ingest_evidence(OrderEvidenceIngestRequest::new(request_event))
+ .ingest_evidence(TradeEvidenceIngestRequest::new(request_event))
.await
.expect("order evidence ingest");
assert!(!duplicate_receipt.inserted);
diff --git a/crates/sdk/tests/unit/relay_targets_tests.rs b/crates/sdk/tests/unit/relay_targets_tests.rs
@@ -1,4 +1,7 @@
-use super::{SdkRelayTargetPolicy, SdkRelayTargetSet, SdkRelayUrlPolicy};
+use super::{
+ AckPolicy, PublishMode, RelayResolutionPolicy, SdkRelayTargetPolicy, SdkRelayTargetSet,
+ SdkRelayUrlPolicy,
+};
use crate::{RadrootsSdkError, SDK_RELAY_TARGET_MAX_COUNT};
#[path = "../support/serializer_failure.rs"]
@@ -6,6 +9,43 @@ mod serializer_failure;
use serializer_failure::assert_struct_serialize_error_paths;
+#[test]
+fn publish_mode_and_ack_policy_serialize_explicit_product_contracts() {
+ assert_eq!(
+ serde_json::to_value(PublishMode::DryRun).expect("json"),
+ serde_json::json!("dry_run")
+ );
+ assert_eq!(
+ serde_json::to_value(PublishMode::EnqueueOnly).expect("json"),
+ serde_json::json!("enqueue_only")
+ );
+ assert_eq!(
+ serde_json::to_value(PublishMode::EnqueueAndPublish).expect("json"),
+ serde_json::json!("enqueue_and_publish")
+ );
+ assert_eq!(
+ serde_json::to_value(AckPolicy::NoWait).expect("json"),
+ serde_json::json!("no_wait")
+ );
+ assert_eq!(
+ serde_json::to_value(AckPolicy::AtLeastOneRelay).expect("json"),
+ serde_json::json!("at_least_one_relay")
+ );
+ assert_eq!(
+ serde_json::to_value(AckPolicy::AllRelays).expect("json"),
+ serde_json::json!("all_relays")
+ );
+ assert_eq!(
+ serde_json::to_value(AckPolicy::quorum(2).expect("quorum")).expect("json"),
+ serde_json::json!({ "quorum": { "required": 2 } })
+ );
+ assert!(matches!(
+ AckPolicy::quorum(0),
+ Err(RadrootsSdkError::InvalidRequest { ref message })
+ if message == "ack policy quorum must require at least one relay"
+ ));
+}
+
fn is_local_ws_relay(value: &str) -> bool {
let Some(rest) = value.strip_prefix("ws://") else {
return false;
@@ -34,6 +74,13 @@ fn relay_authority_host(authority: &str) -> Option<String> {
#[test]
fn use_configured_policy_serializes_as_kind_only() {
+ let trade_policy = RelayResolutionPolicy::ConfiguredRelays;
+ assert_eq!(
+ serde_json::to_value(&trade_policy).expect("json"),
+ serde_json::json!({ "kind": "configured_relays" })
+ );
+ assert_struct_serialize_error_paths(&trade_policy, 1);
+
let policy = SdkRelayTargetPolicy::UseConfiguredRelays;
assert_eq!(
serde_json::to_value(&policy).expect("json"),
@@ -94,6 +141,21 @@ fn target_set_accessors_and_configured_relays_cover_empty_and_dedupe_paths() {
.expect("target set"),
)
);
+ assert_eq!(
+ serde_json::to_value(
+ RelayResolutionPolicy::try_explicit(
+ vec!["wss://relay-c.example.com".to_owned()],
+ SdkRelayUrlPolicy::Public,
+ )
+ .expect("trade explicit policy")
+ )
+ .expect("trade policy json"),
+ serde_json::json!({
+ "kind": "explicit",
+ "relays": ["wss://relay-c.example.com"],
+ "canonical_relays": ["wss://relay-c.example.com"]
+ })
+ );
}
#[test]