use hopper_runtime::ProgramResult;
#[cfg(target_os = "solana")]
#[repr(C)]
struct SolBytes {
ptr: *const u8,
len: u64,
}
#[cfg(target_os = "solana")]
extern "C" {
fn sol_log_data(data: *const SolBytes, data_len: u64);
fn sol_set_return_data(data: *const u8, length: u64);
}
#[inline(always)]
pub fn emit_receipt(data: &[u8]) -> ProgramResult {
#[cfg(target_os = "solana")]
{
let field = SolBytes {
ptr: data.as_ptr(),
len: data.len() as u64,
};
unsafe {
sol_log_data(&field as *const SolBytes, 1);
}
}
#[cfg(not(target_os = "solana"))]
{
let _ = data;
}
Ok(())
}
#[inline(always)]
pub fn emit_tagged_receipt(tag: u8, data: &[u8]) -> ProgramResult {
#[cfg(target_os = "solana")]
{
let tag_byte: [u8; 1] = [tag];
let fields: [SolBytes; 2] = [
SolBytes {
ptr: tag_byte.as_ptr(),
len: 1,
},
SolBytes {
ptr: data.as_ptr(),
len: data.len() as u64,
},
];
unsafe {
sol_log_data(fields.as_ptr(), 2);
}
}
#[cfg(not(target_os = "solana"))]
{
let _ = (tag, data);
}
Ok(())
}
#[inline(always)]
pub fn set_return_data(data: &[u8]) -> ProgramResult {
#[cfg(target_os = "solana")]
{
unsafe {
sol_set_return_data(data.as_ptr(), data.len() as u64);
}
}
#[cfg(not(target_os = "solana"))]
{
let _ = data;
}
Ok(())
}
pub trait Receipt {
const TAG: u8;
fn as_bytes(&self) -> &[u8];
}
#[inline(always)]
pub fn emit_typed_receipt<T: Receipt>(receipt: &T) -> ProgramResult {
emit_tagged_receipt(T::TAG, receipt.as_bytes())
}