lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

commit 575fc38393473a20587457b59689e57824cec057
parent 7364cd90f8c1760f1a8cafd72528e1bf8b8798ad
Author: triesap <tyson@radroots.org>
Date:   Fri, 31 Jul 2026 10:57:58 +0000

sdk: consume the opaque local Nostr signer

- Replace upstream keypair construction in local signer examples and tests.
- Derive local signer identity only through the canonical public-key accessor.
- Keep local and remote test key ownership separate and entirely in memory.
- Preserve configured signing, progress, trade, and runtime consumer coverage.

Diffstat:
Mcrates/sdk/examples/runtime_local.rs | 7+++----
Mcrates/sdk/examples/sdk_v1_local_enqueue_and_mock_sync.rs | 7+++----
Mcrates/sdk/tests/unit/signer_provider_tests.rs | 54+++++++++++++++++++++++++++++++++++++++++-------------
Mcrates/sdk/tests/unit/trade_runtime_tests.rs | 7+++----
4 files changed, 50 insertions(+), 25 deletions(-)

diff --git a/crates/sdk/examples/runtime_local.rs b/crates/sdk/examples/runtime_local.rs @@ -7,7 +7,6 @@ use radroots_event::listing::operational::{ OperationalListingDeliveryMethod, OperationalListingProduct, OperationalListingPublicLocation, OperationalListingStatus, }; -use radroots_nostr::prelude::RadrootsNostrKeys; use radroots_nostr::signing::LocalSigner; use radroots_sdk::{ ListingPreparePublishRequest, NostrRelayUrlPolicy, PushOutboxRequest, RadrootsClient, @@ -20,9 +19,9 @@ const RELAY: &str = "wss://relay.example.com"; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - let keys = RadrootsNostrKeys::generate(); - let seller = keys.public_key().to_hex(); - let signer = RadrootsSdkLocalKeySigner::from_signer(LocalSigner::new(keys), seller.as_str())?; + let signer = LocalSigner::generate()?; + let seller = signer.public_key().to_hex(); + let signer = RadrootsSdkLocalKeySigner::from_signer(signer, seller.as_str())?; let sdk = RadrootsClient::builder() .fixed_clock(RadrootsSdkTimestamp::from_unix_seconds(1_700_000_000)) .signer_provider(RadrootsSdkSignerProvider::LocalKey(signer)) diff --git a/crates/sdk/examples/sdk_v1_local_enqueue_and_mock_sync.rs b/crates/sdk/examples/sdk_v1_local_enqueue_and_mock_sync.rs @@ -7,7 +7,6 @@ use radroots_event::listing::operational::{ OperationalListingDeliveryMethod, OperationalListingProduct, OperationalListingPublicLocation, OperationalListingStatus, }; -use radroots_nostr::prelude::RadrootsNostrKeys; use radroots_nostr::signing::LocalSigner; use radroots_sdk::{ ListingPreparePublishRequest, NostrRelayUrlPolicy, PushOutboxRequest, RadrootsClient, @@ -21,9 +20,9 @@ const LOCAL_RELAY: &str = "ws://localhost:7777"; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { - let keys = RadrootsNostrKeys::generate(); - let seller = keys.public_key().to_hex(); - let signer = RadrootsSdkLocalKeySigner::from_signer(LocalSigner::new(keys), seller.as_str())?; + let signer = LocalSigner::generate()?; + let seller = signer.public_key().to_hex(); + let signer = RadrootsSdkLocalKeySigner::from_signer(signer, seller.as_str())?; let sdk = RadrootsClient::builder() .fixed_clock(RadrootsSdkTimestamp::from_unix_seconds(1_700_000_000)) .signer_provider(RadrootsSdkSignerProvider::LocalKey(signer)) diff --git a/crates/sdk/tests/unit/signer_provider_tests.rs b/crates/sdk/tests/unit/signer_provider_tests.rs @@ -20,6 +20,10 @@ use uuid::Uuid; static USER_KEYS: LazyLock<RadrootsNostrKeys> = LazyLock::new(RadrootsNostrKeys::generate); static USER_PUBLIC_KEY: LazyLock<String> = LazyLock::new(|| USER_KEYS.public_key().to_hex()); +static LOCAL_SIGNER: LazyLock<Arc<LocalSigner>> = + LazyLock::new(|| Arc::new(LocalSigner::generate().expect("generated local signer"))); +static LOCAL_SIGNER_PUBLIC_KEY: LazyLock<String> = + LazyLock::new(|| LOCAL_SIGNER.public_key().to_hex()); static REMOTE_KEYS: LazyLock<RadrootsNostrKeys> = LazyLock::new(RadrootsNostrKeys::generate); static CLIENT_KEYS: LazyLock<RadrootsNostrKeys> = LazyLock::new(RadrootsNostrKeys::generate); @@ -31,9 +35,13 @@ fn user_pubkey() -> &'static str { USER_PUBLIC_KEY.as_str() } -fn local_sdk_signer(keys: RadrootsNostrKeys) -> RadrootsSdkLocalKeySigner { - let signer_pubkey = keys.public_key().to_hex(); - RadrootsSdkLocalKeySigner::from_signer(LocalSigner::new(keys), signer_pubkey) +fn local_signer_pubkey() -> &'static str { + LOCAL_SIGNER_PUBLIC_KEY.as_str() +} + +fn local_sdk_signer() -> RadrootsSdkLocalKeySigner { + let signer: Arc<RadrootsSdkLocalSignerCapability> = LOCAL_SIGNER.clone(); + RadrootsSdkLocalKeySigner::from_shared_signer(signer, LOCAL_SIGNER.public_key()) .expect("sdk local signer") } @@ -54,6 +62,15 @@ fn actor() -> Actor { .expect("actor") } +fn local_actor() -> Actor { + Actor::from_public_key_hex( + local_signer_pubkey(), + ActorSource::ExplicitPublicKey, + [AuthorRole::Farmer], + ) + .expect("local signer actor") +} + fn frozen_draft() -> EventDraft { frozen_draft_with( "radroots.farm.profile.v1", @@ -65,6 +82,17 @@ fn frozen_draft() -> EventDraft { ) } +fn local_frozen_draft() -> EventDraft { + frozen_draft_with( + "radroots.farm.profile.v1", + local_signer_pubkey(), + KIND_FARM, + 1_700_000_000, + vec![vec!["d".to_owned(), "sdk-local-signer".to_owned()]], + "{}", + ) +} + fn frozen_draft_with( contract_id: &str, pubkey: &str, @@ -235,10 +263,10 @@ impl RadrootsSdkNip46Transport for HangingNip46Transport { #[tokio::test] async fn local_key_provider_signs_authorized_frozen_draft() { - let signer = local_sdk_signer(user_keys()); + let signer = local_sdk_signer(); let provider = RadrootsSdkSignerProvider::LocalKey(signer.clone()); - let draft = frozen_draft(); - let actor = actor(); + let draft = local_frozen_draft(); + let actor = local_actor(); let mut progress = Vec::new(); let receipt = provider @@ -257,7 +285,7 @@ async fn local_key_provider_signs_authorized_frozen_draft() { assert_eq!(provider.status(), signer.status()); assert!(provider.capability().nip46_permissions.is_empty()); assert_eq!(receipt.mode, RadrootsSdkSignerMode::LocalKey); - assert_eq!(receipt.signer_pubkey, user_pubkey()); + assert_eq!(receipt.signer_pubkey, local_signer_pubkey()); assert_eq!(receipt.signed_event_id, draft.expected_event_id_hex()); assert_eq!( progress, @@ -274,9 +302,9 @@ async fn local_key_provider_signs_authorized_frozen_draft() { #[tokio::test] async fn local_key_provider_returns_progress_sink_errors_without_transport_state() { - let signer = local_sdk_signer(user_keys()); - let draft = frozen_draft(); - let actor = actor(); + let signer = local_sdk_signer(); + let draft = local_frozen_draft(); + let actor = local_actor(); let wrong_actor = Actor::from_public_key_hex( &"a".repeat(64), ActorSource::ExplicitPublicKey, @@ -1010,8 +1038,8 @@ async fn sdk_builder_installs_configured_signer_provider() { .build() .await .expect("empty sdk"); - let draft = frozen_draft(); - let signer_actor = actor(); + let draft = local_frozen_draft(); + let signer_actor = local_actor(); let error = empty_sdk .sign_with_configured_signer(RadrootsSdkSignRequest::new( "farm.publish", @@ -1026,7 +1054,7 @@ async fn sdk_builder_installs_configured_signer_provider() { if mode == "configured" && reason.contains("no SDK signer provider") )); - let signer = local_sdk_signer(user_keys()); + let signer = local_sdk_signer(); let sdk = crate::RadrootsClient::builder() .signer_provider(RadrootsSdkSignerProvider::LocalKey(signer)) .build() diff --git a/crates/sdk/tests/unit/trade_runtime_tests.rs b/crates/sdk/tests/unit/trade_runtime_tests.rs @@ -18,7 +18,6 @@ use radroots_event::{ }, }; use radroots_identity::PublicKey; -use radroots_nostr::prelude::RadrootsNostrKeys; use radroots_nostr::signing::LocalSigner; use radroots_signing::{Actor, actor::ActorSource}; use radroots_trade::model::RadrootsTradePrivateTermsStateV1; @@ -37,9 +36,9 @@ fn trade_id() -> TradeId { } fn local_signer() -> (String, LocalSigner) { - let keys = RadrootsNostrKeys::generate(); - let pubkey = keys.public_key().to_hex(); - (pubkey, LocalSigner::new(keys)) + let signer = LocalSigner::generate().expect("local signer"); + let pubkey = signer.public_key().to_hex(); + (pubkey, signer) } #[tokio::test]