use crate::{errors::AntegenThreadError, *};
use anchor_lang::prelude::*;
#[derive(Accounts)]
#[instruction(source_fiber_index: u8)]
pub struct FiberSwap<'info> {
#[account(
constraint = authority.key().eq(&thread.authority) || authority.key().eq(&thread.key())
)]
pub authority: Signer<'info>,
#[account(
mut,
constraint = thread.fiber_ids.contains(&source_fiber_index) @ AntegenThreadError::InvalidFiberIndex,
seeds = [
SEED_THREAD,
thread.authority.as_ref(),
thread.id.as_slice(),
],
bump = thread.bump,
)]
pub thread: Account<'info, Thread>,
#[account(
mut,
constraint = target.thread.eq(&thread.key()) @ AntegenThreadError::InvalidFiberAccount,
)]
pub target: Account<'info, antegen_fiber_program::state::FiberState>,
#[account(
mut,
constraint = source.thread.eq(&thread.key()) @ AntegenThreadError::InvalidFiberAccount,
)]
pub source: Account<'info, antegen_fiber_program::state::FiberState>,
pub fiber_program: Program<'info, antegen_fiber_program::program::AntegenFiber>,
}
pub fn fiber_swap(ctx: Context<FiberSwap>, source_fiber_index: u8) -> Result<()> {
let thread = &mut ctx.accounts.thread;
thread.sign(|seeds| {
antegen_fiber_program::cpi::swap(CpiContext::new_with_signer(
ctx.accounts.fiber_program.key(),
antegen_fiber_program::cpi::accounts::Swap {
thread: thread.to_account_info(),
target: ctx.accounts.target.to_account_info(),
source: ctx.accounts.source.to_account_info(),
},
&[seeds],
))
})?;
thread.fiber_ids.retain(|&x| x != source_fiber_index);
if thread.fiber_cursor == source_fiber_index {
if thread.fiber_ids.is_empty() {
thread.fiber_cursor = 0;
} else {
thread.fiber_cursor = thread.fiber_ids[0];
}
}
Ok(())
}