use hopper_runtime::{error::ProgramError, Address};
#[inline(always)]
pub fn check_pending_authority(
data: &[u8],
pending_offset: usize,
expected: &Address,
) -> Result<(), ProgramError> {
if pending_offset + 32 > data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
let stored = &data[pending_offset..pending_offset + 32];
if stored == [0u8; 32] {
return Err(ProgramError::InvalidAccountData);
}
if stored != expected.as_array() {
return Err(ProgramError::InvalidArgument);
}
Ok(())
}
#[inline(always)]
pub fn write_pending_authority(
data: &mut [u8],
pending_offset: usize,
new_authority: &Address,
) -> Result<(), ProgramError> {
if pending_offset + 32 > data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
data[pending_offset..pending_offset + 32].copy_from_slice(new_authority.as_ref());
Ok(())
}
#[inline(always)]
pub fn accept_authority(
data: &mut [u8],
authority_offset: usize,
pending_offset: usize,
caller: &Address,
) -> Result<(), ProgramError> {
if authority_offset + 32 > data.len() || pending_offset + 32 > data.len() {
return Err(ProgramError::AccountDataTooSmall);
}
let mut pending = [0u8; 32];
pending.copy_from_slice(&data[pending_offset..pending_offset + 32]);
if pending == [0u8; 32] {
return Err(ProgramError::InvalidAccountData);
}
if pending != *caller.as_array() {
return Err(ProgramError::InvalidArgument);
}
data[authority_offset..authority_offset + 32].copy_from_slice(&pending);
data[pending_offset..pending_offset + 32].copy_from_slice(&[0u8; 32]);
Ok(())
}