conformance.rs (3501B)
1 use radroots_event::id::Nip01Coordinate; 2 use radroots_identity::PublicKey; 3 use radroots_nostr::{ 4 Error, 5 event::{coordinate_from_nostr, coordinate_to_nostr}, 6 key::{public_key_from_npub, public_key_to_npub}, 7 tag::{from_parts, to_parts}, 8 }; 9 10 const PUBLIC_KEY: &str = "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"; 11 12 #[test] 13 fn public_protocol_conversions_are_canonical_and_typed() { 14 let public_key = PublicKey::from_hex(PUBLIC_KEY).expect("canonical public key"); 15 let npub = public_key_to_npub(public_key).expect("NIP-19 public key"); 16 assert!(npub.starts_with("npub1")); 17 assert_eq!( 18 public_key_from_npub(&npub).expect("canonical public key"), 19 public_key 20 ); 21 22 let coordinate = Nip01Coordinate::parse(format!("30402:{PUBLIC_KEY}:listing-1")) 23 .expect("canonical coordinate"); 24 let nostr_coordinate = coordinate_to_nostr(&coordinate).expect("Nostr coordinate"); 25 assert_eq!( 26 coordinate_from_nostr(&nostr_coordinate).expect("canonical coordinate"), 27 coordinate 28 ); 29 30 let parts = vec!["t".to_owned(), "soil".to_owned()]; 31 let tag = from_parts(parts.clone()).expect("Nostr tag"); 32 assert_eq!(to_parts(&tag), parts); 33 assert!(matches!(from_parts(Vec::new()), Err(Error::TagConversion))); 34 } 35 36 #[cfg(feature = "signing")] 37 #[tokio::test] 38 async fn public_local_signer_signs_only_the_exact_authorized_plan() { 39 use radroots_event::{GenericEventDraft, contract::AuthorRole, envelope::kind::KIND_GEOCHAT}; 40 use radroots_event_codec::authoring::AuthoredEventPlan; 41 use radroots_nostr::{key::SecretKey, signing::LocalSigner}; 42 use radroots_protocol::runtime::v1::OperationId; 43 use radroots_signing::{ 44 Actor, AuthoredArtifactId, SignRequest, Signer, SigningIntentId, SigningOperationId, 45 actor::ActorSource, 46 request::{CancellationPolicy, SignPolicy}, 47 }; 48 49 let secret_key = 50 SecretKey::parse("0000000000000000000000000000000000000000000000000000000000000001") 51 .expect("fixture secret"); 52 let public_key = secret_key.public_key().expect("public key"); 53 assert_eq!(public_key.to_hex(), PUBLIC_KEY); 54 55 let draft = GenericEventDraft::new( 56 "radroots.social.geochat.v1", 57 KIND_GEOCHAT, 58 1_700_000_000, 59 Vec::new(), 60 "package-conformance-message", 61 PUBLIC_KEY, 62 ) 63 .expect("generic event draft"); 64 let plan = AuthoredEventPlan::from_generic(draft).expect("authored plan"); 65 let expected_id = plan.expected_event_id().to_hex(); 66 let actor = Actor::new( 67 public_key, 68 ActorSource::ExplicitPublicKey, 69 [AuthorRole::Any], 70 ) 71 .expect("authorized actor"); 72 let request = SignRequest::new( 73 OperationId::SyncPush, 74 SigningIntentId::new( 75 SigningOperationId::new([1; 16]).expect("operation ID"), 76 AuthoredArtifactId::new([2; 16]).expect("artifact ID"), 77 ), 78 actor, 79 plan, 80 SignPolicy::new(u64::MAX, CancellationPolicy::LocalCooperative) 81 .expect("bounded signing policy"), 82 ) 83 .expect("signing request"); 84 85 let signer = LocalSigner::new(secret_key).expect("local signer"); 86 let receipt = signer.sign(request).await.expect("signed receipt"); 87 88 assert_eq!(receipt.signed_event().id_str(), expected_id); 89 assert_eq!(*receipt.signed_event().pubkey(), public_key); 90 assert_eq!( 91 receipt.signed_event().content(), 92 "package-conformance-message" 93 ); 94 }