lib

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

commit 2e9ebc7298ec0f4b0bb3e340b79954d595d6afed
parent cd92bb6b9df4b75730bffdb96cebdccb52a1f990
Author: triesap <tyson@radroots.org>
Date:   Fri, 31 Jul 2026 20:32:53 +0000

nostr-connect: migrate workspace consumers

- move remote signer tooling to canonical protocol modules and types
- remove hidden-prelude and prefixed compatibility imports
- enforce the final consumer boundary with source assertions
- verify signer tests, strict Clippy, and architecture policy

Diffstat:
Mcrates/nostr_connect/tests/package_boundary.rs | 30++++++++++++++++++++++++++++++
Mcrates/nostr_signer/src/backend.rs | 109++++++++++++++++++++++++++-----------------------------------------------------
Mcrates/nostr_signer/src/capability.rs | 35++++++++++-------------------------
Mcrates/nostr_signer/src/error.rs | 9+++------
Mcrates/nostr_signer/src/evaluation.rs | 167++++++++++++++++++++++++++++++++++---------------------------------------------
Mcrates/nostr_signer/src/manager.rs | 225+++++++++++++++++++++++++++++--------------------------------------------------
Mcrates/nostr_signer/src/model.rs | 103+++++++++++++++++++++++++++----------------------------------------------------
Mcrates/nostr_signer/src/nip46.rs | 566++++++++++++++++++++++++++++++++++---------------------------------------------
Mcrates/nostr_signer/src/store.rs | 50++++++++++++++++++--------------------------------
9 files changed, 529 insertions(+), 765 deletions(-)

