cli

Command-line interface for Radroots
git clone https://radroots.dev/git/cli.git
Log | Files | Refs | README | LICENSE

commit f5b849afcc287bb09544cf7aecc180ff36efac97
parent 570ca1634bad63d9086edc405596d2e5ae320632
Author: triesap <tyson@radroots.org>
Date:   Wed, 17 Jun 2026 13:31:20 -0700

cli: use SDK CLI runtime feature

- switch radroots_sdk to the curated cli-runtime feature bundle

- update SDK module imports after the root re-export cleanup

- align order reducer call sites with typed input structs

- adapt local signer status to the boxed signer capability contract

Diffstat:
MCargo.lock | 248++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
MCargo.toml | 2+-
Msrc/runtime/order.rs | 209+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Msrc/runtime/signer.rs | 4++--
4 files changed, 362 insertions(+), 101 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -259,6 +259,15 @@ dependencies = [ ] [[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] name = "atomic" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -681,6 +690,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] name = "config" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -843,6 +861,21 @@ dependencies = [ ] [[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + +[[package]] name = "crc32fast" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1174,6 +1207,12 @@ dependencies = [ ] [[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] name = "downcast-rs" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1310,6 +1349,17 @@ dependencies = [ ] [[package]] +name = "event-listener" +version = "5.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] name = "eventsource-stream" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1410,6 +1460,17 @@ dependencies = [ ] [[package]] +name = "flume" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] + +[[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1494,6 +1555,17 @@ dependencies = [ ] [[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] name = "futures-io" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1713,6 +1785,15 @@ dependencies = [ ] [[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3070,6 +3151,12 @@ dependencies = [ ] [[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] name = "parking_lot" version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3517,7 +3604,7 @@ name = "radroots_authority" version = "0.1.0-alpha.2" dependencies = [ "radroots_events", - "thiserror 1.0.69", + "radroots_nostr", ] [[package]] @@ -3572,6 +3659,18 @@ dependencies = [ ] [[package]] +name = "radroots_event_store" +version = "0.1.0-alpha.2" +dependencies = [ + "radroots_events", + "radroots_nostr", + "serde", + "serde_json", + "sqlx", + "thiserror 1.0.69", +] + +[[package]] name = "radroots_events" version = "0.1.0-alpha.2" dependencies = [ @@ -3689,6 +3788,20 @@ dependencies = [ ] [[package]] +name = "radroots_outbox" +version = "0.1.0-alpha.2" +dependencies = [ + "hex", + "radroots_event_store", + "radroots_events", + "serde", + "serde_json", + "sha2", + "sqlx", + "thiserror 1.0.69", +] + +[[package]] name = "radroots_protected_store" version = "0.1.0-alpha.2" dependencies = [ @@ -3701,6 +3814,22 @@ dependencies = [ ] [[package]] +name = "radroots_relay_transport" +version = "0.1.0-alpha.2" +dependencies = [ + "futures", + "nostr", + "radroots_event_store", + "radroots_events", + "radroots_nostr", + "radroots_outbox", + "serde", + "serde_json", + "thiserror 1.0.69", + "url", +] + +[[package]] name = "radroots_replica_db" version = "0.1.0-alpha.2" dependencies = [ @@ -3775,14 +3904,20 @@ dependencies = [ name = "radroots_sdk" version = "0.1.0" dependencies = [ + "hex", + "radroots_authority", + "radroots_event_store", "radroots_events", "radroots_events_codec", "radroots_identity", "radroots_nostr", + "radroots_outbox", + "radroots_relay_transport", "radroots_trade", - "reqwest", "serde", "serde_json", + "sha2", + "uuid", ] [[package]] @@ -3837,6 +3972,7 @@ dependencies = [ "hex", "radroots_authority", "radroots_core", + "radroots_event_store", "radroots_events", "radroots_events_codec", "serde", @@ -5606,6 +5742,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spki" @@ -5618,6 +5757,110 @@ dependencies = [ ] [[package]] +name = "sqlx" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +dependencies = [ + "base64 0.22.1", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.15.5", + "hashlink 0.10.0", + "indexmap 2.13.1", + "log", + "memchr", + "once_cell", + "percent-encoding", + "serde", + "sha2", + "smallvec", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.117", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-sqlite", + "syn 2.0.117", + "tokio", + "url", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "thiserror 2.0.18", + "tracing", + "url", +] + +[[package]] name = "stable_deref_trait" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6217,6 +6460,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", diff --git a/Cargo.toml b/Cargo.toml @@ -41,7 +41,7 @@ radroots_replica_db_schema = { path = "../lib/crates/replica_db_schema" } radroots_replica_sync = { path = "../lib/crates/replica_sync" } radroots_runtime = { path = "../lib/crates/runtime" } radroots_runtime_paths = { path = "../lib/crates/runtime_paths" } -radroots_sdk = { path = "../sdk/crates/sdk", features = ["radrootsd-client", "relay-client", "signing"] } +radroots_sdk = { path = "../sdk/crates/sdk", features = ["cli-runtime"] } radroots_secret_vault = { path = "../lib/crates/secret_vault", features = ["std", "os-keyring"] } radroots_sql_core = { path = "../lib/crates/sql_core", features = ["native"] } radroots_sp1_host_trade = { path = "../lib/crates/sp1_host_trade" } diff --git a/src/runtime/order.rs b/src/runtime/order.rs @@ -65,17 +65,20 @@ use radroots_replica_db_schema::nostr_event_head::{ use radroots_replica_db_schema::trade_product::{ ITradeProductFieldsFilter, ITradeProductFindMany, TradeProduct, }; -use radroots_sdk::{ - RadrootsSdkClient, RadrootsSdkConfig, SdkEnvironment, SdkPublishError, SdkPublishReceipt, - SdkRelayFailure, SdkTransportMode, SdkTransportReceipt, SignerConfig as SdkSignerConfig, +use radroots_sdk::client::{ + RadrootsSdkClient, SdkPublishError, SdkPublishReceipt, SdkRelayFailure, SdkTransportReceipt, +}; +use radroots_sdk::config::{ + RadrootsSdkConfig, SdkEnvironment, SdkTransportMode, SignerConfig as SdkSignerConfig, }; use radroots_sql_core::SqliteExecutor; use radroots_trade::order::{ RadrootsListingInventoryAccountingIssue, RadrootsListingInventoryAccountingProjection, - RadrootsListingInventoryBinAvailability, RadrootsOrderCancellationRecord, - RadrootsOrderDecisionRecord, RadrootsOrderFulfillmentRecord, RadrootsOrderIssue, - RadrootsOrderPaymentEventRecord, RadrootsOrderPaymentProjection, RadrootsOrderPaymentState, - RadrootsOrderReceiptRecord, RadrootsOrderRequestRecord, RadrootsOrderRevisionDecisionRecord, + RadrootsListingInventoryAccountingInputs, RadrootsListingInventoryBinAvailability, + RadrootsOrderCancellationRecord, RadrootsOrderDecisionRecord, RadrootsOrderFulfillmentRecord, + RadrootsOrderIssue, RadrootsOrderPaymentEventRecord, RadrootsOrderPaymentProjection, + RadrootsOrderPaymentState, RadrootsOrderReceiptRecord, RadrootsOrderReductionInputs, + RadrootsOrderRequestRecord, RadrootsOrderRevisionDecisionRecord, RadrootsOrderRevisionProposalRecord, RadrootsOrderSettlementRecord, RadrootsOrderSettlementState, RadrootsOrderStatus, canonicalize_order_decision_for_signer, canonicalize_order_request_for_signer, radroots_order_economics_digest, @@ -2547,15 +2550,17 @@ fn order_status_reduction_from_receipt_inner( let receipt_records = receipts.clone(); let projection = reduce_order_events( &reducer_order_id, - requests, - decisions.clone(), - revision_proposals, - revision_decisions, - fulfillments, - cancellations, - receipts, - payments, - settlements, + RadrootsOrderReductionInputs { + requests, + decisions: decisions.clone(), + revision_proposals, + revision_decisions, + fulfillments, + cancellations, + receipts, + payments, + settlements, + }, ); let fulfillment_event_id = projection.fulfillment_event_id.clone(); let fulfillment_status = projection.fulfillment_status; @@ -2822,14 +2827,16 @@ fn enrich_order_status_inventory( let projection = reduce_listing_inventory_accounting( &protocol_listing_addr(listing_addr.as_str(), "listing_addr")?, &listing.event_id, - listing.bins, - requests, - decisions, - revision_proposals, - revision_decisions, - fulfillments, - cancellations, - Vec::<RadrootsOrderReceiptRecord>::new(), + RadrootsListingInventoryAccountingInputs { + bins: listing.bins, + requests, + decisions, + revision_proposals, + revision_decisions, + fulfillments, + cancellations, + receipts: Vec::<RadrootsOrderReceiptRecord>::new(), + }, ); let mut relevant_event_ids = Vec::new(); relevant_event_ids.push(decision_event_id); @@ -6617,14 +6624,16 @@ fn order_accept_inventory_preflight_view( let projection = reduce_listing_inventory_accounting( &request.listing_addr, &listing.event_id, - listing.bins, - requests, - decisions, - revision_proposals, - revision_decisions, - fulfillments, - cancellations, - Vec::<RadrootsOrderReceiptRecord>::new(), + RadrootsListingInventoryAccountingInputs { + bins: listing.bins, + requests, + decisions, + revision_proposals, + revision_decisions, + fulfillments, + cancellations, + receipts: Vec::<RadrootsOrderReceiptRecord>::new(), + }, ); Ok(order_accept_inventory_preflight_view_from_projection( config, args, request, resolution, status, projection, @@ -12731,8 +12740,9 @@ mod tests { use radroots_runtime_paths::RadrootsMigrationReport; use radroots_secret_vault::RadrootsSecretBackend; use radroots_trade::order::{ - RadrootsListingInventoryBinAvailability, RadrootsOrderCancellationRecord, - RadrootsOrderDecisionRecord, RadrootsOrderFulfillmentRecord, RadrootsOrderReceiptRecord, + RadrootsListingInventoryAccountingInputs, RadrootsListingInventoryBinAvailability, + RadrootsOrderCancellationRecord, RadrootsOrderDecisionRecord, + RadrootsOrderFulfillmentRecord, RadrootsOrderReceiptRecord, RadrootsOrderRevisionDecisionRecord, RadrootsOrderRevisionProposalRecord, canonicalize_order_decision_for_signer, reduce_listing_inventory_accounting, }; @@ -12877,14 +12887,17 @@ mod tests { assert_eq!( client.transport(), - radroots_sdk::SdkTransportMode::RelayDirect + radroots_sdk::config::SdkTransportMode::RelayDirect + ); + assert_eq!( + client.signer(), + radroots_sdk::config::SignerConfig::LocalIdentity ); - assert_eq!(client.signer(), radroots_sdk::SignerConfig::LocalIdentity); match client.resolved_transport_target() { - radroots_sdk::SdkResolvedTransportTarget::RelayDirect { relay_urls } => { + radroots_sdk::client::SdkResolvedTransportTarget::RelayDirect { relay_urls } => { assert_eq!(relay_urls.as_slice(), ["ws://127.0.0.1:9001"]); } - radroots_sdk::SdkResolvedTransportTarget::Radrootsd { .. } => { + radroots_sdk::client::SdkResolvedTransportTarget::Radrootsd { .. } => { panic!("order submit must use relay direct transport"); } } @@ -17964,30 +17977,32 @@ mod tests { let projection = reduce_listing_inventory_accounting( &test_listing_addr(fixture.listing_addr.as_str()), &test_event_id(fixture.listing_event_id.as_str()), - vec![RadrootsListingInventoryBinAvailability { - bin_id: test_inventory_bin_id("bin-1"), - available_count: 2, - }], - vec![ - active_request_record_from_resolved(&existing_request), - active_request_record_from_resolved(&request), - ], - vec![ - RadrootsOrderDecisionRecord { - event_id: test_event_id_char('2'), - author_pubkey: test_pubkey(fixture.seller_pubkey.as_str()), - counterparty_pubkey: test_pubkey(fixture.buyer_pubkey.as_str()), - root_event_id: existing_request.request_event_id.clone(), - prev_event_id: existing_request.request_event_id.clone(), - payload: existing_decision_payload, - }, - proposed_accept_decision_record(&request).expect("proposed accept decision"), - ], - Vec::<RadrootsOrderRevisionProposalRecord>::new(), - Vec::<RadrootsOrderRevisionDecisionRecord>::new(), - Vec::<RadrootsOrderFulfillmentRecord>::new(), - Vec::<RadrootsOrderCancellationRecord>::new(), - Vec::<RadrootsOrderReceiptRecord>::new(), + RadrootsListingInventoryAccountingInputs { + bins: vec![RadrootsListingInventoryBinAvailability { + bin_id: test_inventory_bin_id("bin-1"), + available_count: 2, + }], + requests: vec![ + active_request_record_from_resolved(&existing_request), + active_request_record_from_resolved(&request), + ], + decisions: vec![ + RadrootsOrderDecisionRecord { + event_id: test_event_id_char('2'), + author_pubkey: test_pubkey(fixture.seller_pubkey.as_str()), + counterparty_pubkey: test_pubkey(fixture.buyer_pubkey.as_str()), + root_event_id: existing_request.request_event_id.clone(), + prev_event_id: existing_request.request_event_id.clone(), + payload: existing_decision_payload, + }, + proposed_accept_decision_record(&request).expect("proposed accept decision"), + ], + revision_proposals: Vec::<RadrootsOrderRevisionProposalRecord>::new(), + revision_decisions: Vec::<RadrootsOrderRevisionDecisionRecord>::new(), + fulfillments: Vec::<RadrootsOrderFulfillmentRecord>::new(), + cancellations: Vec::<RadrootsOrderCancellationRecord>::new(), + receipts: Vec::<RadrootsOrderReceiptRecord>::new(), + }, ); let args = OrderDecisionArgs { key: fixture.order_id.clone(), @@ -18063,43 +18078,45 @@ mod tests { let projection = reduce_listing_inventory_accounting( &test_listing_addr(fixture.listing_addr.as_str()), &test_event_id(fixture.listing_event_id.as_str()), - vec![RadrootsListingInventoryBinAvailability { - bin_id: test_inventory_bin_id("bin-1"), - available_count: 2, - }], - vec![ - active_request_record_from_resolved(&existing_request), - active_request_record_from_resolved(&request), - ], - vec![ - RadrootsOrderDecisionRecord { - event_id: existing_decision_event_id.clone(), + RadrootsListingInventoryAccountingInputs { + bins: vec![RadrootsListingInventoryBinAvailability { + bin_id: test_inventory_bin_id("bin-1"), + available_count: 2, + }], + requests: vec![ + active_request_record_from_resolved(&existing_request), + active_request_record_from_resolved(&request), + ], + decisions: vec![ + RadrootsOrderDecisionRecord { + event_id: existing_decision_event_id.clone(), + author_pubkey: test_pubkey(fixture.seller_pubkey.as_str()), + counterparty_pubkey: test_pubkey(fixture.buyer_pubkey.as_str()), + root_event_id: existing_request.request_event_id.clone(), + prev_event_id: existing_request.request_event_id.clone(), + payload: existing_decision_payload, + }, + proposed_accept_decision_record(&request).expect("proposed accept decision"), + ], + revision_proposals: Vec::<RadrootsOrderRevisionProposalRecord>::new(), + revision_decisions: Vec::<RadrootsOrderRevisionDecisionRecord>::new(), + fulfillments: vec![RadrootsOrderFulfillmentRecord { + event_id: test_event_id_char('3'), author_pubkey: test_pubkey(fixture.seller_pubkey.as_str()), counterparty_pubkey: test_pubkey(fixture.buyer_pubkey.as_str()), root_event_id: existing_request.request_event_id.clone(), - prev_event_id: existing_request.request_event_id.clone(), - payload: existing_decision_payload, - }, - proposed_accept_decision_record(&request).expect("proposed accept decision"), - ], - Vec::<RadrootsOrderRevisionProposalRecord>::new(), - Vec::<RadrootsOrderRevisionDecisionRecord>::new(), - vec![RadrootsOrderFulfillmentRecord { - event_id: test_event_id_char('3'), - author_pubkey: test_pubkey(fixture.seller_pubkey.as_str()), - counterparty_pubkey: test_pubkey(fixture.buyer_pubkey.as_str()), - root_event_id: existing_request.request_event_id.clone(), - prev_event_id: existing_decision_event_id, - payload: RadrootsOrderFulfillmentUpdate { - order_id: existing_request.order_id.clone(), - listing_addr: existing_request.listing_addr.clone(), - buyer_pubkey: existing_request.buyer_pubkey.clone(), - seller_pubkey: existing_request.seller_pubkey.clone(), - status: RadrootsOrderFulfillmentState::SellerCancelled, - }, - }], - Vec::<RadrootsOrderCancellationRecord>::new(), - Vec::<RadrootsOrderReceiptRecord>::new(), + prev_event_id: existing_decision_event_id, + payload: RadrootsOrderFulfillmentUpdate { + order_id: existing_request.order_id.clone(), + listing_addr: existing_request.listing_addr.clone(), + buyer_pubkey: existing_request.buyer_pubkey.clone(), + seller_pubkey: existing_request.seller_pubkey.clone(), + status: RadrootsOrderFulfillmentState::SellerCancelled, + }, + }], + cancellations: Vec::<RadrootsOrderCancellationRecord>::new(), + receipts: Vec::<RadrootsOrderReceiptRecord>::new(), + }, ); let args = OrderDecisionArgs { key: fixture.order_id.clone(), diff --git a/src/runtime/signer.rs b/src/runtime/signer.rs @@ -146,11 +146,11 @@ fn resolve_local_signer_status(config: &RuntimeConfig) -> SignerStatusView { match crate::runtime::account::resolved_account_signing_status(config) { Ok(RadrootsNostrAccountStatus::Ready { account }) => { let capability = RadrootsNostrSignerCapability::LocalAccount( - RadrootsNostrLocalSignerCapability::new( + Box::new(RadrootsNostrLocalSignerCapability::new( account.account_id.clone(), account.public_identity.clone(), RadrootsNostrLocalSignerAvailability::SecretBacked, - ), + )), ); let local = capability .local_account()