hopper_runtime/
address.rs1pub const ADDRESS_BYTES: usize = 32;
14
15pub const MAX_SEED_LEN: usize = 32;
17
18pub const MAX_SEEDS: usize = 16;
20
21pub const PDA_MARKER: &[u8; 21] = b"ProgramDerivedAddress";
23
24#[repr(transparent)]
31#[derive(Clone, Copy, PartialEq, Eq, Default, PartialOrd, Ord)]
32pub struct Address(pub(crate) [u8; 32]);
33
34#[cfg(feature = "hopper-native-backend")]
43unsafe impl bytemuck::Zeroable for Address {}
44#[cfg(feature = "hopper-native-backend")]
45unsafe impl bytemuck::Pod for Address {}
46
47unsafe impl crate::pod::Pod for Address {}
48unsafe impl crate::zerocopy::__sealed::HopperZeroCopySealed for Address {}
50
51impl Address {
52 #[inline(always)]
54 pub const fn new(bytes: [u8; 32]) -> Self {
55 Self(bytes)
56 }
57
58 #[inline(always)]
60 pub const fn new_from_array(bytes: [u8; 32]) -> Self {
61 Self(bytes)
62 }
63
64 #[inline(always)]
66 pub const fn to_bytes(&self) -> [u8; 32] {
67 self.0
68 }
69
70 #[inline(always)]
72 pub const fn as_array(&self) -> &[u8; 32] {
73 &self.0
74 }
75
76 #[inline(always)]
78 pub const fn as_bytes(&self) -> &[u8; 32] {
79 &self.0
80 }
81
82 #[cfg(target_os = "solana")]
87 pub fn find_program_address(seeds: &[&[u8]], program_id: &Address) -> (Address, u8) {
88 crate::compat::find_program_address(seeds, program_id)
89 }
90
91 #[cfg(target_os = "solana")]
95 pub fn create_program_address(
96 seeds: &[&[u8]],
97 program_id: &Address,
98 ) -> Result<Address, crate::ProgramError> {
99 crate::compat::create_program_address(seeds, program_id)
100 }
101}
102
103impl From<[u8; 32]> for Address {
106 #[inline(always)]
107 fn from(bytes: [u8; 32]) -> Self {
108 Self(bytes)
109 }
110}
111
112impl From<Address> for [u8; 32] {
113 #[inline(always)]
114 fn from(addr: Address) -> [u8; 32] {
115 addr.0
116 }
117}
118
119impl TryFrom<&[u8]> for Address {
120 type Error = core::array::TryFromSliceError;
121
122 #[inline]
123 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
124 let arr: [u8; 32] = slice.try_into()?;
125 Ok(Self(arr))
126 }
127}
128
129impl AsRef<[u8]> for Address {
130 #[inline(always)]
131 fn as_ref(&self) -> &[u8] {
132 &self.0
133 }
134}
135
136impl AsMut<[u8]> for Address {
137 #[inline(always)]
138 fn as_mut(&mut self) -> &mut [u8] {
139 &mut self.0
140 }
141}
142
143impl AsRef<[u8; 32]> for Address {
144 #[inline(always)]
145 fn as_ref(&self) -> &[u8; 32] {
146 &self.0
147 }
148}
149
150impl core::hash::Hash for Address {
151 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
152 self.0.hash(state);
153 }
154}
155
156impl core::fmt::Debug for Address {
157 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
158 write!(f, "Address({:?})", &self.0[..4])
159 }
160}
161
162impl core::fmt::Display for Address {
163 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
164 for byte in &self.0[..4] {
166 write!(f, "{byte:02x}")?;
167 }
168 write!(f, "..")
169 }
170}
171
172#[inline(always)]
176pub fn address_eq(a: &Address, b: &Address) -> bool {
177 let a_ptr = a.0.as_ptr() as *const u64;
178 let b_ptr = b.0.as_ptr() as *const u64;
179 unsafe {
182 core::ptr::read_unaligned(a_ptr) == core::ptr::read_unaligned(b_ptr)
183 && core::ptr::read_unaligned(a_ptr.add(1)) == core::ptr::read_unaligned(b_ptr.add(1))
184 && core::ptr::read_unaligned(a_ptr.add(2)) == core::ptr::read_unaligned(b_ptr.add(2))
185 && core::ptr::read_unaligned(a_ptr.add(3)) == core::ptr::read_unaligned(b_ptr.add(3))
186 }
187}