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:
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,