app

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

commit 152d8bcd7c972822188b7a9a199f174d2018e52d
parent c99b51612fda0af732866b7e550a033af6e22bbe
Author: triesap <tyson@radroots.org>
Date:   Sat, 13 Jun 2026 15:09:29 -0700

sdk: point app at SDK workspace

- update radroots_sdk to resolve from the SDK repo path
- refresh the app lockfile for the new SDK crate version
- parse persisted Nostr IDs before building active order reducer records
- stringify typed event and pubkey values at app projection boundaries

Diffstat:
MCargo.lock | 3+--
MCargo.toml | 2+-
Mcrates/store/src/interop.rs | 58+++++++++++++++++++++++++++++++++++++---------------------
Mcrates/view/src/lib.rs | 5+++--
4 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -5353,7 +5353,7 @@ dependencies = [ [[package]] name = "radroots_sdk" -version = "0.1.0-alpha.2" +version = "0.1.0" dependencies = [ "radroots_events", "radroots_events_codec", @@ -5376,7 +5376,6 @@ dependencies = [ "rusqlite", "serde", "serde_json", - "thiserror 1.0.69", "uuid", ] diff --git a/Cargo.toml b/Cargo.toml @@ -41,7 +41,7 @@ radroots_nostr_connect = { path = "../lib/crates/nostr_connect" } radroots_protected_store = { path = "../lib/crates/protected_store" } radroots_runtime_paths = { path = "../lib/crates/runtime_paths" } radroots_secret_vault = { path = "../lib/crates/secret_vault", default-features = false, features = ["std"] } -radroots_sdk = { path = "../lib/crates/sdk", features = ["relay-client", "signing"] } +radroots_sdk = { path = "../sdk/crates/sdk", features = ["relay-client", "signing"] } radroots_sql_core = { path = "../lib/crates/sql_core", features = ["native"] } radroots_trade = { path = "../lib/crates/trade", default-features = false, features = ["std", "serde", "serde_json"] } radroots_app_core = { path = "crates/runtime", version = "0.1.0" } diff --git a/crates/store/src/interop.rs b/crates/store/src/interop.rs @@ -9,6 +9,7 @@ use radroots_app_view::{ }; use radroots_events::{ RadrootsNostrEvent, + ids::{RadrootsEventId, RadrootsOrderId, RadrootsPublicKey}, kinds::{ KIND_FARM as RADROOTS_KIND_FARM, KIND_LISTING as RADROOTS_KIND_LISTING, KIND_LISTING_DRAFT as RADROOTS_KIND_LISTING_DRAFT, @@ -1187,8 +1188,15 @@ impl<'a> AppLocalInteropRepository<'a> { let requests = buckets.requests.clone(); let revision_proposals = buckets.revision_proposals.clone(); let revision_decisions = buckets.revision_decisions.clone(); + let reducer_order_id = + raw_order_id + .parse::<RadrootsOrderId>() + .map_err(|_| AppSqliteError::DecodeId { + field: "order_id", + value: raw_order_id.clone(), + })?; let projection = reduce_order_events( - raw_order_id.as_str(), + &reducer_order_id, buckets.requests, buckets.decisions, buckets.revision_proposals, @@ -2982,13 +2990,21 @@ fn active_order_event_kind(kind: i64) -> bool { ACTIVE_ORDER_EVENT_KINDS.contains(&kind) } +fn active_event_id(event: &RadrootsNostrEvent) -> Option<RadrootsEventId> { + event.id.parse().ok() +} + +fn active_author_pubkey(event: &RadrootsNostrEvent) -> Option<RadrootsPublicKey> { + event.author.parse().ok() +} + fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<ActiveOrderEvidence> { match i64::from(event.kind) { KIND_ORDER_REQUEST => { let envelope = order_request_from_event(event).ok()?; Some(ActiveOrderEvidence::Request(RadrootsOrderRequestRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, payload: envelope.payload, })) } @@ -2996,8 +3012,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let envelope = order_decision_from_event(event).ok()?; let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::Decision(RadrootsOrderDecisionRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3009,8 +3025,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::RevisionProposal( RadrootsOrderRevisionProposalRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3023,8 +3039,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::RevisionDecision( RadrootsOrderRevisionDecisionRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3037,8 +3053,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::Cancellation( RadrootsOrderCancellationRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3051,8 +3067,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::Fulfillment( RadrootsOrderFulfillmentRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3064,8 +3080,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let envelope = order_receipt_from_event(event).ok()?; let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::Receipt(RadrootsOrderReceiptRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3077,8 +3093,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::Payment( RadrootsOrderPaymentEventRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3091,8 +3107,8 @@ fn active_order_evidence_from_event(event: &RadrootsNostrEvent) -> Option<Active let context = order_event_context_from_tags(envelope.message_type, &event.tags).ok()?; Some(ActiveOrderEvidence::Settlement( RadrootsOrderSettlementRecord { - event_id: event.id.clone(), - author_pubkey: event.author.clone(), + event_id: active_event_id(event)?, + author_pubkey: active_author_pubkey(event)?, counterparty_pubkey: context.counterparty_pubkey, root_event_id: context.root_event_id?, prev_event_id: context.prev_event_id?, @@ -3359,14 +3375,14 @@ fn active_order_agreement_source( { return ActiveOrderAgreementSource { listing_addr: revision_proposal.payload.listing_addr.to_string(), - seller_pubkey: revision_proposal.payload.seller_pubkey.clone(), + seller_pubkey: revision_proposal.payload.seller_pubkey.to_string(), items: revision_proposal.payload.items.clone(), economics: revision_proposal.payload.economics.clone(), }; } ActiveOrderAgreementSource { listing_addr: request.listing_addr.to_string(), - seller_pubkey: request.seller_pubkey.clone(), + seller_pubkey: request.seller_pubkey.to_string(), items: request.items.clone(), economics: request.economics.clone(), } diff --git a/crates/view/src/lib.rs b/crates/view/src/lib.rs @@ -1474,7 +1474,7 @@ pub struct TradeReceiptProjection { impl TradeReceiptProjection { pub fn from_active_order_projection(projection: &RadrootsOrderProjection) -> Option<Self> { Some(Self { - event_id: projection.receipt_event_id.clone()?, + event_id: projection.receipt_event_id.as_ref()?.to_string(), received: projection.receipt_received?, issue: projection.receipt_issue.clone(), received_at: projection.receipt_received_at?, @@ -1662,7 +1662,8 @@ impl TradeWorkflowProjection { workflow.inventory = TradeInventoryStatus::from_active_order_projection(projection); workflow.payment = TradePaymentDisplayStatus::from_active_payment_projection(&projection.payment); - workflow.provenance = provenance.with_last_event_id(projection.last_event_id.clone()); + workflow.provenance = provenance + .with_last_event_id(projection.last_event_id.as_ref().map(ToString::to_string)); workflow }