1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
use self::super::{CryptoAddress, Error, alias_to_fqdn}; use resolve::{DnsResolver, DnsConfig, default_config}; use std::iter::FromIterator; use std::time::Duration; use resolve::record; /// Ask a DNS server for addresses for the specified OpenAlias. /// /// # Examples /// /// ``` /// # use openalias::{CryptoAddress, addresses}; /// # use std::collections::BTreeMap; /// # trait SortedForVec { fn sorted(self) -> Self; } /// # impl<T: Ord> SortedForVec for Vec<T> { fn sorted(mut self) -> Self { self.sort(); self} } /// assert_eq!(addresses("donate@getmonero.org").unwrap().sorted(), /// vec![CryptoAddress { /// cryptocurrency: "btc".to_string(), /// address: "1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H".to_string(), /// /// recipient_name: Some("Monero Development".to_string()), /// tx_description: Some("Donation to Monero Core Team".to_string()), /// tx_amount: None, /// tx_payment_id: None, /// address_signature: None, /// checksum: None, /// /// additional_values: BTreeMap::new(), /// }, /// CryptoAddress { /// cryptocurrency: "xmr".to_string(), /// address: "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft\ /// 3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A".to_string(), /// /// recipient_name: Some("Monero Development".to_string()), /// tx_description: Some("Donation to Monero Core Team".to_string()), /// tx_amount: None, /// tx_payment_id: None, /// address_signature: None, /// checksum: None, /// /// additional_values: BTreeMap::new(), /// }]); /// ``` pub fn addresses(address: &str) -> Result<Vec<CryptoAddress>, Error> { Ok(Result::from_iter(address_strings(address)?.into_iter().map(|s| s.parse()))?) } /// Ask a DNS server for "oa1:"-prefixed TXT records for the specified OpenAlias. /// /// # Examples /// /// ``` /// # use openalias::address_strings; /// # trait SortedForVec { fn sorted(self) -> Self; } /// # impl<T: Ord> SortedForVec for Vec<T> { fn sorted(mut self) -> Self { self.sort(); self} } /// assert_eq!(address_strings("donate@getmonero.org").unwrap().sorted(), /// vec!["oa1:btc recipient_address=1KTexdemPdxSBcG55heUuTjDRYqbC5ZL8H; \ /// recipient_name=Monero Development; \ /// tx_description=Donation to Monero Core Team;".to_string(), /// "oa1:xmr recipient_address=44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft\ /// 3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A; \ /// recipient_name=Monero Development; \ /// tx_description=Donation to Monero Core Team;".to_string()]); /// ``` pub fn address_strings(address: &str) -> Result<Vec<String>, Error> { Ok(Result::from_iter(DnsResolver::new(default_config().unwrap_or_else(|_| { DnsConfig { name_servers: vec!["8.8.8.8:53".parse().unwrap(), "8.8.4.4:53".parse().unwrap()], search: vec![], n_dots: 0, timeout: Duration::from_secs(5), attempts: 5, rotate: true, use_inet6: false, } })) ? .resolve_record::<record::Txt>(&alias_to_fqdn(address).ok_or(Error::AddressParse)?)? .into_iter() .map(|r| r.data) .filter(|s| s.starts_with(b"oa1:")) .map(String::from_utf8))?) }