nostr_types/nip46/
params.rs1use crate::{Error, PublicKey, RelayUrl};
2use lazy_static::lazy_static;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Serialize, Deserialize)]
8pub struct Nip46ConnectionParameters {
9 pub remote_signer_pubkey: PublicKey,
11
12 pub relays: Vec<RelayUrl>,
14
15 pub secret: Option<String>,
17}
18
19impl Nip46ConnectionParameters {
20 #[allow(clippy::should_implement_trait)]
22 pub fn from_str(s: &str) -> Result<Nip46ConnectionParameters, Error> {
23 use regex::Regex;
25 lazy_static! {
26 static ref BUNKER_RE: Regex =
27 Regex::new(r#"^bunker://(.+)\?(.+)$"#).expect("Could not compile bunker regex");
28 }
29
30 let mut relays: Vec<RelayUrl> = Vec::new();
31 let mut secret: Option<String> = None;
32
33 let captures = match BUNKER_RE.captures(s) {
34 Some(c) => c,
35 None => return Err(Error::BadBunkerUrl),
36 };
37
38 let public_key = if let Some(pk_part) = captures.get(1) {
39 PublicKey::try_from_hex_string(pk_part.as_str(), true)?
40 } else {
41 return Err(Error::BadBunkerUrl);
42 };
43
44 if let Some(param_part) = captures.get(2) {
45 let assignments = param_part.as_str().split('&');
46 for assignment in assignments {
47 let halfs: Vec<&str> = assignment.split('=').collect();
48 if halfs.len() != 2 {
49 return Err(Error::BadBunkerUrl);
50 }
51 let var = halfs[0];
52 let val = halfs[1];
53 match var {
54 "relay" => relays.push(RelayUrl::try_from_str(val)?),
55 "secret" => secret = Some(val.to_owned()),
56 _ => continue, }
58 }
59 } else {
60 return Err(Error::BadBunkerUrl);
61 }
62
63 if relays.is_empty() {
64 return Err(Error::BadBunkerUrl);
65 }
66
67 Ok(Nip46ConnectionParameters {
68 remote_signer_pubkey: public_key,
69 relays,
70 secret,
71 })
72 }
73}
74
75#[cfg(test)]
76mod test {
77 use super::*;
78
79 #[test]
80 fn test_nip46_connection_params() {
81 let params = Nip46ConnectionParameters::from_str(
82 "bunker://ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49?relay=wss://chorus.mikedilger.com:444/&secret=5ijGGB0AGmgAAAAAgbaYUxymvgMQnrQh"
83 ).unwrap();
84
85 assert_eq!(params.relays.len(), 1);
86 assert_eq!(
87 params.relays[0].as_str(),
88 "wss://chorus.mikedilger.com:444/"
89 );
90 assert_eq!(
91 params.remote_signer_pubkey,
92 PublicKey::try_from_hex_string(
93 "ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49",
94 true
95 )
96 .unwrap()
97 );
98 assert_eq!(
99 params.secret,
100 Some("5ijGGB0AGmgAAAAAgbaYUxymvgMQnrQh".to_string())
101 );
102 }
103}