@@ -14,7 +14,7 @@ use crate::{utils, HTLCStatus};
1414use bitcoin:: bip32:: { ChildNumber , DerivationPath , ExtendedPrivKey } ;
1515use bitcoin:: hashes:: { sha256, Hash } ;
1616use bitcoin:: secp256k1:: { Secp256k1 , Signing } ;
17- use bitcoin:: { hashes:: hex:: FromHex , secp256k1:: ThirtyTwoByteHash } ;
17+ use bitcoin:: { hashes:: hex:: FromHex , secp256k1:: ThirtyTwoByteHash , Network } ;
1818use fedimint_core:: api:: InviteCode ;
1919use fedimint_core:: config:: FederationId ;
2020use futures:: { pin_mut, select, FutureExt } ;
@@ -1467,6 +1467,7 @@ impl<S: MutinyStorage> NostrManager<S> {
14671467 pub async fn recommend_federation (
14681468 & self ,
14691469 invite_code : & InviteCode ,
1470+ network : Network ,
14701471 review : Option < & str > ,
14711472 ) -> Result < EventId , MutinyError > {
14721473 let kind = Kind :: from ( 38000 ) ;
@@ -1478,6 +1479,12 @@ impl<S: MutinyStorage> NostrManager<S> {
14781479 vec ! [ "38173" . to_string( ) ] ,
14791480 ) ;
14801481
1482+ // tag the network
1483+ let n_tag = Tag :: Generic (
1484+ TagKind :: SingleLetter ( SingleLetterTag :: lowercase ( Alphabet :: N ) ) ,
1485+ vec ! [ network_to_string( network) . to_string( ) ] ,
1486+ ) ;
1487+
14811488 // tag the federation invite code
14821489 let invite_code_tag = Tag :: Generic (
14831490 TagKind :: SingleLetter ( SingleLetterTag :: lowercase ( Alphabet :: U ) ) ,
@@ -1489,7 +1496,7 @@ impl<S: MutinyStorage> NostrManager<S> {
14891496 let builder = EventBuilder :: new (
14901497 kind,
14911498 review. unwrap_or_default ( ) ,
1492- [ d_tag, k_tag, invite_code_tag] ,
1499+ [ d_tag, k_tag, invite_code_tag, n_tag ] ,
14931500 ) ;
14941501
14951502 // send the event
@@ -1512,7 +1519,10 @@ impl<S: MutinyStorage> NostrManager<S> {
15121519 }
15131520
15141521 /// Queries our relays for federation announcements
1515- pub async fn discover_federations ( & self ) -> Result < Vec < NostrDiscoveredFedimint > , MutinyError > {
1522+ pub async fn discover_federations (
1523+ & self ,
1524+ network : Network ,
1525+ ) -> Result < Vec < NostrDiscoveredFedimint > , MutinyError > {
15161526 // get contacts by npub
15171527 let mut npubs: HashMap < nostr:: PublicKey , Contact > = self
15181528 . storage
@@ -1552,6 +1562,8 @@ impl<S: MutinyStorage> NostrManager<S> {
15521562 }
15531563 }
15541564
1565+ let network_str = network_to_string ( network) ;
1566+
15551567 // filter for finding mint announcements
15561568 let mints = Filter :: new ( ) . kind ( Kind :: from ( 38173 ) ) ;
15571569 // filter for finding federation recommendations from trusted people
@@ -1564,6 +1576,7 @@ impl<S: MutinyStorage> NostrManager<S> {
15641576 . kind ( Kind :: from ( 38000 ) )
15651577 . custom_tag ( SingleLetterTag :: lowercase ( Alphabet :: K ) , [ "38173" ] )
15661578 . limit ( NUM_TRUSTED_USERS as usize ) ;
1579+
15671580 // fetch events
15681581 let events = self
15691582 . client
@@ -1581,6 +1594,24 @@ impl<S: MutinyStorage> NostrManager<S> {
15811594 return None ;
15821595 }
15831596
1597+ let network_tag = event. tags . iter ( ) . find_map ( |tag| {
1598+ if tag. kind ( ) == TagKind :: SingleLetter ( SingleLetterTag :: lowercase ( Alphabet :: N ) )
1599+ {
1600+ Some ( tag. as_vec ( ) . get ( 1 ) . cloned ( ) . unwrap_or_default ( ) )
1601+ } else {
1602+ None
1603+ }
1604+ } ) ;
1605+
1606+ // if the network tag is missing, we assume it is on mainnet
1607+ let network_tag = network_tag
1608+ . as_deref ( )
1609+ . unwrap_or ( network_to_string ( Network :: Bitcoin ) ) ;
1610+ // skip if the network doesn't match
1611+ if network_tag != network_str {
1612+ return None ;
1613+ }
1614+
15841615 let federation_id = event. tags . iter ( ) . find_map ( |tag| {
15851616 if let Tag :: Identifier ( id) = tag {
15861617 FederationId :: from_str ( id) . ok ( )
@@ -1642,6 +1673,19 @@ impl<S: MutinyStorage> NostrManager<S> {
16421673 None => continue ,
16431674 } ;
16441675
1676+ let network_tag = event. tags . iter ( ) . find_map ( |tag| {
1677+ if tag. kind ( ) == TagKind :: SingleLetter ( SingleLetterTag :: lowercase ( Alphabet :: N ) ) {
1678+ Some ( tag. as_vec ( ) . get ( 1 ) . cloned ( ) . unwrap_or_default ( ) )
1679+ } else {
1680+ None
1681+ }
1682+ } ) ;
1683+
1684+ // skip if the network doesn't match
1685+ if network_tag. is_none ( ) || network_tag. unwrap ( ) != network_str {
1686+ continue ;
1687+ }
1688+
16451689 let invite_codes = event
16461690 . tags
16471691 . iter ( )
@@ -1833,6 +1877,16 @@ fn get_next_nwc_index(
18331877 Ok ( ( name, index, child_key_index) )
18341878}
18351879
1880+ fn network_to_string ( network : Network ) -> & ' static str {
1881+ match network {
1882+ Network :: Bitcoin => "mainnet" ,
1883+ Network :: Testnet => "testnet" ,
1884+ Network :: Signet => "signet" ,
1885+ Network :: Regtest => "regtest" ,
1886+ net => unreachable ! ( "Unknown network {net}!" ) ,
1887+ }
1888+ }
1889+
18361890#[ cfg( not( target_arch = "wasm32" ) ) ]
18371891#[ cfg( test) ]
18381892mod test {
0 commit comments