universal_address/
lib.rs

1use anchor_lang::prelude::*;
2
3/// UniversalAddress represents a 32-byte address that can be used across different chains
4#[derive(
5    AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, Default, PartialEq, Eq, InitSpace,
6)]
7pub struct UniversalAddress {
8    /// The raw 32-byte address
9    pub bytes: [u8; 32],
10}
11
12impl UniversalAddress {
13    /// Creates a UniversalAddress from a Solana Pubkey
14    pub fn from_pubkey(pubkey: &Pubkey) -> Self {
15        Self {
16            bytes: pubkey.to_bytes(),
17        }
18    }
19
20    /// Converts the UniversalAddress back to a Solana Pubkey
21    pub fn to_pubkey(&self) -> Pubkey {
22        Pubkey::new_from_array(self.bytes)
23    }
24
25    /// Creates a UniversalAddress from raw bytes
26    pub fn from_bytes(bytes: [u8; 32]) -> Self {
27        Self { bytes }
28    }
29
30    /// Returns the raw bytes of the UniversalAddress
31    pub fn to_bytes(&self) -> [u8; 32] {
32        self.bytes
33    }
34}
35
36impl From<Pubkey> for UniversalAddress {
37    fn from(pubkey: Pubkey) -> Self {
38        Self::from_pubkey(&pubkey)
39    }
40}
41
42impl From<UniversalAddress> for Pubkey {
43    fn from(addr: UniversalAddress) -> Self {
44        addr.to_pubkey()
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn test_pubkey_roundtrip() {
54        let original_pubkey = Pubkey::new_unique();
55        let universal = UniversalAddress::from_pubkey(&original_pubkey);
56        let recovered_pubkey = universal.to_pubkey();
57        assert_eq!(original_pubkey, recovered_pubkey);
58    }
59
60    #[test]
61    fn test_bytes_roundtrip() {
62        let original_bytes = [42u8; 32];
63        let universal = UniversalAddress::from_bytes(original_bytes);
64        let recovered_bytes = universal.to_bytes();
65        assert_eq!(original_bytes, recovered_bytes);
66    }
67
68    #[test]
69    fn test_from_into_traits() {
70        let original_pubkey = Pubkey::new_unique();
71
72        // Test From<Pubkey>
73        let universal: UniversalAddress = original_pubkey.into();
74        assert_eq!(universal.bytes, original_pubkey.to_bytes());
75
76        // Test Into<Pubkey>
77        let recovered_pubkey: Pubkey = universal.into();
78        assert_eq!(original_pubkey, recovered_pubkey);
79    }
80
81    #[test]
82    fn test_default() {
83        let universal = UniversalAddress::default();
84        assert_eq!(universal.bytes, [0u8; 32]);
85    }
86
87    #[test]
88    fn test_debug_format() {
89        let bytes = [1u8; 32];
90        let universal = UniversalAddress::from_bytes(bytes);
91        let debug_str = format!("{:?}", universal);
92        assert!(debug_str.contains("UniversalAddress"));
93    }
94
95    #[test]
96    fn test_clone_and_copy() {
97        let original = UniversalAddress::from_bytes([1u8; 32]);
98
99        // Test Clone
100        let cloned = original.clone();
101        assert_eq!(original.bytes, cloned.bytes);
102
103        // Test Copy
104        let copied = original;
105        assert_eq!(original.bytes, copied.bytes);
106    }
107
108    #[test]
109    fn test_equality() {
110        let addr1 = UniversalAddress::from_bytes([1u8; 32]);
111        let addr2 = UniversalAddress::from_bytes([1u8; 32]);
112        let addr3 = UniversalAddress::from_bytes([2u8; 32]);
113
114        assert_eq!(addr1, addr2);
115        assert_ne!(addr1, addr3);
116    }
117
118    #[test]
119    fn test_serialization() {
120        let original = UniversalAddress::from_bytes([1u8; 32]);
121
122        // Test serialization
123        let serialized = original.try_to_vec().unwrap();
124
125        // Test deserialization
126        let deserialized: UniversalAddress = UniversalAddress::try_from_slice(&serialized).unwrap();
127
128        assert_eq!(original, deserialized);
129    }
130}