@@ -9,6 +9,7 @@ use std::hash::{Hash, Hasher};
99use std:: str:: FromStr ;
1010use std:: string:: FromUtf8Error ;
1111
12+ use bitcoin:: hashes:: { sha256, Hash as BitcoinHash } ;
1213use serde:: { de, Deserialize , Deserializer , Serialize } ;
1314use thiserror:: Error ;
1415
@@ -577,16 +578,12 @@ pub enum CurrencyUnit {
577578
578579#[ cfg( feature = "mint" ) ]
579580impl CurrencyUnit {
580- /// Derivation index mint will use for unit
581- pub fn derivation_index ( & self ) -> Option < u32 > {
582- match self {
583- Self :: Sat => Some ( 0 ) ,
584- Self :: Msat => Some ( 1 ) ,
585- Self :: Usd => Some ( 2 ) ,
586- Self :: Eur => Some ( 3 ) ,
587- Self :: Auth => Some ( 4 ) ,
588- _ => None ,
589- }
581+ /// Big endian encoded integer of the first 4 bytes of the sha256 hash of the unit string.
582+ pub fn derivation_index ( & self ) -> u32 {
583+ let unit_str = self . to_string ( ) . to_lowercase ( ) ;
584+ let bytes = <sha256:: Hash as BitcoinHash >:: hash ( unit_str. as_bytes ( ) ) ;
585+ // Take the first 4 bytes and convert to u32 (big endian) make sure the integer
586+ u32:: from_be_bytes ( [ bytes[ 0 ] , bytes[ 1 ] , bytes[ 2 ] , bytes[ 3 ] ] ) & !( 1 << 31 )
590587 }
591588}
592589
@@ -993,6 +990,30 @@ mod tests {
993990 assert_eq ! ( unit, deserialized)
994991 }
995992
993+ #[ test]
994+ fn four_bytes_hash_currency_unit ( ) {
995+ let unit = CurrencyUnit :: Sat ;
996+ let index = unit. derivation_index ( ) ;
997+ assert_eq ! ( index, 866057899 ) ;
998+
999+ let unit = CurrencyUnit :: Msat ;
1000+ let index = unit. derivation_index ( ) ;
1001+ assert_eq ! ( index, 1980671987 ) ;
1002+
1003+ let unit = CurrencyUnit :: Eur ;
1004+ let index = unit. derivation_index ( ) ;
1005+ assert_eq ! ( index, 975082952 ) ;
1006+
1007+ let unit = CurrencyUnit :: Usd ;
1008+ let index = unit. derivation_index ( ) ;
1009+ assert_eq ! ( index, 1443872135 ) ;
1010+
1011+ let unit = CurrencyUnit :: Auth ;
1012+ let index = unit. derivation_index ( ) ;
1013+
1014+ assert_eq ! ( index, 1039440956 )
1015+ }
1016+
9961017 #[ test]
9971018 fn test_payment_method_parsing ( ) {
9981019 // Test standard variants
0 commit comments