commit 2020244abe15b5e225fe0b86063f20be88663b35
parent 50f2f4de1b20c59a0f3cd61144405b5b9bedf6b4
Author: triesap <tyson@radroots.org>
Date: Sun, 14 Jun 2026 14:48:14 -0700
runtime: align trade reducer APIs
- wrap order lifecycle buckets in RadrootsOrderReductionInputs
- use public listing address parsing for seller authority checks
- refresh the lockfile for the current radroots_trade graph
- verify radroots_app_sqlite, radroots_app, and platform integration checks
Diffstat:
3 files changed, 44 insertions(+), 32 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -5186,6 +5186,14 @@ dependencies = [
]
[[package]]
+name = "radroots_authority"
+version = "0.1.0-alpha.2"
+dependencies = [
+ "radroots_events",
+ "thiserror 1.0.69",
+]
+
+[[package]]
name = "radroots_core"
version = "0.1.0-alpha.2"
dependencies = [
@@ -5385,6 +5393,7 @@ version = "0.1.0-alpha.2"
dependencies = [
"base64 0.22.1",
"hex",
+ "radroots_authority",
"radroots_core",
"radroots_events",
"radroots_events_codec",
diff --git a/crates/desktop/src/runtime.rs b/crates/desktop/src/runtime.rs
@@ -113,10 +113,11 @@ use radroots_sdk::{
SdkPublishReceipt, SdkTransportMode, SdkTransportReceipt, SignerConfig,
};
use radroots_sql_core::SqliteExecutor;
+use radroots_trade::listing::parse_public_listing_address;
use radroots_trade::order::{
RadrootsOrderCancellationRecord, RadrootsOrderDecisionRecord, RadrootsOrderFulfillmentRecord,
RadrootsOrderPaymentEventRecord, RadrootsOrderPaymentState, RadrootsOrderReceiptRecord,
- RadrootsOrderRequestRecord, RadrootsOrderRevisionDecisionRecord,
+ RadrootsOrderReductionInputs, RadrootsOrderRequestRecord, RadrootsOrderRevisionDecisionRecord,
RadrootsOrderRevisionProposalRecord, RadrootsOrderSettlementRecord, RadrootsOrderStatus,
reduce_order_events,
};
@@ -2442,12 +2443,11 @@ impl DesktopAppRuntimeState {
reason: "seller order decision seller account does not match order seller",
});
}
- let listing_address =
- radroots_sdk::order::parse_listing_address(request.payload.listing_addr.as_str())
- .map_err(|_| AppSqliteError::InvalidProjection {
- reason: "seller order decision listing address is invalid",
- })?;
- if listing_address.seller_pubkey != seller_pubkey {
+ let listing_address = parse_public_listing_address(request.payload.listing_addr.as_str())
+ .map_err(|_| AppSqliteError::InvalidProjection {
+ reason: "seller order decision listing address is invalid",
+ })?;
+ if listing_address.seller_pubkey.as_str() != seller_pubkey.as_str() {
return Err(AppSqliteError::InvalidProjection {
reason: "seller order decision listing address is outside seller authority",
});
@@ -2729,12 +2729,11 @@ impl DesktopAppRuntimeState {
reason: "seller order revision seller account does not match order seller",
});
}
- let listing_address =
- radroots_sdk::order::parse_listing_address(request.payload.listing_addr.as_str())
- .map_err(|_| AppSqliteError::InvalidProjection {
- reason: "seller order revision listing address is invalid",
- })?;
- if listing_address.seller_pubkey != seller_pubkey {
+ let listing_address = parse_public_listing_address(request.payload.listing_addr.as_str())
+ .map_err(|_| AppSqliteError::InvalidProjection {
+ reason: "seller order revision listing address is invalid",
+ })?;
+ if listing_address.seller_pubkey.as_str() != seller_pubkey.as_str() {
return Err(AppSqliteError::InvalidProjection {
reason: "seller order revision listing address is outside seller authority",
});
@@ -5570,15 +5569,17 @@ impl DesktopAppRuntimeState {
let projection = reduce_order_events(
&request.payload.order_id,
- buckets.requests.clone(),
- buckets.decisions.clone(),
- buckets.revision_proposals.clone(),
- buckets.revision_decisions.clone(),
- buckets.fulfillments.clone(),
- buckets.cancellations.clone(),
- buckets.receipts.clone(),
- buckets.payments.clone(),
- buckets.settlements.clone(),
+ RadrootsOrderReductionInputs {
+ requests: buckets.requests.clone(),
+ decisions: buckets.decisions.clone(),
+ revision_proposals: buckets.revision_proposals.clone(),
+ revision_decisions: buckets.revision_decisions.clone(),
+ fulfillments: buckets.fulfillments.clone(),
+ cancellations: buckets.cancellations.clone(),
+ receipts: buckets.receipts.clone(),
+ payments: buckets.payments.clone(),
+ settlements: buckets.settlements.clone(),
+ },
);
if !projection.issues.is_empty() || projection.status == RadrootsOrderStatus::Invalid {
return Err(AppSqliteError::InvalidProjection {
diff --git a/crates/store/src/interop.rs b/crates/store/src/interop.rs
@@ -43,7 +43,7 @@ use radroots_sql_core::{SqlExecutor, SqliteExecutor};
use radroots_trade::order::{
RadrootsOrderCancellationRecord, RadrootsOrderDecisionRecord, RadrootsOrderFulfillmentRecord,
RadrootsOrderPaymentEventRecord, RadrootsOrderProjection, RadrootsOrderReceiptRecord,
- RadrootsOrderRequestRecord, RadrootsOrderRevisionDecisionRecord,
+ RadrootsOrderReductionInputs, RadrootsOrderRequestRecord, RadrootsOrderRevisionDecisionRecord,
RadrootsOrderRevisionProposalRecord, RadrootsOrderSettlementRecord, reduce_order_events,
};
use radroots_trade::validation_receipt::{
@@ -1197,15 +1197,17 @@ impl<'a> AppLocalInteropRepository<'a> {
})?;
let projection = reduce_order_events(
&reducer_order_id,
- buckets.requests,
- buckets.decisions,
- buckets.revision_proposals,
- buckets.revision_decisions,
- buckets.fulfillments,
- buckets.cancellations,
- buckets.receipts,
- buckets.payments,
- buckets.settlements,
+ RadrootsOrderReductionInputs {
+ requests: buckets.requests,
+ decisions: buckets.decisions,
+ revision_proposals: buckets.revision_proposals,
+ revision_decisions: buckets.revision_decisions,
+ fulfillments: buckets.fulfillments,
+ cancellations: buckets.cancellations,
+ receipts: buckets.receipts,
+ payments: buckets.payments,
+ settlements: buckets.settlements,
+ },
);
let request_payload = projection.request_event_id.as_deref().and_then(|event_id| {
requests