commit 7966cb007b2f29dd7c447fccab93eba1ca79159e
parent 3c4db5b84bdea7c30d7cadfe07e0e9f370422c43
Author: triesap <tyson@radroots.org>
Date: Sun, 22 Mar 2026 18:15:25 +0000
nostr-signer: migrate test fixtures to approved sources
Diffstat:
8 files changed, 355 insertions(+), 459 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -2311,6 +2311,7 @@ dependencies = [
"radroots-identity",
"radroots-nostr-connect",
"radroots-runtime",
+ "radroots-test-fixtures",
"serde",
"serde_json",
"sha2",
diff --git a/crates/nostr-signer/Cargo.toml b/crates/nostr-signer/Cargo.toml
@@ -29,6 +29,7 @@ url = { workspace = true }
uuid = { workspace = true }
[dev-dependencies]
+radroots-test-fixtures = { workspace = true }
serde_json = { workspace = true }
tempfile = { workspace = true }
diff --git a/crates/nostr-signer/src/capability.rs b/crates/nostr-signer/src/capability.rs
@@ -163,23 +163,15 @@ impl RadrootsNostrSignerConnectionRecord {
mod tests {
use super::*;
use crate::model::{RadrootsNostrSignerConnectionDraft, RadrootsNostrSignerConnectionRecord};
- use nostr::{Keys, PublicKey, RelayUrl, SecretKey};
- use radroots_identity::{RadrootsIdentity, RadrootsIdentityPublic};
+ use crate::test_support::{
+ fixture_alice_identity, fixture_bob_identity, fixture_carol_identity,
+ fixture_diego_public_key, primary_relay,
+ };
+ use radroots_identity::RadrootsIdentityPublic;
use radroots_nostr_connect::prelude::{
RadrootsNostrConnectMethod, RadrootsNostrConnectPermission,
};
- fn public_identity(secret_hex: &str) -> RadrootsIdentityPublic {
- RadrootsIdentity::from_secret_key_str(secret_hex)
- .expect("identity")
- .to_public()
- }
-
- fn public_key(secret_hex: &str) -> PublicKey {
- let secret = SecretKey::from_hex(secret_hex).expect("secret");
- Keys::new(secret).public_key()
- }
-
fn assert_public_identity_matches(
actual: &RadrootsIdentityPublic,
expected: &RadrootsIdentityPublic,
@@ -191,8 +183,7 @@ mod tests {
#[test]
fn local_capability_reports_secret_backing_and_public_identity() {
- let public_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000001");
+ let public_identity = fixture_alice_identity();
let capability =
RadrootsNostrSignerCapability::LocalAccount(RadrootsNostrLocalSignerCapability::new(
public_identity.id.clone(),
@@ -212,15 +203,13 @@ mod tests {
#[test]
fn remote_session_capability_reflects_connection_effective_permissions() {
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000002");
- let user_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000003");
+ let signer_identity = fixture_bob_identity();
+ let user_identity = fixture_carol_identity();
let record = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::new_v7(),
signer_identity.clone(),
RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000004"),
+ fixture_diego_public_key(),
user_identity.clone(),
)
.with_requested_permissions(
@@ -229,7 +218,7 @@ mod tests {
)]
.into(),
)
- .with_relays(vec![RelayUrl::parse("wss://relay.example").expect("relay")]),
+ .with_relays(vec![primary_relay()]),
1,
);
@@ -247,8 +236,8 @@ mod tests {
fn remote_session_builder_helpers_replace_default_fields() {
let capability = RadrootsNostrRemoteSessionSignerCapability::new(
RadrootsNostrSignerConnectionId::new_v7(),
- public_identity("0000000000000000000000000000000000000000000000000000000000000005"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000006"),
+ fixture_alice_identity(),
+ fixture_bob_identity(),
)
.with_permissions(
vec![RadrootsNostrConnectPermission::new(
@@ -256,7 +245,7 @@ mod tests {
)]
.into(),
)
- .with_relays(vec![RelayUrl::parse("wss://relay.example").expect("relay")]);
+ .with_relays(vec![primary_relay()]);
assert_eq!(capability.permissions.as_slice().len(), 1);
assert_eq!(capability.relays.len(), 1);
diff --git a/crates/nostr-signer/src/evaluation.rs b/crates/nostr-signer/src/evaluation.rs
@@ -203,28 +203,26 @@ fn identity_public_key(
#[cfg(test)]
mod tests {
use super::*;
- use nostr::{Keys, SecretKey, Timestamp, UnsignedEvent};
- use radroots_identity::RadrootsIdentity;
+ use crate::test_support::{
+ api_primary_https, fixture_alice_identity, fixture_alice_public_key, fixture_bob_identity,
+ fixture_carol_public_key, fixture_diego_identity, primary_relay, synthetic_public_identity,
+ synthetic_public_key,
+ };
+ use nostr::{PublicKey, Timestamp, UnsignedEvent};
+ use radroots_identity::RadrootsIdentityPublic;
use serde_json::json;
- fn public_identity(secret_hex: &str) -> RadrootsIdentityPublic {
- RadrootsIdentity::from_secret_key_str(secret_hex)
- .expect("identity")
- .to_public()
- }
-
- fn public_key(secret_hex: &str) -> PublicKey {
- let secret = SecretKey::from_hex(secret_hex).expect("secret");
- Keys::new(secret).public_key()
+ fn public_identity(index: u32) -> RadrootsIdentityPublic {
+ synthetic_public_identity(index)
}
- fn relay(url: &str) -> RelayUrl {
- RelayUrl::parse(url).expect("relay")
+ fn public_key(index: u32) -> PublicKey {
+ synthetic_public_key(index)
}
fn unsigned_event(kind: u16) -> UnsignedEvent {
serde_json::from_value(json!({
- "pubkey": public_key("0000000000000000000000000000000000000000000000000000000000000001").to_hex(),
+ "pubkey": fixture_alice_public_key().to_hex(),
"created_at": Timestamp::from(1).as_secs(),
"kind": kind,
"tags": [],
@@ -236,12 +234,12 @@ mod tests {
fn connection() -> RadrootsNostrSignerConnectionRecord {
RadrootsNostrSignerConnectionRecord::new(
crate::model::RadrootsNostrSignerConnectionId::new_v7(),
- public_identity("0000000000000000000000000000000000000000000000000000000000000002"),
+ fixture_bob_identity(),
RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000003"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000004"),
+ fixture_carol_public_key(),
+ fixture_diego_identity(),
)
- .with_relays(vec![relay("wss://relay.example")]),
+ .with_relays(vec![primary_relay()]),
1,
)
}
@@ -283,30 +281,22 @@ mod tests {
)]
.into();
let proposal = RadrootsNostrSignerConnectProposal {
- client_public_key: public_key(
- "0000000000000000000000000000000000000000000000000000000000000005",
- ),
+ client_public_key: public_key(5),
connect_secret: Some("secret".into()),
requested_permissions: requested_permissions.clone(),
};
- let draft = proposal.into_connection_draft(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000006",
- ));
+ let draft = proposal.into_connection_draft(fixture_alice_identity());
assert_eq!(draft.connect_secret.as_deref(), Some("secret"));
assert_eq!(draft.requested_permissions, requested_permissions);
let no_secret = RadrootsNostrSignerConnectProposal {
- client_public_key: public_key(
- "0000000000000000000000000000000000000000000000000000000000000007",
- ),
+ client_public_key: public_key(7),
connect_secret: None,
requested_permissions: RadrootsNostrConnectPermissions::default(),
}
- .into_connection_draft(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000008",
- ));
+ .into_connection_draft(fixture_bob_identity());
assert!(no_secret.connect_secret.is_none());
}
@@ -317,7 +307,7 @@ mod tests {
};
let challenged = RadrootsNostrSignerRequestAction::Challenged {
auth_challenge: crate::model::RadrootsNostrSignerAuthChallenge::new(
- "https://auth.example",
+ api_primary_https(),
1,
)
.expect("challenge"),
@@ -387,9 +377,7 @@ mod tests {
assert!(!request_allowed_by_permissions(
&vec![sign_kind, nip44].into(),
&RadrootsNostrConnectRequest::Nip04Encrypt {
- public_key: public_key(
- "0000000000000000000000000000000000000000000000000000000000000007",
- ),
+ public_key: public_key(7),
plaintext: "hello".into(),
},
));
@@ -427,8 +415,7 @@ mod tests {
#[test]
fn required_permission_and_response_hint_cover_request_variants() {
let connection = connection();
- let public_key =
- public_key("0000000000000000000000000000000000000000000000000000000000000008");
+ let public_key = public_key(8);
let connect = RadrootsNostrConnectRequest::Connect {
remote_signer_public_key: public_key,
secret: Some("secret".into()),
@@ -510,14 +497,13 @@ mod tests {
);
assert_eq!(
response_hint_for_request(&connection, &switch_relays).expect("relay hint"),
- RadrootsNostrSignerRequestResponseHint::RelayList(vec![relay("wss://relay.example")])
+ RadrootsNostrSignerRequestResponseHint::RelayList(vec![primary_relay()])
);
}
#[test]
fn invalid_identity_public_key_returns_invalid_state() {
- let mut identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000009");
+ let mut identity = public_identity(9);
identity.public_key_hex = "invalid".into();
let err = identity_public_key(&identity).expect_err("invalid identity");
diff --git a/crates/nostr-signer/src/lib.rs b/crates/nostr-signer/src/lib.rs
@@ -8,6 +8,9 @@ pub mod manager;
pub mod model;
pub mod store;
+#[cfg(test)]
+mod test_support;
+
pub mod prelude {
pub use crate::capability::{
RadrootsNostrLocalSignerAvailability, RadrootsNostrLocalSignerCapability,
diff --git a/crates/nostr-signer/src/manager.rs b/crates/nostr-signer/src/manager.rs
@@ -844,33 +844,30 @@ mod tests {
RadrootsNostrSignerRequestResponseHint, RadrootsNostrSignerSessionLookup,
};
use crate::store::RadrootsNostrSignerStore;
- use nostr::{Keys, SecretKey, Timestamp, UnsignedEvent};
- use radroots_identity::RadrootsIdentity;
+ use crate::test_support::{
+ api_primary_https, fixture_alice_identity, primary_relay, secondary_relay,
+ synthetic_public_identity, synthetic_public_key, tertiary_relay,
+ };
+ use nostr::{PublicKey, Timestamp, UnsignedEvent};
+ use radroots_identity::RadrootsIdentityPublic;
use radroots_nostr_connect::prelude::RadrootsNostrConnectPermission;
use serde_json::json;
use std::sync::Arc;
use std::thread;
- fn public_identity(secret_hex: &str) -> RadrootsIdentityPublic {
- RadrootsIdentity::from_secret_key_str(secret_hex)
- .expect("identity")
- .to_public()
+ fn public_identity(index: u32) -> RadrootsIdentityPublic {
+ synthetic_public_identity(index)
}
- fn invalid_public_identity(secret_hex: &str) -> RadrootsIdentityPublic {
- let mut identity = public_identity(secret_hex);
- let other =
- SecretKey::from_hex("00000000000000000000000000000000000000000000000000000000000000ff")
- .expect("secret");
+ fn invalid_public_identity(index: u32) -> RadrootsIdentityPublic {
+ let mut identity = public_identity(index);
identity.id =
- radroots_identity::RadrootsIdentityId::parse(&Keys::new(other).public_key().to_hex())
- .expect("id");
+ radroots_identity::RadrootsIdentityId::parse(&public_key(0xff).to_hex()).expect("id");
identity
}
- fn public_key(secret_hex: &str) -> PublicKey {
- let secret = SecretKey::from_hex(secret_hex).expect("secret");
- Keys::new(secret).public_key()
+ fn public_key(index: u32) -> PublicKey {
+ synthetic_public_key(index)
}
fn permission(
@@ -883,10 +880,6 @@ mod tests {
}
}
- fn relay(url: &str) -> RelayUrl {
- RelayUrl::parse(url).expect("relay")
- }
-
fn request_message(id: &str) -> RadrootsNostrConnectRequestMessage {
RadrootsNostrConnectRequestMessage::new(
id,
@@ -903,7 +896,7 @@ mod tests {
fn unsigned_event(kind: u16) -> UnsignedEvent {
serde_json::from_value(json!({
- "pubkey": public_key("00000000000000000000000000000000000000000000000000000000000000a1").to_hex(),
+ "pubkey": public_key(0xa1).to_hex(),
"created_at": Timestamp::from(1).as_secs(),
"kind": kind,
"tags": [],
@@ -1115,8 +1108,7 @@ mod tests {
#[test]
fn set_signer_identity_validates_and_persists() {
let manager = RadrootsNostrSignerManager::new_in_memory();
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000001");
+ let signer_identity = fixture_alice_identity();
manager
.set_signer_identity(signer_identity.clone())
.expect("set signer");
@@ -1128,9 +1120,7 @@ mod tests {
assert_same_public_identity(&loaded, &signer_identity);
let err = manager
- .set_signer_identity(invalid_public_identity(
- "0000000000000000000000000000000000000000000000000000000000000002",
- ))
+ .set_signer_identity(invalid_public_identity(0x2))
.expect_err("invalid identity");
assert!(
err.to_string()
@@ -1143,37 +1133,26 @@ mod tests {
let manager = RadrootsNostrSignerManager::new_in_memory();
let err = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000003"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000004"),
+ public_key(0x3),
+ public_identity(0x4),
))
.expect_err("missing signer");
assert!(err.to_string().contains("missing signer identity"));
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000005",
- ))
+ .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 record = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000006"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000007",
- ),
- )
- .with_connect_secret(" secret ")
- .with_requested_permissions(
- vec![sign_event.clone(), ping.clone(), sign_event.clone()].into(),
- )
- .with_relays(vec![
- relay("wss://z.example"),
- relay("wss://a.example"),
- relay("wss://a.example"),
- ]),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x6), public_identity(0x7))
+ .with_connect_secret(" secret ")
+ .with_requested_permissions(
+ vec![sign_event.clone(), ping.clone(), sign_event.clone()].into(),
+ )
+ .with_relays(vec![primary_relay(), secondary_relay(), secondary_relay()]),
)
.expect("register");
@@ -1191,29 +1170,18 @@ mod tests {
);
assert_eq!(record.auth_state, RadrootsNostrSignerAuthState::NotRequired);
assert_eq!(record.requested_permissions.as_slice(), &[sign_event, ping]);
- assert_eq!(
- record
- .relays
- .iter()
- .map(|relay| relay.as_str().to_owned())
- .collect::<Vec<_>>(),
- vec!["wss://a.example", "wss://z.example"]
- );
+ assert_eq!(record.relays, vec![secondary_relay(), primary_relay()]);
}
#[test]
fn register_connection_enforces_identity_and_uniqueness_rules() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000008",
- ))
+ .set_signer_identity(public_identity(0x8))
.expect("set signer");
- let user_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000009");
- let client_public_key =
- public_key("0000000000000000000000000000000000000000000000000000000000000010");
+ let user_identity = public_identity(0x9);
+ let client_public_key = public_key(0x10);
let pending = manager
.register_connection(
RadrootsNostrSignerConnectionDraft::new(client_public_key, user_identity.clone())
@@ -1239,13 +1207,8 @@ mod tests {
let duplicate_secret = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000011"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000012",
- ),
- )
- .with_connect_secret("shared-secret"),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x11), public_identity(0x12))
+ .with_connect_secret("shared-secret"),
)
.expect_err("duplicate secret");
assert!(
@@ -1256,10 +1219,8 @@ mod tests {
let invalid_user = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000013"),
- invalid_public_identity(
- "0000000000000000000000000000000000000000000000000000000000000014",
- ),
+ public_key(0x13),
+ invalid_public_identity(0x14),
))
.expect_err("invalid user identity");
assert!(
@@ -1273,22 +1234,14 @@ mod tests {
fn manager_query_helpers_find_connections() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000015",
- ))
+ .set_signer_identity(public_identity(0x15))
.expect("set signer");
- let client_public_key =
- public_key("0000000000000000000000000000000000000000000000000000000000000016");
+ let client_public_key = public_key(0x16);
let record = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- client_public_key,
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000017",
- ),
- )
- .with_connect_secret("lookup-secret"),
+ RadrootsNostrSignerConnectionDraft::new(client_public_key, public_identity(0x17))
+ .with_connect_secret("lookup-secret"),
)
.expect("register");
@@ -1319,9 +1272,7 @@ mod tests {
fn granted_permissions_and_approval_enforce_subset_rules() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000018",
- ))
+ .set_signer_identity(public_identity(0x18))
.expect("set signer");
let requested = vec![
permission(RadrootsNostrConnectMethod::SignEvent, Some("kind:1")),
@@ -1334,14 +1285,11 @@ mod tests {
)];
let pending = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000019"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000020",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x19), public_identity(0x20))
+ .with_requested_permissions(requested.clone().into())
+ .with_approval_requirement(
+ RadrootsNostrSignerApprovalRequirement::ExplicitUser,
),
- )
- .with_requested_permissions(requested.clone().into())
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser),
)
.expect("register");
@@ -1389,8 +1337,8 @@ mod tests {
let auto = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000021"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000022"),
+ public_key(0x21),
+ public_identity(0x22),
))
.expect("register auto");
let err = manager
@@ -1403,14 +1351,11 @@ mod tests {
let terminal_pending = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000040"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000041",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x40), public_identity(0x41))
+ .with_connect_secret("terminal-secret")
+ .with_approval_requirement(
+ RadrootsNostrSignerApprovalRequirement::ExplicitUser,
),
- )
- .with_connect_secret("terminal-secret")
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser),
)
.expect("register terminal");
manager
@@ -1430,8 +1375,8 @@ mod tests {
let unrestricted = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000023"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000024"),
+ public_key(0x23),
+ public_identity(0x24),
))
.expect("register unrestricted");
let unrestricted_grants = manager
@@ -1444,20 +1389,15 @@ mod tests {
fn reject_revoke_and_relay_updates_cover_terminal_paths() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000025",
- ))
+ .set_signer_identity(public_identity(0x25))
.expect("set signer");
let rejected = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000026"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000027",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x26), public_identity(0x27))
+ .with_connect_secret("shared-secret")
+ .with_approval_requirement(
+ RadrootsNostrSignerApprovalRequirement::ExplicitUser,
),
- )
- .with_connect_secret("shared-secret")
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser),
)
.expect("register reject");
let rejected = manager
@@ -1479,7 +1419,7 @@ mod tests {
);
let relay_err = manager
- .update_relays(&rejected.connection_id, vec![relay("wss://relay.example")])
+ .update_relays(&rejected.connection_id, vec![primary_relay()])
.expect_err("update rejected");
assert!(
relay_err
@@ -1493,28 +1433,17 @@ mod tests {
let active = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000028"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000029"),
+ public_key(0x28),
+ public_identity(0x29),
))
.expect("register active");
let active = manager
.update_relays(
&active.connection_id,
- vec![
- relay("wss://b.example"),
- relay("wss://a.example"),
- relay("wss://a.example"),
- ],
+ vec![tertiary_relay(), secondary_relay(), secondary_relay()],
)
.expect("update relays");
- assert_eq!(
- active
- .relays
- .iter()
- .map(|relay| relay.as_str().to_owned())
- .collect::<Vec<_>>(),
- vec!["wss://a.example", "wss://b.example"]
- );
+ assert_eq!(active.relays, vec![secondary_relay(), tertiary_relay()]);
let revoked = manager
.revoke_connection(&active.connection_id, Some("manual".into()))
@@ -1544,7 +1473,7 @@ mod tests {
);
let require_auth_err = manager
- .require_auth_challenge(&active.connection_id, "https://auth.example")
+ .require_auth_challenge(&active.connection_id, api_primary_https())
.expect_err("require auth revoked");
assert!(
require_auth_err
@@ -1575,14 +1504,12 @@ mod tests {
fn authentication_and_request_audit_paths_are_recorded() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000030",
- ))
+ .set_signer_identity(public_identity(0x30))
.expect("set signer");
let record = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000031"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000032"),
+ public_key(0x31),
+ public_identity(0x32),
))
.expect("register");
@@ -1651,19 +1578,20 @@ mod tests {
fn auth_challenge_and_pending_request_state_are_persisted_and_replayed() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000034",
- ))
+ .set_signer_identity(public_identity(0x34))
.expect("set signer");
let record = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000035"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000036"),
+ public_key(0x35),
+ public_identity(0x36),
))
.expect("register");
let required = manager
- .require_auth_challenge(&record.connection_id, " https://auth.example/flow ")
+ .require_auth_challenge(
+ &record.connection_id,
+ format!(" {}/flow ", api_primary_https()).as_str(),
+ )
.expect("require auth");
assert_eq!(required.auth_state, RadrootsNostrSignerAuthState::Pending);
assert_eq!(
@@ -1672,7 +1600,7 @@ mod tests {
.as_ref()
.expect("auth challenge")
.auth_url,
- "https://auth.example/flow"
+ format!("{}/flow", api_primary_https())
);
assert!(required.pending_request.is_none());
@@ -1745,19 +1673,20 @@ mod tests {
fn restored_authorized_auth_challenge_requeues_pending_request() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000134",
- ))
+ .set_signer_identity(public_identity(0x134))
.expect("set signer");
let record = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000135"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000136"),
+ public_key(0x135),
+ public_identity(0x136),
))
.expect("register");
manager
- .require_auth_challenge(&record.connection_id, "https://auth.example/flow")
+ .require_auth_challenge(
+ &record.connection_id,
+ format!("{}/flow", api_primary_https()).as_str(),
+ )
.expect("require auth");
manager
.set_pending_request(&record.connection_id, request_message("req-replay"))
@@ -1796,19 +1725,12 @@ mod tests {
fn connect_secret_consumption_persists_and_remains_idempotent() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000037",
- ))
+ .set_signer_identity(public_identity(0x37))
.expect("set signer");
let record = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000038"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000039",
- ),
- )
- .with_connect_secret("one-shot-secret"),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x38), public_identity(0x39))
+ .with_connect_secret("one-shot-secret"),
)
.expect("register");
@@ -1855,9 +1777,7 @@ mod tests {
assert_eq!(loaded_state.version, RADROOTS_NOSTR_SIGNER_STORE_VERSION);
let manager = RadrootsNostrSignerManager::new(save_error_store).expect("manager");
let err = manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000033",
- ))
+ .set_signer_identity(public_identity(0x33))
.expect_err("save error");
assert!(err.to_string().contains("store save failed"));
}
@@ -1866,9 +1786,7 @@ mod tests {
fn mutation_methods_cover_remaining_error_paths() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000051",
- ))
+ .set_signer_identity(public_identity(0x51))
.expect("set signer");
let missing_id = RadrootsNostrSignerConnectionId::parse("missing-2").expect("id");
@@ -1888,10 +1806,10 @@ mod tests {
.revoke_connection(&missing_id, None)
.expect_err("missing revoke");
let missing_relays = manager
- .update_relays(&missing_id, vec![relay("wss://relay.example")])
+ .update_relays(&missing_id, vec![primary_relay()])
.expect_err("missing relays");
let missing_require_auth = manager
- .require_auth_challenge(&missing_id, "https://auth.example")
+ .require_auth_challenge(&missing_id, api_primary_https())
.expect_err("missing require auth");
let missing_pending_request = manager
.set_pending_request(&missing_id, request_message("req-missing-2"))
@@ -1926,14 +1844,11 @@ mod tests {
let requested = vec![permission(RadrootsNostrConnectMethod::Ping, None)];
let pending = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000052"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000053",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x52), public_identity(0x53))
+ .with_requested_permissions(requested.into())
+ .with_approval_requirement(
+ RadrootsNostrSignerApprovalRequirement::ExplicitUser,
),
- )
- .with_requested_permissions(requested.into())
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser),
)
.expect("register pending");
let invalid_approve = manager
@@ -1953,7 +1868,7 @@ mod tests {
);
let auth_required = manager
- .require_auth_challenge(&pending.connection_id, "https://auth.example")
+ .require_auth_challenge(&pending.connection_id, api_primary_https())
.expect("require auth");
assert_eq!(
auth_required.auth_state,
@@ -1979,16 +1894,14 @@ mod tests {
fn register_connection_rejects_invalid_persisted_signer_identity() {
let store = Arc::new(RadrootsNostrMemorySignerStore::new());
let mut state = RadrootsNostrSignerStoreState::default();
- state.signer_identity = Some(invalid_public_identity(
- "0000000000000000000000000000000000000000000000000000000000000054",
- ));
+ state.signer_identity = Some(invalid_public_identity(0x54));
store.save(&state).expect("seed state");
let manager = RadrootsNostrSignerManager::new(store).expect("manager");
let err = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000055"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000056"),
+ public_key(0x55),
+ public_identity(0x56),
))
.expect_err("invalid signer identity");
assert!(
@@ -2012,8 +1925,7 @@ mod tests {
poison_manager_state(&manager);
let connection_id = RadrootsNostrSignerConnectionId::parse("conn-1").expect("id");
- let client_public_key =
- public_key("0000000000000000000000000000000000000000000000000000000000000047");
+ let client_public_key = public_key(0x47);
let get_err = manager
.get_connection(&connection_id)
@@ -2055,8 +1967,7 @@ mod tests {
#[test]
fn evaluate_connect_request_reports_poisoned_state_lock() {
let store = Arc::new(RadrootsNostrMemorySignerStore::new());
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000057");
+ let signer_identity = public_identity(0x57);
let mut state = RadrootsNostrSignerStoreState::default();
state.signer_identity = Some(signer_identity.clone());
store.save(&state).expect("save state");
@@ -2066,7 +1977,7 @@ mod tests {
let err = manager
.evaluate_connect_request(
- public_key("0000000000000000000000000000000000000000000000000000000000000058"),
+ public_key(0x58),
RadrootsNostrConnectRequest::Connect {
remote_signer_public_key: PublicKey::parse(
signer_identity.public_key_hex.as_str(),
@@ -2085,13 +1996,10 @@ mod tests {
let manager = RadrootsNostrSignerManager::new_in_memory();
poison_manager_state(&manager);
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000048");
+ let signer_identity = public_identity(0x48);
let connection_id = RadrootsNostrSignerConnectionId::parse("conn-2").expect("id");
- let connect_draft = RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000049"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000050"),
- );
+ let connect_draft =
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x49), public_identity(0x50));
let set_signer_err = manager
.set_signer_identity(signer_identity)
@@ -2115,10 +2023,10 @@ mod tests {
.revoke_connection(&connection_id, Some("reason".into()))
.expect_err("poisoned revoke");
let update_relays_err = manager
- .update_relays(&connection_id, vec![relay("wss://relay.example")])
+ .update_relays(&connection_id, vec![primary_relay()])
.expect_err("poisoned relays");
let require_auth_err = manager
- .require_auth_challenge(&connection_id, "https://auth.example")
+ .require_auth_challenge(&connection_id, api_primary_https())
.expect_err("poisoned require auth");
let set_pending_request_err = manager
.set_pending_request(&connection_id, request_message("req-2"))
@@ -2193,21 +2101,16 @@ mod tests {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000042",
- ))
+ .set_signer_identity(public_identity(0x42))
.expect("set signer");
let initial = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000043"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000044",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x43), public_identity(0x44))
+ .with_connect_secret("reusable-secret")
+ .with_approval_requirement(
+ RadrootsNostrSignerApprovalRequirement::ExplicitUser,
),
- )
- .with_connect_secret("reusable-secret")
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser),
)
.expect("register initial");
manager
@@ -2216,13 +2119,8 @@ mod tests {
let reused = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000045"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000046",
- ),
- )
- .with_connect_secret("reusable-secret"),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x45), public_identity(0x46))
+ .with_connect_secret("reusable-secret"),
)
.expect("register reused secret");
@@ -2244,13 +2142,8 @@ mod tests {
let blocked_reuse = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000047"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000048",
- ),
- )
- .with_connect_secret("reusable-secret"),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x47), public_identity(0x48))
+ .with_connect_secret("reusable-secret"),
)
.expect_err("block consumed secret reuse");
assert!(matches!(
@@ -2262,25 +2155,18 @@ mod tests {
#[test]
fn session_lookup_and_connect_evaluation_cover_new_paths() {
let manager = RadrootsNostrSignerManager::new_in_memory();
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000060");
+ let signer_identity = public_identity(0x60);
let signer_public_key =
PublicKey::parse(signer_identity.public_key_hex.as_str()).expect("signer public key");
manager
.set_signer_identity(signer_identity)
.expect("set signer");
- let client_public_key =
- public_key("0000000000000000000000000000000000000000000000000000000000000061");
+ let client_public_key = public_key(0x61);
let primary = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- client_public_key,
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000062",
- ),
- )
- .with_connect_secret("connect-secret"),
+ RadrootsNostrSignerConnectionDraft::new(client_public_key, public_identity(0x62))
+ .with_connect_secret("connect-secret"),
)
.expect("register primary");
@@ -2300,13 +2186,8 @@ mod tests {
let second = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- client_public_key,
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000063",
- ),
- )
- .with_connect_secret("second-secret"),
+ RadrootsNostrSignerConnectionDraft::new(client_public_key, public_identity(0x63))
+ .with_connect_secret("second-secret"),
)
.expect("register second");
@@ -2326,10 +2207,7 @@ mod tests {
assert_same_connection(&found[1], &second);
let mismatch_secret = manager
- .lookup_session(
- &public_key("0000000000000000000000000000000000000000000000000000000000000064"),
- Some("connect-secret"),
- )
+ .lookup_session(&public_key(0x64), Some("connect-secret"))
.expect_err("secret mismatch");
assert!(
mismatch_secret
@@ -2338,10 +2216,7 @@ mod tests {
);
let none_lookup = manager
- .lookup_session(
- &public_key("0000000000000000000000000000000000000000000000000000000000000065"),
- None,
- )
+ .lookup_session(&public_key(0x65), None)
.expect("lookup none");
expect_none_lookup(none_lookup);
@@ -2370,9 +2245,7 @@ mod tests {
.evaluate_connect_request(
client_public_key,
RadrootsNostrConnectRequest::Connect {
- remote_signer_public_key: public_key(
- "0000000000000000000000000000000000000000000000000000000000000066",
- ),
+ remote_signer_public_key: public_key(0x66),
secret: None,
requested_permissions: RadrootsNostrConnectPermissions::default(),
},
@@ -2402,7 +2275,7 @@ mod tests {
let registration_connect = manager
.evaluate_connect_request(
- public_key("0000000000000000000000000000000000000000000000000000000000000067"),
+ public_key(0x67),
RadrootsNostrConnectRequest::Connect {
remote_signer_public_key: signer_public_key,
secret: Some(" fresh-secret ".into()),
@@ -2416,10 +2289,7 @@ mod tests {
)
.expect("registration connect request");
let proposal = expect_registration_connect(registration_connect);
- assert_eq!(
- proposal.client_public_key,
- public_key("0000000000000000000000000000000000000000000000000000000000000067")
- );
+ assert_eq!(proposal.client_public_key, public_key(0x67));
assert_eq!(proposal.connect_secret.as_deref(), Some("fresh-secret"));
assert_eq!(
proposal.requested_permissions.as_slice(),
@@ -2431,7 +2301,7 @@ mod tests {
let existing_secret_mismatch = manager
.evaluate_connect_request(
- public_key("0000000000000000000000000000000000000000000000000000000000000068"),
+ public_key(0x68),
RadrootsNostrConnectRequest::Connect {
remote_signer_public_key: signer_public_key,
secret: Some("connect-secret".into()),
@@ -2447,8 +2317,7 @@ mod tests {
let store = Arc::new(RadrootsNostrMemorySignerStore::new());
let mut invalid_state = RadrootsNostrSignerStoreState::default();
- let mut invalid_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000069");
+ let mut invalid_identity = public_identity(0x69);
invalid_identity.public_key_hex = "invalid".into();
invalid_state.signer_identity = Some(invalid_identity);
store
@@ -2457,7 +2326,7 @@ mod tests {
let invalid_manager = RadrootsNostrSignerManager::new(store).expect("invalid manager");
let invalid_signer_err = invalid_manager
.evaluate_connect_request(
- public_key("0000000000000000000000000000000000000000000000000000000000000070"),
+ public_key(0x70),
RadrootsNostrConnectRequest::Connect {
remote_signer_public_key: signer_public_key,
secret: None,
@@ -2476,26 +2345,19 @@ mod tests {
fn evaluate_request_covers_allowed_denied_and_challenged_paths() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000071",
- ))
+ .set_signer_identity(public_identity(0x71))
.expect("set signer");
let active = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000072"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000073",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x72), public_identity(0x73))
+ .with_requested_permissions(
+ vec![permission(
+ RadrootsNostrConnectMethod::SignEvent,
+ Some("kind:1"),
+ )]
+ .into(),
),
- )
- .with_requested_permissions(
- vec![permission(
- RadrootsNostrConnectMethod::SignEvent,
- Some("kind:1"),
- )]
- .into(),
- ),
)
.expect("register active");
@@ -2540,13 +2402,10 @@ mod tests {
let pending = manager
.register_connection(
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000074"),
- public_identity(
- "0000000000000000000000000000000000000000000000000000000000000075",
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x74), public_identity(0x75))
+ .with_approval_requirement(
+ RadrootsNostrSignerApprovalRequirement::ExplicitUser,
),
- )
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser),
)
.expect("register pending");
let pending_eval = manager
@@ -2556,12 +2415,12 @@ mod tests {
let challenged = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000076"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000077"),
+ public_key(0x76),
+ public_identity(0x77),
))
.expect("register challenged");
manager
- .require_auth_challenge(&challenged.connection_id, "https://auth.example")
+ .require_auth_challenge(&challenged.connection_id, api_primary_https())
.expect("require auth challenge");
let challenged_eval = manager
.evaluate_request(&challenged.connection_id, request_message("req-auth"))
@@ -2616,17 +2475,13 @@ mod tests {
#[test]
fn evaluate_request_reports_invalid_corrupted_auth_state() {
let store = Arc::new(RadrootsNostrMemorySignerStore::new());
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000078");
+ let signer_identity = public_identity(0x78);
let mut state = RadrootsNostrSignerStoreState::default();
state.signer_identity = Some(signer_identity.clone());
let mut record = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::new_v7(),
signer_identity,
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000079"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000080"),
- ),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x79), public_identity(0x80)),
1,
);
record.auth_state = RadrootsNostrSignerAuthState::Pending;
@@ -2645,15 +2500,13 @@ mod tests {
fn evaluate_request_reports_invalid_request_id_and_missing_connection() {
let manager = RadrootsNostrSignerManager::new_in_memory();
manager
- .set_signer_identity(public_identity(
- "0000000000000000000000000000000000000000000000000000000000000081",
- ))
+ .set_signer_identity(public_identity(0x81))
.expect("set signer");
let active = manager
.register_connection(RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000082"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000083"),
+ public_key(0x82),
+ public_identity(0x83),
))
.expect("register active");
@@ -2686,18 +2539,14 @@ mod tests {
fn evaluate_request_action_reports_pending_request_and_response_hint_errors() {
let mut pending_record = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::new_v7(),
- public_identity("0000000000000000000000000000000000000000000000000000000000000084"),
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000085"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000086"),
- ),
+ public_identity(0x84),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x85), public_identity(0x86)),
1,
);
pending_record.status = RadrootsNostrSignerConnectionStatus::Active;
pending_record.auth_state = RadrootsNostrSignerAuthState::Pending;
- pending_record.auth_challenge = Some(
- RadrootsNostrSignerAuthChallenge::new("https://auth.example", 1).expect("challenge"),
- );
+ pending_record.auth_challenge =
+ Some(RadrootsNostrSignerAuthChallenge::new(api_primary_https(), 1).expect("challenge"));
let invalid_pending = evaluate_request_action(
&mut pending_record,
&request_message_with_request(" ", RadrootsNostrConnectRequest::Ping),
@@ -2708,11 +2557,8 @@ mod tests {
let mut invalid_user_record = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::new_v7(),
- public_identity("0000000000000000000000000000000000000000000000000000000000000087"),
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000088"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000089"),
- ),
+ public_identity(0x87),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x88), public_identity(0x89)),
1,
);
invalid_user_record.status = RadrootsNostrSignerConnectionStatus::Active;
diff --git a/crates/nostr-signer/src/model.rs b/crates/nostr-signer/src/model.rs
@@ -640,21 +640,22 @@ fn normalize_optional_string(value: &str) -> Option<String> {
#[cfg(test)]
mod tests {
use super::*;
- use nostr::{Keys, SecretKey};
- use radroots_identity::RadrootsIdentity;
+ use crate::test_support::{
+ api_primary_https, fixture_alice_identity, fixture_bob_identity, fixture_carol_public_key,
+ primary_relay, synthetic_public_identity, synthetic_public_key,
+ };
+ use nostr::PublicKey;
+ use radroots_identity::RadrootsIdentityPublic;
use serde_json::json;
use std::str::FromStr;
use tempfile::tempdir;
- fn public_identity(secret_hex: &str) -> RadrootsIdentityPublic {
- RadrootsIdentity::from_secret_key_str(secret_hex)
- .expect("identity")
- .to_public()
+ fn public_identity(index: u32) -> RadrootsIdentityPublic {
+ synthetic_public_identity(index)
}
- fn public_key(secret_hex: &str) -> PublicKey {
- let secret = SecretKey::from_hex(secret_hex).expect("secret");
- Keys::new(secret).public_key()
+ fn public_key(index: u32) -> PublicKey {
+ synthetic_public_key(index)
}
fn request_message(id: &str) -> RadrootsNostrConnectRequestMessage {
@@ -711,10 +712,10 @@ mod tests {
RadrootsNostrConnectMethod::SignEvent,
"kind:1",
);
- let relay = RelayUrl::parse("wss://relay.example").expect("relay");
+ let relay = primary_relay();
let draft = RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000001"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000002"),
+ fixture_carol_public_key(),
+ fixture_bob_identity(),
)
.with_connect_secret(" secret ")
.with_requested_permissions(vec![permission.clone()].into())
@@ -732,17 +733,13 @@ mod tests {
#[test]
fn connection_record_defaults_follow_approval_requirement_and_tracking_helpers() {
- let signer_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000003");
- let user_identity =
- public_identity("0000000000000000000000000000000000000000000000000000000000000004");
+ let signer_identity = fixture_alice_identity();
+ let user_identity = fixture_bob_identity();
let connection_id = RadrootsNostrSignerConnectionId::parse("conn-1").expect("id");
- let draft = RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000005"),
- user_identity,
- )
- .with_connect_secret(" secret ")
- .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser);
+ let draft =
+ RadrootsNostrSignerConnectionDraft::new(fixture_carol_public_key(), user_identity)
+ .with_connect_secret(" secret ")
+ .with_approval_requirement(RadrootsNostrSignerApprovalRequirement::ExplicitUser);
let mut record =
RadrootsNostrSignerConnectionRecord::new(connection_id, signer_identity, draft, 10);
@@ -767,8 +764,11 @@ mod tests {
record.mark_request(16);
record.mark_connect_secret_consumed(17);
record.require_auth_challenge(
- RadrootsNostrSignerAuthChallenge::new("https://auth.example/path", 18)
- .expect("auth challenge"),
+ RadrootsNostrSignerAuthChallenge::new(
+ format!("{}/path", api_primary_https()).as_str(),
+ 18,
+ )
+ .expect("auth challenge"),
);
record.set_pending_request(
RadrootsNostrSignerPendingRequest::new(request_message("req-1"), 20)
@@ -777,11 +777,8 @@ mod tests {
let replay = record.authorize_auth_challenge(22).expect("replay");
let no_challenge_replay = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::parse("conn-1b").expect("id"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000009"),
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000010"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000011"),
- ),
+ public_identity(0x9),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x10), public_identity(0x11)),
24,
)
.authorize_auth_challenge(25);
@@ -834,11 +831,8 @@ mod tests {
let grant = RadrootsNostrSignerPermissionGrant::new(permission.clone(), 42);
let mut record = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::parse("conn-2").expect("id"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000006"),
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000007"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000008"),
- ),
+ public_identity(0x6),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x7), public_identity(0x8)),
20,
);
record.granted_permissions = vec![grant];
@@ -872,12 +866,9 @@ mod tests {
.into();
let auto_record = RadrootsNostrSignerConnectionRecord::new(
RadrootsNostrSignerConnectionId::new_v7(),
- public_identity("0000000000000000000000000000000000000000000000000000000000000031"),
- RadrootsNostrSignerConnectionDraft::new(
- public_key("0000000000000000000000000000000000000000000000000000000000000032"),
- public_identity("0000000000000000000000000000000000000000000000000000000000000033"),
- )
- .with_requested_permissions(requested.clone()),
+ public_identity(0x31),
+ RadrootsNostrSignerConnectionDraft::new(public_key(0x32), public_identity(0x33))
+ .with_requested_permissions(requested.clone()),
1,
);
assert_eq!(auto_record.effective_permissions(), requested);
@@ -969,9 +960,10 @@ mod tests {
.expect_err("invalid pending request id");
assert!(invalid_pending.to_string().contains("invalid request id"));
+ let auth_url = format!(" {} ", api_primary_https());
let challenge =
- RadrootsNostrSignerAuthChallenge::new(" https://auth.example ", 31).expect("challenge");
- assert_eq!(challenge.auth_url, "https://auth.example/");
+ RadrootsNostrSignerAuthChallenge::new(auth_url.as_str(), 31).expect("challenge");
+ assert_eq!(challenge.auth_url, format!("{}/", api_primary_https()));
let invalid_challenge =
RadrootsNostrSignerAuthChallenge::new("not-a-url", 31).expect_err("invalid challenge");
@@ -1056,9 +1048,9 @@ mod tests {
fn connection_record_serde_migrates_legacy_connect_secret_and_validates_new_fields() {
let record_json = json!({
"connection_id": "conn-legacy",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000009").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000010"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000011"),
+ "client_public_key": public_key(0x9).to_hex(),
+ "signer_identity": public_identity(0x10),
+ "user_identity": public_identity(0x11),
"connect_secret": " legacy-secret ",
"requested_permissions": "",
"granted_permissions": [],
@@ -1073,12 +1065,12 @@ mod tests {
"last_request_at_unix": null
});
- let decoded_without_secret: RadrootsNostrSignerConnectionRecord = serde_json::from_value(
- json!({
+ let decoded_without_secret: RadrootsNostrSignerConnectionRecord =
+ serde_json::from_value(json!({
"connection_id": "conn-no-secret",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000008").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000007"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000006"),
+ "client_public_key": public_key(0x8).to_hex(),
+ "signer_identity": public_identity(0x7),
+ "user_identity": public_identity(0x6),
"requested_permissions": "",
"granted_permissions": [],
"relays": [],
@@ -1089,9 +1081,8 @@ mod tests {
"updated_at_unix": 0,
"last_authenticated_at_unix": null,
"last_request_at_unix": null
- }),
- )
- .expect("deserialize record without secret");
+ }))
+ .expect("deserialize record without secret");
assert!(decoded_without_secret.connect_secret_hash.is_none());
assert!(
decoded_without_secret
@@ -1099,12 +1090,12 @@ mod tests {
.is_none()
);
- let decoded_with_null_secret: RadrootsNostrSignerConnectionRecord = serde_json::from_value(
- json!({
+ let decoded_with_null_secret: RadrootsNostrSignerConnectionRecord =
+ serde_json::from_value(json!({
"connection_id": "conn-null-secret",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000005").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000004"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000003"),
+ "client_public_key": public_key(0x5).to_hex(),
+ "signer_identity": public_identity(0x4),
+ "user_identity": public_identity(0x3),
"connect_secret_hash": null,
"requested_permissions": "",
"granted_permissions": [],
@@ -1116,9 +1107,8 @@ mod tests {
"updated_at_unix": 0,
"last_authenticated_at_unix": null,
"last_request_at_unix": null
- }),
- )
- .expect("deserialize record with null secret");
+ }))
+ .expect("deserialize record with null secret");
assert!(decoded_with_null_secret.connect_secret_hash.is_none());
assert!(
decoded_with_null_secret
@@ -1149,12 +1139,12 @@ mod tests {
let valid_hash = RadrootsNostrSignerConnectSecretHash::from_secret("explicit-secret")
.expect("valid hash");
- let decoded_new_format: RadrootsNostrSignerConnectionRecord = serde_json::from_value(
- json!({
+ let decoded_new_format: RadrootsNostrSignerConnectionRecord =
+ serde_json::from_value(json!({
"connection_id": "conn-new",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000015").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000016"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000017"),
+ "client_public_key": public_key(0x15).to_hex(),
+ "signer_identity": public_identity(0x16),
+ "user_identity": public_identity(0x17),
"connect_secret_hash": {
"algorithm": "sha256",
"digest_hex": valid_hash.digest_hex
@@ -1170,9 +1160,8 @@ mod tests {
"updated_at_unix": 3,
"last_authenticated_at_unix": null,
"last_request_at_unix": null
- }),
- )
- .expect("deserialize new-format record");
+ }))
+ .expect("deserialize new-format record");
assert!(
decoded_new_format
.connect_secret_hash
@@ -1187,9 +1176,9 @@ mod tests {
let path = temp.path().join("connection-record.json");
let reader_json = json!({
"connection_id": "conn-reader",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000021").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000022"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000023"),
+ "client_public_key": public_key(0x21).to_hex(),
+ "signer_identity": public_identity(0x22),
+ "user_identity": public_identity(0x23),
"connect_secret_hash": {
"algorithm": "sha256",
"digest_hex": RadrootsNostrSignerConnectSecretHash::from_secret("reader-secret")
@@ -1203,7 +1192,7 @@ mod tests {
"approval_state": "NotRequired",
"auth_state": "Pending",
"auth_challenge": {
- "auth_url": "https://auth.example/reader",
+ "auth_url": format!("{}/reader", api_primary_https()),
"required_at_unix": 5
},
"status": "Active",
@@ -1234,14 +1223,14 @@ mod tests {
.as_ref()
.expect("reader auth challenge")
.auth_url,
- "https://auth.example/reader"
+ format!("{}/reader", api_primary_https())
);
let invalid_hash_json = json!({
"connection_id": "conn-invalid",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000012").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000013"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000014"),
+ "client_public_key": public_key(0x12).to_hex(),
+ "signer_identity": public_identity(0x13),
+ "user_identity": public_identity(0x14),
"connect_secret_hash": {
"algorithm": "sha256",
"digest_hex": "not-hex"
@@ -1254,7 +1243,7 @@ mod tests {
"status": "Active",
"auth_state": "Authorized",
"auth_challenge": {
- "auth_url": "https://auth.example",
+ "auth_url": api_primary_https(),
"required_at_unix": 2
},
"status_reason": null,
@@ -1272,12 +1261,12 @@ mod tests {
.contains("invalid connect secret digest")
);
- let invalid_nonhex_hash = serde_json::from_value::<RadrootsNostrSignerConnectionRecord>(
- json!({
+ let invalid_nonhex_hash =
+ serde_json::from_value::<RadrootsNostrSignerConnectionRecord>(json!({
"connection_id": "conn-invalid-nonhex",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000018").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000019"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000020"),
+ "client_public_key": public_key(0x18).to_hex(),
+ "signer_identity": public_identity(0x19),
+ "user_identity": public_identity(0x20),
"connect_secret_hash": {
"algorithm": "sha256",
"digest_hex": "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
@@ -1292,9 +1281,8 @@ mod tests {
"updated_at_unix": 4,
"last_authenticated_at_unix": null,
"last_request_at_unix": null
- }),
- )
- .expect_err("invalid nonhex hash");
+ }))
+ .expect_err("invalid nonhex hash");
assert!(
invalid_nonhex_hash
.to_string()
@@ -1304,9 +1292,9 @@ mod tests {
let invalid_connect_secret_hash_type =
serde_json::from_value::<RadrootsNostrSignerConnectionRecord>(json!({
"connection_id": "conn-invalid-type",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000024").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000025"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000026"),
+ "client_public_key": public_key(0x24).to_hex(),
+ "signer_identity": public_identity(0x25),
+ "user_identity": public_identity(0x26),
"connect_secret_hash": 7,
"requested_permissions": "",
"granted_permissions": [],
@@ -1327,9 +1315,9 @@ mod tests {
&invalid_connect_secret_hash_path,
serde_json::to_vec(&json!({
"connection_id": "conn-invalid-type-reader",
- "client_public_key": public_key("0000000000000000000000000000000000000000000000000000000000000027").to_hex(),
- "signer_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000028"),
- "user_identity": public_identity("0000000000000000000000000000000000000000000000000000000000000029"),
+ "client_public_key": public_key(0x27).to_hex(),
+ "signer_identity": public_identity(0x28),
+ "user_identity": public_identity(0x29),
"connect_secret_hash": 9,
"requested_permissions": "",
"granted_permissions": [],
diff --git a/crates/nostr-signer/src/test_support.rs b/crates/nostr-signer/src/test_support.rs
@@ -0,0 +1,82 @@
+use nostr::{Keys, PublicKey, RelayUrl, SecretKey};
+use radroots_identity::{RadrootsIdentity, RadrootsIdentityPublic};
+use radroots_test_fixtures::{
+ API_PRIMARY_HTTPS, ApprovedFixtureIdentity, FIXTURE_ALICE, FIXTURE_BOB, FIXTURE_CAROL,
+ FIXTURE_DIEGO, RELAY_PRIMARY_WSS, RELAY_SECONDARY_WSS, RELAY_TERTIARY_WSS,
+};
+
+fn approved_public_identity(identity: ApprovedFixtureIdentity) -> RadrootsIdentityPublic {
+ RadrootsIdentity::from_secret_key_str(identity.secret_key_hex)
+ .expect("identity")
+ .to_public()
+}
+
+fn approved_public_key(identity: ApprovedFixtureIdentity) -> PublicKey {
+ let secret = SecretKey::from_hex(identity.secret_key_hex).expect("secret");
+ Keys::new(secret).public_key()
+}
+
+fn relay(url: &str) -> RelayUrl {
+ RelayUrl::parse(url).expect("relay")
+}
+
+pub(crate) fn fixture_alice_identity() -> RadrootsIdentityPublic {
+ approved_public_identity(FIXTURE_ALICE)
+}
+
+pub(crate) fn fixture_alice_public_key() -> PublicKey {
+ approved_public_key(FIXTURE_ALICE)
+}
+
+pub(crate) fn fixture_bob_identity() -> RadrootsIdentityPublic {
+ approved_public_identity(FIXTURE_BOB)
+}
+
+pub(crate) fn fixture_carol_identity() -> RadrootsIdentityPublic {
+ approved_public_identity(FIXTURE_CAROL)
+}
+
+pub(crate) fn fixture_carol_public_key() -> PublicKey {
+ approved_public_key(FIXTURE_CAROL)
+}
+
+pub(crate) fn fixture_diego_identity() -> RadrootsIdentityPublic {
+ approved_public_identity(FIXTURE_DIEGO)
+}
+
+pub(crate) fn fixture_diego_public_key() -> PublicKey {
+ approved_public_key(FIXTURE_DIEGO)
+}
+
+pub(crate) fn primary_relay() -> RelayUrl {
+ relay(RELAY_PRIMARY_WSS)
+}
+
+pub(crate) fn secondary_relay() -> RelayUrl {
+ relay(RELAY_SECONDARY_WSS)
+}
+
+pub(crate) fn tertiary_relay() -> RelayUrl {
+ relay(RELAY_TERTIARY_WSS)
+}
+
+pub(crate) fn api_primary_https() -> &'static str {
+ API_PRIMARY_HTTPS
+}
+
+pub(crate) fn synthetic_secret_hex(index: u32) -> String {
+ format!("{index:064x}")
+}
+
+pub(crate) fn synthetic_public_identity(index: u32) -> RadrootsIdentityPublic {
+ let secret_hex = synthetic_secret_hex(index);
+ RadrootsIdentity::from_secret_key_str(secret_hex.as_str())
+ .expect("identity")
+ .to_public()
+}
+
+pub(crate) fn synthetic_public_key(index: u32) -> PublicKey {
+ let secret_hex = synthetic_secret_hex(index);
+ let secret = SecretKey::from_hex(secret_hex.as_str()).expect("secret");
+ Keys::new(secret).public_key()
+}