app

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

commit 50f2f4de1b20c59a0f3cd61144405b5b9bedf6b4
parent 152d8bcd7c972822188b7a9a199f174d2018e52d
Author: triesap <tyson@radroots.org>
Date:   Sat, 13 Jun 2026 16:37:13 -0700

sdk: align app order event types

- parse order event IDs and pubkeys at SDK boundaries

- keep app payload and projection surfaces string-shaped

- update app fixtures for deterministic protocol IDs

Diffstat:
Mcrates/desktop/src/runtime.rs | 632++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mcrates/store/src/interop.rs | 211+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Mcrates/sync/src/publish.rs | 2+-
Mcrates/view/src/lib.rs | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
4 files changed, 586 insertions(+), 343 deletions(-)

diff --git a/crates/desktop/src/runtime.rs b/crates/desktop/src/runtime.rs @@ -67,8 +67,8 @@ use radroots_core::{ }; use radroots_events::{ ids::{ - RadrootsDTag, RadrootsInventoryBinId, RadrootsListingAddress, RadrootsOrderId, - RadrootsOrderRevisionId, + RadrootsDTag, RadrootsEventId, RadrootsInventoryBinId, RadrootsListingAddress, + RadrootsOrderId, RadrootsOrderRevisionId, RadrootsPublicKey, }, kinds::{ KIND_FARM, KIND_LISTING, KIND_LISTING_DRAFT, KIND_ORDER_CANCELLATION, KIND_ORDER_DECISION, @@ -2489,8 +2489,8 @@ impl DesktopAppRuntimeState { request_event_id: request.request_event_id, listing_event_id: request.listing_event_id, listing_addr: request.payload.listing_addr.to_string(), - buyer_pubkey: request.payload.buyer_pubkey, - seller_pubkey: request.payload.seller_pubkey, + buyer_pubkey: request.payload.buyer_pubkey.to_string(), + seller_pubkey: request.payload.seller_pubkey.to_string(), decision, }; AppPublishPayload::OrderDecision(payload.clone()) @@ -2649,8 +2649,8 @@ impl DesktopAppRuntimeState { request_event_id: request.request_event_id, prev_event_id, listing_addr: request.payload.listing_addr.to_string(), - buyer_pubkey: request.payload.buyer_pubkey, - seller_pubkey: request.payload.seller_pubkey, + buyer_pubkey: request.payload.buyer_pubkey.to_string(), + seller_pubkey: request.payload.seller_pubkey.to_string(), status, }; AppPublishPayload::OrderFulfillment(payload.clone()) @@ -2796,8 +2796,8 @@ impl DesktopAppRuntimeState { prev_event_id, revision_id: format!("app-revision-{}", d_tag_from_uuid(Uuid::now_v7())), listing_addr: request.payload.listing_addr.to_string(), - buyer_pubkey: request.payload.buyer_pubkey, - seller_pubkey: request.payload.seller_pubkey, + buyer_pubkey: request.payload.buyer_pubkey.to_string(), + seller_pubkey: request.payload.seller_pubkey.to_string(), items, economics, reason: reason.to_owned(), @@ -2923,8 +2923,8 @@ impl DesktopAppRuntimeState { prev_event_id: proposal.event_id.clone(), 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, + buyer_pubkey: request.payload.buyer_pubkey.to_string(), + seller_pubkey: request.payload.seller_pubkey.to_string(), decision, }; AppPublishPayload::OrderRevisionDecision(payload.clone()) @@ -3069,8 +3069,8 @@ impl DesktopAppRuntimeState { request_event_id: request.request_event_id, prev_event_id, listing_addr: request.payload.listing_addr.to_string(), - buyer_pubkey: request.payload.buyer_pubkey, - seller_pubkey: request.payload.seller_pubkey, + buyer_pubkey: request.payload.buyer_pubkey.to_string(), + seller_pubkey: request.payload.seller_pubkey.to_string(), reason: "buyer cancelled order".to_owned(), }; AppPublishPayload::OrderCancellation(payload.clone()) @@ -3185,8 +3185,8 @@ impl DesktopAppRuntimeState { request_event_id: request.request_event_id, prev_event_id: fulfillment.event_id.clone(), listing_addr: request.payload.listing_addr.to_string(), - buyer_pubkey: request.payload.buyer_pubkey, - seller_pubkey: request.payload.seller_pubkey, + buyer_pubkey: request.payload.buyer_pubkey.to_string(), + seller_pubkey: request.payload.seller_pubkey.to_string(), received, issue: outcome.issue_text(), received_at, @@ -5409,9 +5409,15 @@ impl DesktopAppRuntimeState { }); let mut buckets = AppActiveOrderEvidenceBuckets::default(); + let request_event_id = + active_order_event_id(request.request_event_id.as_str(), "request_event_id")?; + let request_author_pubkey = active_order_pubkey( + request.request_author_pubkey.as_str(), + "request_author_pubkey", + )?; buckets.requests.push(RadrootsOrderRequestRecord { - event_id: request.request_event_id.clone(), - author_pubkey: request.request_author_pubkey.clone(), + event_id: request_event_id.clone(), + author_pubkey: request_author_pubkey, payload: request.payload.clone(), }); for event in events { @@ -5420,6 +5426,8 @@ impl DesktopAppRuntimeState { { continue; } + let event_id = active_order_event_id(event.id.as_str(), "event_id")?; + let author_pubkey = active_order_pubkey(event.author.as_str(), "author_pubkey")?; match event.kind { KIND_ORDER_DECISION => { let envelope = @@ -5430,8 +5438,8 @@ impl DesktopAppRuntimeState { })?; let context = active_order_event_record_context(&event, envelope.message_type)?; buckets.decisions.push(RadrootsOrderDecisionRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5449,8 +5457,8 @@ impl DesktopAppRuntimeState { buckets .revision_proposals .push(RadrootsOrderRevisionProposalRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5468,8 +5476,8 @@ impl DesktopAppRuntimeState { buckets .revision_decisions .push(RadrootsOrderRevisionDecisionRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5484,8 +5492,8 @@ impl DesktopAppRuntimeState { }; let context = active_order_event_record_context(&event, envelope.message_type)?; buckets.cancellations.push(RadrootsOrderCancellationRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5500,8 +5508,8 @@ impl DesktopAppRuntimeState { }; let context = active_order_event_record_context(&event, envelope.message_type)?; buckets.fulfillments.push(RadrootsOrderFulfillmentRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5516,8 +5524,8 @@ impl DesktopAppRuntimeState { }; let context = active_order_event_record_context(&event, envelope.message_type)?; buckets.receipts.push(RadrootsOrderReceiptRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5532,8 +5540,8 @@ impl DesktopAppRuntimeState { })?; let context = active_order_event_record_context(&event, envelope.message_type)?; buckets.payments.push(RadrootsOrderPaymentEventRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5548,8 +5556,8 @@ impl DesktopAppRuntimeState { })?; let context = active_order_event_record_context(&event, envelope.message_type)?; buckets.settlements.push(RadrootsOrderSettlementRecord { - event_id: event.id, - author_pubkey: event.author, + event_id, + author_pubkey, counterparty_pubkey: context.0, root_event_id: context.1, prev_event_id: context.2, @@ -5561,7 +5569,7 @@ impl DesktopAppRuntimeState { } let projection = reduce_order_events( - request.payload.order_id.as_str(), + &request.payload.order_id, buckets.requests.clone(), buckets.decisions.clone(), buckets.revision_proposals.clone(), @@ -5577,7 +5585,7 @@ impl DesktopAppRuntimeState { reason: "order lifecycle evidence is invalid", }); } - if projection.request_event_id.as_deref() != Some(request.request_event_id.as_str()) { + if projection.request_event_id.as_ref() != Some(&request_event_id) { return Err(AppSqliteError::InvalidProjection { reason: "order lifecycle evidence is invalid", }); @@ -5585,14 +5593,14 @@ impl DesktopAppRuntimeState { let decision = projection .decision_event_id - .as_deref() + .as_ref() .map(|event_id| { buckets .decisions .iter() - .find(|decision| decision.event_id == event_id) + .find(|decision| decision.event_id == *event_id) .map(|decision| ResolvedAppOrderDecisionEvidence { - event_id: decision.event_id.clone(), + event_id: decision.event_id.to_string(), payload: decision.payload.clone(), }) .ok_or(AppSqliteError::InvalidProjection { @@ -5602,14 +5610,14 @@ impl DesktopAppRuntimeState { .transpose()?; let latest_fulfillment = projection .fulfillment_event_id - .as_deref() + .as_ref() .map(|event_id| { buckets .fulfillments .iter() - .find(|fulfillment| fulfillment.event_id == event_id) + .find(|fulfillment| fulfillment.event_id == *event_id) .map(|fulfillment| ResolvedAppOrderFulfillmentEvidence { - event_id: fulfillment.event_id.clone(), + event_id: fulfillment.event_id.to_string(), status: fulfillment.payload.status, }) .ok_or(AppSqliteError::InvalidProjection { @@ -5621,14 +5629,18 @@ impl DesktopAppRuntimeState { Ok(ResolvedAppOrderLifecycleEvidence { status: projection.status, payment_state: projection.payment.state, - agreement_event_id: projection.agreement_event_id, - last_event_id: projection.last_event_id, + agreement_event_id: projection + .agreement_event_id + .map(|event_id| event_id.to_string()), + last_event_id: projection + .last_event_id + .map(|event_id| event_id.to_string()), decision, revision_proposals: buckets .revision_proposals .into_iter() .map(|proposal| ResolvedAppOrderRevisionProposalEvidence { - event_id: proposal.event_id, + event_id: proposal.event_id.to_string(), payload: proposal.payload, }) .collect(), @@ -5636,13 +5648,17 @@ impl DesktopAppRuntimeState { .revision_decisions .into_iter() .map(|decision| ResolvedAppOrderRevisionDecisionEvidence { - event_id: decision.event_id, + event_id: decision.event_id.to_string(), payload: decision.payload, }) .collect(), latest_fulfillment, - cancellation_event_id: projection.cancellation_event_id, - receipt_event_id: projection.receipt_event_id, + cancellation_event_id: projection + .cancellation_event_id + .map(|event_id| event_id.to_string()), + receipt_event_id: projection + .receipt_event_id + .map(|event_id| event_id.to_string()), }) } @@ -7191,12 +7207,13 @@ async fn publish_app_payload( } AppPublishPayload::OrderDecision(payload) => { let decision = order_decision_publish_payload_to_sdk_decision(payload)?; + let request_event_id = publish_event_id(payload.request_event_id.as_str())?; client .order() .publish_order_decision_with_identity( identity, - payload.request_event_id.as_str(), - payload.request_event_id.as_str(), + &request_event_id, + &request_event_id, &decision, ) .await @@ -7204,12 +7221,14 @@ async fn publish_app_payload( } AppPublishPayload::OrderRevisionProposal(payload) => { let proposal = order_revision_proposal_publish_payload_to_sdk_revision(payload)?; + let request_event_id = publish_event_id(payload.request_event_id.as_str())?; + let prev_event_id = publish_event_id(payload.prev_event_id.as_str())?; client .order() .publish_order_revision_proposal_with_identity( identity, - payload.request_event_id.as_str(), - payload.prev_event_id.as_str(), + &request_event_id, + &prev_event_id, &proposal, ) .await @@ -7218,12 +7237,14 @@ async fn publish_app_payload( AppPublishPayload::OrderRevisionDecision(payload) => { let decision = order_revision_decision_publish_payload_to_sdk_revision_decision(payload)?; + let request_event_id = publish_event_id(payload.request_event_id.as_str())?; + let prev_event_id = publish_event_id(payload.prev_event_id.as_str())?; client .order() .publish_order_revision_decision_with_identity( identity, - payload.request_event_id.as_str(), - payload.prev_event_id.as_str(), + &request_event_id, + &prev_event_id, &decision, ) .await @@ -7231,12 +7252,14 @@ async fn publish_app_payload( } AppPublishPayload::OrderCancellation(payload) => { let cancellation = order_cancellation_publish_payload_to_sdk_cancellation(payload)?; + let request_event_id = publish_event_id(payload.request_event_id.as_str())?; + let prev_event_id = publish_event_id(payload.prev_event_id.as_str())?; client .order() .publish_order_cancellation_with_identity( identity, - payload.request_event_id.as_str(), - payload.prev_event_id.as_str(), + &request_event_id, + &prev_event_id, &cancellation, ) .await @@ -7244,12 +7267,14 @@ async fn publish_app_payload( } AppPublishPayload::OrderFulfillment(payload) => { let fulfillment = order_fulfillment_publish_payload_to_sdk_fulfillment(payload)?; + let request_event_id = publish_event_id(payload.request_event_id.as_str())?; + let prev_event_id = publish_event_id(payload.prev_event_id.as_str())?; client .order() .publish_fulfillment_update_with_identity( identity, - payload.request_event_id.as_str(), - payload.prev_event_id.as_str(), + &request_event_id, + &prev_event_id, &fulfillment, ) .await @@ -7257,12 +7282,14 @@ async fn publish_app_payload( } AppPublishPayload::OrderReceipt(payload) => { let receipt = order_receipt_publish_payload_to_sdk_receipt(payload)?; + let request_event_id = publish_event_id(payload.request_event_id.as_str())?; + let prev_event_id = publish_event_id(payload.prev_event_id.as_str())?; client .order() .publish_buyer_receipt_with_identity( identity, - payload.request_event_id.as_str(), - payload.prev_event_id.as_str(), + &request_event_id, + &prev_event_id, &receipt, ) .await @@ -9400,10 +9427,30 @@ fn trade_chain_tag_value(event: &radroots_sdk::RadrootsNostrEvent, key: &str) -> }) } +fn active_order_event_id( + value: &str, + field: &'static str, +) -> Result<RadrootsEventId, AppSqliteError> { + value.parse().map_err(|_| AppSqliteError::DecodeId { + field, + value: value.to_owned(), + }) +} + +fn active_order_pubkey( + value: &str, + field: &'static str, +) -> Result<RadrootsPublicKey, AppSqliteError> { + value.parse().map_err(|_| AppSqliteError::DecodeId { + field, + value: value.to_owned(), + }) +} + fn active_order_event_record_context( event: &radroots_sdk::RadrootsNostrEvent, message_type: radroots_sdk::order::RadrootsOrderEventType, -) -> Result<(String, String, String), AppSqliteError> { +) -> Result<(RadrootsPublicKey, RadrootsEventId, RadrootsEventId), AppSqliteError> { let context = order_event_context_from_tags(message_type, &event.tags).map_err(|_| { AppSqliteError::InvalidProjection { reason: "order lifecycle evidence is invalid", @@ -9571,6 +9618,15 @@ fn publish_revision_id(value: &str) -> Result<RadrootsOrderRevisionId, AppSyncTr .map_err(|error| AppSyncTransportError::failed(error.to_string())) } +fn publish_event_id(value: &str) -> Result<RadrootsEventId, AppSyncTransportError> { + RadrootsEventId::parse(value).map_err(|error| AppSyncTransportError::failed(error.to_string())) +} + +fn publish_pubkey(value: &str) -> Result<RadrootsPublicKey, AppSyncTransportError> { + RadrootsPublicKey::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())) @@ -9587,8 +9643,8 @@ fn order_decision_publish_payload_to_sdk_decision( 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(), + buyer_pubkey: publish_pubkey(payload.buyer_pubkey.as_str())?, + seller_pubkey: publish_pubkey(payload.seller_pubkey.as_str())?, decision: match &payload.decision { AppOrderDecisionPayload::Accepted { inventory_commitments, @@ -9619,10 +9675,10 @@ fn order_revision_proposal_publish_payload_to_sdk_revision( 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(), + buyer_pubkey: publish_pubkey(payload.buyer_pubkey.as_str())?, + seller_pubkey: publish_pubkey(payload.seller_pubkey.as_str())?, + root_event_id: publish_event_id(payload.request_event_id.as_str())?, + prev_event_id: publish_event_id(payload.prev_event_id.as_str())?, items: payload.items.clone(), economics: payload.economics.clone(), reason: payload.reason.clone(), @@ -9636,10 +9692,10 @@ fn order_revision_decision_publish_payload_to_sdk_revision_decision( 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(), + buyer_pubkey: publish_pubkey(payload.buyer_pubkey.as_str())?, + seller_pubkey: publish_pubkey(payload.seller_pubkey.as_str())?, + root_event_id: publish_event_id(payload.request_event_id.as_str())?, + prev_event_id: publish_event_id(payload.prev_event_id.as_str())?, decision: payload.decision.clone(), }) } @@ -9650,8 +9706,8 @@ fn order_fulfillment_publish_payload_to_sdk_fulfillment( 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(), + buyer_pubkey: publish_pubkey(payload.buyer_pubkey.as_str())?, + seller_pubkey: publish_pubkey(payload.seller_pubkey.as_str())?, status: payload.status, }) } @@ -9662,8 +9718,8 @@ fn order_cancellation_publish_payload_to_sdk_cancellation( 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(), + buyer_pubkey: publish_pubkey(payload.buyer_pubkey.as_str())?, + seller_pubkey: publish_pubkey(payload.seller_pubkey.as_str())?, reason: payload.reason.clone(), }) } @@ -9674,8 +9730,8 @@ fn order_receipt_publish_payload_to_sdk_receipt( 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(), + buyer_pubkey: publish_pubkey(payload.buyer_pubkey.as_str())?, + seller_pubkey: publish_pubkey(payload.seller_pubkey.as_str())?, received: payload.received, issue: payload.issue.clone(), received_at: payload.received_at, @@ -9796,6 +9852,10 @@ mod tests { use radroots_core::{ RadrootsCoreCurrency, RadrootsCoreDecimal, RadrootsCoreMoney, RadrootsCoreUnit, }; + use radroots_events::ids::{ + RadrootsEconomicsDigest, RadrootsEventId, RadrootsInventoryBinId, RadrootsListingAddress, + RadrootsOrderId, RadrootsOrderQuoteId, RadrootsOrderRevisionId, RadrootsPublicKey, + }; use radroots_events_codec::order::{ order_payment_record_event_build, order_settlement_decision_event_build, }; @@ -10050,6 +10110,70 @@ mod tests { } } + fn test_event_id_seed(seed: &str) -> String { + if RadrootsEventId::parse(seed).is_ok() { + return seed.to_owned(); + } + let mut bytes = [0u8; 32]; + for (index, byte) in seed.bytes().enumerate() { + let primary = index % bytes.len(); + let secondary = (index * 7 + 13) % bytes.len(); + bytes[primary] = bytes[primary] + .wrapping_add(byte) + .wrapping_add((index as u8).wrapping_mul(31)); + bytes[secondary] ^= byte.rotate_left((index % 8) as u32); + } + let mut hex = String::with_capacity(64); + for byte in bytes { + hex.push_str(format!("{byte:02x}").as_str()); + } + hex + } + + fn test_event_id(seed: &str) -> RadrootsEventId { + RadrootsEventId::parse(test_event_id_seed(seed)).expect("event id") + } + + fn signed_event_id(record_id: &str) -> String { + test_event_id_seed(record_id) + } + + fn signed_listing_event_id(label: &str) -> String { + signed_event_id(format!("app:signed_event:listing:{label}").as_str()) + } + + fn signed_order_request_event_id(trade_order_id: &str) -> String { + signed_event_id(format!("app:signed_event:order-request:{trade_order_id}").as_str()) + } + + fn test_order_id(value: &str) -> RadrootsOrderId { + RadrootsOrderId::parse(value).expect("order id") + } + + fn test_revision_id(value: &str) -> RadrootsOrderRevisionId { + RadrootsOrderRevisionId::parse(value).expect("revision id") + } + + fn test_quote_id(value: &str) -> RadrootsOrderQuoteId { + RadrootsOrderQuoteId::parse(value).expect("quote id") + } + + fn test_bin_id(value: &str) -> RadrootsInventoryBinId { + RadrootsInventoryBinId::parse(value).expect("bin id") + } + + fn test_pubkey(value: &str) -> RadrootsPublicKey { + RadrootsPublicKey::parse(value).expect("pubkey") + } + + fn test_listing_addr(value: &str) -> RadrootsListingAddress { + RadrootsListingAddress::parse(value).expect("listing address") + } + + fn test_economics_digest(value: impl AsRef<str>) -> RadrootsEconomicsDigest { + RadrootsEconomicsDigest::parse(value).expect("economics digest") + } + fn install_recorded_sync_transport( runtime: &DesktopAppRuntime, transport: RecordedAppSyncTransport, @@ -10231,21 +10355,21 @@ mod tests { super::d_tag_from_uuid(ProductId::new().as_uuid()) ); let order_document = RadrootsOrderRequest { - order_id: order_id.to_string(), - listing_addr: listing_addr.clone(), - buyer_pubkey: buyer_identity.public_key_hex(), - seller_pubkey: seller_identity.public_key_hex(), + order_id: test_order_id(order_id.to_string().as_str()), + listing_addr: test_listing_addr(listing_addr.as_str()), + buyer_pubkey: test_pubkey(buyer_identity.public_key_hex().as_str()), + seller_pubkey: test_pubkey(seller_identity.public_key_hex().as_str()), items: vec![RadrootsOrderItem { - bin_id: "bin-1".to_owned(), + bin_id: test_bin_id("bin-1"), bin_count: 1, }], economics: RadrootsOrderEconomics { - quote_id: format!("quote-{order_id}"), + quote_id: test_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: test_bin_id("bin-1"), bin_count: 1, quantity_amount: RadrootsCoreDecimal::from(1u32), quantity_unit: RadrootsCoreUnit::Each, @@ -10332,8 +10456,8 @@ mod tests { app_order_id: OrderId::new(), farm_id: FarmId::new(), trade_order_id: "order-1".to_owned(), - request_event_id: "order-request-event-1".to_owned(), - listing_event_id: Some("listing-event-1".to_owned()), + request_event_id: test_event_id_seed("order-request-event-1"), + listing_event_id: Some(test_event_id_seed("listing-event-1")), listing_addr: format!("30402:{}:listing-key", identity.public_key_hex()), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: identity.public_key_hex(), @@ -10397,18 +10521,18 @@ mod tests { app_order_id, farm_id, "order-1".to_owned(), - "order-request-event-1".to_owned(), + test_event_id_seed("order-request-event-1"), listing_addr, buyer_identity.public_key_hex(), seller_identity.public_key_hex(), ); let revision_economics = RadrootsOrderEconomics { - quote_id: "quote-revision-1".to_owned(), + quote_id: test_quote_id("quote-revision-1"), quote_version: 2, pricing_basis: RadrootsOrderPricingBasis::ListingEvent, currency: RadrootsCoreCurrency::USD, items: vec![RadrootsOrderEconomicItem { - bin_id: "bin-1".to_owned(), + bin_id: test_bin_id("bin-1"), bin_count: 3, quantity_amount: RadrootsCoreDecimal::from(1u32), quantity_unit: RadrootsCoreUnit::Each, @@ -10436,13 +10560,13 @@ mod tests { farm_id: common.1, trade_order_id: common.2.clone(), request_event_id: common.3.clone(), - prev_event_id: "order-decision-event-1".to_owned(), + prev_event_id: test_event_id_seed("order-decision-event-1"), revision_id: "revision-1".to_owned(), listing_addr: common.4.clone(), buyer_pubkey: common.5.clone(), seller_pubkey: common.6.clone(), items: vec![RadrootsOrderItem { - bin_id: "bin-1".to_owned(), + bin_id: test_bin_id("bin-1"), bin_count: 3, }], economics: revision_economics, @@ -10458,7 +10582,7 @@ mod tests { farm_id: common.1, trade_order_id: common.2.clone(), request_event_id: common.3.clone(), - prev_event_id: "order-revision-proposal-event-1".to_owned(), + prev_event_id: test_event_id_seed("order-revision-proposal-event-1"), revision_id: "revision-1".to_owned(), listing_addr: common.4.clone(), buyer_pubkey: common.5.clone(), @@ -10490,7 +10614,7 @@ mod tests { farm_id: common.1, trade_order_id: common.2.clone(), request_event_id: common.3.clone(), - prev_event_id: "order-decision-event-1".to_owned(), + prev_event_id: test_event_id_seed("order-decision-event-1"), listing_addr: common.4.clone(), buyer_pubkey: common.5.clone(), seller_pubkey: common.6.clone(), @@ -10502,7 +10626,7 @@ mod tests { farm_id: common.1, trade_order_id: common.2.clone(), request_event_id: common.3.clone(), - prev_event_id: "fulfillment-event-1".to_owned(), + prev_event_id: test_event_id_seed("fulfillment-event-1"), listing_addr: common.4.clone(), buyer_pubkey: common.5.clone(), seller_pubkey: common.6.clone(), @@ -14790,17 +14914,18 @@ mod tests { let payload = runtime .prepare_order_accept(order_id) .expect("seller order accept payload should prepare"); - let decision = order_decision_publish_payload_to_sdk_decision(&payload); + let decision = order_decision_publish_payload_to_sdk_decision(&payload) + .expect("order accept payload should convert to SDK decision"); assert_eq!(payload.app_order_id, order_id); assert_eq!(payload.trade_order_id, "seller-order-decision-1"); assert_eq!( payload.request_event_id, - "event-app:signed_event:order-request:seller-order-decision-1" + signed_order_request_event_id("seller-order-decision-1") ); assert_eq!( - payload.listing_event_id.as_deref(), - Some("event-app:signed_event:listing:seller-order-decision") + payload.listing_event_id, + Some(signed_listing_event_id("seller-order-decision")) ); assert_eq!(payload.buyer_pubkey, buyer_pubkey); assert_eq!(payload.seller_pubkey, seller_pubkey); @@ -14828,7 +14953,8 @@ mod tests { let payload = runtime .prepare_order_decline(order_id, " out of stock ") .expect("seller order decline payload should prepare"); - let decision = order_decision_publish_payload_to_sdk_decision(&payload); + let decision = order_decision_publish_payload_to_sdk_decision(&payload) + .expect("order decline payload should convert to SDK decision"); assert_eq!(payload.buyer_pubkey, buyer_pubkey); assert_eq!(payload.seller_pubkey, seller_pubkey); @@ -14861,7 +14987,7 @@ mod tests { assert_eq!(payload.trade_order_id, "seller-order-decision-1"); assert_eq!( payload.request_event_id, - "event-app:signed_event:order-request:seller-order-decision-1" + signed_order_request_event_id("seller-order-decision-1") ); cleanup_bootstrapped_runtime_paths(&paths); @@ -15007,15 +15133,16 @@ mod tests { envelope.payload.decision, RadrootsOrderDecisionOutcome::Accepted { .. } )); + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); assert!(event_has_tag( &decision_event, "e_root", - "event-app:signed_event:order-request:seller-order-decision-1" + request_event_id.as_str() )); assert!(event_has_tag( &decision_event, "e_prev", - "event-app:signed_event:order-request:seller-order-decision-1" + request_event_id.as_str() )); cleanup_bootstrapped_runtime_paths(&paths); @@ -15048,15 +15175,16 @@ mod tests { panic!("expected declined decision"); }; assert_eq!(reason, "not available"); + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); assert!(event_has_tag( &decision_event, "e_root", - "event-app:signed_event:order-request:seller-order-decision-1" + request_event_id.as_str() )); assert!(event_has_tag( &decision_event, "e_prev", - "event-app:signed_event:order-request:seller-order-decision-1" + request_event_id.as_str() )); cleanup_bootstrapped_runtime_paths(&paths); @@ -15128,10 +15256,11 @@ mod tests { let envelope = radroots_sdk::order::parse_fulfillment_update(fulfillment_event) .expect("fulfillment should parse"); assert_eq!(envelope.payload.status, expected_status); + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); assert!(event_has_tag( fulfillment_event, "e_root", - "event-app:signed_event:order-request:seller-order-decision-1" + request_event_id.as_str() )); assert!(event_has_nonempty_value_tag(fulfillment_event, "e_prev")); @@ -15157,7 +15286,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15228,7 +15358,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15298,7 +15429,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15349,7 +15481,7 @@ mod tests { "e_prev", latest_fulfillment .map(|_| { - "event-app:signed_event:fulfillment:seller-order-decision-1".to_owned() + signed_event_id("app:signed_event:fulfillment:seller-order-decision-1") }) .unwrap_or_else(|| decision_event_id.clone()) .as_str() @@ -15370,7 +15502,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15439,7 +15572,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15492,7 +15626,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15540,7 +15675,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15609,7 +15745,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15678,7 +15815,8 @@ mod tests { install_direct_relay_sync_transport(&runtime, &relay); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let request_event_id = "event-app:signed_event:order-request:seller-order-decision-1"; + let request_event_id = signed_order_request_event_id("seller-order-decision-1"); + let request_event_id = request_event_id.as_str(); let decision_event_id = append_signed_order_decision_record( &paths, "seller-order-decision-1", @@ -15816,7 +15954,7 @@ mod tests { ); assert_eq!( pending_payload.listing_event_id.as_deref(), - Some("event-cli:signed_event:buyer-order-supported-listing") + Some(signed_event_id("cli:signed_event:buyer-order-supported-listing").as_str()) ); assert_eq!(pending_payload.listing_relays, vec!["ws://127.0.0.1:1234/"]); assert_eq!( @@ -15922,7 +16060,7 @@ mod tests { ); assert_eq!( payload["document"]["order"]["listing_event_id"], - "event-cli:signed_event:buyer-order-supported-listing" + signed_event_id("cli:signed_event:buyer-order-supported-listing") ); assert_eq!( payload["document"]["order"]["listing_relays"], @@ -20373,6 +20511,7 @@ mod tests { "primary": "North barn pickup" } }); + let event_id = signed_event_id(record_id.as_str()); store .append_record(&LocalEventRecordInput { record_id: record_id.to_owned(), @@ -20386,7 +20525,7 @@ mod tests { farm_id: Some(farm_key.to_owned()), listing_addr: Some(format!("30402:{owner_pubkey}:{listing_key}")), local_work_json: None, - event_id: Some(format!("event-{record_id}")), + event_id: Some(event_id.clone()), event_kind: Some(30402), event_pubkey: Some(owner_pubkey.to_owned()), event_created_at: Some(created_at_ms), @@ -20408,7 +20547,7 @@ mod tests { event_content: Some(content.to_string()), event_sig: Some("signature".to_owned()), raw_event_json: Some(json!({ - "id": format!("event-{record_id}"), + "id": event_id, "kind": 30402, "pubkey": owner_pubkey, "content": content.to_string() @@ -20484,7 +20623,7 @@ mod tests { let farm_key = super::d_tag_from_uuid(FarmId::new().as_uuid()); let listing_key = super::d_tag_from_uuid(ProductId::new().as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let listing_event_id = format!("event-app:signed_event:listing:{label}"); + let listing_event_id = signed_listing_event_id(label); let trade_order_id = format!("{label}-trade-order"); let order_id = projected_order_id_from_trade_request(trade_order_id.as_str(), buyer_pubkey.as_str()); @@ -20506,7 +20645,7 @@ mod tests { seller_pubkey, 2, ); - let request_event_id = format!("event-app:signed_event:order-request:{trade_order_id}"); + let request_event_id = signed_order_request_event_id(trade_order_id.as_str()); let decision_event_id = append_signed_order_decision_record( &paths, trade_order_id.as_str(), @@ -20576,21 +20715,21 @@ mod tests { let farm_key = super::d_tag_from_uuid(farm_id.as_uuid()); let listing_key = super::d_tag_from_uuid(product_id.as_uuid()); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); - let listing_event_id = "event-app:signed_event:listing:seller-order-decision"; + let listing_event_id = signed_listing_event_id("seller-order-decision"); append_app_signed_listing_record( &paths, account_id.as_str(), seller_pubkey.as_str(), farm_key.as_str(), listing_key.as_str(), - listing_event_id, + listing_event_id.as_str(), stock_count, ); append_signed_order_request_record( &paths, trade_order_id, listing_addr.as_str(), - listing_event_id, + listing_event_id.as_str(), buyer_pubkey.as_str(), seller_pubkey.as_str(), order_quantity, @@ -20638,11 +20777,8 @@ mod tests { app_order_id: order_id, farm_id, trade_order_id: "seller-order-decision-1".to_owned(), - request_event_id: "event-app:signed_event:order-request:seller-order-decision-1" - .to_owned(), - listing_event_id: Some( - "event-app:signed_event:listing:seller-order-decision".to_owned(), - ), + request_event_id: signed_order_request_event_id("seller-order-decision-1"), + listing_event_id: Some(signed_listing_event_id("seller-order-decision")), listing_addr: format!("30402:{seller_pubkey}:{listing_key}"), buyer_pubkey: buyer_pubkey.to_owned(), seller_pubkey: seller_pubkey.to_owned(), @@ -20692,6 +20828,7 @@ mod tests { let store = LocalEventsStore::new(executor); store.migrate_up().expect("migrate shared local events"); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); + let listing_event_id = test_event_id_seed(listing_event_id); let content = json!({ "d_tag": listing_key, "status": "active", @@ -20731,7 +20868,7 @@ mod tests { farm_id: Some(farm_key.to_owned()), listing_addr: Some(listing_addr), local_work_json: None, - event_id: Some(listing_event_id.to_owned()), + event_id: Some(listing_event_id.clone()), event_kind: Some(30402), event_pubkey: Some(seller_pubkey.to_owned()), event_created_at: Some(1_774_000_000), @@ -20797,19 +20934,19 @@ mod tests { let store = LocalEventsStore::new(executor); store.migrate_up().expect("migrate shared local events"); let order = RadrootsOrderRequest { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), items: vec![RadrootsOrderItem { - bin_id: "seller-order-primary-bin".to_owned(), + bin_id: test_bin_id("seller-order-primary-bin"), bin_count: order_quantity, }], economics: signed_order_request_economics(trade_order_id, order_quantity), }; let parts = radroots_sdk::order::build_order_request_draft( &RadrootsNostrEventPtr { - id: listing_event_id.to_owned(), + id: test_event_id_seed(listing_event_id), relays: Some("wss://relay.example".to_owned()), }, &order, @@ -20817,7 +20954,7 @@ mod tests { .expect("order request draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:order-request:{trade_order_id}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); let relay_delivery_json = RelayDeliveryEvidence::acknowledged( ["wss://relay.example"], ["wss://relay.example"], @@ -20871,12 +21008,12 @@ mod tests { .expect("order total should fit"); RadrootsOrderEconomics { - quote_id: format!("{trade_order_id}-quote"), + quote_id: test_quote_id(format!("{trade_order_id}-quote").as_str()), quote_version: 1, pricing_basis: RadrootsOrderPricingBasis::ListingEvent, currency, items: vec![RadrootsOrderEconomicItem { - bin_id: "seller-order-primary-bin".to_owned(), + bin_id: test_bin_id("seller-order-primary-bin"), bin_count: order_quantity, quantity_amount: RadrootsCoreDecimal::from(1u32), quantity_unit: RadrootsCoreUnit::Each, @@ -20903,26 +21040,27 @@ mod tests { order_quantity: u32, ) -> String { let payload = RadrootsOrderDecision { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), decision: RadrootsOrderDecisionOutcome::Accepted { inventory_commitments: vec![RadrootsOrderInventoryCommitment { - bin_id: "seller-order-primary-bin".to_owned(), + bin_id: test_bin_id("seller-order-primary-bin"), bin_count: order_quantity, }], }, }; + let request_event_id = test_event_id(request_event_id); let parts = radroots_sdk::order::build_order_decision_draft( - request_event_id, - request_event_id, + &request_event_id, + &request_event_id, &payload, ) .expect("order decision draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:order-decision:{trade_order_id}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -20974,28 +21112,32 @@ mod tests { order_quantity: u32, ) -> String { let economics = signed_order_request_economics(trade_order_id, order_quantity); + let request_event_id = test_event_id(request_event_id); + let prev_event_id = test_event_id(prev_event_id); + let agreement_event_id = test_event_id(agreement_event_id); let payload = RadrootsOrderPaymentRecord { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), - root_event_id: request_event_id.to_owned(), - previous_event_id: prev_event_id.to_owned(), - agreement_event_id: agreement_event_id.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), + root_event_id: request_event_id.clone(), + previous_event_id: prev_event_id.clone(), + agreement_event_id, quote_id: economics.quote_id.clone(), quote_version: economics.quote_version, - economics_digest: radroots_order_economics_digest(&economics) - .expect("payment economics digest"), + economics_digest: test_economics_digest( + radroots_order_economics_digest(&economics).expect("payment economics digest"), + ), amount: economics.total.amount, currency: economics.total.currency, method: RadrootsOrderPaymentMethod::ManualTransfer, reference: Some(format!("memo-{event_key}")), paid_at: Some(1_774_000_050), }; - let parts = order_payment_record_event_build(request_event_id, prev_event_id, &payload) + let parts = order_payment_record_event_build(&request_event_id, &prev_event_id, &payload) .expect("payment recorded draft should build"); let record_id = format!("app:signed_event:payment:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21023,19 +21165,23 @@ mod tests { decision: RadrootsOrderSettlementOutcome, ) -> String { let economics = signed_order_request_economics(trade_order_id, order_quantity); + let request_event_id = test_event_id(request_event_id); + let payment_event_id = test_event_id(payment_event_id); + let agreement_event_id = test_event_id(agreement_event_id); let payload = RadrootsOrderSettlementDecision { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - root_event_id: request_event_id.to_owned(), - previous_event_id: payment_event_id.to_owned(), - agreement_event_id: agreement_event_id.to_owned(), - payment_event_id: payment_event_id.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + seller_pubkey: test_pubkey(seller_pubkey), + buyer_pubkey: test_pubkey(buyer_pubkey), + root_event_id: request_event_id.clone(), + previous_event_id: payment_event_id.clone(), + agreement_event_id, + payment_event_id: payment_event_id.clone(), quote_id: economics.quote_id.clone(), quote_version: economics.quote_version, - economics_digest: radroots_order_economics_digest(&economics) - .expect("k3436 economics digest"), + economics_digest: test_economics_digest( + radroots_order_economics_digest(&economics).expect("k3436 economics digest"), + ), amount: economics.total.amount, currency: economics.total.currency, decision, @@ -21043,10 +21189,10 @@ mod tests { .then(|| "reference mismatch".to_owned()), }; let parts = - order_settlement_decision_event_build(request_event_id, payment_event_id, &payload) + order_settlement_decision_event_build(&request_event_id, &payment_event_id, &payload) .expect("k3436 draft should build"); let record_id = format!("app:signed_event:k3436:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21071,18 +21217,22 @@ mod tests { order_quantity: u32, ) -> radroots_nostr::prelude::RadrootsNostrEvent { let economics = signed_order_request_economics(trade_order_id, order_quantity); + let request_event_id = test_event_id(request_event_id); + let agreement_event_id = test_event_id(agreement_event_id); let payload = RadrootsOrderPaymentRecord { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), - root_event_id: request_event_id.to_owned(), - previous_event_id: agreement_event_id.to_owned(), - agreement_event_id: agreement_event_id.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), + root_event_id: request_event_id.clone(), + previous_event_id: agreement_event_id.clone(), + agreement_event_id: agreement_event_id.clone(), quote_id: economics.quote_id.clone(), quote_version: economics.quote_version, - economics_digest: radroots_order_economics_digest(&economics) - .expect("relay payment economics digest"), + economics_digest: test_economics_digest( + radroots_order_economics_digest(&economics) + .expect("relay payment economics digest"), + ), amount: economics.total.amount, currency: economics.total.currency, method: RadrootsOrderPaymentMethod::ManualTransfer, @@ -21090,7 +21240,7 @@ mod tests { paid_at: Some(1_774_000_050), }; let parts = - order_payment_record_event_build(request_event_id, agreement_event_id, &payload) + order_payment_record_event_build(&request_event_id, &agreement_event_id, &payload) .expect("relay payment draft should build"); radroots_nostr_build_event(parts.kind, parts.content, parts.tags) @@ -21112,19 +21262,23 @@ mod tests { decision: RadrootsOrderSettlementOutcome, ) -> radroots_nostr::prelude::RadrootsNostrEvent { let economics = signed_order_request_economics(trade_order_id, order_quantity); + let request_event_id = test_event_id(request_event_id); + let agreement_event_id = test_event_id(agreement_event_id); + let payment_event_id = test_event_id(payment_event_id); let payload = RadrootsOrderSettlementDecision { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - root_event_id: request_event_id.to_owned(), - previous_event_id: payment_event_id.to_owned(), - agreement_event_id: agreement_event_id.to_owned(), - payment_event_id: payment_event_id.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + seller_pubkey: test_pubkey(seller_pubkey), + buyer_pubkey: test_pubkey(buyer_pubkey), + root_event_id: request_event_id.clone(), + previous_event_id: payment_event_id.clone(), + agreement_event_id, + payment_event_id: payment_event_id.clone(), quote_id: economics.quote_id.clone(), quote_version: economics.quote_version, - economics_digest: radroots_order_economics_digest(&economics) - .expect("relay k3436 economics digest"), + economics_digest: test_economics_digest( + radroots_order_economics_digest(&economics).expect("relay k3436 economics digest"), + ), amount: economics.total.amount, currency: economics.total.currency, decision, @@ -21132,7 +21286,7 @@ mod tests { .then(|| "reference mismatch".to_owned()), }; let parts = - order_settlement_decision_event_build(request_event_id, payment_event_id, &payload) + order_settlement_decision_event_build(&request_event_id, &payment_event_id, &payload) .expect("relay k3436 draft should build"); radroots_nostr_build_event(parts.kind, parts.content, parts.tags) @@ -21218,22 +21372,24 @@ mod tests { seller_pubkey: &str, status: RadrootsOrderFulfillmentState, ) -> String { + let request_event_id = test_event_id(request_event_id); + let prev_event_id = test_event_id(prev_event_id); let payload = RadrootsOrderFulfillmentUpdate { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), status, }; let parts = radroots_sdk::order::build_fulfillment_update_draft( - request_event_id, - prev_event_id, + &request_event_id, + &prev_event_id, &payload, ) .expect("fulfillment update draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:fulfillment:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21257,22 +21413,24 @@ mod tests { buyer_pubkey: &str, seller_pubkey: &str, ) -> String { + let request_event_id = test_event_id(request_event_id); + let prev_event_id = test_event_id(prev_event_id); let payload = RadrootsOrderCancellation { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), reason: "buyer cancelled order".to_owned(), }; let parts = radroots_sdk::order::build_order_cancellation_draft( - request_event_id, - prev_event_id, + &request_event_id, + &prev_event_id, &payload, ) .expect("order cancellation draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:cancellation:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21297,24 +21455,26 @@ mod tests { seller_pubkey: &str, received: bool, ) -> String { + let request_event_id = test_event_id(request_event_id); + let prev_event_id = test_event_id(prev_event_id); let payload = RadrootsOrderReceipt { - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), received, issue: (!received).then(|| "items need review".to_owned()), received_at: 1_774_000_030, }; let parts = radroots_sdk::order::build_buyer_receipt_draft( - request_event_id, - prev_event_id, + &request_event_id, + &prev_event_id, &payload, ) .expect("buyer receipt draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:receipt:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21338,27 +21498,29 @@ mod tests { buyer_pubkey: &str, seller_pubkey: &str, ) -> String { + let request_event_id = test_event_id(request_event_id); + let prev_event_id = test_event_id(prev_event_id); let payload = RadrootsOrderRevisionProposal { - revision_id: format!("revision-{event_key}"), - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), - root_event_id: request_event_id.to_owned(), - prev_event_id: prev_event_id.to_owned(), + revision_id: test_revision_id(format!("revision-{event_key}").as_str()), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), + root_event_id: request_event_id.clone(), + prev_event_id: prev_event_id.clone(), items: revision_test_order_items(), economics: revision_test_order_economics(), reason: "harvest count updated".to_owned(), }; let parts = radroots_sdk::order::build_order_revision_proposal_draft( - request_event_id, - prev_event_id, + &request_event_id, + &prev_event_id, &payload, ) .expect("order revision proposal draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:revision-proposal:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21384,25 +21546,27 @@ mod tests { seller_pubkey: &str, decision: RadrootsOrderRevisionOutcome, ) -> String { + let request_event_id = test_event_id(request_event_id); + let proposal_event_id = test_event_id(proposal_event_id); let payload = RadrootsOrderRevisionDecision { - revision_id: revision_id.to_owned(), - order_id: trade_order_id.to_owned(), - listing_addr: listing_addr.to_owned(), - buyer_pubkey: buyer_pubkey.to_owned(), - seller_pubkey: seller_pubkey.to_owned(), - root_event_id: request_event_id.to_owned(), - prev_event_id: proposal_event_id.to_owned(), + revision_id: test_revision_id(revision_id), + order_id: test_order_id(trade_order_id), + listing_addr: test_listing_addr(listing_addr), + buyer_pubkey: test_pubkey(buyer_pubkey), + seller_pubkey: test_pubkey(seller_pubkey), + root_event_id: request_event_id.clone(), + prev_event_id: proposal_event_id.clone(), decision, }; let parts = radroots_sdk::order::build_order_revision_decision_draft( - request_event_id, - proposal_event_id, + &request_event_id, + &proposal_event_id, &payload, ) .expect("order revision decision draft should build") .into_wire_parts(); let record_id = format!("app:signed_event:revision-decision:{event_key}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); append_trade_signed_event_record( paths, record_id.as_str(), @@ -21418,19 +21582,19 @@ mod tests { fn revision_test_order_items() -> Vec<RadrootsOrderItem> { vec![RadrootsOrderItem { - bin_id: "seller-order-primary-bin".to_owned(), + bin_id: test_bin_id("seller-order-primary-bin"), bin_count: 3, }] } fn revision_test_order_economics() -> RadrootsOrderEconomics { RadrootsOrderEconomics { - quote_id: "quote-revision-test".to_owned(), + quote_id: test_quote_id("quote-revision-test"), quote_version: 2, pricing_basis: RadrootsOrderPricingBasis::ListingEvent, currency: RadrootsCoreCurrency::USD, items: vec![RadrootsOrderEconomicItem { - bin_id: "seller-order-primary-bin".to_owned(), + bin_id: test_bin_id("seller-order-primary-bin"), bin_count: 3, quantity_amount: RadrootsCoreDecimal::from(1u32), quantity_unit: RadrootsCoreUnit::Each, @@ -21556,7 +21720,7 @@ mod tests { for index in 0..count { let record_id = format!("app:signed_event:unrelated:{index}"); - let event_id = format!("event-{record_id}"); + let event_id = signed_event_id(record_id.as_str()); store .append_record(&LocalEventRecordInput { record_id, diff --git a/crates/store/src/interop.rs b/crates/store/src/interop.rs @@ -3875,8 +3875,9 @@ mod tests { use radroots_events::{ RadrootsNostrEvent, RadrootsNostrEventPtr, ids::{ - RadrootsEconomicsDigest, RadrootsInventoryBinId, RadrootsListingAddress, - RadrootsOrderId, RadrootsOrderQuoteId, RadrootsOrderRevisionId, + RadrootsEconomicsDigest, RadrootsEventId, RadrootsInventoryBinId, + RadrootsListingAddress, RadrootsOrderId, RadrootsOrderQuoteId, RadrootsOrderRevisionId, + RadrootsPublicKey, }, kinds::KIND_ORDER_RECEIPT, order::{ @@ -4383,6 +4384,10 @@ mod tests { format!("{}{}", left.simple(), right.simple()) } + fn test_event_id_seed(seed: &str) -> String { + test_pubkey(seed) + } + fn typed_order_id(raw: &str) -> RadrootsOrderId { raw.parse().expect("valid order id") } @@ -4399,6 +4404,14 @@ mod tests { raw.parse().expect("valid bin id") } + fn typed_event_id(raw: &str) -> RadrootsEventId { + raw.parse().expect("valid event id") + } + + fn typed_pubkey(raw: &str) -> RadrootsPublicKey { + raw.parse().expect("valid pubkey") + } + fn typed_listing_addr(raw: &str) -> RadrootsListingAddress { raw.parse().expect("valid listing address") } @@ -4409,7 +4422,7 @@ mod tests { fn listing_event_ptr(event_id: &str) -> RadrootsNostrEventPtr { RadrootsNostrEventPtr { - id: event_id.to_owned(), + id: test_event_id_seed(event_id), relays: Some("ws://127.0.0.1:1234/".to_owned()), } } @@ -4423,8 +4436,8 @@ mod tests { RadrootsOrderRequest { 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(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), items: vec![RadrootsOrderItem { bin_id: typed_bin_id("bin-1"), bin_count: 2, @@ -4462,8 +4475,8 @@ mod tests { RadrootsOrderDecision { 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(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), decision: RadrootsOrderDecisionOutcome::Accepted { inventory_commitments: vec![RadrootsOrderInventoryCommitment { bin_id: typed_bin_id("bin-1"), @@ -4482,8 +4495,8 @@ mod tests { RadrootsOrderDecision { 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(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), decision: RadrootsOrderDecisionOutcome::Declined { reason: "not available for this pickup".to_owned(), }, @@ -4513,10 +4526,10 @@ mod tests { 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(), - prev_event_id: prev_event_id.to_owned(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), + root_event_id: typed_event_id(root_event_id), + prev_event_id: typed_event_id(prev_event_id), items: request.items, economics: request.economics, reason: "seller confirmed updated pickup details".to_owned(), @@ -4537,10 +4550,10 @@ mod tests { 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(), - prev_event_id: prev_event_id.to_owned(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), + root_event_id: typed_event_id(root_event_id), + prev_event_id: typed_event_id(prev_event_id), decision, } } @@ -4555,8 +4568,8 @@ mod tests { RadrootsOrderFulfillmentUpdate { 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(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), status, } } @@ -4570,8 +4583,8 @@ mod tests { RadrootsOrderCancellation { 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(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), reason: "buyer changed pickup plan".to_owned(), } } @@ -4586,8 +4599,8 @@ mod tests { RadrootsOrderReceipt { 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(), + buyer_pubkey: typed_pubkey(buyer_pubkey), + seller_pubkey: typed_pubkey(seller_pubkey), received, issue: (!received).then(|| "items need review".to_owned()), received_at: 1_777_665_700, @@ -4630,7 +4643,7 @@ mod tests { let farm_key = "DDDDDDDDDDDDDDDDDDDDDD"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; let seller_pubkey = test_pubkey(format!("{label}-seller").as_str()); - let buyer_pubkey = format!("{label}-buyer"); + let buyer_pubkey = test_pubkey(format!("{label}-buyer").as_str()); let order_id_raw = format!("{label}-order"); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); events @@ -4693,8 +4706,8 @@ mod tests { seller_pubkey.as_str(), ); let decision_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &decision_payload, ) .expect("build lifecycle order decision"); @@ -4724,8 +4737,8 @@ mod tests { RadrootsOrderFulfillmentState::ReadyForPickup, ); let fulfillment_parts = order_fulfillment_update_event_build( - request_event.id.as_str(), - decision_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(decision_event.id.as_str()), &fulfillment_payload, ) .expect("build lifecycle fulfillment update"); @@ -4769,7 +4782,7 @@ mod tests { let farm_key = "DDDDDDDDDDDDDDDDDDDDDD"; let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; let seller_pubkey = test_pubkey(format!("{label}-seller").as_str()); - let buyer_pubkey = format!("{label}-buyer"); + let buyer_pubkey = test_pubkey(format!("{label}-buyer").as_str()); let order_id_raw = format!("{label}-order"); let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); let listing_event_id = hex_event_id(21); @@ -4831,8 +4844,8 @@ mod tests { seller_pubkey.as_str(), ); let decision_parts = order_decision_event_build( - request_event_id.as_str(), - request_event_id.as_str(), + &typed_event_id(request_event_id.as_str()), + &typed_event_id(request_event_id.as_str()), &decision_payload, ) .expect("build validation order decision"); @@ -4882,9 +4895,9 @@ mod tests { listing_addr: request.listing_addr.clone(), buyer_pubkey: request.buyer_pubkey.clone(), seller_pubkey: request.seller_pubkey.clone(), - root_event_id: root_event_id.to_owned(), - previous_event_id: previous_event_id.to_owned(), - agreement_event_id: agreement_event_id.to_owned(), + root_event_id: typed_event_id(root_event_id), + previous_event_id: typed_event_id(previous_event_id), + agreement_event_id: typed_event_id(agreement_event_id), quote_id: request.economics.quote_id.clone(), quote_version: request.economics.quote_version, economics_digest: typed_economics_digest( @@ -4915,10 +4928,10 @@ mod tests { listing_addr: request.listing_addr.clone(), buyer_pubkey: request.buyer_pubkey.clone(), seller_pubkey: request.seller_pubkey.clone(), - root_event_id: root_event_id.to_owned(), - previous_event_id: previous_event_id.to_owned(), - agreement_event_id: agreement_event_id.to_owned(), - payment_event_id: payment_event_id.to_owned(), + root_event_id: typed_event_id(root_event_id), + previous_event_id: typed_event_id(previous_event_id), + agreement_event_id: typed_event_id(agreement_event_id), + payment_event_id: typed_event_id(payment_event_id), quote_id: request.economics.quote_id.clone(), quote_version: request.economics.quote_version, economics_digest: typed_economics_digest( @@ -4934,14 +4947,18 @@ mod tests { } fn event_from_parts(event_id: &str, author: &str, parts: WireEventParts) -> RadrootsNostrEvent { + let event_id = event_id + .parse::<RadrootsEventId>() + .map(|event_id| event_id.to_string()) + .unwrap_or_else(|_| test_event_id_seed(event_id)); RadrootsNostrEvent { - id: event_id.to_owned(), + sig: format!("sig-{event_id}"), + id: event_id, author: author.to_owned(), created_at: 1_777_665_600, kind: parts.kind, tags: parts.tags, content: parts.content, - sig: format!("sig-{event_id}"), } } @@ -5081,7 +5098,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAg"; let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); - let buyer_pubkey = "buyer-pubkey"; + let buyer_pubkey = test_pubkey("buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = "relay-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); events @@ -5162,7 +5180,7 @@ mod tests { .iter() .any(|record| record.projected_kind == "signed_event" && record.event_kind == Some(KIND_ORDER_REQUEST) - && record.event_id.as_deref() == Some("order-request-event-1")) + && record.event_id.as_deref() == Some(event.id.as_str())) ); assert_eq!(signed_evidence, vec![event.clone()]); assert_eq!(orders.rows.len(), 1); @@ -5170,12 +5188,12 @@ mod tests { assert_eq!(orders.rows[0].status, OrderStatus::NeedsAction); assert_eq!( orders.rows[0].customer_display_name, - "Relay buyer buyer-pubkey" + format!("Relay buyer {}", &buyer_pubkey[..12]) ); assert_eq!(detail.items.len(), 1); assert_eq!(detail.items[0].title, "Order Visible Eggs"); assert_eq!(detail.items[0].quantity_display, "2 each"); - assert_eq!(buyer_context_key, "nostr:buyer-pubkey"); + assert_eq!(buyer_context_key, format!("nostr:{buyer_pubkey}")); } #[test] @@ -5183,7 +5201,8 @@ mod tests { let app_store = AppSqliteStore::open(DatabaseTarget::InMemory).expect("open app sqlite store"); let events = local_events_store(); - let buyer_pubkey = "buyer-pubkey"; + let buyer_pubkey = test_pubkey("buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); let listing_addr = format!("30402:{seller_pubkey}:AAAAAAAAAAAAAAAAAAAAAg"); @@ -5335,7 +5354,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAg"; let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); - let buyer_pubkey = "app-buyer-pubkey"; + let buyer_pubkey = test_pubkey("app-buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = "app-relay-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); events @@ -5403,8 +5423,8 @@ mod tests { seller_pubkey, ); let decision_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &decision_payload, ) .expect("build order decision event"); @@ -5457,8 +5477,8 @@ mod tests { decision_event.id.as_str(), ); let payment_parts = order_payment_record_event_build( - request_event.id.as_str(), - decision_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(decision_event.id.as_str()), &payment_payload, ) .expect("build payment recorded event"); @@ -5533,8 +5553,8 @@ mod tests { RadrootsOrderSettlementOutcome::Accepted, ); let settlement_parts = order_settlement_decision_event_build( - request_event.id.as_str(), - payment_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(payment_event.id.as_str()), &settlement_payload, ) .expect("build settlement decision event"); @@ -5599,7 +5619,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAg"; let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); - let buyer_pubkey = "app-buyer-pubkey"; + let buyer_pubkey = test_pubkey("app-buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = "app-relay-order-declined-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); events @@ -5669,8 +5690,8 @@ mod tests { seller_pubkey, ); let decision_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &decision_payload, ) .expect("build declined order decision event"); @@ -5729,7 +5750,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); - let buyer_pubkey = "app-buyer-pubkey"; + let buyer_pubkey = test_pubkey("app-buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = "active-lifecycle-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); events @@ -5792,8 +5814,8 @@ mod tests { seller_pubkey, ); let decision_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &decision_payload, ) .expect("build lifecycle order decision"); @@ -5841,8 +5863,8 @@ mod tests { RadrootsOrderFulfillmentState::ReadyForPickup, ); let fulfillment_parts = order_fulfillment_update_event_build( - request_event.id.as_str(), - decision_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(decision_event.id.as_str()), &fulfillment_payload, ) .expect("build lifecycle fulfillment update"); @@ -5902,8 +5924,8 @@ mod tests { true, ); let receipt_parts = order_receipt_event_build( - request_event.id.as_str(), - fulfillment_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(fulfillment_event.id.as_str()), &receipt_payload, ) .expect("build lifecycle buyer receipt"); @@ -5972,8 +5994,8 @@ mod tests { false, ); let receipt_parts = order_receipt_event_build( - fixture.request_event_id.as_str(), - fixture.fulfillment_event_id.as_str(), + &typed_event_id(fixture.request_event_id.as_str()), + &typed_event_id(fixture.fulfillment_event_id.as_str()), &receipt_payload, ) .expect("build lifecycle buyer issue receipt"); @@ -6195,7 +6217,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; 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 buyer_pubkey = test_pubkey("validation-out-of-order-buyer"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = "validation-out-of-order"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); let listing_event_id = hex_event_id(51); @@ -6418,7 +6441,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); - let buyer_pubkey = "app-buyer-pubkey"; + let buyer_pubkey = test_pubkey("app-buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = "active-revision-order-1"; let listing_addr = format!("30402:{seller_pubkey}:{listing_key}"); events @@ -6475,8 +6499,8 @@ mod tests { seller_pubkey, ); let decision_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &decision_payload, ) .expect("build revision order decision"); @@ -6508,8 +6532,8 @@ mod tests { decision_event.id.as_str(), ); let proposal_parts = order_revision_proposal_event_build( - request_event.id.as_str(), - decision_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(decision_event.id.as_str()), &proposal_payload, ) .expect("build revision proposal"); @@ -6569,8 +6593,8 @@ mod tests { RadrootsOrderRevisionOutcome::Accepted, ); let revision_decision_parts = order_revision_decision_event_build( - request_event.id.as_str(), - proposal_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(proposal_event.id.as_str()), &revision_decision_payload, ) .expect("build revision decision"); @@ -6628,8 +6652,8 @@ mod tests { seller_pubkey, ); let cancel_parts = order_cancellation_event_build( - request_event.id.as_str(), - revision_decision_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(revision_decision_event.id.as_str()), &cancel_payload, ) .expect("build revision cancellation"); @@ -6677,7 +6701,8 @@ mod tests { let listing_key = "AAAAAAAAAAAAAAAAAAAAAw"; let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); - let buyer_pubkey = "app-buyer-pubkey"; + let buyer_pubkey = test_pubkey("app-buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let order_id_raw = if accepted_first { "active-conflict-order-accepted-first" } else { @@ -6730,8 +6755,8 @@ mod tests { seller_pubkey, ); let accepted_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &accepted_payload, ) .expect("build accepted conflict decision"); @@ -6747,8 +6772,8 @@ mod tests { seller_pubkey, ); let declined_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &declined_payload, ) .expect("build declined conflict decision"); @@ -8583,16 +8608,18 @@ mod tests { let events = local_events_store(); let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); + let buyer_pubkey = test_pubkey("buyer-pubkey"); + let buyer_pubkey = buyer_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.as_str(), - "buyer-pubkey", + buyer_pubkey, seller_pubkey, ); let parts = order_request_event_build(&listing_event_ptr("listing-event"), &payload) .expect("build order request event"); - let event = event_from_parts("app-order-request-event", "buyer-pubkey", parts); + let event = event_from_parts("app-order-request-event", buyer_pubkey, parts); let mut relay_record = signed_order_event_record( "app:relay_event:order-request:duplicate", &event, @@ -8626,7 +8653,7 @@ mod tests { .expect("load imported records"); let stored = imported .iter() - .find(|record| record.event_id.as_deref() == Some("app-order-request-event")) + .find(|record| record.event_id.as_deref() == Some(event.id.as_str())) .expect("app order request evidence"); assert_eq!(report.imported_records, 2); @@ -8634,7 +8661,7 @@ mod tests { assert_eq!( imported .iter() - .filter(|record| record.event_id.as_deref() == Some("app-order-request-event")) + .filter(|record| record.event_id.as_deref() == Some(event.id.as_str())) .count(), 1 ); @@ -8655,32 +8682,34 @@ mod tests { let events = local_events_store(); let seller_pubkey = test_pubkey("seller-pubkey"); let seller_pubkey = seller_pubkey.as_str(); + let buyer_pubkey = test_pubkey("buyer-pubkey"); + let buyer_pubkey = buyer_pubkey.as_str(); let listing_addr = format!("30402:{seller_pubkey}:app-decision-listing"); let request_payload = order_request_payload( "app-decision-receipt", listing_addr.as_str(), - "buyer-pubkey", + buyer_pubkey, seller_pubkey, ); let request_parts = order_request_event_build(&listing_event_ptr("listing-event"), &request_payload) .expect("build order request event"); let request_event = - event_from_parts("app-decision-request-event", "buyer-pubkey", request_parts); + event_from_parts("app-decision-request-event", buyer_pubkey, request_parts); let decision_payload = accepted_order_decision_payload( "app-decision-receipt", listing_addr.as_str(), - "buyer-pubkey", + buyer_pubkey, seller_pubkey, ); let decision_parts = order_decision_event_build( - request_event.id.as_str(), - request_event.id.as_str(), + &typed_event_id(request_event.id.as_str()), + &typed_event_id(request_event.id.as_str()), &decision_payload, ) .expect("build order decision event"); let decision_event = - event_from_parts("app-order-decision-event", "seller-pubkey", decision_parts); + event_from_parts("app-order-decision-event", seller_pubkey, decision_parts); let app_record = events .append_record(&signed_order_event_record( "app:signed_event:order-decision:duplicate", @@ -8714,7 +8743,7 @@ mod tests { .expect("load imported records"); let stored = imported .iter() - .find(|record| record.event_id.as_deref() == Some("app-order-decision-event")) + .find(|record| record.event_id.as_deref() == Some(decision_event.id.as_str())) .expect("app order decision evidence"); assert_eq!(report.imported_records, 1); @@ -8722,7 +8751,7 @@ mod tests { assert_eq!( imported .iter() - .filter(|record| record.event_id.as_deref() == Some("app-order-decision-event")) + .filter(|record| record.event_id.as_deref() == Some(decision_event.id.as_str())) .count(), 1 ); diff --git a/crates/sync/src/publish.rs b/crates/sync/src/publish.rs @@ -1174,7 +1174,7 @@ mod tests { buyer_pubkey: "buyer".to_owned(), seller_pubkey: "seller".to_owned(), items: vec![RadrootsOrderItem { - bin_id: "bin-1".to_owned(), + bin_id: "bin-1".parse().expect("valid bin id"), bin_count: 2, }], economics: economics.clone(), diff --git a/crates/view/src/lib.rs b/crates/view/src/lib.rs @@ -2436,6 +2436,10 @@ mod tests { use radroots_core::{ RadrootsCoreCurrency, RadrootsCoreDecimal, RadrootsCoreMoney, RadrootsCoreUnit, }; + use radroots_events::ids::{ + RadrootsEventId, RadrootsInventoryBinId, RadrootsListingAddress, RadrootsOrderId, + RadrootsOrderQuoteId, RadrootsPublicKey, + }; use radroots_events::order::{ RadrootsOrderEconomicItem, RadrootsOrderEconomics, RadrootsOrderFulfillmentState, RadrootsOrderPricingBasis, @@ -3144,14 +3148,38 @@ mod tests { RadrootsCoreMoney::new(test_decimal(raw), RadrootsCoreCurrency::USD) } + fn test_order_id(raw: &str) -> RadrootsOrderId { + raw.parse().expect("test order id should parse") + } + + fn test_quote_id(raw: &str) -> RadrootsOrderQuoteId { + raw.parse().expect("test quote id should parse") + } + + fn test_bin_id(raw: &str) -> RadrootsInventoryBinId { + raw.parse().expect("test bin id should parse") + } + + fn test_event_id(raw: &str) -> RadrootsEventId { + raw.parse().expect("test event id should parse") + } + + fn test_pubkey(raw: &str) -> RadrootsPublicKey { + raw.parse().expect("test pubkey should parse") + } + + fn test_listing_addr(raw: &str) -> RadrootsListingAddress { + raw.parse().expect("test listing address should parse") + } + fn test_trade_economics() -> RadrootsOrderEconomics { RadrootsOrderEconomics { - quote_id: "quote-active-order".to_owned(), + quote_id: test_quote_id("quote-1"), quote_version: 2, pricing_basis: RadrootsOrderPricingBasis::ListingEvent, currency: RadrootsCoreCurrency::USD, items: vec![RadrootsOrderEconomicItem { - bin_id: "bin-1".to_owned(), + bin_id: test_bin_id("bin-1"), bin_count: 2, quantity_amount: test_decimal("1"), quantity_unit: RadrootsCoreUnit::Each, @@ -3171,7 +3199,9 @@ mod tests { fn test_payment_projection(state: RadrootsOrderPaymentState) -> RadrootsOrderPaymentProjection { let mut projection = RadrootsOrderPaymentProjection::not_recorded(); projection.payment_event_id = (!matches!(&state, RadrootsOrderPaymentState::NotRecorded)) - .then(|| "payment-event-1".to_owned()); + .then(|| { + test_event_id("4444444444444444444444444444444444444444444444444444444444444444") + }); projection.settlement_state = match &state { RadrootsOrderPaymentState::Settled => RadrootsOrderSettlementState::Accepted, RadrootsOrderPaymentState::Invalid => RadrootsOrderSettlementState::Invalid, @@ -3187,13 +3217,17 @@ mod tests { payment_state: RadrootsOrderPaymentState, ) -> RadrootsOrderProjection { RadrootsOrderProjection { - order_id: "active-order-1".to_owned(), + order_id: test_order_id("ord_AAAAAAAAAAAAAAAAAAAAAg"), status, - request_event_id: Some("request-event-1".to_owned()), - decision_event_id: Some("decision-event-1".to_owned()), - fulfillment_event_id: fulfillment_status - .as_ref() - .map(|_| "fulfillment-event-1".to_owned()), + request_event_id: Some(test_event_id( + "1111111111111111111111111111111111111111111111111111111111111111", + )), + decision_event_id: Some(test_event_id( + "2222222222222222222222222222222222222222222222222222222222222222", + )), + fulfillment_event_id: fulfillment_status.as_ref().map(|_| { + test_event_id("3333333333333333333333333333333333333333333333333333333333333333") + }), fulfillment_status, cancellation_event_id: None, receipt_event_id: None, @@ -3203,11 +3237,21 @@ mod tests { lifecycle_terminal: false, payment: test_payment_projection(payment_state), economics: Some(test_trade_economics()), - agreement_event_id: Some("decision-event-1".to_owned()), - listing_addr: Some("30402:seller:listing".to_owned()), - buyer_pubkey: Some("buyer".to_owned()), - seller_pubkey: Some("seller".to_owned()), - last_event_id: Some("fulfillment-event-1".to_owned()), + agreement_event_id: Some(test_event_id( + "2222222222222222222222222222222222222222222222222222222222222222", + )), + listing_addr: Some(test_listing_addr( + "30402:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:AAAAAAAAAAAAAAAAAAAAAg", + )), + buyer_pubkey: Some(test_pubkey( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + )), + seller_pubkey: Some(test_pubkey( + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + )), + last_event_id: Some(test_event_id( + "3333333333333333333333333333333333333333333333333333333333333333", + )), issues: Vec::new(), } } @@ -3308,7 +3352,9 @@ mod tests { assert_eq!( projection.provenance, TradeProvenanceProjection::from_primary_source(TradeWorkflowSource::LocalEvents) - .with_last_event_id(Some("fulfillment-event-1".to_owned())) + .with_last_event_id(Some( + "3333333333333333333333333333333333333333333333333333333333333333".to_owned() + )) ); assert_eq!( order_status_from_active_order_projection(&active_order), @@ -3407,7 +3453,9 @@ mod tests { fn trade_payment_display_projection_maps_reducer_payment_states() { let mut pending = RadrootsOrderPaymentProjection::not_recorded(); pending.state = RadrootsOrderPaymentState::Recorded; - pending.payment_event_id = Some("payment-event-1".to_owned()); + pending.payment_event_id = Some(test_event_id( + "4444444444444444444444444444444444444444444444444444444444444444", + )); pending.settlement_state = RadrootsOrderSettlementState::Pending; assert_eq!( TradePaymentDisplayStatus::from_active_payment_projection(&pending), @@ -3416,7 +3464,9 @@ mod tests { let mut settled = RadrootsOrderPaymentProjection::not_recorded(); settled.state = RadrootsOrderPaymentState::Settled; - settled.payment_event_id = Some("payment-event-1".to_owned()); + settled.payment_event_id = Some(test_event_id( + "4444444444444444444444444444444444444444444444444444444444444444", + )); settled.settlement_state = RadrootsOrderSettlementState::Accepted; assert_eq!( TradePaymentDisplayStatus::from_active_payment_projection(&settled),