|  | 
|  | 1 | +// Copyright © 2017-2023 Trust Wallet. | 
|  | 2 | +// | 
|  | 3 | +// This file is part of Trust. The full Trust copyright notice, including | 
|  | 4 | +// terms governing use, modification, and redistribution, is contained in the | 
|  | 5 | +// file LICENSE at the root of the source code distribution tree. | 
|  | 6 | + | 
|  | 7 | +use serde::Serialize; | 
|  | 8 | +use std::fmt; | 
|  | 9 | +use std::str::FromStr; | 
|  | 10 | +use tw_bech32_address::bech32_prefix::Bech32Prefix; | 
|  | 11 | +use tw_bech32_address::Bech32Address; | 
|  | 12 | +use tw_coin_entry::coin_context::CoinContext; | 
|  | 13 | +use tw_coin_entry::coin_entry::CoinAddress; | 
|  | 14 | +use tw_coin_entry::error::{AddressError, AddressResult}; | 
|  | 15 | +use tw_keypair::tw::PublicKey; | 
|  | 16 | +use tw_memory::Data; | 
|  | 17 | + | 
|  | 18 | +/// The list of known BNB hrps. | 
|  | 19 | +const BNB_KNOWN_HRPS: [&str; 2] = [ | 
|  | 20 | +    BinanceAddress::VALIDATOR_HRP, // BNB Validator HRP. | 
|  | 21 | +    "bca", | 
|  | 22 | +]; | 
|  | 23 | + | 
|  | 24 | +#[derive(Serialize)] | 
|  | 25 | +pub struct BinanceAddress(Bech32Address); | 
|  | 26 | + | 
|  | 27 | +impl CoinAddress for BinanceAddress { | 
|  | 28 | +    #[inline] | 
|  | 29 | +    fn data(&self) -> Data { | 
|  | 30 | +        self.0.data() | 
|  | 31 | +    } | 
|  | 32 | +} | 
|  | 33 | + | 
|  | 34 | +impl BinanceAddress { | 
|  | 35 | +    pub const VALIDATOR_HRP: &'static str = "bva"; | 
|  | 36 | + | 
|  | 37 | +    pub fn new_validator_addr(key_hash: Data) -> AddressResult<BinanceAddress> { | 
|  | 38 | +        Bech32Address::new(Self::VALIDATOR_HRP.to_string(), key_hash).map(BinanceAddress) | 
|  | 39 | +    } | 
|  | 40 | + | 
|  | 41 | +    /// Creates a Binance address with the only `prefix` | 
|  | 42 | +    pub fn from_str_with_coin_and_prefix( | 
|  | 43 | +        coin: &dyn CoinContext, | 
|  | 44 | +        address_str: String, | 
|  | 45 | +        prefix: Option<Bech32Prefix>, | 
|  | 46 | +    ) -> AddressResult<BinanceAddress> | 
|  | 47 | +    where | 
|  | 48 | +        Self: Sized, | 
|  | 49 | +    { | 
|  | 50 | +        let possible_hrps = match prefix { | 
|  | 51 | +            Some(Bech32Prefix { hrp }) => vec![hrp], | 
|  | 52 | +            None => { | 
|  | 53 | +                let coin_hrp = coin.hrp().ok_or(AddressError::InvalidHrp)?; | 
|  | 54 | +                let other_hrps = BNB_KNOWN_HRPS | 
|  | 55 | +                    .iter() | 
|  | 56 | +                    .map(|another_hrp| another_hrp.to_string()); | 
|  | 57 | +                std::iter::once(coin_hrp).chain(other_hrps).collect() | 
|  | 58 | +            }, | 
|  | 59 | +        }; | 
|  | 60 | +        Bech32Address::from_str_checked(possible_hrps, address_str).map(BinanceAddress) | 
|  | 61 | +    } | 
|  | 62 | + | 
|  | 63 | +    pub fn with_public_key_coin_context( | 
|  | 64 | +        coin: &dyn CoinContext, | 
|  | 65 | +        public_key: &PublicKey, | 
|  | 66 | +        prefix: Option<Bech32Prefix>, | 
|  | 67 | +    ) -> AddressResult<BinanceAddress> { | 
|  | 68 | +        Bech32Address::with_public_key_coin_context(coin, public_key, prefix).map(BinanceAddress) | 
|  | 69 | +    } | 
|  | 70 | + | 
|  | 71 | +    pub fn from_key_hash_with_coin( | 
|  | 72 | +        coin: &dyn CoinContext, | 
|  | 73 | +        key_hash: Data, | 
|  | 74 | +    ) -> AddressResult<BinanceAddress> { | 
|  | 75 | +        Bech32Address::from_key_hash_with_coin(coin, key_hash).map(BinanceAddress) | 
|  | 76 | +    } | 
|  | 77 | +} | 
|  | 78 | + | 
|  | 79 | +impl FromStr for BinanceAddress { | 
|  | 80 | +    type Err = AddressError; | 
|  | 81 | + | 
|  | 82 | +    fn from_str(s: &str) -> Result<Self, Self::Err> { | 
|  | 83 | +        Bech32Address::from_str(s).map(BinanceAddress) | 
|  | 84 | +    } | 
|  | 85 | +} | 
|  | 86 | + | 
|  | 87 | +impl fmt::Display for BinanceAddress { | 
|  | 88 | +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | 
|  | 89 | +        fmt::Display::fmt(&self.0, f) | 
|  | 90 | +    } | 
|  | 91 | +} | 
0 commit comments