diff --git a/crates/nostr_connect/tests/package_boundary.rs b/crates/nostr_connect/tests/package_boundary.rs @@ -12,6 +12,16 @@ const PERMISSION: &str = include_str!("../src/permission.rs"); const ROOT: &str = include_str!("../src/lib.rs"); const SERVER: &str = include_str!("../src/server.rs"); const URI: &str = include_str!("../src/uri.rs"); +const SIGNER_CONSUMERS: &[&str] = &[ + include_str!("../../nostr_signer/src/backend.rs"), + include_str!("../../nostr_signer/src/capability.rs"), + include_str!("../../nostr_signer/src/error.rs"), + include_str!("../../nostr_signer/src/evaluation.rs"), + include_str!("../../nostr_signer/src/manager.rs"), + include_str!("../../nostr_signer/src/model.rs"), + include_str!("../../nostr_signer/src/nip46.rs"), + include_str!("../../nostr_signer/src/store.rs"), +]; #[test] fn manifest_has_final_identity_feature_vocabulary_and_radroots_dependencies() { @@ -239,6 +249,26 @@ fn protocol_transport_boundary_has_no_relay_pool_or_runtime_owner() { assert!(CLIENT.contains("T: Transport + ?Sized")); } +#[test] +fn workspace_signer_consumers_use_only_final_protocol_paths() { + for source in SIGNER_CONSUMERS { + for retired in [ + "radroots_nostr_connect::prelude", + "RadrootsNostrConnectClient", + "RadrootsNostrConnectMethod", + "RadrootsNostrConnectPermission", + "RadrootsNostrConnectRequest", + "RadrootsNostrConnectResponse", + "RADROOTS_NOSTR_CONNECT_", + ] { + assert!( + !source.contains(retired), + "workspace signer consumer retains retired protocol surface `{retired}`" + ); + } + } +} + fn table_keys<'a>(source: &'a str, header: &str) -> BTreeSet<&'a str> { let Some((_, tail)) = source.split_once(header) else { panic!("manifest is missing {header}"); diff --git a/crates/nostr_signer/src/backend.rs b/crates/nostr_signer/src/backend.rs @@ -17,10 +17,7 @@ use crate::model::{ }; use nostr::{Event, Keys, PublicKey, RelayUrl, UnsignedEvent}; use radroots_identity::{AccountId, PublicIdentity, PublicKey as IdentityPublicKey}; -use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectMethod, RadrootsNostrConnectPermissions, RadrootsNostrConnectRequest, - RadrootsNostrConnectRequestMessage, -}; +use radroots_nostr_connect::{Method, Request, message::RequestMessage, permission::Permissions}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -102,7 +99,7 @@ pub trait RadrootsNostrSignerBackend: Send + Sync { fn evaluate_connect_request( &self, client_public_key: PublicKey, - request: RadrootsNostrConnectRequest, + request: Request, ) -> Result<RadrootsNostrSignerConnectEvaluation, RadrootsNostrSignerError>; fn register_connection( @@ -113,13 +110,13 @@ pub trait RadrootsNostrSignerBackend: Send + Sync { fn set_granted_permissions( &self, connection_id: &RadrootsNostrSignerConnectionId, - granted_permissions: RadrootsNostrConnectPermissions, + granted_permissions: Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError>; fn approve_connection( &self, connection_id: &RadrootsNostrSignerConnectionId, - granted_permissions: RadrootsNostrConnectPermissions, + granted_permissions: Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError>; fn reject_connection( @@ -149,7 +146,7 @@ pub trait RadrootsNostrSignerBackend: Send + Sync { fn set_pending_request( &self, connection_id: &RadrootsNostrSignerConnectionId, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError>; fn authorize_auth_challenge( @@ -201,7 +198,7 @@ pub trait RadrootsNostrSignerBackend: Send + Sync { fn evaluate_request( &self, connection_id: &RadrootsNostrSignerConnectionId, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerRequestEvaluation, RadrootsNostrSignerError>; fn evaluate_auth_replay_publish_workflow( @@ -213,7 +210,7 @@ pub trait RadrootsNostrSignerBackend: Send + Sync { &self, connection_id: &RadrootsNostrSignerConnectionId, request_id: &str, - method: RadrootsNostrConnectMethod, + method: Method, decision: RadrootsNostrSignerRequestDecision, message: Option<String>, ) -> Result<RadrootsNostrSignerRequestAuditRecord, RadrootsNostrSignerError>; @@ -438,7 +435,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { fn evaluate_connect_request( &self, client_public_key: PublicKey, - request: RadrootsNostrConnectRequest, + request: Request, ) -> Result<RadrootsNostrSignerConnectEvaluation, RadrootsNostrSignerError> { self.manager .evaluate_connect_request(client_public_key, request) @@ -454,7 +451,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { fn set_granted_permissions( &self, connection_id: &RadrootsNostrSignerConnectionId, - granted_permissions: RadrootsNostrConnectPermissions, + granted_permissions: Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { self.manager .set_granted_permissions(connection_id, granted_permissions) @@ -463,7 +460,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { fn approve_connection( &self, connection_id: &RadrootsNostrSignerConnectionId, - granted_permissions: RadrootsNostrConnectPermissions, + granted_permissions: Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { self.manager .approve_connection(connection_id, granted_permissions) @@ -504,7 +501,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { fn set_pending_request( &self, connection_id: &RadrootsNostrSignerConnectionId, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { self.manager .set_pending_request(connection_id, request_message) @@ -592,7 +589,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { fn evaluate_request( &self, connection_id: &RadrootsNostrSignerConnectionId, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerRequestEvaluation, RadrootsNostrSignerError> { self.manager .evaluate_request(connection_id, request_message) @@ -610,7 +607,7 @@ impl RadrootsNostrSignerBackend for RadrootsNostrEmbeddedSignerBackend { &self, connection_id: &RadrootsNostrSignerConnectionId, request_id: &str, - method: RadrootsNostrConnectMethod, + method: Method, decision: RadrootsNostrSignerRequestDecision, message: Option<String>, ) -> Result<RadrootsNostrSignerRequestAuditRecord, RadrootsNostrSignerError> { @@ -670,10 +667,7 @@ mod tests { }; use nostr::{EventBuilder, EventId, Keys, Kind}; use radroots_identity::{PublicIdentity, PublicKey as IdentityPublicKey}; - use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, RadrootsNostrConnectRequest, - RadrootsNostrConnectRequestMessage, - }; + use radroots_nostr_connect::{Method, Permission, Request, message::RequestMessage}; use std::panic::{AssertUnwindSafe, catch_unwind}; use std::sync::Arc; use std::sync::RwLock; @@ -849,7 +843,7 @@ mod tests { fn evaluate_connect_request( &self, _client_public_key: nostr::PublicKey, - _request: RadrootsNostrConnectRequest, + _request: Request, ) -> Result<RadrootsNostrSignerConnectEvaluation, RadrootsNostrSignerError> { unreachable!("evaluate_connect_request not used in tests") } @@ -864,7 +858,7 @@ mod tests { fn set_granted_permissions( &self, _connection_id: &crate::model::RadrootsNostrSignerConnectionId, - _granted_permissions: radroots_nostr_connect::prelude::RadrootsNostrConnectPermissions, + _granted_permissions: radroots_nostr_connect::permission::Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { unreachable!("set_granted_permissions not used in tests") } @@ -872,7 +866,7 @@ mod tests { fn approve_connection( &self, _connection_id: &crate::model::RadrootsNostrSignerConnectionId, - _granted_permissions: radroots_nostr_connect::prelude::RadrootsNostrConnectPermissions, + _granted_permissions: radroots_nostr_connect::permission::Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { unreachable!("approve_connection not used in tests") } @@ -912,7 +906,7 @@ mod tests { fn set_pending_request( &self, _connection_id: &crate::model::RadrootsNostrSignerConnectionId, - _request_message: RadrootsNostrConnectRequestMessage, + _request_message: RequestMessage, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { unreachable!("set_pending_request not used in tests") } @@ -985,7 +979,7 @@ mod tests { fn evaluate_request( &self, _connection_id: &crate::model::RadrootsNostrSignerConnectionId, - _request_message: RadrootsNostrConnectRequestMessage, + _request_message: RequestMessage, ) -> Result<crate::evaluation::RadrootsNostrSignerRequestEvaluation, RadrootsNostrSignerError> { unreachable!("evaluate_request not used in tests") @@ -1003,7 +997,7 @@ mod tests { &self, _connection_id: &crate::model::RadrootsNostrSignerConnectionId, _request_id: &str, - _method: RadrootsNostrConnectMethod, + _method: Method, _decision: RadrootsNostrSignerRequestDecision, _message: Option<String>, ) -> Result<crate::model::RadrootsNostrSignerRequestAuditRecord, RadrootsNostrSignerError> @@ -1302,13 +1296,10 @@ mod tests { let evaluation = backend .evaluate_connect_request( synthetic_public_key(0x93), - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: embedded_public_identity(&identity).public_key(), secret: Some("connect-secret".into()), - requested_permissions: vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), + requested_permissions: vec![Permission::new(Method::Ping)].into(), client_metadata: None, }, ) @@ -1353,12 +1344,12 @@ mod tests { .record_request( &connection.connection_id, "req-1", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Allowed, None, ) .expect("record request"); - assert_eq!(audit.method, RadrootsNostrConnectMethod::Ping); + assert_eq!(audit.method, Method::Ping); } #[test] @@ -1371,13 +1362,10 @@ mod tests { let connect_evaluation = backend_trait .evaluate_connect_request( synthetic_public_key(0xa1), - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: embedded_public_identity(&identity).public_key(), secret: Some("connect-secret-2".into()), - requested_permissions: vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), + requested_permissions: vec![Permission::new(Method::Ping)].into(), client_metadata: None, }, ) @@ -1433,10 +1421,7 @@ mod tests { let evaluation = backend_trait .evaluate_request( &connection.connection_id, - RadrootsNostrConnectRequestMessage::new( - "req-ping", - RadrootsNostrConnectRequest::Ping, - ), + RequestMessage::new("req-ping", Request::Ping), ) .expect("evaluate request"); assert!(matches!( @@ -1455,20 +1440,12 @@ mod tests { synthetic_public_key(0xab), synthetic_public_identity(0xac), ) - .with_requested_permissions( - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), - ) + .with_requested_permissions(vec![Permission::new(Method::Ping)].into()) .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser), ) .expect("register pending connection"); - let granted_permissions: radroots_nostr_connect::prelude::RadrootsNostrConnectPermissions = - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(); + let granted_permissions: radroots_nostr_connect::permission::Permissions = + vec![Permission::new(Method::Ping)].into(); let granted = backend_trait .set_granted_permissions( &pending_connection.connection_id, @@ -1530,7 +1507,7 @@ mod tests { .record_request( &connection.connection_id, "req-audit", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Allowed, None, ) @@ -1571,12 +1548,7 @@ mod tests { synthetic_public_key(0xa7), synthetic_public_identity(0xa8), ) - .with_requested_permissions( - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), - ), + .with_requested_permissions(vec![Permission::new(Method::Ping)].into()), ) .expect("register auth connection"); backend_trait @@ -1588,10 +1560,7 @@ mod tests { let pending = backend_trait .set_pending_request( &auth_connection.connection_id, - RadrootsNostrConnectRequestMessage::new( - "req-auth-replay", - RadrootsNostrConnectRequest::Ping, - ), + RequestMessage::new("req-auth-replay", Request::Ping), ) .expect("set pending request"); assert!(pending.pending_request.is_some()); @@ -1665,12 +1634,7 @@ mod tests { synthetic_public_key(0x97), synthetic_public_identity(0x98), ) - .with_requested_permissions( - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), - ), + .with_requested_permissions(vec![Permission::new(Method::Ping)].into()), ) .expect("register connection"); backend @@ -1679,10 +1643,7 @@ mod tests { backend .set_pending_request( &connection.connection_id, - RadrootsNostrConnectRequestMessage::new( - "req-auth", - RadrootsNostrConnectRequest::Ping, - ), + RequestMessage::new("req-auth", Request::Ping), ) .expect("set pending request"); diff --git a/crates/nostr_signer/src/capability.rs b/crates/nostr_signer/src/capability.rs @@ -1,7 +1,7 @@ use crate::model::{RadrootsNostrSignerConnectionId, RadrootsNostrSignerConnectionRecord}; use nostr::RelayUrl; use radroots_identity::{AccountId, PublicIdentity}; -use radroots_nostr_connect::prelude::RadrootsNostrConnectPermissions; +use radroots_nostr_connect::permission::Permissions; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] @@ -23,7 +23,7 @@ pub struct RadrootsNostrRemoteSessionSignerCapability { pub signer_identity: PublicIdentity, pub user_identity: PublicIdentity, pub relays: Vec<RelayUrl>, - pub permissions: RadrootsNostrConnectPermissions, + pub permissions: Permissions, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -65,7 +65,7 @@ impl RadrootsNostrRemoteSessionSignerCapability { signer_identity, user_identity, relays: Vec::new(), - permissions: RadrootsNostrConnectPermissions::default(), + permissions: Permissions::default(), } } @@ -74,7 +74,7 @@ impl RadrootsNostrRemoteSessionSignerCapability { self } - pub fn with_permissions(mut self, permissions: RadrootsNostrConnectPermissions) -> Self { + pub fn with_permissions(mut self, permissions: Permissions) -> Self { self.permissions = permissions; self } @@ -170,9 +170,7 @@ mod tests { fixture_diego_public_key, primary_relay, secondary_relay, }; use radroots_identity::PublicIdentity; - use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, - }; + use radroots_nostr_connect::{Method, Permission}; fn assert_public_identity_matches(actual: &PublicIdentity, expected: &PublicIdentity) { assert_eq!(actual, expected); @@ -210,12 +208,7 @@ mod tests { fixture_diego_public_key(), user_identity.clone(), ) - .with_requested_permissions( - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), - ) + .with_requested_permissions(vec![Permission::new(Method::Ping)].into()) .with_relays(vec![primary_relay()]), 1, ); @@ -238,12 +231,7 @@ mod tests { fixture_alice_identity(), fixture_bob_identity(), ) - .with_permissions( - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::SwitchRelays, - )] - .into(), - ) + .with_permissions(vec![Permission::new(Method::SwitchRelays)].into()) .with_relays(vec![primary_relay()]); assert_eq!(capability.permissions.as_slice().len(), 1); @@ -300,12 +288,9 @@ mod tests { .with_relays(remote.relays.clone()) .with_permissions(remote.permissions.clone()); let remote_changed_relays = remote.clone().with_relays(vec![secondary_relay()]); - let remote_changed_permissions = remote.clone().with_permissions( - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping, - )] - .into(), - ); + let remote_changed_permissions = remote + .clone() + .with_permissions(vec![Permission::new(Method::Ping)].into()); let mut remote_changed_signer = remote.clone(); remote_changed_signer.signer_identity = fixture_alice_identity(); let mut remote_changed_user = remote.clone(); diff --git a/crates/nostr_signer/src/error.rs b/crates/nostr_signer/src/error.rs @@ -82,8 +82,8 @@ impl From<radroots_nostr::Error> for RadrootsNostrSignerError { } } -impl From<radroots_nostr_connect::prelude::RadrootsNostrConnectError> for RadrootsNostrSignerError { - fn from(value: radroots_nostr_connect::prelude::RadrootsNostrConnectError) -> Self { +impl From<radroots_nostr_connect::Error> for RadrootsNostrSignerError { + fn from(value: radroots_nostr_connect::Error) -> Self { Self::InvalidState(value.to_string()) } } @@ -132,10 +132,7 @@ mod tests { #[test] fn converts_nostr_connect_error() { let converted: RadrootsNostrSignerError = - radroots_nostr_connect::prelude::RadrootsNostrConnectError::InvalidMethod( - "bad".to_string(), - ) - .into(); + radroots_nostr_connect::Error::InvalidMethod("bad".to_string()).into(); assert!(converted.to_string().starts_with("invalid signer state:")); } diff --git a/crates/nostr_signer/src/evaluation.rs b/crates/nostr_signer/src/evaluation.rs @@ -6,12 +6,11 @@ use crate::model::{ }; use nostr::PublicKey; use radroots_identity::PublicIdentity; -use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, - RadrootsNostrConnectPermissions, RadrootsNostrConnectRemoteSessionCapability, - RadrootsNostrConnectRequest, -}; use radroots_nostr_connect::uri::RelayUrl as ConnectRelayUrl; +use radroots_nostr_connect::{ + Method, Permission, Request, message::RemoteSessionCapability, permission::Permissions, + uri::ClientMetadata, +}; #[derive(Debug, Clone)] pub enum RadrootsNostrSignerSessionLookup { @@ -24,8 +23,8 @@ pub enum RadrootsNostrSignerSessionLookup { pub struct RadrootsNostrSignerConnectProposal { pub client_public_key: PublicKey, pub connect_secret: Option<String>, - pub client_metadata: Option<RadrootsNostrConnectClientMetadata>, - pub requested_permissions: RadrootsNostrConnectPermissions, + pub client_metadata: Option<ClientMetadata>, + pub requested_permissions: Permissions, } #[derive(Debug, Clone)] @@ -39,14 +38,14 @@ pub enum RadrootsNostrSignerRequestResponseHint { None, Pong, UserPublicKey(radroots_identity::PublicKey), - RemoteSessionCapability(RadrootsNostrConnectRemoteSessionCapability), + RemoteSessionCapability(RemoteSessionCapability), RelayList(Vec<ConnectRelayUrl>), } #[derive(Debug, Clone, PartialEq, Eq)] pub enum RadrootsNostrSignerRequestAction { Allowed { - required_permission: Option<RadrootsNostrConnectPermission>, + required_permission: Option<Permission>, response_hint: RadrootsNostrSignerRequestResponseHint, }, Denied { @@ -61,7 +60,7 @@ pub enum RadrootsNostrSignerRequestAction { #[derive(Debug, Clone)] pub struct RadrootsNostrSignerRequestEvaluation { pub request_id: RadrootsNostrSignerRequestId, - pub method: RadrootsNostrConnectMethod, + pub method: Method, pub connection: RadrootsNostrSignerConnectionRecord, pub audit: RadrootsNostrSignerRequestAuditRecord, pub action: RadrootsNostrSignerRequestAction, @@ -104,15 +103,13 @@ impl RadrootsNostrSignerRequestAction { } } -pub(crate) fn required_permission_for_request( - request: &RadrootsNostrConnectRequest, -) -> Option<RadrootsNostrConnectPermission> { +pub(crate) fn required_permission_for_request(request: &Request) -> Option<Permission> { radroots_nostr_connect::server::required_permission(request) } pub(crate) fn request_allowed_by_permissions( - granted_permissions: &RadrootsNostrConnectPermissions, - request: &RadrootsNostrConnectRequest, + granted_permissions: &Permissions, + request: &Request, ) -> bool { let Some(required_permission) = required_permission_for_request(request) else { return true; @@ -126,17 +123,15 @@ pub(crate) fn request_allowed_by_permissions( pub(crate) fn response_hint_for_request( connection: &RadrootsNostrSignerConnectionRecord, - request: &RadrootsNostrConnectRequest, + request: &Request, ) -> Result<RadrootsNostrSignerRequestResponseHint, RadrootsNostrSignerError> { match request { - RadrootsNostrConnectRequest::GetPublicKey => { - Ok(RadrootsNostrSignerRequestResponseHint::UserPublicKey( - identity_public_key(&connection.user_identity)?, - )) - } - RadrootsNostrConnectRequest::GetSessionCapability => Ok( + Request::GetPublicKey => Ok(RadrootsNostrSignerRequestResponseHint::UserPublicKey( + identity_public_key(&connection.user_identity)?, + )), + Request::GetSessionCapability => Ok( RadrootsNostrSignerRequestResponseHint::RemoteSessionCapability( - RadrootsNostrConnectRemoteSessionCapability { + RemoteSessionCapability { user_public_key: identity_public_key(&connection.user_identity)?, relays: connection .relays @@ -147,24 +142,19 @@ pub(crate) fn response_hint_for_request( }, ), ), - RadrootsNostrConnectRequest::Ping => Ok(RadrootsNostrSignerRequestResponseHint::Pong), - RadrootsNostrConnectRequest::SwitchRelays => { - Ok(RadrootsNostrSignerRequestResponseHint::RelayList( - connection - .relays - .iter() - .map(|relay| ConnectRelayUrl::parse(&relay.to_string())) - .collect::<Result<Vec<_>, _>>()?, - )) - } + Request::Ping => Ok(RadrootsNostrSignerRequestResponseHint::Pong), + Request::SwitchRelays => Ok(RadrootsNostrSignerRequestResponseHint::RelayList( + connection + .relays + .iter() + .map(|relay| ConnectRelayUrl::parse(&relay.to_string())) + .collect::<Result<Vec<_>, _>>()?, + )), _ => Ok(RadrootsNostrSignerRequestResponseHint::None), } } -fn permission_matches( - granted_permission: &RadrootsNostrConnectPermission, - required_permission: &RadrootsNostrConnectPermission, -) -> bool { +fn permission_matches(granted_permission: &Permission, required_permission: &Permission) -> bool { if granted_permission.method != required_permission.method { return false; } @@ -174,8 +164,8 @@ fn permission_matches( granted_permission.parameter.as_deref(), required_permission.parameter.as_deref(), ) { - (RadrootsNostrConnectMethod::SignEvent, None, _) => true, - (RadrootsNostrConnectMethod::SignEvent, Some(parameter), Some(required)) => { + (Method::SignEvent, None, _) => true, + (Method::SignEvent, Some(parameter), Some(required)) => { parameter == required || parameter == sign_event_kind_suffix(required) } (_, None, _) => true, @@ -203,7 +193,7 @@ mod tests { fixture_carol_public_key, fixture_diego_identity, primary_relay, synthetic_public_key, }; use nostr::{PublicKey, Timestamp}; - use radroots_nostr_connect::prelude::UnsignedEvent as ConnectUnsignedEvent; + use radroots_nostr_connect::message::UnsignedEvent as ConnectUnsignedEvent; use serde_json::json; fn public_key(index: u32) -> PublicKey { @@ -277,7 +267,7 @@ mod tests { #[cfg_attr(coverage_nightly, coverage(off))] fn assert_response_hint_remote_session_capability( hint: RadrootsNostrSignerRequestResponseHint, - expected_permissions: RadrootsNostrConnectPermissions, + expected_permissions: Permissions, ) { match hint { RadrootsNostrSignerRequestResponseHint::RemoteSessionCapability(capability) => { @@ -292,16 +282,12 @@ mod tests { #[test] fn connect_proposal_builds_connection_draft() { - let requested_permissions: RadrootsNostrConnectPermissions = - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Nip04Encrypt, - )] - .into(); + let requested_permissions: Permissions = vec![Permission::new(Method::Nip04Encrypt)].into(); let proposal = RadrootsNostrSignerConnectProposal { client_public_key: public_key(5), connect_secret: Some("secret".into()), - client_metadata: Some(RadrootsNostrConnectClientMetadata { - requested_permissions: RadrootsNostrConnectPermissions::default(), + client_metadata: Some(ClientMetadata { + requested_permissions: Permissions::default(), name: Some("Example Client".into()), url: Some("https://client.example.com/".into()), image: None, @@ -325,7 +311,7 @@ mod tests { client_public_key: public_key(7), connect_secret: None, client_metadata: None, - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), } .into_connection_draft(fixture_bob_identity()); assert!(no_secret.connect_secret.is_none()); @@ -343,22 +329,19 @@ mod tests { ) .expect("challenge"), pending_request: crate::model::RadrootsNostrSignerPendingRequest::new( - radroots_nostr_connect::prelude::RadrootsNostrConnectRequestMessage::new( - "req-1", - RadrootsNostrConnectRequest::Ping, - ), + radroots_nostr_connect::message::RequestMessage::new("req-1", Request::Ping), 1, ) .expect("pending"), }; let evaluation = RadrootsNostrSignerRequestEvaluation { request_id: RadrootsNostrSignerRequestId::new_v7(), - method: RadrootsNostrConnectMethod::Ping, + method: Method::Ping, connection: connection(), audit: crate::model::RadrootsNostrSignerRequestAuditRecord::new( RadrootsNostrSignerRequestId::new_v7(), crate::model::RadrootsNostrSignerConnectionId::new_v7(), - RadrootsNostrConnectMethod::Ping, + Method::Ping, crate::model::RadrootsNostrSignerRequestDecision::Denied, Some("unauthorized".into()), 1, @@ -382,63 +365,56 @@ mod tests { fn request_permission_matching_covers_generic_and_sign_event_forms() { let kind_one = unsigned_event(1); let kind_two = unsigned_event(2); - let sign_kind = RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "kind:1", - ); - let sign_numeric = RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "1", - ); - let sign_all = RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::SignEvent); - let nip44 = RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip44Encrypt); + let sign_kind = Permission::with_parameter(Method::SignEvent, "kind:1"); + let sign_numeric = Permission::with_parameter(Method::SignEvent, "1"); + let sign_all = Permission::new(Method::SignEvent); + let nip44 = Permission::new(Method::Nip44Encrypt); assert!(request_allowed_by_permissions( &vec![sign_kind.clone()].into(), - &RadrootsNostrConnectRequest::SignEvent(kind_one.clone()), + &Request::SignEvent(kind_one.clone()), )); assert!(request_allowed_by_permissions( &vec![sign_numeric].into(), - &RadrootsNostrConnectRequest::SignEvent(kind_one), + &Request::SignEvent(kind_one), )); assert!(request_allowed_by_permissions( &vec![sign_all].into(), - &RadrootsNostrConnectRequest::SignEvent(kind_two), + &Request::SignEvent(kind_two), )); assert!(!request_allowed_by_permissions( &vec![sign_kind, nip44].into(), - &RadrootsNostrConnectRequest::Nip04Encrypt { + &Request::Nip04Encrypt { public_key: connect_public_key(public_key(7)), plaintext: "hello".into(), }, )); assert!(request_allowed_by_permissions( - &RadrootsNostrConnectPermissions::default(), - &RadrootsNostrConnectRequest::Ping, + &Permissions::default(), + &Request::Ping, )); assert!(!request_allowed_by_permissions( - &vec![RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::custom("do_thing").expect("valid custom NIP-46 method"), + &vec![Permission::with_parameter( + Method::custom("do_thing").expect("valid custom NIP-46 method"), "scoped", )] .into(), - &RadrootsNostrConnectRequest::Custom { - method: RadrootsNostrConnectMethod::custom("do_thing") - .expect("valid custom NIP-46 method"), + &Request::Custom { + method: Method::custom("do_thing").expect("valid custom NIP-46 method"), params: vec!["value".into()], }, )); assert!(permission_matches( - &RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip04Encrypt), - &RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip04Encrypt), + &Permission::new(Method::Nip04Encrypt), + &Permission::new(Method::Nip04Encrypt), )); assert!(permission_matches( - &RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::custom("scoped").expect("valid custom NIP-46 method"), + &Permission::with_parameter( + Method::custom("scoped").expect("valid custom NIP-46 method"), "alpha", ), - &RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::custom("scoped").expect("valid custom NIP-46 method"), + &Permission::with_parameter( + Method::custom("scoped").expect("valid custom NIP-46 method"), "alpha", ), )); @@ -448,20 +424,19 @@ mod tests { fn required_permission_and_response_hint_cover_request_variants() { let connection = connection(); let public_key = public_key(8); - let connect = RadrootsNostrConnectRequest::Connect { + let connect = Request::Connect { remote_signer_public_key: connect_public_key(public_key), secret: Some("secret".into()), - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), client_metadata: None, }; - let ping = RadrootsNostrConnectRequest::Ping; - let get_public_key = RadrootsNostrConnectRequest::GetPublicKey; - let get_session_capability = RadrootsNostrConnectRequest::GetSessionCapability; - let switch_relays = RadrootsNostrConnectRequest::SwitchRelays; - let sign_event = RadrootsNostrConnectRequest::SignEvent(unsigned_event(7)); - let custom = RadrootsNostrConnectRequest::Custom { - method: RadrootsNostrConnectMethod::custom("do_thing") - .expect("valid custom NIP-46 method"), + let ping = Request::Ping; + let get_public_key = Request::GetPublicKey; + let get_session_capability = Request::GetSessionCapability; + let switch_relays = Request::SwitchRelays; + let sign_event = Request::SignEvent(unsigned_event(7)); + let custom = Request::Custom { + method: Method::custom("do_thing").expect("valid custom NIP-46 method"), params: vec!["a".into()], }; @@ -470,7 +445,7 @@ mod tests { assert!(required_permission_for_request(&get_public_key).is_none()); assert!(required_permission_for_request(&get_session_capability).is_none()); assert_eq!( - required_permission_for_request(&RadrootsNostrConnectRequest::Nip04Decrypt { + required_permission_for_request(&Request::Nip04Decrypt { public_key: connect_public_key(public_key), ciphertext: "cipher".into(), }) @@ -479,7 +454,7 @@ mod tests { "nip04_decrypt" ); assert_eq!( - required_permission_for_request(&RadrootsNostrConnectRequest::Nip44Encrypt { + required_permission_for_request(&Request::Nip44Encrypt { public_key: connect_public_key(public_key), plaintext: "hello".into(), }) @@ -488,7 +463,7 @@ mod tests { "nip44_encrypt" ); assert_eq!( - required_permission_for_request(&RadrootsNostrConnectRequest::Nip44Decrypt { + required_permission_for_request(&Request::Nip44Decrypt { public_key: connect_public_key(public_key), ciphertext: "cipher".into(), }) @@ -518,7 +493,7 @@ mod tests { assert_response_hint_none( response_hint_for_request( &connection, - &RadrootsNostrConnectRequest::Nip04Decrypt { + &Request::Nip04Decrypt { public_key: connect_public_key(public_key), ciphertext: "cipher".into(), }, diff --git a/crates/nostr_signer/src/manager.rs b/crates/nostr_signer/src/manager.rs @@ -20,10 +20,8 @@ use crate::model::{ use crate::store::{RadrootsNostrMemorySignerStore, RadrootsNostrSignerStore}; use nostr::{PublicKey, RelayUrl}; use radroots_identity::PublicIdentity; -use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, - RadrootsNostrConnectPermissions, RadrootsNostrConnectRequest, - RadrootsNostrConnectRequestMessage, +use radroots_nostr_connect::{ + Method, Request, message::RequestMessage, permission::Permissions, uri::ClientMetadata, }; use std::sync::{Arc, RwLock}; use std::time::{SystemTime, UNIX_EPOCH}; @@ -196,9 +194,9 @@ impl RadrootsNostrSignerManager { pub fn evaluate_connect_request( &self, client_public_key: PublicKey, - request: RadrootsNostrConnectRequest, + request: Request, ) -> Result<RadrootsNostrSignerConnectEvaluation, RadrootsNostrSignerError> { - let RadrootsNostrConnectRequest::Connect { + let Request::Connect { remote_signer_public_key, secret, requested_permissions, @@ -323,7 +321,7 @@ impl RadrootsNostrSignerManager { pub fn set_granted_permissions( &self, connection_id: &RadrootsNostrSignerConnectionId, - granted_permissions: RadrootsNostrConnectPermissions, + granted_permissions: Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { self.update_state_with(|state| { let updated_at_unix = now_unix_secs(); @@ -353,7 +351,7 @@ impl RadrootsNostrSignerManager { pub fn approve_connection( &self, connection_id: &RadrootsNostrSignerConnectionId, - granted_permissions: RadrootsNostrConnectPermissions, + granted_permissions: Permissions, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { self.update_state_with(|state| { let updated_at_unix = now_unix_secs(); @@ -476,7 +474,7 @@ impl RadrootsNostrSignerManager { pub fn set_pending_request( &self, connection_id: &RadrootsNostrSignerConnectionId, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrSignerError> { self.update_state_with(|state| { let record = find_connection_mut(state, connection_id)?; @@ -763,12 +761,9 @@ impl RadrootsNostrSignerManager { pub fn evaluate_request( &self, connection_id: &RadrootsNostrSignerConnectionId, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerRequestEvaluation, RadrootsNostrSignerError> { - if matches!( - request_message.request, - RadrootsNostrConnectRequest::Connect { .. } - ) { + if matches!(request_message.request, Request::Connect { .. }) { return Err(RadrootsNostrSignerError::InvalidState( "connect requests must be evaluated via evaluate_connect_request".into(), )); @@ -886,7 +881,7 @@ impl RadrootsNostrSignerManager { &self, connection_id: &RadrootsNostrSignerConnectionId, request_id: impl AsRef<str>, - method: RadrootsNostrConnectMethod, + method: Method, decision: RadrootsNostrSignerRequestDecision, message: Option<String>, ) -> Result<RadrootsNostrSignerRequestAuditRecord, RadrootsNostrSignerError> { @@ -1031,8 +1026,8 @@ fn validate_public_identity(_identity: &PublicIdentity) -> Result<(), RadrootsNo } fn validate_granted_permissions( - requested_permissions: &RadrootsNostrConnectPermissions, - granted_permissions: &RadrootsNostrConnectPermissions, + requested_permissions: &Permissions, + granted_permissions: &Permissions, ) -> Result<(), RadrootsNostrSignerError> { if requested_permissions.is_empty() { return Ok(()); @@ -1053,7 +1048,7 @@ fn validate_granted_permissions( fn evaluate_request_action( record: &mut RadrootsNostrSignerConnectionRecord, - request_message: &RadrootsNostrConnectRequestMessage, + request_message: &RequestMessage, request_at_unix: u64, ) -> Result<RadrootsNostrSignerRequestAction, RadrootsNostrSignerError> { if record.is_terminal() { @@ -1096,9 +1091,7 @@ fn evaluate_request_action( }) } -fn normalize_permissions( - permissions: RadrootsNostrConnectPermissions, -) -> RadrootsNostrConnectPermissions { +fn normalize_permissions(permissions: Permissions) -> Permissions { let mut permissions = permissions.into_vec(); permissions.sort(); permissions.dedup(); @@ -1106,9 +1099,9 @@ fn normalize_permissions( } fn normalize_client_metadata( - mut metadata: RadrootsNostrConnectClientMetadata, -) -> Result<RadrootsNostrConnectClientMetadata, RadrootsNostrSignerError> { - metadata.requested_permissions = RadrootsNostrConnectPermissions::default(); + mut metadata: ClientMetadata, +) -> Result<ClientMetadata, RadrootsNostrSignerError> { + metadata.requested_permissions = Permissions::default(); Ok(metadata.normalized()?) } @@ -1218,9 +1211,7 @@ mod tests { }; use nostr::{PublicKey, Timestamp}; use radroots_identity::PublicIdentity; - use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectPermission, UnsignedEvent as ConnectUnsignedEvent, - }; + use radroots_nostr_connect::{Permission, message::UnsignedEvent as ConnectUnsignedEvent}; use serde_json::json; use std::sync::Arc; use std::thread; @@ -1237,28 +1228,19 @@ mod tests { radroots_nostr::key::public_key_from_nostr(public_key).expect("identity public key") } - fn permission( - method: RadrootsNostrConnectMethod, - parameter: Option<&str>, - ) -> RadrootsNostrConnectPermission { + fn permission(method: Method, parameter: Option<&str>) -> Permission { match parameter { - Some(parameter) => RadrootsNostrConnectPermission::with_parameter(method, parameter), - None => RadrootsNostrConnectPermission::new(method), + Some(parameter) => Permission::with_parameter(method, parameter), + None => Permission::new(method), } } - fn request_message(id: &str) -> RadrootsNostrConnectRequestMessage { - RadrootsNostrConnectRequestMessage::new( - id, - radroots_nostr_connect::prelude::RadrootsNostrConnectRequest::Ping, - ) + fn request_message(id: &str) -> RequestMessage { + RequestMessage::new(id, radroots_nostr_connect::Request::Ping) } - fn request_message_with_request( - id: &str, - request: RadrootsNostrConnectRequest, - ) -> RadrootsNostrConnectRequestMessage { - RadrootsNostrConnectRequestMessage::new(id, request) + fn request_message_with_request(id: &str, request: Request) -> RequestMessage { + RequestMessage::new(id, request) } fn unsigned_event(kind: u16) -> ConnectUnsignedEvent { @@ -1443,7 +1425,7 @@ mod tests { #[test] fn auth_replay_audit_replacement_rejects_identity_mismatches() { - let audit = |connection_id: &str, method: RadrootsNostrConnectMethod| { + let audit = |connection_id: &str, method: Method| { RadrootsNostrSignerRequestAuditRecord::new( RadrootsNostrSignerRequestId::parse("req-auth-replay").expect("request id"), RadrootsNostrSignerConnectionId::parse(connection_id).expect("connection id"), @@ -1454,20 +1436,14 @@ mod tests { ) }; let mut state = RadrootsNostrSignerStoreState::default(); - replace_or_insert_auth_replay_audit( - &mut state, - audit("conn-auth-replay", RadrootsNostrConnectMethod::Ping), - ) - .expect("insert audit"); - replace_or_insert_auth_replay_audit( - &mut state, - audit("conn-auth-replay", RadrootsNostrConnectMethod::Ping), - ) - .expect("replace matching audit"); + replace_or_insert_auth_replay_audit(&mut state, audit("conn-auth-replay", Method::Ping)) + .expect("insert audit"); + replace_or_insert_auth_replay_audit(&mut state, audit("conn-auth-replay", Method::Ping)) + .expect("replace matching audit"); for replacement in [ - audit("conn-other", RadrootsNostrConnectMethod::Ping), - audit("conn-auth-replay", RadrootsNostrConnectMethod::Logout), + audit("conn-other", Method::Ping), + audit("conn-auth-replay", Method::Logout), ] { let error = replace_or_insert_auth_replay_audit(&mut state, replacement) .expect_err("reject mismatched audit"); @@ -1549,8 +1525,8 @@ mod tests { .set_signer_identity(public_identity(0x5)) .expect("set signer"); - let sign_event = permission(RadrootsNostrConnectMethod::SignEvent, Some("kind:1")); - let ping = permission(RadrootsNostrConnectMethod::Ping, None); + let sign_event = permission(Method::SignEvent, Some("kind:1")); + let ping = permission(Method::Ping, None); let record = manager .register_connection( RadrootsNostrSignerConnectionDraft::new(public_key(0x6), public_identity(0x7)) @@ -1585,17 +1561,13 @@ mod tests { manager .set_signer_identity(fixture_alice_identity()) .expect("set signer identity"); - let requested_permissions = vec![permission(RadrootsNostrConnectMethod::Ping, None)].into(); + let requested_permissions = vec![permission(Method::Ping, None)].into(); let record = manager .register_connection( RadrootsNostrSignerConnectionDraft::new(public_key(0x90), public_identity(0x91)) .with_requested_permissions(requested_permissions) - .with_client_metadata(RadrootsNostrConnectClientMetadata { - requested_permissions: vec![permission( - RadrootsNostrConnectMethod::Nip44Encrypt, - None, - )] - .into(), + .with_client_metadata(ClientMetadata { + requested_permissions: vec![permission(Method::Nip44Encrypt, None)].into(), name: Some(" Example Client ".into()), url: Some("https://client.example.com".into()), image: None, @@ -1609,7 +1581,7 @@ mod tests { assert!(metadata.requested_permissions.is_empty()); assert_eq!( record.requested_permissions.as_slice(), - &[permission(RadrootsNostrConnectMethod::Ping, None)] + &[permission(Method::Ping, None)] ); } @@ -1703,14 +1675,11 @@ mod tests { .set_signer_identity(public_identity(0x18)) .expect("set signer"); let requested = vec![ - permission(RadrootsNostrConnectMethod::SignEvent, Some("kind:1")), - permission(RadrootsNostrConnectMethod::Ping, None), + permission(Method::SignEvent, Some("kind:1")), + permission(Method::Ping, None), ]; let granted = vec![requested[1].clone()]; - let invalid = vec![permission( - RadrootsNostrConnectMethod::Nip44Encrypt, - Some("kind:1"), - )]; + let invalid = vec![permission(Method::Nip44Encrypt, Some("kind:1"))]; let pending = manager .register_connection( RadrootsNostrSignerConnectionDraft::new(public_key(0x19), public_identity(0x20)) @@ -1770,10 +1739,7 @@ mod tests { )) .expect("register auto"); let err = manager - .approve_connection( - &auto.connection_id, - RadrootsNostrConnectPermissions::default(), - ) + .approve_connection(&auto.connection_id, Permissions::default()) .expect_err("approval not required"); assert!(err.to_string().contains("approval not required")); @@ -1892,7 +1858,7 @@ mod tests { let grants_err = manager .set_granted_permissions( &active.connection_id, - vec![permission(RadrootsNostrConnectMethod::Ping, None)].into(), + vec![permission(Method::Ping, None)].into(), ) .expect_err("update grants revoked"); assert!( @@ -1960,7 +1926,7 @@ mod tests { .record_request( &record.connection_id, " request-1 ", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Challenged, Some(" challenge ".into()), ) @@ -1972,7 +1938,7 @@ mod tests { .record_request( &record.connection_id, "request-2", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Denied, Some(" ".into()), ) @@ -1995,7 +1961,7 @@ mod tests { .record_request( &record.connection_id, " ", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Denied, None, ) @@ -2404,10 +2370,7 @@ mod tests { let challenged = manager .evaluate_request( &record.connection_id, - RadrootsNostrConnectRequestMessage::new( - "req-auth-preview", - RadrootsNostrConnectRequest::GetPublicKey, - ), + RequestMessage::new("req-auth-preview", Request::GetPublicKey), ) .expect("evaluate challenged request"); assert_eq!( @@ -3282,14 +3245,13 @@ mod tests { .expect("set signer"); let missing_id = RadrootsNostrSignerConnectionId::parse("missing-2").expect("id"); - let missing_permissions: RadrootsNostrConnectPermissions = - vec![permission(RadrootsNostrConnectMethod::Ping, None)].into(); + let missing_permissions: Permissions = vec![permission(Method::Ping, None)].into(); let missing_grants = manager .set_granted_permissions(&missing_id, missing_permissions.clone()) .expect_err("missing grants"); let missing_approve = manager - .approve_connection(&missing_id, RadrootsNostrConnectPermissions::default()) + .approve_connection(&missing_id, Permissions::default()) .expect_err("missing approve"); let missing_reject = manager .reject_connection(&missing_id, None) @@ -3319,7 +3281,7 @@ mod tests { .record_request( &missing_id, "req-missing", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Denied, None, ) @@ -3341,7 +3303,7 @@ mod tests { assert!(err.to_string().contains("connection not found")); } - let requested = vec![permission(RadrootsNostrConnectMethod::Ping, None)]; + let requested = vec![permission(Method::Ping, None)]; let pending = manager .register_connection( RadrootsNostrSignerConnectionDraft::new(public_key(0x52), public_identity(0x53)) @@ -3354,11 +3316,7 @@ mod tests { let invalid_approve = manager .approve_connection( &pending.connection_id, - vec![permission( - RadrootsNostrConnectMethod::Nip44Encrypt, - Some("kind:1"), - )] - .into(), + vec![permission(Method::Nip44Encrypt, Some("kind:1"))].into(), ) .expect_err("invalid approve grants"); assert!( @@ -3468,10 +3426,10 @@ mod tests { let err = manager .evaluate_connect_request( public_key(0x58), - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: signer_identity.public_key(), secret: Some("secret".into()), - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), client_metadata: None, }, ) @@ -3497,13 +3455,10 @@ mod tests { .register_connection(connect_draft) .expect_err("poisoned register"); let grants_err = manager - .set_granted_permissions( - &connection_id, - vec![permission(RadrootsNostrConnectMethod::Ping, None)].into(), - ) + .set_granted_permissions(&connection_id, vec![permission(Method::Ping, None)].into()) .expect_err("poisoned set grants"); let approve_err = manager - .approve_connection(&connection_id, RadrootsNostrConnectPermissions::default()) + .approve_connection(&connection_id, Permissions::default()) .expect_err("poisoned approve"); let reject_err = manager .reject_connection(&connection_id, Some("reason".into())) @@ -3545,7 +3500,7 @@ mod tests { .record_request( &connection_id, "req-1", - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Allowed, None, ) @@ -3730,7 +3685,7 @@ mod tests { expect_none_lookup(none_lookup); let non_connect_err = manager - .evaluate_connect_request(client_public_key, RadrootsNostrConnectRequest::Ping) + .evaluate_connect_request(client_public_key, Request::Ping) .expect_err("non-connect evaluation"); assert!( non_connect_err @@ -3741,10 +3696,10 @@ mod tests { let missing_signer_err = RadrootsNostrSignerManager::new_in_memory() .evaluate_connect_request( client_public_key, - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(signer_public_key), secret: None, - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), client_metadata: None, }, ) @@ -3754,10 +3709,10 @@ mod tests { let signer_mismatch_err = manager .evaluate_connect_request( client_public_key, - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(public_key(0x66)), secret: None, - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), client_metadata: None, }, ) @@ -3771,12 +3726,12 @@ mod tests { let existing_connect = manager .evaluate_connect_request( client_public_key, - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(signer_public_key), secret: Some(" connect-secret ".into()), requested_permissions: vec![ - permission(RadrootsNostrConnectMethod::Ping, None), - permission(RadrootsNostrConnectMethod::Ping, None), + permission(Method::Ping, None), + permission(Method::Ping, None), ] .into(), client_metadata: None, @@ -3788,21 +3743,17 @@ mod tests { let registration_connect = manager .evaluate_connect_request( public_key(0x67), - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(signer_public_key), secret: Some(" fresh-secret ".into()), requested_permissions: vec![ - permission(RadrootsNostrConnectMethod::Ping, None), - permission(RadrootsNostrConnectMethod::SignEvent, Some("kind:1")), - permission(RadrootsNostrConnectMethod::Ping, None), + permission(Method::Ping, None), + permission(Method::SignEvent, Some("kind:1")), + permission(Method::Ping, None), ] .into(), - client_metadata: Some(RadrootsNostrConnectClientMetadata { - requested_permissions: vec![permission( - RadrootsNostrConnectMethod::Nip44Encrypt, - None, - )] - .into(), + client_metadata: Some(ClientMetadata { + requested_permissions: vec![permission(Method::Nip44Encrypt, None)].into(), name: Some(" Example Client ".into()), url: Some("https://client.example.com".into()), image: None, @@ -3820,18 +3771,18 @@ mod tests { assert_eq!( proposal.requested_permissions.as_slice(), &[ - permission(RadrootsNostrConnectMethod::Ping, None), - permission(RadrootsNostrConnectMethod::SignEvent, Some("kind:1")), + permission(Method::Ping, None), + permission(Method::SignEvent, Some("kind:1")), ] ); let existing_secret_mismatch = manager .evaluate_connect_request( public_key(0x68), - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(signer_public_key), secret: Some("connect-secret".into()), - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), client_metadata: None, }, ) @@ -3854,11 +3805,7 @@ mod tests { .register_connection( RadrootsNostrSignerConnectionDraft::new(public_key(0x72), public_identity(0x73)) .with_requested_permissions( - vec![permission( - RadrootsNostrConnectMethod::SignEvent, - Some("kind:1"), - )] - .into(), + vec![permission(Method::SignEvent, Some("kind:1"))].into(), ), ) .expect("register active"); @@ -3866,7 +3813,7 @@ mod tests { let get_public_key = manager .evaluate_request( &active.connection_id, - request_message_with_request("req-get", RadrootsNostrConnectRequest::GetPublicKey), + request_message_with_request("req-get", Request::GetPublicKey), ) .expect("evaluate get_public_key"); expect_allowed_user_public_key(&get_public_key.action); @@ -3879,10 +3826,7 @@ mod tests { let allowed_sign = manager .evaluate_request( &active.connection_id, - request_message_with_request( - "req-sign-1", - RadrootsNostrConnectRequest::SignEvent(unsigned_event(1)), - ), + request_message_with_request("req-sign-1", Request::SignEvent(unsigned_event(1))), ) .expect("evaluate sign allowed"); expect_allowed_without_response_hint(&allowed_sign.action); @@ -3890,10 +3834,7 @@ mod tests { let denied_sign = manager .evaluate_request( &active.connection_id, - request_message_with_request( - "req-sign-2", - RadrootsNostrConnectRequest::SignEvent(unsigned_event(2)), - ), + request_message_with_request("req-sign-2", Request::SignEvent(unsigned_event(2))), ) .expect("evaluate sign denied"); assert_eq!(denied_sign.denied_reason(), Some("unauthorized sign_event")); @@ -3959,10 +3900,10 @@ mod tests { &active.connection_id, request_message_with_request( "req-connect", - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(active.client_public_key), secret: None, - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), client_metadata: None, }, ), @@ -4018,7 +3959,7 @@ mod tests { let invalid_request_id = manager .evaluate_request( &active.connection_id, - request_message_with_request(" ", RadrootsNostrConnectRequest::Ping), + request_message_with_request(" ", Request::Ping), ) .expect_err("invalid request id"); assert!( @@ -4054,7 +3995,7 @@ mod tests { Some(RadrootsNostrSignerAuthChallenge::new(api_primary_https(), 1).expect("challenge")); let invalid_pending = evaluate_request_action( &mut pending_record, - &request_message_with_request(" ", RadrootsNostrConnectRequest::Ping), + &request_message_with_request(" ", Request::Ping), 1, ) .expect_err("invalid pending request"); diff --git a/crates/nostr_signer/src/model.rs b/crates/nostr_signer/src/model.rs @@ -2,9 +2,8 @@ use crate::error::RadrootsNostrSignerError; use hex::encode as hex_encode; use nostr::{PublicKey, RelayUrl}; use radroots_identity::PublicIdentity; -use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, - RadrootsNostrConnectPermissions, RadrootsNostrConnectRequestMessage, +use radroots_nostr_connect::{ + Method, Permission, message::RequestMessage, permission::Permissions, uri::ClientMetadata, }; use serde::{Deserialize, Deserializer, Serialize}; use sha2::{Digest, Sha256}; @@ -97,7 +96,7 @@ pub struct RadrootsNostrSignerAuthChallenge { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct RadrootsNostrSignerPendingRequest { - pub request_message: RadrootsNostrConnectRequestMessage, + pub request_message: RequestMessage, pub created_at_unix: u64, } @@ -113,7 +112,7 @@ pub struct RadrootsNostrSignerPermissionGrant { serialize_with = "serialize_permission", deserialize_with = "deserialize_permission" )] - pub permission: RadrootsNostrConnectPermission, + pub permission: Permission, pub granted_at_unix: u64, } @@ -122,8 +121,8 @@ pub struct RadrootsNostrSignerConnectionDraft { pub client_public_key: PublicKey, pub user_identity: PublicIdentity, pub connect_secret: Option<String>, - pub client_metadata: Option<RadrootsNostrConnectClientMetadata>, - pub requested_permissions: RadrootsNostrConnectPermissions, + pub client_metadata: Option<ClientMetadata>, + pub requested_permissions: Permissions, pub relays: Vec<RelayUrl>, pub approval_requirement: RadrootsNostrSignerApprovalRequirement, } @@ -144,8 +143,8 @@ pub struct RadrootsNostrSignerConnectionRecord { #[serde(default, skip_serializing_if = "Option::is_none")] pub connect_secret_consumed_at_unix: Option<u64>, #[serde(default, skip_serializing_if = "Option::is_none")] - pub client_metadata: Option<RadrootsNostrConnectClientMetadata>, - pub requested_permissions: RadrootsNostrConnectPermissions, + pub client_metadata: Option<ClientMetadata>, + pub requested_permissions: Permissions, #[serde(default)] pub granted_permissions: Vec<RadrootsNostrSignerPermissionGrant>, #[serde(default)] @@ -173,7 +172,7 @@ pub struct RadrootsNostrSignerConnectionRecord { pub struct RadrootsNostrSignerRequestAuditRecord { pub request_id: RadrootsNostrSignerRequestId, pub connection_id: RadrootsNostrSignerConnectionId, - pub method: RadrootsNostrConnectMethod, + pub method: Method, pub decision: RadrootsNostrSignerRequestDecision, #[serde(default, skip_serializing_if = "Option::is_none")] pub message: Option<String>, @@ -411,20 +410,17 @@ impl<'de> Deserialize<'de> for RadrootsNostrSignerAuthChallenge { impl RadrootsNostrSignerPendingRequest { pub fn new( - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, created_at_unix: u64, ) -> Result<Self, RadrootsNostrSignerError> { let normalized_id = RadrootsNostrSignerRequestId::parse(&request_message.id)?; Ok(Self { - request_message: RadrootsNostrConnectRequestMessage::new( - normalized_id.as_str(), - request_message.request, - ), + request_message: RequestMessage::new(normalized_id.as_str(), request_message.request), created_at_unix, }) } - pub fn request_message(&self) -> RadrootsNostrConnectRequestMessage { + pub fn request_message(&self) -> RequestMessage { self.request_message.clone() } @@ -447,7 +443,7 @@ impl RadrootsNostrSignerAuthorizationOutcome { } impl RadrootsNostrSignerPermissionGrant { - pub fn new(permission: RadrootsNostrConnectPermission, granted_at_unix: u64) -> Self { + pub fn new(permission: Permission, granted_at_unix: u64) -> Self { Self { permission, granted_at_unix, @@ -462,7 +458,7 @@ impl RadrootsNostrSignerConnectionDraft { user_identity, connect_secret: None, client_metadata: None, - requested_permissions: RadrootsNostrConnectPermissions::default(), + requested_permissions: Permissions::default(), relays: Vec::new(), approval_requirement: RadrootsNostrSignerApprovalRequirement::NotRequired, } @@ -473,18 +469,12 @@ impl RadrootsNostrSignerConnectionDraft { self } - pub fn with_requested_permissions( - mut self, - requested_permissions: RadrootsNostrConnectPermissions, - ) -> Self { + pub fn with_requested_permissions(mut self, requested_permissions: Permissions) -> Self { self.requested_permissions = requested_permissions; self } - pub fn with_client_metadata( - mut self, - client_metadata: RadrootsNostrConnectClientMetadata, - ) -> Self { + pub fn with_client_metadata(mut self, client_metadata: ClientMetadata) -> Self { self.client_metadata = Some(client_metadata); self } @@ -549,7 +539,7 @@ impl RadrootsNostrSignerConnectionRecord { } } - pub fn granted_permissions(&self) -> RadrootsNostrConnectPermissions { + pub fn granted_permissions(&self) -> Permissions { self.granted_permissions .iter() .map(|grant| grant.permission.clone()) @@ -557,14 +547,14 @@ impl RadrootsNostrSignerConnectionRecord { .into() } - pub fn effective_permissions(&self) -> RadrootsNostrConnectPermissions { + pub fn effective_permissions(&self) -> Permissions { let granted_permissions = self.granted_permissions(); if !granted_permissions.is_empty() { granted_permissions } else if self.approval_state == RadrootsNostrSignerApprovalState::NotRequired { self.requested_permissions.clone() } else { - RadrootsNostrConnectPermissions::default() + Permissions::default() } } @@ -648,7 +638,7 @@ impl RadrootsNostrSignerRequestAuditRecord { pub fn new( request_id: RadrootsNostrSignerRequestId, connection_id: RadrootsNostrSignerConnectionId, - method: RadrootsNostrConnectMethod, + method: Method, decision: RadrootsNostrSignerRequestDecision, message: Option<String>, created_at_unix: u64, @@ -716,19 +706,14 @@ impl Default for RadrootsNostrSignerStoreState { } } -fn serialize_permission<S>( - permission: &RadrootsNostrConnectPermission, - serializer: S, -) -> Result<S::Ok, S::Error> +fn serialize_permission<S>(permission: &Permission, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { serializer.serialize_str(&permission.to_string()) } -fn deserialize_permission<'de, D>( - deserializer: D, -) -> Result<RadrootsNostrConnectPermission, D::Error> +fn deserialize_permission<'de, D>(deserializer: D) -> Result<Permission, D::Error> where D: serde::Deserializer<'de>, { @@ -784,11 +769,8 @@ mod tests { synthetic_public_key(index) } - fn request_message(id: &str) -> RadrootsNostrConnectRequestMessage { - RadrootsNostrConnectRequestMessage::new( - id, - radroots_nostr_connect::prelude::RadrootsNostrConnectRequest::Ping, - ) + fn request_message(id: &str) -> RequestMessage { + RequestMessage::new(id, radroots_nostr_connect::Request::Ping) } #[test] @@ -846,13 +828,10 @@ mod tests { #[test] fn connection_draft_builders_apply_values() { - let permission = RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "kind:1", - ); + let permission = Permission::with_parameter(Method::SignEvent, "kind:1"); let relay = primary_relay(); - let metadata = RadrootsNostrConnectClientMetadata { - requested_permissions: RadrootsNostrConnectPermissions::default(), + let metadata = ClientMetadata { + requested_permissions: Permissions::default(), name: Some("Example Client".into()), url: None, image: None, @@ -1044,7 +1023,7 @@ mod tests { #[test] fn granted_permissions_and_request_audit_build_correctly() { - let permission = RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Ping); + let permission = Permission::new(Method::Ping); let grant = RadrootsNostrSignerPermissionGrant::new(permission.clone(), 42); let mut record = RadrootsNostrSignerConnectionRecord::new( RadrootsNostrSignerConnectionId::parse("conn-2").expect("id"), @@ -1056,7 +1035,7 @@ mod tests { let audit = RadrootsNostrSignerRequestAuditRecord::new( RadrootsNostrSignerRequestId::parse("req-2").expect("request"), RadrootsNostrSignerConnectionId::parse("conn-2").expect("id"), - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Allowed, Some("ok".into()), 25, @@ -1069,10 +1048,7 @@ mod tests { let json = serde_json::to_string(&record.granted_permissions[0]).expect("serialize grant"); let decoded: RadrootsNostrSignerPermissionGrant = serde_json::from_str(&json).expect("deserialize grant"); - assert_eq!( - decoded.permission, - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Ping) - ); + assert_eq!(decoded.permission, Permission::new(Method::Ping)); } #[test] @@ -1125,10 +1101,7 @@ mod tests { #[test] fn effective_permissions_prefers_grants_then_auto_requested_then_empty() { - let requested: RadrootsNostrConnectPermissions = vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Nip04Encrypt, - )] - .into(); + let requested: Permissions = vec![Permission::new(Method::Nip04Encrypt)].into(); let auto_record = RadrootsNostrSignerConnectionRecord::new( RadrootsNostrSignerConnectionId::new_v7(), public_identity(0x31), @@ -1140,15 +1113,12 @@ mod tests { let mut granted_record = auto_record.clone(); granted_record.granted_permissions = vec![RadrootsNostrSignerPermissionGrant::new( - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Ping), + Permission::new(Method::Ping), 2, )]; assert_eq!( granted_record.effective_permissions(), - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Ping - )] - .into() + vec![Permission::new(Method::Ping)].into() ); let mut approved_without_grants = auto_record; @@ -1164,14 +1134,11 @@ mod tests { serialize_with = "serialize_permission", deserialize_with = "deserialize_permission" )] - permission: RadrootsNostrConnectPermission, + permission: Permission, } let wrapper = PermissionWrapper { - permission: RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "kind:1", - ), + permission: Permission::with_parameter(Method::SignEvent, "kind:1"), }; let json = serde_json::to_vec_pretty(&wrapper).expect("serialize wrapper"); diff --git a/crates/nostr_signer/src/nip46.rs b/crates/nostr_signer/src/nip46.rs @@ -10,10 +10,13 @@ use radroots_nostr::event::Kind as RadrootsNostrKind; use radroots_nostr::event::Timestamp as RadrootsNostrTimestamp; use radroots_nostr::filter::Filter as RadrootsNostrFilter; use radroots_nostr::tag::Tag as RadrootsNostrTag; -use radroots_nostr_connect::prelude::{ - RADROOTS_NOSTR_CONNECT_RPC_KIND, RadrootsNostrConnectError, RadrootsNostrConnectPermissions, - RadrootsNostrConnectRequest, RadrootsNostrConnectRequestMessage, RadrootsNostrConnectResponse, - SignedEvent as ConnectSignedEvent, UnsignedEvent as ConnectUnsignedEvent, +use radroots_nostr_connect::{ + Error as ConnectError, Request, Response, + message::{ + RPC_KIND, RequestMessage, SignedEvent as ConnectSignedEvent, + UnsignedEvent as ConnectUnsignedEvent, + }, + permission::Permissions, }; use crate::backend::RadrootsNostrSignerBackend; @@ -100,21 +103,15 @@ pub trait RadrootsNostrSignerNip46Policy<B: RadrootsNostrSignerBackend>: client_public_key: &RadrootsNostrPublicKey, ) -> Option<RadrootsNostrSignerApprovalRequirement>; - fn filtered_requested_permissions( - &self, - requested_permissions: &RadrootsNostrConnectPermissions, - ) -> RadrootsNostrConnectPermissions; + fn filtered_requested_permissions(&self, requested_permissions: &Permissions) -> Permissions; - fn auto_granted_permissions( - &self, - requested_permissions: &RadrootsNostrConnectPermissions, - ) -> RadrootsNostrConnectPermissions; + fn auto_granted_permissions(&self, requested_permissions: &Permissions) -> Permissions; fn prepare_request( &self, backend: &B, connection: &RadrootsNostrSignerConnectionRecord, - request_message: &RadrootsNostrConnectRequestMessage, + request_message: &RequestMessage, ) -> Result<Option<String>, RadrootsNostrSignerError>; } @@ -134,7 +131,7 @@ pub struct RadrootsNostrSignerNip46Handler<B, P, S> { #[derive(Debug, Clone, PartialEq, Eq)] pub enum RadrootsNostrSignerHandledRequest { Respond { - response: Box<RadrootsNostrConnectResponse>, + response: Box<Response>, connection_id: Option<RadrootsNostrSignerConnectionId>, consume_connect_secret_for: Option<RadrootsNostrSignerConnectionId>, }, @@ -162,7 +159,7 @@ impl<S: RadrootsNostrSignerNip46Signer> RadrootsNostrSignerNip46Codec<S> { pub fn filter(&self) -> Result<RadrootsNostrFilter, RadrootsNostrSignerError> { let filter = RadrootsNostrFilter::new() - .kind(RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND)) + .kind(RadrootsNostrKind::Custom(RPC_KIND)) .since(RadrootsNostrTimestamp::now()); Ok(filter.custom_tags( SingleLetterTag::lowercase(Alphabet::P), @@ -173,26 +170,25 @@ impl<S: RadrootsNostrSignerNip46Signer> RadrootsNostrSignerNip46Codec<S> { pub fn parse_request_event( &self, event: &RadrootsNostrEvent, - ) -> Result<RadrootsNostrConnectRequestMessage, RadrootsNostrSignerError> { + ) -> Result<RequestMessage, RadrootsNostrSignerError> { let decrypted = self.signer.decrypt_request(&event.pubkey, &event.content)?; - Ok(serde_json::from_str(&decrypted).map_err(RadrootsNostrConnectError::from)?) + Ok(serde_json::from_str(&decrypted).map_err(ConnectError::from)?) } pub fn build_response_event( &self, client_public_key: RadrootsNostrPublicKey, request_id: impl Into<String>, - response: RadrootsNostrConnectResponse, + response: Response, ) -> Result<GenericBuilder, RadrootsNostrSignerError> { let envelope = response.into_envelope(request_id.into())?; - let payload = serde_json::to_string(&envelope).map_err(RadrootsNostrConnectError::from)?; + let payload = serde_json::to_string(&envelope).map_err(ConnectError::from)?; let ciphertext = self.signer.encrypt_response(&client_public_key, &payload)?; - Ok(GenericBuilder::new( - RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND), - ciphertext, + Ok( + GenericBuilder::new(RadrootsNostrKind::Custom(RPC_KIND), ciphertext) + .tags(vec![RadrootsNostrTag::public_key(client_public_key)]), ) - .tags(vec![RadrootsNostrTag::public_key(client_public_key)])) } /// Produces a NIP-46 response for an externally supplied unsigned event. @@ -202,20 +198,17 @@ impl<S: RadrootsNostrSignerNip46Signer> RadrootsNostrSignerNip46Codec<S> { pub fn sign_event_response( &self, unsigned_event: UnsignedEvent, - ) -> Result<RadrootsNostrConnectResponse, RadrootsNostrSignerError> { + ) -> Result<Response, RadrootsNostrSignerError> { let unsigned_event = ConnectUnsignedEvent::from_json(&unsigned_event.as_json())?; Ok(self.sign_event_response_value(unsigned_event)) } - fn sign_event_response_value( - &self, - unsigned_event: ConnectUnsignedEvent, - ) -> RadrootsNostrConnectResponse { + fn sign_event_response_value(&self, unsigned_event: ConnectUnsignedEvent) -> Response { let unsigned_event = match serde_json::from_str::<UnsignedEvent>(&unsigned_event.as_json()) { Ok(unsigned_event) => unsigned_event, Err(error) => { - return RadrootsNostrConnectResponse::Error { + return Response::Error { result: None, error: format!("invalid sign_event payload: {error}"), }; @@ -223,7 +216,7 @@ impl<S: RadrootsNostrSignerNip46Signer> RadrootsNostrSignerNip46Codec<S> { }; let user_public_key = self.signer.user_identity().public_key().to_hex(); if unsigned_event.pubkey.to_hex() != user_public_key { - return RadrootsNostrConnectResponse::Error { + return Response::Error { result: None, error: "sign_event pubkey does not match the managed user identity".to_owned(), }; @@ -231,80 +224,74 @@ impl<S: RadrootsNostrSignerNip46Signer> RadrootsNostrSignerNip46Codec<S> { match self.signer.sign_user_event(unsigned_event) { Ok(event) => match ConnectSignedEvent::from_json(&event.as_json()) { - Ok(event) => RadrootsNostrConnectResponse::SignedEvent(event), - Err(error) => RadrootsNostrConnectResponse::Error { + Ok(event) => Response::SignedEvent(event), + Err(error) => Response::Error { result: None, error: format!("failed to encode signed event: {error}"), }, }, - Err(error) => RadrootsNostrConnectResponse::Error { + Err(error) => Response::Error { result: None, error: format!("failed to sign event: {error}"), }, } } - pub fn crypto_response( - &self, - request: RadrootsNostrConnectRequest, - ) -> Result<RadrootsNostrConnectResponse, RadrootsNostrSignerError> { + pub fn crypto_response(&self, request: Request) -> Result<Response, RadrootsNostrSignerError> { Ok(self.crypto_response_value(request)) } - fn crypto_response_value( - &self, - request: RadrootsNostrConnectRequest, - ) -> RadrootsNostrConnectResponse { + fn crypto_response_value(&self, request: Request) -> Response { match request { - RadrootsNostrConnectRequest::Nip04Encrypt { + Request::Nip04Encrypt { public_key, plaintext, } => match nostr_public_key(public_key) .and_then(|public_key| self.signer.nip04_encrypt(&public_key, &plaintext)) { - Ok(ciphertext) => RadrootsNostrConnectResponse::Nip04Encrypt(ciphertext), - Err(error) => RadrootsNostrConnectResponse::Error { + Ok(ciphertext) => Response::Nip04Encrypt(ciphertext), + Err(error) => Response::Error { result: None, error: format!("nip04 encrypt failed: {error}"), }, }, - RadrootsNostrConnectRequest::Nip04Decrypt { + Request::Nip04Decrypt { public_key, ciphertext, } => match nostr_public_key(public_key) .and_then(|public_key| self.signer.nip04_decrypt(&public_key, &ciphertext)) { - Ok(plaintext) => RadrootsNostrConnectResponse::Nip04Decrypt(plaintext), - Err(error) => RadrootsNostrConnectResponse::Error { + Ok(plaintext) => Response::Nip04Decrypt(plaintext), + Err(error) => Response::Error { result: None, error: format!("nip04 decrypt failed: {error}"), }, }, - RadrootsNostrConnectRequest::Nip44Encrypt { + Request::Nip44Encrypt { public_key, plaintext, } => match nostr_public_key(public_key) .and_then(|public_key| self.signer.nip44_encrypt(&public_key, &plaintext)) { - Ok(ciphertext) => RadrootsNostrConnectResponse::Nip44Encrypt(ciphertext), - Err(error) => RadrootsNostrConnectResponse::Error { + Ok(ciphertext) => Response::Nip44Encrypt(ciphertext), + Err(error) => Response::Error { result: None, error: format!("nip44 encrypt failed: {error}"), }, }, - RadrootsNostrConnectRequest::Nip44Decrypt { + Request::Nip44Decrypt { public_key, ciphertext, } => match nostr_public_key(public_key) .and_then(|public_key| self.signer.nip44_decrypt(&public_key, &ciphertext)) { - Ok(plaintext) => RadrootsNostrConnectResponse::Nip44Decrypt(plaintext), - Err(error) => RadrootsNostrConnectResponse::Error { + Ok(plaintext) => Response::Nip44Decrypt(plaintext), + Err(error) => Response::Error { result: None, error: format!("nip44 decrypt failed: {error}"), }, }, - other => RadrootsNostrConnectResponse::Error { + other => Response::Error { result: None, error: format!("request `{}` is not a crypto method", other.method()), }, @@ -334,7 +321,7 @@ where pub fn parse_request_event( &self, event: &RadrootsNostrEvent, - ) -> Result<RadrootsNostrConnectRequestMessage, RadrootsNostrSignerError> { + ) -> Result<RequestMessage, RadrootsNostrSignerError> { self.codec.parse_request_event(event) } @@ -342,7 +329,7 @@ where &self, client_public_key: RadrootsNostrPublicKey, request_id: impl Into<String>, - response: RadrootsNostrConnectResponse, + response: Response, ) -> Result<GenericBuilder, RadrootsNostrSignerError> { self.codec .build_response_event(client_public_key, request_id, response) @@ -351,29 +338,27 @@ where pub fn handle_request( &self, client_public_key: RadrootsNostrPublicKey, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerHandledRequestOutcome, RadrootsNostrSignerError> { match request_message.request.clone() { - RadrootsNostrConnectRequest::Connect { secret, .. } => { + Request::Connect { secret, .. } => { self.handle_connect_request(client_public_key, request_message.request, secret) } - RadrootsNostrConnectRequest::SignEvent(unsigned_event) => { + Request::SignEvent(unsigned_event) => { self.handle_sign_event_request(client_public_key, request_message, unsigned_event) } - RadrootsNostrConnectRequest::Nip04Encrypt { .. } - | RadrootsNostrConnectRequest::Nip04Decrypt { .. } - | RadrootsNostrConnectRequest::Nip44Encrypt { .. } - | RadrootsNostrConnectRequest::Nip44Decrypt { .. } => { + Request::Nip04Encrypt { .. } + | Request::Nip04Decrypt { .. } + | Request::Nip44Encrypt { .. } + | Request::Nip44Decrypt { .. } => { self.handle_crypto_request(client_public_key, request_message) } - RadrootsNostrConnectRequest::GetPublicKey - | RadrootsNostrConnectRequest::GetSessionCapability - | RadrootsNostrConnectRequest::Ping - | RadrootsNostrConnectRequest::SwitchRelays => { - self.handle_base_request(client_public_key, request_message) - } + Request::GetPublicKey + | Request::GetSessionCapability + | Request::Ping + | Request::SwitchRelays => self.handle_base_request(client_public_key, request_message), _ => Ok(RadrootsNostrSignerHandledRequestOutcome::new( - RadrootsNostrSignerHandledRequest::respond(RadrootsNostrConnectResponse::Error { + RadrootsNostrSignerHandledRequest::respond(Response::Error { result: None, error: format!( "method `{}` is not implemented yet", @@ -387,7 +372,7 @@ where pub fn handle_authorized_request_evaluation( &self, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, evaluation: RadrootsNostrSignerRequestEvaluation, ) -> Result<RadrootsNostrSignerHandledRequestOutcome, RadrootsNostrSignerError> { let audit = evaluation.audit.clone(); @@ -401,7 +386,7 @@ where fn handle_connect_request( &self, client_public_key: RadrootsNostrPublicKey, - request: RadrootsNostrConnectRequest, + request: Request, secret: Option<String>, ) -> Result<RadrootsNostrSignerHandledRequestOutcome, RadrootsNostrSignerError> { let connect_decision = self.policy.connect_decision(&client_public_key); @@ -421,7 +406,7 @@ where .connect_rate_limit_denied_reason(&client_public_key) { return Ok(RadrootsNostrSignerHandledRequestOutcome::respond( - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: reason, }, @@ -439,7 +424,7 @@ where RadrootsNostrSignerNip46ConnectDecision::Deny ) { return Ok(RadrootsNostrSignerHandledRequestOutcome::respond( - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "client public key denied by policy".to_owned(), }, @@ -459,7 +444,7 @@ where .approval_requirement_for_client(&client_public_key) else { return Ok(RadrootsNostrSignerHandledRequestOutcome::respond( - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "client public key denied by policy".to_owned(), }, @@ -490,7 +475,7 @@ where fn handle_base_request( &self, client_public_key: RadrootsNostrPublicKey, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerHandledRequestOutcome, RadrootsNostrSignerError> { let connection = match self.lookup_connection(client_public_key)? { Ok(connection) => connection, @@ -504,7 +489,7 @@ where Ok(RadrootsNostrSignerHandledRequestOutcome::new( RadrootsNostrSignerHandledRequest::respond_for_connection( Some(connection.connection_id.clone()), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: reason, }, @@ -537,7 +522,7 @@ where fn handle_sign_event_request( &self, client_public_key: RadrootsNostrPublicKey, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, unsigned_event: ConnectUnsignedEvent, ) -> Result<RadrootsNostrSignerHandledRequestOutcome, RadrootsNostrSignerError> { let connection = match self.lookup_connection(client_public_key)? { @@ -552,7 +537,7 @@ where Ok(RadrootsNostrSignerHandledRequestOutcome::new( RadrootsNostrSignerHandledRequest::respond_for_connection( Some(connection.connection_id.clone()), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: reason, }, @@ -577,7 +562,7 @@ where fn handle_crypto_request( &self, client_public_key: RadrootsNostrPublicKey, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerHandledRequestOutcome, RadrootsNostrSignerError> { let request = request_message.request.clone(); let connection = match self.lookup_connection(client_public_key)? { @@ -592,7 +577,7 @@ where Ok(RadrootsNostrSignerHandledRequestOutcome::new( RadrootsNostrSignerHandledRequest::respond_for_connection( Some(connection.connection_id.clone()), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: reason, }, @@ -616,29 +601,27 @@ where fn handled_request_for_evaluation( &self, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, evaluation: RadrootsNostrSignerRequestEvaluation, ) -> Result<RadrootsNostrSignerHandledRequest, RadrootsNostrSignerError> { match request_message.request.clone() { - RadrootsNostrConnectRequest::SignEvent(unsigned_event) => self - .handled_request_for_authorized_action( - &evaluation.connection, - evaluation.action, - || Ok(self.codec.sign_event_response_value(unsigned_event)), - ), - RadrootsNostrConnectRequest::Nip04Encrypt { .. } - | RadrootsNostrConnectRequest::Nip04Decrypt { .. } - | RadrootsNostrConnectRequest::Nip44Encrypt { .. } - | RadrootsNostrConnectRequest::Nip44Decrypt { .. } => self - .handled_request_for_authorized_action( - &evaluation.connection, - evaluation.action, - || Ok(self.codec.crypto_response_value(request_message.request)), - ), - RadrootsNostrConnectRequest::GetPublicKey - | RadrootsNostrConnectRequest::GetSessionCapability - | RadrootsNostrConnectRequest::Ping - | RadrootsNostrConnectRequest::SwitchRelays => { + Request::SignEvent(unsigned_event) => self.handled_request_for_authorized_action( + &evaluation.connection, + evaluation.action, + || Ok(self.codec.sign_event_response_value(unsigned_event)), + ), + Request::Nip04Encrypt { .. } + | Request::Nip04Decrypt { .. } + | Request::Nip44Encrypt { .. } + | Request::Nip44Decrypt { .. } => self.handled_request_for_authorized_action( + &evaluation.connection, + evaluation.action, + || Ok(self.codec.crypto_response_value(request_message.request)), + ), + Request::GetPublicKey + | Request::GetSessionCapability + | Request::Ping + | Request::SwitchRelays => { let response_hint = match &evaluation.action { RadrootsNostrSignerRequestAction::Allowed { response_hint, .. } => { Some(response_hint.clone()) @@ -658,7 +641,7 @@ where } other => Ok(RadrootsNostrSignerHandledRequest::respond_for_connection( Some(evaluation.connection.connection_id.clone()), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: format!("method `{}` is not implemented yet", other.method()), }, @@ -673,7 +656,7 @@ where on_allowed: F, ) -> Result<RadrootsNostrSignerHandledRequest, RadrootsNostrSignerError> where - F: FnOnce() -> Result<RadrootsNostrConnectResponse, RadrootsNostrSignerError>, + F: FnOnce() -> Result<Response, RadrootsNostrSignerError>, { handled_request_for_action(connection, action, on_allowed) } @@ -681,7 +664,7 @@ where fn evaluate_request_with_policy( &self, connection: &RadrootsNostrSignerConnectionRecord, - request_message: RadrootsNostrConnectRequestMessage, + request_message: RequestMessage, ) -> Result<RadrootsNostrSignerPreparedRequestEvaluation, RadrootsNostrSignerError> { if let Some(reason) = self.policy @@ -708,38 +691,32 @@ where fn lookup_connection( &self, client_public_key: RadrootsNostrPublicKey, - ) -> Result< - Result<RadrootsNostrSignerConnectionRecord, RadrootsNostrConnectResponse>, - RadrootsNostrSignerError, - > { + ) -> Result<Result<RadrootsNostrSignerConnectionRecord, Response>, RadrootsNostrSignerError> + { Ok( match self.backend.lookup_session(&client_public_key, None)? { RadrootsNostrSignerSessionLookup::Connection(connection) => Ok(*connection), - RadrootsNostrSignerSessionLookup::None => { - Err(RadrootsNostrConnectResponse::Error { - result: None, - error: "unauthorized".to_owned(), - }) - } - RadrootsNostrSignerSessionLookup::Ambiguous(_) => { - Err(RadrootsNostrConnectResponse::Error { - result: None, - error: "ambiguous client sessions".to_owned(), - }) - } + RadrootsNostrSignerSessionLookup::None => Err(Response::Error { + result: None, + error: "unauthorized".to_owned(), + }), + RadrootsNostrSignerSessionLookup::Ambiguous(_) => Err(Response::Error { + result: None, + error: "ambiguous client sessions".to_owned(), + }), }, ) } } impl RadrootsNostrSignerHandledRequest { - pub fn respond(response: RadrootsNostrConnectResponse) -> Self { + pub fn respond(response: Response) -> Self { Self::respond_for_connection(None, response) } pub fn respond_for_connection( connection_id: Option<RadrootsNostrSignerConnectionId>, - response: RadrootsNostrConnectResponse, + response: Response, ) -> Self { Self::Respond { response: Box::new(response), @@ -751,7 +728,7 @@ impl RadrootsNostrSignerHandledRequest { pub fn into_publish_parts( self, ) -> Option<( - RadrootsNostrConnectResponse, + Response, Option<RadrootsNostrSignerConnectionId>, Option<RadrootsNostrSignerConnectionId>, )> { @@ -777,7 +754,7 @@ impl RadrootsNostrSignerHandledRequestOutcome { } } - pub fn respond(response: RadrootsNostrConnectResponse) -> Self { + pub fn respond(response: Response) -> Self { Self::new(RadrootsNostrSignerHandledRequest::respond(response), None) } @@ -793,8 +770,8 @@ pub fn connect_response_outcome( let consume_connect_secret_for = secret.as_ref().map(|_| connection.connection_id.clone()); RadrootsNostrSignerHandledRequest::Respond { response: Box::new(match secret { - Some(secret) => RadrootsNostrConnectResponse::ConnectSecretEcho(secret), - None => RadrootsNostrConnectResponse::ConnectAcknowledged, + Some(secret) => Response::ConnectSecretEcho(secret), + None => Response::ConnectAcknowledged, }), connection_id: Some(connection.connection_id.clone()), consume_connect_secret_for, @@ -804,14 +781,14 @@ pub fn connect_response_outcome( pub fn response_from_hint( connection: &RadrootsNostrSignerConnectionRecord, hint: RadrootsNostrSignerRequestResponseHint, -) -> RadrootsNostrConnectResponse { +) -> Response { match hint { - RadrootsNostrSignerRequestResponseHint::Pong => RadrootsNostrConnectResponse::Pong, + RadrootsNostrSignerRequestResponseHint::Pong => Response::Pong, RadrootsNostrSignerRequestResponseHint::UserPublicKey(public_key) => { - RadrootsNostrConnectResponse::UserPublicKey(public_key) + Response::UserPublicKey(public_key) } RadrootsNostrSignerRequestResponseHint::RemoteSessionCapability(capability) => { - RadrootsNostrConnectResponse::RemoteSessionCapability(capability) + Response::RemoteSessionCapability(capability) } RadrootsNostrSignerRequestResponseHint::RelayList(relays) => match connection .relays @@ -819,16 +796,14 @@ pub fn response_from_hint( .map(|relay| radroots_nostr_connect::uri::RelayUrl::parse(&relay.to_string())) .collect::<Result<Vec<_>, _>>() { - Ok(connection_relays) if relays == connection_relays => { - RadrootsNostrConnectResponse::RelayList(relays) - } - Ok(connection_relays) => RadrootsNostrConnectResponse::RelayList(connection_relays), - Err(error) => RadrootsNostrConnectResponse::Error { + Ok(connection_relays) if relays == connection_relays => Response::RelayList(relays), + Ok(connection_relays) => Response::RelayList(connection_relays), + Err(error) => Response::Error { result: None, error: format!("invalid connection relay state: {error}"), }, }, - RadrootsNostrSignerRequestResponseHint::None => RadrootsNostrConnectResponse::Error { + RadrootsNostrSignerRequestResponseHint::None => Response::Error { result: None, error: "request evaluation did not provide a response hint".to_owned(), }, @@ -847,13 +822,13 @@ pub fn handled_request_for_action<F>( on_allowed: F, ) -> Result<RadrootsNostrSignerHandledRequest, RadrootsNostrSignerError> where - F: FnOnce() -> Result<RadrootsNostrConnectResponse, RadrootsNostrSignerError>, + F: FnOnce() -> Result<Response, RadrootsNostrSignerError>, { Ok(match action { RadrootsNostrSignerRequestAction::Denied { reason } => { RadrootsNostrSignerHandledRequest::respond_for_connection( Some(connection.connection_id.clone()), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: reason, }, @@ -862,7 +837,7 @@ where RadrootsNostrSignerRequestAction::Challenged { auth_challenge, .. } => { RadrootsNostrSignerHandledRequest::respond_for_connection( Some(connection.connection_id.clone()), - RadrootsNostrConnectResponse::AuthUrl(auth_challenge.auth_url), + Response::AuthUrl(auth_challenge.auth_url), ) } RadrootsNostrSignerRequestAction::Allowed { .. } => { @@ -903,14 +878,15 @@ mod tests { use radroots_nostr::event::GenericBuilder; use radroots_nostr::event::Kind as RadrootsNostrKind; use radroots_nostr::tag::TagKind as RadrootsNostrTagKind; - use radroots_nostr_connect::prelude::{ - RADROOTS_NOSTR_CONNECT_RPC_KIND, RadrootsNostrConnectMethod, - RadrootsNostrConnectPermission, RadrootsNostrConnectPermissions, - RadrootsNostrConnectRemoteSessionCapability, RadrootsNostrConnectRequest, - RadrootsNostrConnectRequestMessage, RadrootsNostrConnectResponse, - UnsignedEvent as ConnectUnsignedEvent, - }; use radroots_nostr_connect::uri::RelayUrl as ConnectRelayUrl; + use radroots_nostr_connect::{ + Method, Permission, Request, Response, + message::{ + RPC_KIND, RemoteSessionCapability, RequestMessage, + UnsignedEvent as ConnectUnsignedEvent, + }, + permission::Permissions, + }; use std::sync::{ Arc, RwLock, atomic::{AtomicBool, Ordering}, @@ -1089,15 +1065,12 @@ mod tests { fn filtered_requested_permissions( &self, - requested_permissions: &RadrootsNostrConnectPermissions, - ) -> RadrootsNostrConnectPermissions { + requested_permissions: &Permissions, + ) -> Permissions { requested_permissions.clone() } - fn auto_granted_permissions( - &self, - requested_permissions: &RadrootsNostrConnectPermissions, - ) -> RadrootsNostrConnectPermissions { + fn auto_granted_permissions(&self, requested_permissions: &Permissions) -> Permissions { requested_permissions.clone() } @@ -1105,7 +1078,7 @@ mod tests { &self, _backend: &B, _connection: &crate::model::RadrootsNostrSignerConnectionRecord, - _request_message: &RadrootsNostrConnectRequestMessage, + _request_message: &RequestMessage, ) -> Result<Option<String>, RadrootsNostrSignerError> { Ok(self.prepare_denial.map(ToOwned::to_owned)) } @@ -1169,23 +1142,18 @@ mod tests { RadrootsNostrSignerNip46Handler::new(backend, policy, vec![primary_relay()], test_signer()) } - fn connect_request(secret: Option<&str>) -> RadrootsNostrConnectRequestMessage { - connect_request_with_permissions( - secret, - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Nip04Encrypt, - )], - ) + fn connect_request(secret: Option<&str>) -> RequestMessage { + connect_request_with_permissions(secret, vec![Permission::new(Method::Nip04Encrypt)]) } fn connect_request_with_permissions( secret: Option<&str>, - permissions: Vec<RadrootsNostrConnectPermission>, - ) -> RadrootsNostrConnectRequestMessage { + permissions: Vec<Permission>, + ) -> RequestMessage { let signer_public_key = test_signer().signer_identity.public_key(); - RadrootsNostrConnectRequestMessage::new( + RequestMessage::new( "req-connect", - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key(signer_public_key), secret: secret.map(ToOwned::to_owned), requested_permissions: permissions.into(), @@ -1194,22 +1162,19 @@ mod tests { ) } - fn all_runtime_permissions() -> Vec<RadrootsNostrConnectPermission> { + fn all_runtime_permissions() -> Vec<Permission> { vec![ - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::SignEvent), - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip04Encrypt), - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip04Decrypt), - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip44Encrypt), - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip44Decrypt), - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::SwitchRelays), + Permission::new(Method::SignEvent), + Permission::new(Method::Nip04Encrypt), + Permission::new(Method::Nip04Decrypt), + Permission::new(Method::Nip44Encrypt), + Permission::new(Method::Nip44Decrypt), + Permission::new(Method::SwitchRelays), ] } - fn request_message( - id: &str, - request: RadrootsNostrConnectRequest, - ) -> RadrootsNostrConnectRequestMessage { - RadrootsNostrConnectRequestMessage::new(id, request) + fn request_message(id: &str, request: Request) -> RequestMessage { + RequestMessage::new(id, request) } fn unsigned_user_event(kind: u16) -> UnsignedEvent { @@ -1247,7 +1212,7 @@ mod tests { TestSigner, >, client_public_key: RadrootsNostrPublicKey, - permissions: Vec<RadrootsNostrConnectPermission>, + permissions: Vec<Permission>, ) { let outcome = handler .handle_request( @@ -1261,9 +1226,7 @@ mod tests { )); } - fn response_from_outcome( - outcome: RadrootsNostrSignerHandledRequestOutcome, - ) -> RadrootsNostrConnectResponse { + fn response_from_outcome(outcome: RadrootsNostrSignerHandledRequestOutcome) -> Response { match outcome.handled_request { RadrootsNostrSignerHandledRequest::Respond { response, .. } => *response, other => panic!("unexpected handled request: {other:?}"), @@ -1275,32 +1238,22 @@ mod tests { let codec = super::RadrootsNostrSignerNip46Codec::new(test_signer()); let _ = codec.filter().expect("codec filter"); let client_public_key = fixture_carol_public_key(); - let request = request_message("req-parse", RadrootsNostrConnectRequest::Ping); + let request = request_message("req-parse", Request::Ping); let raw = serde_json::to_string(&request).expect("serialize request"); - let event = GenericBuilder::new( - RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND), - raw, - ) - .sign_with_keys(&Keys::generate()) - .expect("sign request event"); + let event = GenericBuilder::new(RadrootsNostrKind::Custom(RPC_KIND), raw) + .sign_with_keys(&Keys::generate()) + .expect("sign request event"); let parsed = codec.parse_request_event(&event).expect("parse request"); assert_eq!(parsed, request); let response_builder = codec - .build_response_event( - client_public_key, - "req-parse", - RadrootsNostrConnectResponse::Pong, - ) + .build_response_event(client_public_key, "req-parse", Response::Pong) .expect("response builder"); let response_event = response_builder .sign_with_keys(&Keys::generate()) .expect("sign response event"); - assert_eq!( - response_event.kind, - RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND) - ); + assert_eq!(response_event.kind, RadrootsNostrKind::Custom(RPC_KIND)); assert!(response_event.tags.iter().any(|tag| { tag.kind() == RadrootsNostrTagKind::p() && tag.content() == Some(client_public_key.to_hex().as_str()) @@ -1316,15 +1269,12 @@ mod tests { .build_response_event( client_public_key, "req-handler", - RadrootsNostrConnectResponse::ConnectAcknowledged, + Response::ConnectAcknowledged, ) .expect("handler response") .sign_with_keys(&Keys::generate()) .expect("sign handler response event"); - assert_eq!( - handler_event.kind, - RadrootsNostrKind::Custom(RADROOTS_NOSTR_CONNECT_RPC_KIND) - ); + assert_eq!(handler_event.kind, RadrootsNostrKind::Custom(RPC_KIND)); } #[test] @@ -1334,65 +1284,62 @@ mod tests { assert_eq!( codec - .crypto_response(RadrootsNostrConnectRequest::Nip04Encrypt { + .crypto_response(Request::Nip04Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain".to_owned(), }) .expect("nip04 encrypt"), - RadrootsNostrConnectResponse::Nip04Encrypt("plain".to_owned()) + Response::Nip04Encrypt("plain".to_owned()) ); assert_eq!( codec - .crypto_response(RadrootsNostrConnectRequest::Nip04Decrypt { + .crypto_response(Request::Nip04Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher".to_owned(), }) .expect("nip04 decrypt"), - RadrootsNostrConnectResponse::Nip04Decrypt("cipher".to_owned()) + Response::Nip04Decrypt("cipher".to_owned()) ); assert_eq!( codec - .crypto_response(RadrootsNostrConnectRequest::Nip44Encrypt { + .crypto_response(Request::Nip44Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain44".to_owned(), }) .expect("nip44 encrypt"), - RadrootsNostrConnectResponse::Nip44Encrypt("plain44".to_owned()) + Response::Nip44Encrypt("plain44".to_owned()) ); assert_eq!( codec - .crypto_response(RadrootsNostrConnectRequest::Nip44Decrypt { + .crypto_response(Request::Nip44Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher44".to_owned(), }) .expect("nip44 decrypt"), - RadrootsNostrConnectResponse::Nip44Decrypt("cipher44".to_owned()) + Response::Nip44Decrypt("cipher44".to_owned()) ); let non_crypto = codec - .crypto_response(RadrootsNostrConnectRequest::Ping) + .crypto_response(Request::Ping) .expect("non crypto response"); - assert!(matches!( - non_crypto, - RadrootsNostrConnectResponse::Error { .. } - )); + assert!(matches!(non_crypto, Response::Error { .. })); let failing_codec = super::RadrootsNostrSignerNip46Codec::new(test_signer_with_options(false, true)); for request in [ - RadrootsNostrConnectRequest::Nip04Encrypt { + Request::Nip04Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain".to_owned(), }, - RadrootsNostrConnectRequest::Nip04Decrypt { + Request::Nip04Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher".to_owned(), }, - RadrootsNostrConnectRequest::Nip44Encrypt { + Request::Nip44Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain44".to_owned(), }, - RadrootsNostrConnectRequest::Nip44Decrypt { + Request::Nip44Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher44".to_owned(), }, @@ -1401,7 +1348,7 @@ mod tests { failing_codec .crypto_response(request) .expect("failing crypto response"), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); } @@ -1409,7 +1356,7 @@ mod tests { .sign_event_response(unsigned_user_event(1)) .expect("signing response"); match signing { - RadrootsNostrConnectResponse::Error { error, .. } => { + Response::Error { error, .. } => { assert!(error.contains("failed to sign event")); } other => panic!("unexpected sign response: {other:?}"), @@ -1419,10 +1366,7 @@ mod tests { super::RadrootsNostrSignerNip46Codec::new(test_signer_with_options(true, false)) .sign_event_response(unsigned_user_event(1)) .expect("signed response"); - assert!(matches!( - signed, - RadrootsNostrConnectResponse::SignedEvent(_) - )); + assert!(matches!(signed, Response::SignedEvent(_))); } #[test] @@ -1440,7 +1384,7 @@ mod tests { .expect("rate limit outcome"); assert_eq!( response_from_outcome(rate_limited), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "slow down".to_owned(), } @@ -1457,7 +1401,7 @@ mod tests { .expect("registration denial"); assert_eq!( response_from_outcome(denied_registration), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "client public key denied by policy".to_owned(), } @@ -1493,14 +1437,14 @@ mod tests { .expect("initial connect"); assert_eq!( response_from_outcome(first), - RadrootsNostrConnectResponse::ConnectSecretEcho(secret.to_owned()) + Response::ConnectSecretEcho(secret.to_owned()) ); let existing = existing_handler .handle_request(client_public_key, connect_request(Some(secret))) .expect("existing connect by secret"); assert_eq!( response_from_outcome(existing), - RadrootsNostrConnectResponse::ConnectSecretEcho(secret.to_owned()) + Response::ConnectSecretEcho(secret.to_owned()) ); let denied_backend = embedded_backend(); @@ -1520,7 +1464,7 @@ mod tests { .expect("existing connect denied"); assert_eq!( response_from_outcome(denied), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "client public key denied by policy".to_owned(), } @@ -1539,50 +1483,44 @@ mod tests { handler .handle_request( client_public_key, - request_message("req-pubkey", RadrootsNostrConnectRequest::GetPublicKey), + request_message("req-pubkey", Request::GetPublicKey), ) .expect("pubkey") ), - RadrootsNostrConnectResponse::UserPublicKey(_) + Response::UserPublicKey(_) )); assert!(matches!( response_from_outcome( handler .handle_request( client_public_key, - request_message( - "req-capability", - RadrootsNostrConnectRequest::GetSessionCapability, - ), + request_message("req-capability", Request::GetSessionCapability,), ) .expect("capability") ), - RadrootsNostrConnectResponse::RemoteSessionCapability(_) + Response::RemoteSessionCapability(_) )); assert_eq!( response_from_outcome( handler .handle_request( client_public_key, - request_message("req-relays", RadrootsNostrConnectRequest::SwitchRelays), + request_message("req-relays", Request::SwitchRelays), ) .expect("relays") ), - RadrootsNostrConnectResponse::RelayList(vec![connect_relay(primary_relay())]) + Response::RelayList(vec![connect_relay(primary_relay())]) ); assert!(matches!( response_from_outcome( handler .handle_request( client_public_key, - request_message( - "req-sign", - RadrootsNostrConnectRequest::SignEvent(connect_unsigned_event(1)), - ), + request_message("req-sign", Request::SignEvent(connect_unsigned_event(1)),), ) .expect("sign") ), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); assert_eq!( response_from_outcome( @@ -1591,7 +1529,7 @@ mod tests { client_public_key, request_message( "req-nip04-decrypt", - RadrootsNostrConnectRequest::Nip04Decrypt { + Request::Nip04Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher".to_owned(), }, @@ -1599,7 +1537,7 @@ mod tests { ) .expect("nip04 decrypt") ), - RadrootsNostrConnectResponse::Nip04Decrypt("cipher".to_owned()) + Response::Nip04Decrypt("cipher".to_owned()) ); assert_eq!( response_from_outcome( @@ -1608,7 +1546,7 @@ mod tests { client_public_key, request_message( "req-nip44-encrypt", - RadrootsNostrConnectRequest::Nip44Encrypt { + Request::Nip44Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain".to_owned(), }, @@ -1616,7 +1554,7 @@ mod tests { ) .expect("nip44 encrypt") ), - RadrootsNostrConnectResponse::Nip44Encrypt("plain".to_owned()) + Response::Nip44Encrypt("plain".to_owned()) ); let unimplemented = handler @@ -1624,9 +1562,8 @@ mod tests { client_public_key, request_message( "req-custom", - RadrootsNostrConnectRequest::Custom { - method: RadrootsNostrConnectMethod::custom("publish_note") - .expect("valid custom NIP-46 method"), + Request::Custom { + method: Method::custom("publish_note").expect("valid custom NIP-46 method"), params: vec![], }, ), @@ -1634,7 +1571,7 @@ mod tests { .expect("custom"); assert!(matches!( response_from_outcome(unimplemented), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let limited_backend = embedded_backend(); @@ -1642,16 +1579,14 @@ mod tests { connect_with_permissions( &limited_handler, client_public_key, - vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Nip04Encrypt, - )], + vec![Permission::new(Method::Nip04Encrypt)], ); let denied_crypto = limited_handler .handle_request( client_public_key, request_message( "req-denied", - RadrootsNostrConnectRequest::Nip04Decrypt { + Request::Nip04Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher".to_owned(), }, @@ -1660,7 +1595,7 @@ mod tests { .expect("denied crypto"); assert!(matches!( response_from_outcome(denied_crypto), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let denied_backend = embedded_backend(); @@ -1676,32 +1611,32 @@ mod tests { let denied_base = denying_handler .handle_request( client_public_key, - request_message("req-policy-denied", RadrootsNostrConnectRequest::Ping), + request_message("req-policy-denied", Request::Ping), ) .expect("policy denied"); assert!(matches!( response_from_outcome(denied_base), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let denied_sign = denying_handler .handle_request( client_public_key, request_message( "req-policy-denied-sign", - RadrootsNostrConnectRequest::SignEvent(connect_unsigned_event(1)), + Request::SignEvent(connect_unsigned_event(1)), ), ) .expect("policy denied sign"); assert!(matches!( response_from_outcome(denied_sign), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let denied_crypto = denying_handler .handle_request( client_public_key, request_message( "req-policy-denied-crypto", - RadrootsNostrConnectRequest::Nip44Encrypt { + Request::Nip44Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain".to_owned(), }, @@ -1710,7 +1645,7 @@ mod tests { .expect("policy denied crypto"); assert!(matches!( response_from_outcome(denied_crypto), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let challenge_backend = embedded_backend(); @@ -1728,12 +1663,12 @@ mod tests { let auth_url = challenge_handler .handle_request( client_public_key, - request_message("req-challenge", RadrootsNostrConnectRequest::Ping), + request_message("req-challenge", Request::Ping), ) .expect("challenge"); assert_eq!( response_from_outcome(auth_url), - RadrootsNostrConnectResponse::AuthUrl("https://example.test/auth".to_owned()) + Response::AuthUrl("https://example.test/auth".to_owned()) ); } @@ -1763,7 +1698,7 @@ mod tests { let error = handler .handle_request( client_public_key, - request_message("req-audit-save", RadrootsNostrConnectRequest::Ping), + request_message("req-audit-save", Request::Ping), ) .expect_err("audit persistence failure"); assert!(error.to_string().contains("test store save failure")); @@ -1775,9 +1710,9 @@ mod tests { let client_public_key = fixture_carol_public_key(); for request in [ - RadrootsNostrConnectRequest::Ping, - RadrootsNostrConnectRequest::SignEvent(connect_unsigned_event(1)), - RadrootsNostrConnectRequest::Nip04Decrypt { + Request::Ping, + Request::SignEvent(connect_unsigned_event(1)), + Request::Nip04Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "cipher".to_owned(), }, @@ -1790,7 +1725,7 @@ mod tests { .expect("unauthorized request"); assert_eq!( response_from_outcome(outcome), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "unauthorized".to_owned(), } @@ -1812,11 +1747,8 @@ mod tests { &handler, client_public_key, vec![ - RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "kind:1", - ), - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Nip04Encrypt), + Permission::with_parameter(Method::SignEvent, "kind:1"), + Permission::new(Method::Nip04Encrypt), ], ); @@ -1827,12 +1759,12 @@ mod tests { client_public_key, request_message( "req-allowed-sign", - RadrootsNostrConnectRequest::SignEvent(connect_unsigned_event(1)), + Request::SignEvent(connect_unsigned_event(1)), ), ) .expect("allowed sign") ), - RadrootsNostrConnectResponse::SignedEvent(_) + Response::SignedEvent(_) )); assert_eq!( response_from_outcome( @@ -1841,7 +1773,7 @@ mod tests { client_public_key, request_message( "req-allowed-nip04-encrypt", - RadrootsNostrConnectRequest::Nip04Encrypt { + Request::Nip04Encrypt { public_key: connect_public_key(client_public_key), plaintext: "plain".to_owned(), }, @@ -1849,7 +1781,7 @@ mod tests { ) .expect("allowed nip04 encrypt") ), - RadrootsNostrConnectResponse::Nip04Encrypt("plain".to_owned()) + Response::Nip04Encrypt("plain".to_owned()) ); } @@ -1861,7 +1793,7 @@ mod tests { connect_with_permissions(&handler, client_public_key, all_runtime_permissions()); let connection = registered_connection(&backend, &client_public_key); - let base = request_message("req-eval-ping", RadrootsNostrConnectRequest::Ping); + let base = request_message("req-eval-ping", Request::Ping); let base_eval = backend .evaluate_request(&connection.connection_id, base.clone()) .expect("base evaluation"); @@ -1871,12 +1803,12 @@ mod tests { .handle_authorized_request_evaluation(base, base_eval) .expect("base authorized") ), - RadrootsNostrConnectResponse::Pong + Response::Pong ); let mut denied_base_eval = backend .evaluate_request( &connection.connection_id, - request_message("req-eval-denied-ping", RadrootsNostrConnectRequest::Ping), + request_message("req-eval-denied-ping", Request::Ping), ) .expect("denied base evaluation"); denied_base_eval.action = RadrootsNostrSignerRequestAction::Denied { @@ -1886,17 +1818,17 @@ mod tests { response_from_outcome( handler .handle_authorized_request_evaluation( - request_message("req-eval-denied-ping", RadrootsNostrConnectRequest::Ping), + request_message("req-eval-denied-ping", Request::Ping), denied_base_eval, ) .expect("denied base authorized") ), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let crypto = request_message( "req-eval-crypto", - RadrootsNostrConnectRequest::Nip44Decrypt { + Request::Nip44Decrypt { public_key: connect_public_key(client_public_key), ciphertext: "sealed".to_owned(), }, @@ -1910,12 +1842,12 @@ mod tests { .handle_authorized_request_evaluation(crypto, crypto_eval) .expect("crypto authorized") ), - RadrootsNostrConnectResponse::Nip44Decrypt("sealed".to_owned()) + Response::Nip44Decrypt("sealed".to_owned()) ); let sign = request_message( "req-eval-sign", - RadrootsNostrConnectRequest::SignEvent(connect_unsigned_event(1)), + Request::SignEvent(connect_unsigned_event(1)), ); let sign_eval = backend .evaluate_request(&connection.connection_id, sign.clone()) @@ -1926,14 +1858,13 @@ mod tests { .handle_authorized_request_evaluation(sign, sign_eval) .expect("sign authorized") ), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let custom = request_message( "req-eval-custom", - RadrootsNostrConnectRequest::Custom { - method: RadrootsNostrConnectMethod::custom("do_work") - .expect("valid custom NIP-46 method"), + Request::Custom { + method: Method::custom("do_work").expect("valid custom NIP-46 method"), params: vec![], }, ); @@ -1946,7 +1877,7 @@ mod tests { .handle_authorized_request_evaluation(custom, custom_eval) .expect("custom authorized") ), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); } @@ -1961,10 +1892,7 @@ mod tests { let parts = super::connect_response_outcome(&connection, Some("secret".to_owned())) .into_publish_parts() .expect("publish parts"); - assert_eq!( - parts.0, - RadrootsNostrConnectResponse::ConnectSecretEcho("secret".to_owned()) - ); + assert_eq!(parts.0, Response::ConnectSecretEcho("secret".to_owned())); assert_eq!(parts.1, Some(connection.connection_id.clone())); assert_eq!(parts.2, Some(connection.connection_id.clone())); assert!( @@ -1973,15 +1901,15 @@ mod tests { .is_none() ); assert!( - RadrootsNostrSignerHandledRequest::respond(RadrootsNostrConnectResponse::Pong) + RadrootsNostrSignerHandledRequest::respond(Response::Pong) .into_publish_parts() .is_some() ); assert_eq!( response_from_outcome(RadrootsNostrSignerHandledRequestOutcome::respond( - RadrootsNostrConnectResponse::Pong, + Response::Pong, )), - RadrootsNostrConnectResponse::Pong + Response::Pong ); assert_eq!( @@ -1991,9 +1919,9 @@ mod tests { client_public_key, )), ), - RadrootsNostrConnectResponse::UserPublicKey(connect_public_key(client_public_key)) + Response::UserPublicKey(connect_public_key(client_public_key)) ); - let capability = RadrootsNostrConnectRemoteSessionCapability { + let capability = RemoteSessionCapability { user_public_key: connect_public_key(client_public_key), relays: vec![connect_relay(primary_relay())], permissions: all_runtime_permissions().into(), @@ -2003,7 +1931,7 @@ mod tests { &connection, RadrootsNostrSignerRequestResponseHint::RemoteSessionCapability(capability.clone(),), ), - RadrootsNostrConnectResponse::RemoteSessionCapability(capability) + Response::RemoteSessionCapability(capability) ); assert_eq!( super::response_from_hint( @@ -2012,18 +1940,18 @@ mod tests { primary_relay(), )]), ), - RadrootsNostrConnectResponse::RelayList(vec![connect_relay(primary_relay())]) + Response::RelayList(vec![connect_relay(primary_relay())]) ); assert_eq!( super::response_from_hint( &connection, RadrootsNostrSignerRequestResponseHint::RelayList(Vec::new()), ), - RadrootsNostrConnectResponse::RelayList(vec![connect_relay(primary_relay())]) + Response::RelayList(vec![connect_relay(primary_relay())]) ); assert!(matches!( super::response_from_hint(&connection, RadrootsNostrSignerRequestResponseHint::None), - RadrootsNostrConnectResponse::Error { .. } + Response::Error { .. } )); let denied = super::handled_request_for_action( @@ -2031,7 +1959,7 @@ mod tests { RadrootsNostrSignerRequestAction::Denied { reason: "blocked".to_owned(), }, - || Ok(RadrootsNostrConnectResponse::Pong), + || Ok(Response::Pong), ) .expect("denied action"); assert!(matches!( @@ -2045,7 +1973,7 @@ mod tests { required_permission: None, response_hint: RadrootsNostrSignerRequestResponseHint::Pong, }, - || Ok(RadrootsNostrConnectResponse::Pong), + || Ok(Response::Pong), ) .expect("allowed action"); assert!(matches!( @@ -2062,12 +1990,12 @@ mod tests { ) .expect("challenge"), pending_request: RadrootsNostrSignerPendingRequest::new( - request_message("req-pending", RadrootsNostrConnectRequest::Ping), + request_message("req-pending", Request::Ping), 1, ) .expect("pending"), }, - || Ok(RadrootsNostrConnectResponse::Pong), + || Ok(Response::Pong), ) .expect("challenged action"); assert!(matches!( @@ -2098,12 +2026,12 @@ mod tests { let outcome = handler_with_backend(backend) .handle_request( client_public_key, - request_message("req-ambiguous", RadrootsNostrConnectRequest::Ping), + request_message("req-ambiguous", Request::Ping), ) .expect("ambiguous request"); assert_eq!( response_from_outcome(outcome), - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "ambiguous client sessions".to_owned(), } @@ -2122,7 +2050,7 @@ mod tests { assert!(connect.audit.is_none()); match connect.handled_request { RadrootsNostrSignerHandledRequest::Respond { response, .. } => { - assert_eq!(*response, RadrootsNostrConnectResponse::ConnectAcknowledged); + assert_eq!(*response, Response::ConnectAcknowledged); } other => panic!("unexpected connect outcome: {other:?}"), } @@ -2130,15 +2058,12 @@ mod tests { let ping = handler .handle_request( client_public_key, - RadrootsNostrConnectRequestMessage::new( - "req-ping", - RadrootsNostrConnectRequest::Ping, - ), + RequestMessage::new("req-ping", Request::Ping), ) .expect("ping outcome"); match ping.handled_request { RadrootsNostrSignerHandledRequest::Respond { response, .. } => { - assert_eq!(*response, RadrootsNostrConnectResponse::Pong); + assert_eq!(*response, Response::Pong); } other => panic!("unexpected ping outcome: {other:?}"), } @@ -2202,7 +2127,7 @@ mod tests { assert_eq!( response, - RadrootsNostrConnectResponse::Error { + Response::Error { result: None, error: "sign_event pubkey does not match the managed user identity".to_owned(), } @@ -2227,15 +2152,12 @@ mod tests { let request = connect_request(None); assert_eq!( request.request, - RadrootsNostrConnectRequest::Connect { + Request::Connect { remote_signer_public_key: connect_public_key( test_signer().signer_identity.public_key(), ), secret: None, - requested_permissions: vec![RadrootsNostrConnectPermission::new( - RadrootsNostrConnectMethod::Nip04Encrypt, - )] - .into(), + requested_permissions: vec![Permission::new(Method::Nip04Encrypt,)].into(), client_metadata: None, } ); diff --git a/crates/nostr_signer/src/store.rs b/crates/nostr_signer/src/store.rs @@ -25,10 +25,7 @@ use nostr::RelayUrl; #[cfg(feature = "native")] use radroots_identity::PublicIdentity; #[cfg(feature = "native")] -use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, RadrootsNostrConnectPermission, - RadrootsNostrConnectRequestMessage, -}; +use radroots_nostr_connect::{Method, Permission, message::RequestMessage, uri::ClientMetadata}; #[cfg(feature = "native")] use radroots_sql_core::SqlExecutor; #[cfg(feature = "native")] @@ -252,9 +249,8 @@ impl RadrootsNostrSignerStore for RadrootsNostrSqliteSignerStore { row.connection_id )) })?; - let request_message = parse_json_field::<RadrootsNostrConnectRequestMessage>( - row.request_message_json.as_str(), - )?; + let request_message = + parse_json_field::<RequestMessage>(row.request_message_json.as_str())?; state.connections[index].pending_request = Some( RadrootsNostrSignerPendingRequest::new(request_message, row.created_at_unix)?, ); @@ -515,7 +511,7 @@ impl SignerConnectionRow { client_metadata: self .client_metadata_json .as_deref() - .map(parse_json_field::<RadrootsNostrConnectClientMetadata>) + .map(parse_json_field::<ClientMetadata>) .transpose()?, granted_permissions: Vec::new(), relays: Vec::new(), @@ -548,7 +544,7 @@ impl SignerConnectionPermissionGrantRow { Ok(RadrootsNostrSignerPermissionGrant { permission: self .permission - .parse::<RadrootsNostrConnectPermission>() + .parse::<Permission>() .map_err(|error| RadrootsNostrSignerError::Store(error.to_string()))?, granted_at_unix: self.granted_at_unix, }) @@ -600,7 +596,7 @@ impl SignerRequestAuditRow { connection_id: self.connection_id.parse()?, method: self .method - .parse::<RadrootsNostrConnectMethod>() + .parse::<Method>() .map_err(|error| RadrootsNostrSignerError::Store(error.to_string()))?, decision: parse_request_decision(self.decision.as_str())?, message: self.message, @@ -881,10 +877,9 @@ mod tests { primary_relay, secondary_relay, }; #[cfg(feature = "native")] - use radroots_nostr_connect::prelude::{ - RadrootsNostrConnectClientMetadata, RadrootsNostrConnectMethod, - RadrootsNostrConnectPermission, RadrootsNostrConnectPermissions, - RadrootsNostrConnectRequest, RadrootsNostrConnectRequestMessage, + use radroots_nostr_connect::{ + Method, Permission, Request, message::RequestMessage, permission::Permissions, + uri::ClientMetadata, }; use std::thread; @@ -990,8 +985,8 @@ mod tests { } #[cfg(feature = "native")] - fn sample_request_message(id: &str) -> RadrootsNostrConnectRequestMessage { - RadrootsNostrConnectRequestMessage::new(id, RadrootsNostrConnectRequest::Ping) + fn sample_request_message(id: &str) -> RequestMessage { + RequestMessage::new(id, Request::Ping) } #[cfg(feature = "native")] @@ -1004,8 +999,8 @@ mod tests { signer_identity.clone(), RadrootsNostrSignerConnectionDraft::new(fixture_carol_public_key(), user_identity) .with_connect_secret("sqlite-secret") - .with_client_metadata(RadrootsNostrConnectClientMetadata { - requested_permissions: RadrootsNostrConnectPermissions::default(), + .with_client_metadata(ClientMetadata { + requested_permissions: Permissions::default(), name: Some("Example Client".to_owned()), url: Some("https://client.example.com/".to_owned()), image: Some("https://client.example.com/icon.png".to_owned()), @@ -1013,11 +1008,8 @@ mod tests { .with_relays(vec![primary_relay(), secondary_relay()]) .with_requested_permissions( vec![ - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Ping), - RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "kind:1", - ), + Permission::new(Method::Ping), + Permission::with_parameter(Method::SignEvent, "kind:1"), ] .into(), ) @@ -1033,15 +1025,9 @@ mod tests { connection.last_request_at_unix = Some(135); connection.mark_connect_secret_consumed(125); connection.granted_permissions = vec![ + RadrootsNostrSignerPermissionGrant::new(Permission::new(Method::Ping), 110), RadrootsNostrSignerPermissionGrant::new( - RadrootsNostrConnectPermission::new(RadrootsNostrConnectMethod::Ping), - 110, - ), - RadrootsNostrSignerPermissionGrant::new( - RadrootsNostrConnectPermission::with_parameter( - RadrootsNostrConnectMethod::SignEvent, - "kind:1", - ), + Permission::with_parameter(Method::SignEvent, "kind:1"), 111, ), ]; @@ -1064,7 +1050,7 @@ mod tests { audit_records: vec![RadrootsNostrSignerRequestAuditRecord::new( RadrootsNostrSignerRequestId::parse("audit-1").expect("request id"), connection_id, - RadrootsNostrConnectMethod::Ping, + Method::Ping, RadrootsNostrSignerRequestDecision::Allowed, Some("permitted".to_owned()), 150,