lib

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

nip09_deletion_request_profile.rs (4228B)


      1 mod support;
      2 
      3 use nostr::{Keys as RadrootsNostrKeys, SecretKey as RadrootsNostrSecretKey};
      4 use radroots_event::{
      5     envelope::kind::KIND_DELETION_REQUEST,
      6     post::deletion::{
      7         AuthoredNip09DeletionRequest, Nip09DeletionAddressTarget, Nip09DeletionEventTarget,
      8     },
      9 };
     10 use radroots_event_codec::admission::deletion::verify_and_admit_nip09_deletion_request_event;
     11 use radroots_nostr::Error;
     12 use radroots_nostr::event::Kind as RadrootsNostrKind;
     13 use radroots_nostr::event::Timestamp as RadrootsNostrTimestamp;
     14 use radroots_nostr::event::from_nostr;
     15 use radroots_nostr::event::{
     16     GenericBuilder, build_nip09_deletion_request as build_nip09_deletion_request_event,
     17 };
     18 use support::{FIXTURE_ALICE_SECRET_KEY_HEX, FIXTURE_BOB_PUBLIC_KEY_HEX};
     19 
     20 const CREATED_AT: u64 = 1_784_347_200;
     21 const TARGET_EVENT_ID: &str = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
     22 
     23 #[test]
     24 fn typed_nip09_deletion_request_signs_exact_tags_and_admits() {
     25     let request = request();
     26     let created_at = RadrootsNostrTimestamp::from_secs(CREATED_AT);
     27     let profile_coordinate = format!("0:{FIXTURE_BOB_PUBLIC_KEY_HEX}:");
     28     let listing_coordinate = format!("30402:{FIXTURE_BOB_PUBLIC_KEY_HEX}:carrots");
     29     let expected_tags = vec![
     30         tag(&["e", TARGET_EVENT_ID]),
     31         tag(&["a", &profile_coordinate]),
     32         tag(&["a", &listing_coordinate]),
     33         tag(&["k", "0"]),
     34         tag(&["k", "1"]),
     35         tag(&["k", "30402"]),
     36     ];
     37 
     38     let event = build_nip09_deletion_request_event(&request)
     39         .expect("typed NIP-09 builder")
     40         .custom_created_at(created_at)
     41         .sign_with_keys(&fixture_keys())
     42         .expect("signed NIP-09 deletion request");
     43 
     44     assert_eq!(event.kind.as_u16(), KIND_DELETION_REQUEST as u16);
     45     assert_eq!(event.created_at, created_at);
     46     assert_eq!(event.content, "superseded");
     47     assert_eq!(event_tags(&event), expected_tags);
     48     event.verify().expect("valid deletion-request signature");
     49 
     50     let admitted = verify_and_admit_nip09_deletion_request_event(
     51         from_nostr(&event).expect("deletion-request event adapter"),
     52     )
     53     .expect("deletion-request admission");
     54     assert_eq!(
     55         admitted.contract().id,
     56         "radroots.social.deletion_request.v1"
     57     );
     58     assert_eq!(admitted.projection().event_targets().len(), 1);
     59     assert_eq!(admitted.projection().address_targets().len(), 2);
     60     assert_eq!(
     61         admitted
     62             .projection()
     63             .kind_advisories()
     64             .iter()
     65             .map(|advisory| advisory.kind())
     66             .collect::<Vec<_>>(),
     67         vec![0, 1, 30_402]
     68     );
     69     assert!(admitted.projection().diagnostics().is_empty());
     70     assert_eq!(admitted.projection().raw_tags(), expected_tags.as_slice());
     71 }
     72 
     73 #[test]
     74 fn generic_kind_five_builder_cannot_bypass_typed_deletion_authoring() {
     75     let error = GenericBuilder::new(
     76         RadrootsNostrKind::Custom(KIND_DELETION_REQUEST as u16),
     77         "Raw deletion request",
     78     )
     79     .sign_with_keys(&fixture_keys())
     80     .expect_err("every generic kind 5 must be reserved");
     81 
     82     assert!(matches!(
     83         error,
     84         Error::TypedAuthoringRequired { kind }
     85             if kind == KIND_DELETION_REQUEST as u16
     86     ));
     87 }
     88 
     89 fn request() -> AuthoredNip09DeletionRequest {
     90     AuthoredNip09DeletionRequest::new(
     91         "superseded",
     92         vec![Nip09DeletionEventTarget::parse(TARGET_EVENT_ID, 1).expect("event target")],
     93         vec![
     94             Nip09DeletionAddressTarget::parse(format!(
     95                 "30402:{FIXTURE_BOB_PUBLIC_KEY_HEX}:carrots"
     96             ))
     97             .expect("listing target"),
     98             Nip09DeletionAddressTarget::parse(format!("0:{FIXTURE_BOB_PUBLIC_KEY_HEX}:"))
     99                 .expect("profile target"),
    100         ],
    101     )
    102     .expect("authored deletion request")
    103 }
    104 
    105 fn fixture_keys() -> RadrootsNostrKeys {
    106     RadrootsNostrKeys::new(
    107         RadrootsNostrSecretKey::from_hex(FIXTURE_ALICE_SECRET_KEY_HEX).expect("fixture secret key"),
    108     )
    109 }
    110 
    111 fn event_tags(event: &nostr::Event) -> Vec<Vec<String>> {
    112     event
    113         .tags
    114         .iter()
    115         .map(|tag| tag.as_slice().to_vec())
    116         .collect()
    117 }
    118 
    119 fn tag(values: &[&str]) -> Vec<String> {
    120     values.iter().map(|value| (*value).to_owned()).collect()
    121 }