stellar_axelar_std/
address.rs1use soroban_sdk::{Address, Bytes, Env, String};
2
3const ZERO_ADDRESS: &str = "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF";
4const STELLAR_ADDRESS_LEN: usize = ZERO_ADDRESS.len();
5
6pub trait AddressExt {
7 fn zero(env: &Env) -> Address;
8
9 fn to_string_bytes(&self) -> Bytes;
10
11 fn to_raw_bytes(&self) -> [u8; STELLAR_ADDRESS_LEN];
12}
13
14impl AddressExt for Address {
15 fn zero(env: &Env) -> Address {
17 Self::from_string(&String::from_str(env, ZERO_ADDRESS))
18 }
19
20 fn to_string_bytes(&self) -> Bytes {
22 let mut address_string_bytes = [0u8; STELLAR_ADDRESS_LEN];
23 self.to_string().copy_into_slice(&mut address_string_bytes);
24 Bytes::from_slice(self.env(), &address_string_bytes)
25 }
26
27 fn to_raw_bytes(&self) -> [u8; STELLAR_ADDRESS_LEN] {
28 let mut address_string_bytes = [0u8; STELLAR_ADDRESS_LEN];
29 self.to_string().copy_into_slice(&mut address_string_bytes);
30 address_string_bytes
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use stellar_axelar_std::testutils::Address as _;
37 use stellar_axelar_std::{Address, Bytes, Env, String};
38
39 use super::{AddressExt, ZERO_ADDRESS};
40 use crate as stellar_axelar_std;
41
42 #[test]
43 fn zero_address_to_string() {
44 let env = &Env::default();
45 assert_eq!(
46 Address::zero(env).to_string(),
47 String::from_str(env, ZERO_ADDRESS)
48 );
49 }
50
51 #[test]
52 fn string_to_address_to_string() {
53 let env = &Env::default();
54 let cases = [
55 ZERO_ADDRESS,
56 "GC7OHFPWPSWXL4HMN6TXAG54MTZSMJIASWHO6KVRQNHNCXEAHWDSGGC3",
57 "CB6743BTQ2TZHTUCRSUFAH2X5ICOZGI6I3UCQBY3VFSSJ7IERGXUM7TX",
58 ]
59 .into_iter()
60 .map(|s| Bytes::from_slice(env, s.as_bytes()));
61
62 for address_bytes in cases {
63 let address = Address::from_string_bytes(&address_bytes);
64 assert_eq!(address.to_string_bytes(), address_bytes);
65 }
66 }
67
68 #[test]
69 fn address_to_string_to_address() {
70 let env = &Env::default();
71
72 let cases = [
73 Address::zero(env),
74 Address::generate(env),
75 env.register_stellar_asset_contract_v2(Address::generate(env))
76 .address(),
77 ];
78
79 for address in cases {
80 let address_bytes = address.to_string_bytes();
81 assert_eq!(Address::from_string_bytes(&address_bytes), address);
82 }
83 }
84
85 #[test]
86 #[should_panic(expected = "HostError: Error(Value, InvalidInput)")]
87 fn unsupported_muxed_address_format_fails_on_conversion() {
88 let env = &Env::default();
89
90 let unsupported_address =
91 "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUQ";
92 Address::from_string(&String::from_str(env, unsupported_address));
93 }
94
95 #[test]
96 #[should_panic(expected = "HostError: Error(Value, InvalidInput)")]
97 fn unsupported_signed_payload_address_format_fails_on_conversion() {
98 let env = &Env::default();
99
100 let unsupported_address = "PA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAOQCAQDAQCQMBYIBEFAWDANBYHRAEISCMKBKFQXDAMRUGY4DUAAAAFGBU";
101 Address::from_string(&String::from_str(env, unsupported_address));
102 }
103}