app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit c99b51612fda0af732866b7e550a033af6e22bbe
parent bde62f3210d42b006cae01cf7ee63f959ccb4dc1
Author: triesap <tyson@radroots.org>
Date:   Sat, 13 Jun 2026 00:44:57 -0700

app: align typed order ids

- Refresh the app lockfile for the shared SQLite binding graph
- Parse rr-rs listing, order, bin, quote, and digest IDs at interop boundaries
- Preserve app-facing string projections for UI and local store surfaces
- Validate the app check and SQLite interop test lanes

Diffstat:
MCargo.lock | 59++++++++++++-----------------------------------------------
MCargo.toml | 2+-
Mcrates/desktop/src/runtime.rs | 152+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mcrates/store/src/interop.rs | 188++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
4 files changed, 227 insertions(+), 174 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -2023,12 +2023,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "foldhash" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" - -[[package]] name = "font-types" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2784,16 +2778,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash 0.1.5", -] - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "foldhash 0.2.0", + "foldhash", ] [[package]] @@ -2813,11 +2798,11 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.11.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0b22561a9c04a7cb1a302c013e0259cd3b4bb619f145b32f72b8b4bcbed230" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown 0.16.1", + "hashbrown 0.14.5", ] [[package]] @@ -3520,9 +3505,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.37.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f111c8c41e7c61a49cd34e44c7619462967221a6443b0ec299e0ac30cfb9b1" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -5213,8 +5198,11 @@ dependencies = [ name = "radroots_events" version = "0.1.0-alpha.2" dependencies = [ + "hex", "radroots_core", "serde", + "serde_json", + "sha2", ] [[package]] @@ -5722,28 +5710,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" [[package]] -name = "rsqlite-vfs" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c" -dependencies = [ - "hashbrown 0.16.1", - "thiserror 2.0.18", -] - -[[package]] name = "rusqlite" -version = "0.39.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2b0146dd9661bf67bb107c0bb2a55064d556eeb3fc314151b957f313bcd4e" +checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ "bitflags 2.11.1", "fallible-iterator", "fallible-streaming-iterator", - "hashlink 0.11.0", + "hashlink 0.9.1", "libsqlite3-sys", "smallvec", - "sqlite-wasm-rs", ] [[package]] @@ -6504,18 +6481,6 @@ dependencies = [ ] [[package]] -name = "sqlite-wasm-rs" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd578e94101503d97e2b286bbf8db2135035ca24b2ce4cbf3f9e2fb2bbf1eee" -dependencies = [ - "cc", - "js-sys", - "rsqlite-vfs", - "wasm-bindgen", -] - -[[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -52,7 +52,7 @@ radroots_app_sqlite = { path = "crates/store", version = "0.1.0" } radroots_app_state = { path = "crates/state", version = "0.1.0" } radroots_app_sync = { path = "crates/sync", version = "0.1.0" } radroots_app_ui = { path = "crates/ui", version = "0.1.0" } -rusqlite = { version = "0.39", features = ["bundled"] } +rusqlite = { version = "0.32.1", features = ["bundled"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "2" diff --git a/crates/desktop/src/runtime.rs b/crates/desktop/src/runtime.rs @@ -65,11 +65,17 @@ use radroots_core::{ RadrootsCoreCurrency, RadrootsCoreDecimal, RadrootsCoreMoney, RadrootsCoreQuantity, RadrootsCoreQuantityPrice, RadrootsCoreUnit, }; -use radroots_events::kinds::{ - KIND_FARM, KIND_LISTING, KIND_LISTING_DRAFT, KIND_ORDER_CANCELLATION, KIND_ORDER_DECISION, - KIND_ORDER_FULFILLMENT_UPDATE, KIND_ORDER_PAYMENT_RECORD, KIND_ORDER_RECEIPT, - KIND_ORDER_REQUEST, KIND_ORDER_REVISION_DECISION, KIND_ORDER_REVISION_PROPOSAL, - KIND_ORDER_SETTLEMENT_DECISION, KIND_PROFILE, +use radroots_events::{ + ids::{ + RadrootsDTag, RadrootsInventoryBinId, RadrootsListingAddress, RadrootsOrderId, + RadrootsOrderRevisionId, + }, + kinds::{ + KIND_FARM, KIND_LISTING, KIND_LISTING_DRAFT, KIND_ORDER_CANCELLATION, KIND_ORDER_DECISION, + KIND_ORDER_FULFILLMENT_UPDATE, KIND_ORDER_PAYMENT_RECORD, KIND_ORDER_RECEIPT, + KIND_ORDER_REQUEST, KIND_ORDER_REVISION_DECISION, KIND_ORDER_REVISION_PROPOSAL, + KIND_ORDER_SETTLEMENT_DECISION, KIND_PROFILE, + }, }; use radroots_events_codec::order::{ order_event_context_from_tags, order_payment_record_from_event, @@ -2479,10 +2485,10 @@ impl DesktopAppRuntimeState { context: AppPublishContext::new(account_id, "seller_order_decision"), app_order_id: order_id, farm_id, - trade_order_id: request.payload.order_id.clone(), + trade_order_id: request.payload.order_id.to_string(), request_event_id: request.request_event_id, listing_event_id: request.listing_event_id, - listing_addr: request.payload.listing_addr, + listing_addr: request.payload.listing_addr.to_string(), buyer_pubkey: request.payload.buyer_pubkey, seller_pubkey: request.payload.seller_pubkey, decision, @@ -2639,10 +2645,10 @@ impl DesktopAppRuntimeState { context: AppPublishContext::new(account_id, "seller_order_fulfillment"), app_order_id: order_id, farm_id, - trade_order_id: request.payload.order_id, + trade_order_id: request.payload.order_id.to_string(), request_event_id: request.request_event_id, prev_event_id, - listing_addr: request.payload.listing_addr, + listing_addr: request.payload.listing_addr.to_string(), buyer_pubkey: request.payload.buyer_pubkey, seller_pubkey: request.payload.seller_pubkey, status, @@ -2785,11 +2791,11 @@ impl DesktopAppRuntimeState { context: AppPublishContext::new(account_id, "seller_order_revision_proposal"), app_order_id: order_id, farm_id, - trade_order_id: request.payload.order_id, + trade_order_id: request.payload.order_id.to_string(), request_event_id: request.request_event_id, prev_event_id, revision_id: format!("app-revision-{}", d_tag_from_uuid(Uuid::now_v7())), - listing_addr: request.payload.listing_addr, + listing_addr: request.payload.listing_addr.to_string(), buyer_pubkey: request.payload.buyer_pubkey, seller_pubkey: request.payload.seller_pubkey, items, @@ -2912,11 +2918,11 @@ impl DesktopAppRuntimeState { context: AppPublishContext::new(account_id.clone(), "buyer_order_revision_decision"), app_order_id: order_id, farm_id: detail.farm_id, - trade_order_id: request.payload.order_id, + trade_order_id: request.payload.order_id.to_string(), request_event_id: request.request_event_id, prev_event_id: proposal.event_id.clone(), - revision_id: proposal.payload.revision_id.clone(), - listing_addr: request.payload.listing_addr, + revision_id: proposal.payload.revision_id.to_string(), + listing_addr: request.payload.listing_addr.to_string(), buyer_pubkey: request.payload.buyer_pubkey, seller_pubkey: request.payload.seller_pubkey, decision, @@ -3059,10 +3065,10 @@ impl DesktopAppRuntimeState { context: AppPublishContext::new(account_id.clone(), "buyer_order_cancellation"), app_order_id: order_id, farm_id: detail.farm_id, - trade_order_id: request.payload.order_id, + trade_order_id: request.payload.order_id.to_string(), request_event_id: request.request_event_id, prev_event_id, - listing_addr: request.payload.listing_addr, + listing_addr: request.payload.listing_addr.to_string(), buyer_pubkey: request.payload.buyer_pubkey, seller_pubkey: request.payload.seller_pubkey, reason: "buyer cancelled order".to_owned(), @@ -3175,10 +3181,10 @@ impl DesktopAppRuntimeState { context: AppPublishContext::new(account_id.clone(), "buyer_order_receipt"), app_order_id: order_id, farm_id: detail.farm_id, - trade_order_id: request.payload.order_id, + trade_order_id: request.payload.order_id.to_string(), request_event_id: request.request_event_id, prev_event_id: fulfillment.event_id.clone(), - listing_addr: request.payload.listing_addr, + listing_addr: request.payload.listing_addr.to_string(), buyer_pubkey: request.payload.buyer_pubkey, seller_pubkey: request.payload.seller_pubkey, received, @@ -7184,7 +7190,7 @@ async fn publish_app_payload( .map_err(|error| AppSyncTransportError::failed(error.to_string())) } AppPublishPayload::OrderDecision(payload) => { - let decision = order_decision_publish_payload_to_sdk_decision(payload); + let decision = order_decision_publish_payload_to_sdk_decision(payload)?; client .order() .publish_order_decision_with_identity( @@ -7197,7 +7203,7 @@ async fn publish_app_payload( .map_err(|error| AppSyncTransportError::failed(error.to_string())) } AppPublishPayload::OrderRevisionProposal(payload) => { - let proposal = order_revision_proposal_publish_payload_to_sdk_revision(payload); + let proposal = order_revision_proposal_publish_payload_to_sdk_revision(payload)?; client .order() .publish_order_revision_proposal_with_identity( @@ -7211,7 +7217,7 @@ async fn publish_app_payload( } AppPublishPayload::OrderRevisionDecision(payload) => { let decision = - order_revision_decision_publish_payload_to_sdk_revision_decision(payload); + order_revision_decision_publish_payload_to_sdk_revision_decision(payload)?; client .order() .publish_order_revision_decision_with_identity( @@ -7224,7 +7230,7 @@ async fn publish_app_payload( .map_err(|error| AppSyncTransportError::failed(error.to_string())) } AppPublishPayload::OrderCancellation(payload) => { - let cancellation = order_cancellation_publish_payload_to_sdk_cancellation(payload); + let cancellation = order_cancellation_publish_payload_to_sdk_cancellation(payload)?; client .order() .publish_order_cancellation_with_identity( @@ -7237,7 +7243,7 @@ async fn publish_app_payload( .map_err(|error| AppSyncTransportError::failed(error.to_string())) } AppPublishPayload::OrderFulfillment(payload) => { - let fulfillment = order_fulfillment_publish_payload_to_sdk_fulfillment(payload); + let fulfillment = order_fulfillment_publish_payload_to_sdk_fulfillment(payload)?; client .order() .publish_fulfillment_update_with_identity( @@ -7250,7 +7256,7 @@ async fn publish_app_payload( .map_err(|error| AppSyncTransportError::failed(error.to_string())) } AppPublishPayload::OrderReceipt(payload) => { - let receipt = order_receipt_publish_payload_to_sdk_receipt(payload); + let receipt = order_receipt_publish_payload_to_sdk_receipt(payload)?; client .order() .publish_buyer_receipt_with_identity( @@ -7291,7 +7297,10 @@ fn listing_publish_payload_to_sdk_listing( .filter(|value| !value.trim().is_empty()) .map(str::to_owned) .unwrap_or_else(|| d_tag_from_uuid(payload.product_id.as_uuid())); - let bin_id = listing_primary_bin_id(d_tag.as_str()); + let d_tag = RadrootsDTag::parse(d_tag.as_str()) + .map_err(|error| AppSyncTransportError::failed(error.to_string()))?; + let bin_id = RadrootsInventoryBinId::parse(listing_primary_bin_id(d_tag.as_str())) + .map_err(|error| AppSyncTransportError::failed(error.to_string()))?; Ok(RadrootsListing { d_tag, @@ -9553,12 +9562,31 @@ fn seller_order_inventory_commitments( .collect() } +fn publish_order_id(value: &str) -> Result<RadrootsOrderId, AppSyncTransportError> { + RadrootsOrderId::parse(value).map_err(|error| AppSyncTransportError::failed(error.to_string())) +} + +fn publish_revision_id(value: &str) -> Result<RadrootsOrderRevisionId, AppSyncTransportError> { + RadrootsOrderRevisionId::parse(value) + .map_err(|error| AppSyncTransportError::failed(error.to_string())) +} + +fn publish_listing_addr(value: &str) -> Result<RadrootsListingAddress, AppSyncTransportError> { + RadrootsListingAddress::parse(value) + .map_err(|error| AppSyncTransportError::failed(error.to_string())) +} + +fn publish_bin_id(value: &str) -> Result<RadrootsInventoryBinId, AppSyncTransportError> { + RadrootsInventoryBinId::parse(value) + .map_err(|error| AppSyncTransportError::failed(error.to_string())) +} + fn order_decision_publish_payload_to_sdk_decision( payload: &AppOrderDecisionPublishPayload, -) -> RadrootsOrderDecision { - RadrootsOrderDecision { - order_id: payload.trade_order_id.clone(), - listing_addr: payload.listing_addr.clone(), +) -> Result<RadrootsOrderDecision, AppSyncTransportError> { + Ok(RadrootsOrderDecision { + order_id: publish_order_id(payload.trade_order_id.as_str())?, + listing_addr: publish_listing_addr(payload.listing_addr.as_str())?, buyer_pubkey: payload.buyer_pubkey.clone(), seller_pubkey: payload.seller_pubkey.clone(), decision: match &payload.decision { @@ -9567,11 +9595,13 @@ fn order_decision_publish_payload_to_sdk_decision( } => RadrootsOrderDecisionOutcome::Accepted { inventory_commitments: inventory_commitments .iter() - .map(|commitment| RadrootsOrderInventoryCommitment { - bin_id: commitment.bin_id.clone(), - bin_count: commitment.bin_count, + .map(|commitment| { + Ok(RadrootsOrderInventoryCommitment { + bin_id: publish_bin_id(commitment.bin_id.as_str())?, + bin_count: commitment.bin_count, + }) }) - .collect(), + .collect::<Result<Vec<_>, AppSyncTransportError>>()?, }, AppOrderDecisionPayload::Declined { reason } => { RadrootsOrderDecisionOutcome::Declined { @@ -9579,16 +9609,16 @@ fn order_decision_publish_payload_to_sdk_decision( } } }, - } + }) } fn order_revision_proposal_publish_payload_to_sdk_revision( payload: &AppOrderRevisionProposalPublishPayload, -) -> RadrootsOrderRevisionProposal { - RadrootsOrderRevisionProposal { - revision_id: payload.revision_id.clone(), - order_id: payload.trade_order_id.clone(), - listing_addr: payload.listing_addr.clone(), +) -> Result<RadrootsOrderRevisionProposal, AppSyncTransportError> { + Ok(RadrootsOrderRevisionProposal { + revision_id: publish_revision_id(payload.revision_id.as_str())?, + order_id: publish_order_id(payload.trade_order_id.as_str())?, + listing_addr: publish_listing_addr(payload.listing_addr.as_str())?, buyer_pubkey: payload.buyer_pubkey.clone(), seller_pubkey: payload.seller_pubkey.clone(), root_event_id: payload.request_event_id.clone(), @@ -9596,60 +9626,60 @@ fn order_revision_proposal_publish_payload_to_sdk_revision( items: payload.items.clone(), economics: payload.economics.clone(), reason: payload.reason.clone(), - } + }) } fn order_revision_decision_publish_payload_to_sdk_revision_decision( payload: &AppOrderRevisionDecisionPublishPayload, -) -> RadrootsOrderRevisionDecision { - RadrootsOrderRevisionDecision { - revision_id: payload.revision_id.clone(), - order_id: payload.trade_order_id.clone(), - listing_addr: payload.listing_addr.clone(), +) -> Result<RadrootsOrderRevisionDecision, AppSyncTransportError> { + Ok(RadrootsOrderRevisionDecision { + revision_id: publish_revision_id(payload.revision_id.as_str())?, + order_id: publish_order_id(payload.trade_order_id.as_str())?, + listing_addr: publish_listing_addr(payload.listing_addr.as_str())?, buyer_pubkey: payload.buyer_pubkey.clone(), seller_pubkey: payload.seller_pubkey.clone(), root_event_id: payload.request_event_id.clone(), prev_event_id: payload.prev_event_id.clone(), decision: payload.decision.clone(), - } + }) } fn order_fulfillment_publish_payload_to_sdk_fulfillment( payload: &AppOrderFulfillmentPublishPayload, -) -> RadrootsOrderFulfillmentUpdate { - RadrootsOrderFulfillmentUpdate { - order_id: payload.trade_order_id.clone(), - listing_addr: payload.listing_addr.clone(), +) -> Result<RadrootsOrderFulfillmentUpdate, AppSyncTransportError> { + Ok(RadrootsOrderFulfillmentUpdate { + order_id: publish_order_id(payload.trade_order_id.as_str())?, + listing_addr: publish_listing_addr(payload.listing_addr.as_str())?, buyer_pubkey: payload.buyer_pubkey.clone(), seller_pubkey: payload.seller_pubkey.clone(), status: payload.status, - } + }) } fn order_cancellation_publish_payload_to_sdk_cancellation( payload: &AppOrderCancellationPublishPayload, -) -> RadrootsOrderCancellation { - RadrootsOrderCancellation { - order_id: payload.trade_order_id.clone(), - listing_addr: payload.listing_addr.clone(), +) -> Result<RadrootsOrderCancellation, AppSyncTransportError> { + Ok(RadrootsOrderCancellation { + order_id: publish_order_id(payload.trade_order_id.as_str())?, + listing_addr: publish_listing_addr(payload.listing_addr.as_str())?, buyer_pubkey: payload.buyer_pubkey.clone(), seller_pubkey: payload.seller_pubkey.clone(), reason: payload.reason.clone(), - } + }) } fn order_receipt_publish_payload_to_sdk_receipt( payload: &AppOrderReceiptPublishPayload, -) -> RadrootsOrderReceipt { - RadrootsOrderReceipt { - order_id: payload.trade_order_id.clone(), - listing_addr: payload.listing_addr.clone(), +) -> Result<RadrootsOrderReceipt, AppSyncTransportError> { + Ok(RadrootsOrderReceipt { + order_id: publish_order_id(payload.trade_order_id.as_str())?, + listing_addr: publish_listing_addr(payload.listing_addr.as_str())?, buyer_pubkey: payload.buyer_pubkey.clone(), seller_pubkey: payload.seller_pubkey.clone(), received: payload.received, issue: payload.issue.clone(), received_at: payload.received_at, - } + }) } fn pending_sync_upsert(aggregate: SyncAggregateRef, payload_json: String) -> PendingSyncOperation { diff --git a/crates/store/src/interop.rs b/crates/store/src/interop.rs @@ -1527,7 +1527,7 @@ impl<'a> AppLocalInteropRepository<'a> { .unwrap_or_else(|| payload.economics.currency.to_string()); let title = existing_listing .map(|listing| listing.title.clone()) - .unwrap_or_else(|| item.bin_id.clone()); + .unwrap_or_else(|| item.bin_id.to_string()); self.connection .execute( "INSERT INTO order_lines ( @@ -1622,7 +1622,7 @@ impl<'a> AppLocalInteropRepository<'a> { .is_none_or(|listing_bin_id| listing_bin_id == item.bin_id) }) .map(|listing| listing.title.clone()) - .unwrap_or_else(|| item.bin_id.clone()); + .unwrap_or_else(|| item.bin_id.to_string()); self.connection .execute( "INSERT INTO order_lines ( @@ -3358,14 +3358,14 @@ fn active_order_agreement_source( }) { return ActiveOrderAgreementSource { - listing_addr: revision_proposal.payload.listing_addr.clone(), + listing_addr: revision_proposal.payload.listing_addr.to_string(), seller_pubkey: revision_proposal.payload.seller_pubkey.clone(), items: revision_proposal.payload.items.clone(), economics: revision_proposal.payload.economics.clone(), }; } ActiveOrderAgreementSource { - listing_addr: request.listing_addr.clone(), + listing_addr: request.listing_addr.to_string(), seller_pubkey: request.seller_pubkey.clone(), items: request.items.clone(), economics: request.economics.clone(), @@ -3858,6 +3858,10 @@ mod tests { }; use radroots_events::{ RadrootsNostrEvent, RadrootsNostrEventPtr, + ids::{ + RadrootsEconomicsDigest, RadrootsInventoryBinId, RadrootsListingAddress, + RadrootsOrderId, RadrootsOrderQuoteId, RadrootsOrderRevisionId, + }, kinds::KIND_ORDER_RECEIPT, order::{ RadrootsOrderCancellation, RadrootsOrderDecision, RadrootsOrderDecisionOutcome, @@ -4356,6 +4360,37 @@ mod tests { RadrootsCoreMoney::new(decimal(raw), RadrootsCoreCurrency::USD) } + fn test_pubkey(seed: &str) -> String { + let left = Uuid::new_v5(&Uuid::NAMESPACE_URL, seed.as_bytes()); + let right_seed = format!("{seed}:right"); + let right = Uuid::new_v5(&Uuid::NAMESPACE_URL, right_seed.as_bytes()); + format!("{}{}", left.simple(), right.simple()) + } + + fn typed_order_id(raw: &str) -> RadrootsOrderId { + raw.parse().expect("valid order id") + } + + fn typed_revision_id(raw: &str) -> RadrootsOrderRevisionId { + raw.parse().expect("valid revision id") + } + + fn typed_quote_id(raw: &str) -> RadrootsOrderQuoteId { + raw.parse().expect("valid quote id") + } + + fn typed_bin_id(raw: &str) -> RadrootsInventoryBinId { + raw.parse().expect("valid bin id") + } + + fn typed_listing_addr(raw: &str) -> RadrootsListingAddress { + raw.parse().expect("valid listing address") + } + + fn typed_economics_digest(raw: &str) -> RadrootsEconomicsDigest { + raw.parse().expect("valid economics digest") + } + fn listing_event_ptr(event_id: &str) -> RadrootsNostrEventPtr { RadrootsNostrEventPtr { id: event_id.to_owned(), @@ -4370,21 +4405,21 @@ mod tests { seller_pubkey: &str, ) -> RadrootsOrderRequest { RadrootsOrderRequest { - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), items: vec![RadrootsOrderItem { - bin_id: "bin-1".to_owned(), + bin_id: typed_bin_id("bin-1"), bin_count: 2, }], economics: RadrootsOrderEconomics { - quote_id: format!("quote-{order_id}"), + quote_id: typed_quote_id(format!("quote-{order_id}").as_str()), quote_version: 1, pricing_basis: RadrootsOrderPricingBasis::ListingEvent, currency: RadrootsCoreCurrency::USD, items: vec![RadrootsOrderEconomicItem { - bin_id: "bin-1".to_owned(), + bin_id: typed_bin_id("bin-1"), bin_count: 2, quantity_amount: decimal("1"), quantity_unit: RadrootsCoreUnit::Each, @@ -4409,13 +4444,13 @@ mod tests { seller_pubkey: &str, ) -> RadrootsOrderDecision { RadrootsOrderDecision { - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), decision: RadrootsOrderDecisionOutcome::Accepted { inventory_commitments: vec![RadrootsOrderInventoryCommitment { - bin_id: "bin-1".to_owned(), + bin_id: typed_bin_id("bin-1"), bin_count: 2, }], }, @@ -4429,8 +4464,8 @@ mod tests { seller_pubkey: &str, ) -> RadrootsOrderDecision { RadrootsOrderDecision { - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), decision: RadrootsOrderDecisionOutcome::Declined { @@ -4451,16 +4486,17 @@ mod tests { let mut request = order_request_payload(order_id, listing_addr, buyer_pubkey, seller_pubkey); request.items[0].bin_count = 3; - request.economics.quote_id = format!("quote-{order_id}-{revision_id}"); + request.economics.quote_id = + typed_quote_id(format!("quote-{order_id}-{revision_id}").as_str()); request.economics.quote_version = 2; request.economics.items[0].bin_count = 3; request.economics.items[0].line_subtotal = usd("24"); request.economics.subtotal = usd("24"); request.economics.total = usd("24"); RadrootsOrderRevisionProposal { - revision_id: revision_id.to_owned(), - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + revision_id: typed_revision_id(revision_id), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), root_event_id: root_event_id.to_owned(), @@ -4482,9 +4518,9 @@ mod tests { decision: RadrootsOrderRevisionOutcome, ) -> RadrootsOrderRevisionDecision { RadrootsOrderRevisionDecision { - revision_id: revision_id.to_owned(), - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + revision_id: typed_revision_id(revision_id), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), root_event_id: root_event_id.to_owned(), @@ -4501,8 +4537,8 @@ mod tests { status: RadrootsOrderFulfillmentState, ) -> RadrootsOrderFulfillmentUpdate { RadrootsOrderFulfillmentUpdate { - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), status, @@ -4516,8 +4552,8 @@ mod tests { seller_pubkey: &str, ) -> RadrootsOrderCancellation { RadrootsOrderCancellation { - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), reason: "buyer changed pickup plan".to_owned(), @@ -4532,8 +4568,8 @@ mod tests { received: bool, ) -> RadrootsOrderReceipt { RadrootsOrderReceipt { - order_id: order_id.to_owned(), - listing_addr: listing_addr.to_owned(), + order_id: typed_order_id(order_id), + listing_addr: typed_listing_addr(listing_addr), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), received, @@ -4577,7 +4613,7 @@ mod tests { let events = local_events_store(); let farm_key = "DDDDDDDDDDDDDDDDDDDDDD"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; - let seller_pubkey = format!("{label}-seller"); + let seller_pubkey = test_pubkey(format!("{label}-seller").as_str()); let buyer_pubkey = format!("{label}-buyer"); let order_id_raw = format!("{label}-order"); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -4716,7 +4752,7 @@ mod tests { let events = local_events_store(); let farm_key = "DDDDDDDDDDDDDDDDDDDDDD"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; - let seller_pubkey = format!("{label}-seller"); + let seller_pubkey = test_pubkey(format!("{label}-seller").as_str()); let buyer_pubkey = format!("{label}-buyer"); let order_id_raw = format!("{label}-order"); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -4835,8 +4871,11 @@ mod tests { agreement_event_id: agreement_event_id.to_owned(), quote_id: request.economics.quote_id.clone(), quote_version: request.economics.quote_version, - economics_digest: radroots_order_economics_digest(&request.economics) - .expect("order economics digest should encode"), + economics_digest: typed_economics_digest( + radroots_order_economics_digest(&request.economics) + .expect("order economics digest should encode") + .as_str(), + ), amount: request.economics.total.amount, currency: request.economics.total.currency, method: RadrootsOrderPaymentMethod::ManualTransfer, @@ -4866,8 +4905,11 @@ mod tests { payment_event_id: payment_event_id.to_owned(), quote_id: request.economics.quote_id.clone(), quote_version: request.economics.quote_version, - economics_digest: radroots_order_economics_digest(&request.economics) - .expect("order economics digest should encode"), + economics_digest: typed_economics_digest( + radroots_order_economics_digest(&request.economics) + .expect("order economics digest should encode") + .as_str(), + ), amount: request.economics.total.amount, currency: request.economics.total.currency, decision, @@ -5021,7 +5063,8 @@ mod tests { let events = local_events_store(); let farm_key = "AAAAAAAAAAAAAAAAAAAAAA"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAg"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "buyer-pubkey"; let order_id_raw = "relay-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -5124,13 +5167,18 @@ mod tests { let app_store = AppSqliteStore::open(DatabaseTarget::InMemory).expect("open app sqlite store"); let events = local_events_store(); - let listing_addr = "30402:seller-pubkey:AAAAAAAAAAAAAAAAAAAAAg"; let buyer_pubkey = "buyer-pubkey"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); + let listing_addr = format!("30402:{seller_pubkey}:AAAAAAAAAAAAAAAAAAAAAg"); let relay_url = "ws://127.0.0.1:1234"; let build_event = |event_id: &str, order_id_raw: &str| { - let payload = - order_request_payload(order_id_raw, listing_addr, buyer_pubkey, seller_pubkey); + let payload = order_request_payload( + order_id_raw, + listing_addr.as_str(), + buyer_pubkey, + seller_pubkey, + ); let parts = order_request_event_build(&listing_event_ptr("listing-event-1"), &payload) .expect("build order request event"); event_from_parts(event_id, buyer_pubkey, parts) @@ -5140,7 +5188,7 @@ mod tests { .append_record(&signed_order_event_record( "cli:signed_event:order-request:evidence-ack", &acknowledged_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, )) @@ -5150,7 +5198,7 @@ mod tests { let mut observed_record = signed_order_event_record( "cli:signed_event:order-request:evidence-observed", &observed_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -5169,7 +5217,7 @@ mod tests { let mut pending_record = signed_order_event_record( "cli:signed_event:order-request:evidence-pending", &pending_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -5189,7 +5237,7 @@ mod tests { let mut failed_record = signed_order_event_record( "cli:signed_event:order-request:evidence-failed", &failed_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -5209,7 +5257,7 @@ mod tests { let mut local_only_record = signed_order_event_record( "cli:signed_event:order-request:evidence-local-only", &local_only_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -5227,7 +5275,7 @@ mod tests { let mut malformed_delivery_record = signed_order_event_record( "cli:signed_event:order-request:evidence-malformed-delivery", &malformed_delivery_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -5243,7 +5291,7 @@ mod tests { let mut malformed_record = signed_order_event_record( "cli:signed_event:order-request:evidence-malformed-event", &malformed_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -5269,7 +5317,8 @@ mod tests { let events = local_events_store(); let farm_key = "CCCCCCCCCCCCCCCCCCCCCC"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAg"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "app-buyer-pubkey"; let order_id_raw = "app-relay-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -5532,7 +5581,8 @@ mod tests { let events = local_events_store(); let farm_key = "CCCCCCCCCCCCCCCCCCCCCC"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAg"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "app-buyer-pubkey"; let order_id_raw = "app-relay-order-declined-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -5661,7 +5711,8 @@ mod tests { let events = local_events_store(); let farm_key = "DDDDDDDDDDDDDDDDDDDDDD"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "app-buyer-pubkey"; let order_id_raw = "active-lifecycle-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -6126,7 +6177,8 @@ mod tests { let events = local_events_store(); let farm_key = "DDDDDDDDDDDDDDDDDDDDDD"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; - let seller_pubkey = "validation-out-of-order-seller"; + let seller_pubkey = test_pubkey("validation-out-of-order-seller"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "validation-out-of-order-buyer"; let order_id_raw = "validation-out-of-order"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -6348,7 +6400,8 @@ mod tests { let events = local_events_store(); let farm_key = "EEEEEEEEEEEEEEEEEEEEEE"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "app-buyer-pubkey"; let order_id_raw = "active-revision-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); @@ -6606,7 +6659,8 @@ mod tests { let events = local_events_store(); let farm_key = "FFFFFFFFFFFFFFFFFFFFFF"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; - let seller_pubkey = "seller-pubkey"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); let buyer_pubkey = "app-buyer-pubkey"; let order_id_raw = if accepted_first { "active-conflict-order-accepted-first" @@ -8511,12 +8565,14 @@ mod tests { let app_store = AppSqliteStore::open(DatabaseTarget::InMemory).expect("open app sqlite store"); let events = local_events_store(); - let listing_addr = "30402:seller-pubkey:app-order-listing"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); + let listing_addr = format!("30402:{seller_pubkey}:app-order-listing"); let payload = order_request_payload( "app-order-receipt-replaces-relay", - listing_addr, + listing_addr.as_str(), "buyer-pubkey", - "seller-pubkey", + seller_pubkey, ); let parts = order_request_event_build(&listing_event_ptr("listing-event"), &payload) .expect("build order request event"); @@ -8524,7 +8580,7 @@ mod tests { let mut relay_record = signed_order_event_record( "app:relay_event:order-request:duplicate", &event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -8540,7 +8596,7 @@ mod tests { .append_record(&signed_order_event_record( "app:signed_event:order-request:duplicate", &event, - listing_addr, + listing_addr.as_str(), SourceRuntime::App, Some("acct_buyer"), )) @@ -8573,7 +8629,7 @@ mod tests { stored.outbox_status, PublishOutboxStatus::Acknowledged.as_str() ); - assert_eq!(stored.listing_addr.as_deref(), Some(listing_addr)); + assert_eq!(stored.listing_addr.as_deref(), Some(listing_addr.as_str())); } #[test] @@ -8581,12 +8637,14 @@ mod tests { let app_store = AppSqliteStore::open(DatabaseTarget::InMemory).expect("open app sqlite store"); let events = local_events_store(); - let listing_addr = "30402:seller-pubkey:app-decision-listing"; + let seller_pubkey = test_pubkey("seller-pubkey"); + let seller_pubkey = seller_pubkey.as_str(); + let listing_addr = format!("30402:{seller_pubkey}:app-decision-listing"); let request_payload = order_request_payload( "app-decision-receipt", - listing_addr, + listing_addr.as_str(), "buyer-pubkey", - "seller-pubkey", + seller_pubkey, ); let request_parts = order_request_event_build(&listing_event_ptr("listing-event"), &request_payload) @@ -8595,9 +8653,9 @@ mod tests { event_from_parts("app-decision-request-event", "buyer-pubkey", request_parts); let decision_payload = accepted_order_decision_payload( "app-decision-receipt", - listing_addr, + listing_addr.as_str(), "buyer-pubkey", - "seller-pubkey", + seller_pubkey, ); let decision_parts = order_decision_event_build( request_event.id.as_str(), @@ -8611,7 +8669,7 @@ mod tests { .append_record(&signed_order_event_record( "app:signed_event:order-decision:duplicate", &decision_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::App, Some("acct_seller"), )) @@ -8619,7 +8677,7 @@ mod tests { let mut relay_record = signed_order_event_record( "app:relay_event:order-decision:duplicate", &decision_event, - listing_addr, + listing_addr.as_str(), SourceRuntime::Cli, None, ); @@ -8662,7 +8720,7 @@ mod tests { stored.outbox_status, PublishOutboxStatus::Acknowledged.as_str() ); - assert_eq!(stored.listing_addr.as_deref(), Some(listing_addr)); + assert_eq!(stored.listing_addr.as_deref(), Some(listing_addr.as_str())); } #[test]