sdk

Radroots SDK and bindings
git clone https://radroots.dev/git/sdk.git
Log | Files | Refs | README

commit 9883c1c0e7139d2552f21457f8819f14ca3467a3
parent dd50171d8225615ca9368a2c2ff987344118fe9b
Author: triesap <tyson@radroots.org>
Date:   Tue, 30 Jun 2026 20:05:50 +0000

docs: align grouped trade SDK surface

- document grouped trade product handles in the SDK README
- forbid root trade handle claims in README guards
- remove duplicate status and inert validation handle expectations
- guard product client handles against root escape methods

Diffstat:
Mcrates/sdk/README | 12++++++------
Mcrates/sdk/tests/source_boundary.rs | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 62 insertions(+), 20 deletions(-)

diff --git a/crates/sdk/README b/crates/sdk/README @@ -41,12 +41,12 @@ transport owns signing. `push_outbox_with_adapter(...)` remains available for te adapter-level substrate checks. `radrootsd-proxy` adds daemon-resolved publishing through `publish.event`. -`sdk.trades()` exposes local trade evidence ingestion and status projection APIs. Product workflow -actions are split into role-specific handles: `sdk.trade_buyer()`, `sdk.trade_seller()`, -`sdk.trade_status()`, `sdk.trade_resync()`, and `sdk.trade_validation()`. `sdk.trades().status(...)` -and `sdk.trade_status().status(...)` accept `TradeStatusRequest` and read local projections; they -return typed source, event count, limit state, event IDs, ambiguity candidates, eligibility, -next-action, and reducer issue data. Status is not a network fetch. +`sdk.trades()` exposes local trade evidence ingestion, status projection, and grouped product workflow +handles. Product workflow actions use `sdk.trades().buyer()`, `sdk.trades().seller()`, and +`sdk.trades().resync()`. `sdk.trades().status(...)` accepts `TradeStatusRequest` and reads local +projections; it returns typed source, event count, limit state, event IDs, ambiguity candidates, +eligibility, next-action, and reducer issue data. Status is not a network fetch. DVM proof requests and +validation receipt ingestion use `sdk.dvm()`. The `local-runtime` feature is the curated feature bundle for local product runtime consumers. It enables `std`, `serde`, `serde_json`, `runtime`, `signer-adapters`, `relay-runtime`, and diff --git a/crates/sdk/tests/source_boundary.rs b/crates/sdk/tests/source_boundary.rs @@ -56,15 +56,37 @@ const FORBIDDEN_SDK_README_CONCEPTS: &[ForbiddenSdkConcept] = &[ pattern: "protocol::", reason: "SDK docs must not advertise a public protocol workflow bypass", }, + ForbiddenSdkConcept { + pattern: "sdk.trade_buyer()", + reason: "SDK docs must use grouped trade product handles", + }, + ForbiddenSdkConcept { + pattern: "sdk.trade_seller()", + reason: "SDK docs must use grouped trade product handles", + }, + ForbiddenSdkConcept { + pattern: "sdk.trade_status()", + reason: "SDK docs must use sdk.trades().status(...) as the only product status entrypoint", + }, + ForbiddenSdkConcept { + pattern: "sdk.trade_resync()", + reason: "SDK docs must use grouped trade product handles", + }, + ForbiddenSdkConcept { + pattern: "sdk.trade_validation()", + reason: "SDK docs must use sdk.dvm() for validation receipt ingestion", + }, ]; const REQUIRED_SDK_README_CONCEPTS: &[&str] = &[ "RadrootsClient::builder()", "sdk.trades()", "TradeStatusRequest", - "sdk.trade_buyer()", - "sdk.trade_seller()", - "sdk.trade_status()", + "sdk.trades().buyer()", + "sdk.trades().seller()", + "sdk.trades().status(...)", + "sdk.trades().resync()", + "sdk.dvm()", ]; const REQUIRED_TRADE_RUNTIME_EXPORTS: &[&str] = &[ @@ -234,10 +256,21 @@ const REQUIRED_TRADE_SELLER_CLIENT_METHODS: &[&str] = &[ "pub async fn propose_revision(", ]; -const REQUIRED_TRADE_STATUS_CLIENT_METHODS: &[&str] = &["pub async fn status("]; - const REQUIRED_TRADE_RESYNC_CLIENT_METHODS: &[&str] = &["pub async fn resync("]; +const FORBIDDEN_PRODUCT_CLIENT_HANDLES: &[&str] = &[ + "TradeStatusClient", + "TradeValidationClient", + "pub struct TradeStatusClient", + "pub struct TradeValidationClient", +]; + +const FORBIDDEN_PRODUCT_CLIENT_METHODS: &[&str] = &[ + "pub fn status_client(", + "pub fn validation(", + "pub fn root(&self) -> &'client RadrootsClient", +]; + const FORBIDDEN_ORDER_RUNTIME_PUBLIC_EXPORTS: &[&str] = &[ "CheckoutClient", "EscrowClient", @@ -673,13 +706,6 @@ fn trade_product_facade_methods_are_inventory_guarded() { ); } - for method in REQUIRED_TRADE_STATUS_CLIENT_METHODS { - assert!( - source.contains(method), - "TradeStatusClient must expose product workflow method `{method}`" - ); - } - for method in REQUIRED_TRADE_RESYNC_CLIENT_METHODS { assert!( source.contains(method), @@ -751,8 +777,6 @@ fn product_clients_remain_thin_sdk_handles() { "TradeBuyerClient", "TradeResyncClient", "TradeSellerClient", - "TradeStatusClient", - "TradeValidationClient", "TradesClient", ] { assert!( @@ -764,6 +788,24 @@ fn product_clients_remain_thin_sdk_handles() { "product_clients.rs must define thin handle `{client}`" ); } + + for forbidden in FORBIDDEN_PRODUCT_CLIENT_HANDLES { + assert!( + !lib_source.contains(forbidden), + "src/lib.rs must not export removed product client handle `{forbidden}`" + ); + assert!( + !clients_source.contains(forbidden), + "product_clients.rs must not define removed product client handle `{forbidden}`" + ); + } + + for forbidden in FORBIDDEN_PRODUCT_CLIENT_METHODS { + assert!( + !clients_source.contains(forbidden), + "product_clients.rs must not expose removed product client method `{forbidden}`" + ); + } } #[test]