33//! This module bridges the Network enum with address codecs, providing
44//! convenient functions to encode/decode addresses using network identifiers.
55
6+ use super :: bech32:: is_p2mr;
67use super :: {
78 from_output_script, to_output_script_try_codecs, AddressCodec , AddressError , Result , ScriptBuf ,
89 BITCOIN , BITCOIN_BECH32 , BITCOIN_CASH , BITCOIN_CASH_CASHADDR , BITCOIN_CASH_TESTNET ,
@@ -76,6 +77,7 @@ impl AddressFormat {
7677pub struct OutputScriptSupport {
7778 pub segwit : bool ,
7879 pub taproot : bool ,
80+ pub p2mr : bool ,
7981}
8082
8183impl OutputScriptSupport {
@@ -102,6 +104,15 @@ impl OutputScriptSupport {
102104 Ok ( ( ) )
103105 }
104106
107+ pub ( crate ) fn assert_p2mr ( & self ) -> Result < ( ) > {
108+ if !self . p2mr {
109+ return Err ( AddressError :: UnsupportedScriptType (
110+ "Network does not support P2MR" . to_string ( ) ,
111+ ) ) ;
112+ }
113+ Ok ( ( ) )
114+ }
115+
105116 pub fn assert_support ( & self , script : & Script ) -> Result < ( ) > {
106117 match script. witness_version ( ) {
107118 None => {
@@ -113,6 +124,9 @@ impl OutputScriptSupport {
113124 Some ( WitnessVersion :: V1 ) => {
114125 self . assert_taproot ( ) ?;
115126 }
127+ Some ( WitnessVersion :: V2 ) => {
128+ self . assert_p2mr ( ) ?;
129+ }
116130 _ => {
117131 return Err ( AddressError :: UnsupportedScriptType (
118132 "Unsupported witness version" . to_string ( ) ,
@@ -170,7 +184,15 @@ impl Network {
170184 // - https://github.com/litecoin-project/litecoin/blob/v0.21.4/src/script/interpreter.h#L129-L131
171185 let taproot = segwit && matches ! ( self . mainnet( ) , Network :: Bitcoin ) ;
172186
173- OutputScriptSupport { segwit, taproot }
187+ // P2MR (BIP-360) support:
188+ // Currently only enabled on the BitGo Signet for testing.
189+ let p2mr = matches ! ( self , Network :: BitcoinBitGoSignet ) ;
190+
191+ OutputScriptSupport {
192+ segwit,
193+ taproot,
194+ p2mr,
195+ }
174196 }
175197}
176198
@@ -182,12 +204,13 @@ fn get_encode_codec(
182204) -> Result < & ' static dyn AddressCodec > {
183205 network. output_script_support ( ) . assert_support ( script) ?;
184206
185- let is_witness = script. is_p2wpkh ( ) || script. is_p2wsh ( ) || script. is_p2tr ( ) ;
207+ let is_witness = script. is_p2wpkh ( ) || script. is_p2wsh ( ) || script. is_p2tr ( ) || is_p2mr ( script ) ;
186208 let is_legacy = script. is_p2pkh ( ) || script. is_p2sh ( ) ;
187209
188210 if !is_witness && !is_legacy {
189211 return Err ( AddressError :: UnsupportedScriptType (
190- "Script is not a standard address type (P2PKH, P2SH, P2WPKH, P2WSH, P2TR)" . to_string ( ) ,
212+ "Script is not a standard address type (P2PKH, P2SH, P2WPKH, P2WSH, P2TR, P2MR)"
213+ . to_string ( ) ,
191214 ) ) ;
192215 }
193216
@@ -554,12 +577,14 @@ mod tests {
554577 let support_none = OutputScriptSupport {
555578 segwit : false ,
556579 taproot : false ,
580+ p2mr : false ,
557581 } ;
558582 assert ! ( support_none. assert_legacy( ) . is_ok( ) ) ;
559583
560584 let support_all = OutputScriptSupport {
561585 segwit : true ,
562586 taproot : true ,
587+ p2mr : false ,
563588 } ;
564589 assert ! ( support_all. assert_legacy( ) . is_ok( ) ) ;
565590 }
@@ -570,13 +595,15 @@ mod tests {
570595 let support_segwit = OutputScriptSupport {
571596 segwit : true ,
572597 taproot : false ,
598+ p2mr : false ,
573599 } ;
574600 assert ! ( support_segwit. assert_segwit( ) . is_ok( ) ) ;
575601
576602 // Should fail when segwit is not supported
577603 let no_support = OutputScriptSupport {
578604 segwit : false ,
579605 taproot : false ,
606+ p2mr : false ,
580607 } ;
581608 let result = no_support. assert_segwit ( ) ;
582609 assert ! ( result. is_err( ) ) ;
@@ -592,13 +619,15 @@ mod tests {
592619 let support_taproot = OutputScriptSupport {
593620 segwit : true ,
594621 taproot : true ,
622+ p2mr : false ,
595623 } ;
596624 assert ! ( support_taproot. assert_taproot( ) . is_ok( ) ) ;
597625
598626 // Should fail when taproot is not supported
599627 let no_support = OutputScriptSupport {
600628 segwit : true ,
601629 taproot : false ,
630+ p2mr : false ,
602631 } ;
603632 let result = no_support. assert_taproot ( ) ;
604633 assert ! ( result. is_err( ) ) ;
@@ -619,6 +648,7 @@ mod tests {
619648 let no_support = OutputScriptSupport {
620649 segwit : false ,
621650 taproot : false ,
651+ p2mr : false ,
622652 } ;
623653 assert ! ( no_support. assert_support( & p2pkh_script) . is_ok( ) ) ;
624654
@@ -640,13 +670,15 @@ mod tests {
640670 let support_segwit = OutputScriptSupport {
641671 segwit : true ,
642672 taproot : false ,
673+ p2mr : false ,
643674 } ;
644675 assert ! ( support_segwit. assert_support( & p2wpkh_script) . is_ok( ) ) ;
645676
646677 // Should fail without segwit support
647678 let no_support = OutputScriptSupport {
648679 segwit : false ,
649680 taproot : false ,
681+ p2mr : false ,
650682 } ;
651683 let result = no_support. assert_support ( & p2wpkh_script) ;
652684 assert ! ( result. is_err( ) ) ;
@@ -685,13 +717,15 @@ mod tests {
685717 let support_taproot = OutputScriptSupport {
686718 segwit : true ,
687719 taproot : true ,
720+ p2mr : false ,
688721 } ;
689722 assert ! ( support_taproot. assert_support( & p2tr_script) . is_ok( ) ) ;
690723
691724 // Should fail without taproot support (but with segwit)
692725 let no_taproot = OutputScriptSupport {
693726 segwit : true ,
694727 taproot : false ,
728+ p2mr : false ,
695729 } ;
696730 let result = no_taproot. assert_support ( & p2tr_script) ;
697731 assert ! ( result. is_err( ) ) ;
@@ -704,6 +738,7 @@ mod tests {
704738 let no_support = OutputScriptSupport {
705739 segwit : false ,
706740 taproot : false ,
741+ p2mr : false ,
707742 } ;
708743 let result = no_support. assert_support ( & p2tr_script) ;
709744 assert ! ( result. is_err( ) ) ;
0 commit comments