antegen_thread_program/instructions/
fiber_swap.rs1use crate::{errors::AntegenThreadError, *};
2use anchor_lang::prelude::*;
3
4#[derive(Accounts)]
8#[instruction(source_fiber_index: u8)]
9pub struct FiberSwap<'info> {
10 #[account(
12 constraint = authority.key().eq(&thread.authority) || authority.key().eq(&thread.key())
13 )]
14 pub authority: Signer<'info>,
15
16 #[account(
18 mut,
19 constraint = thread.fiber_ids.contains(&source_fiber_index) @ AntegenThreadError::InvalidFiberIndex,
20 seeds = [
21 SEED_THREAD,
22 thread.authority.as_ref(),
23 thread.id.as_slice(),
24 ],
25 bump = thread.bump,
26 )]
27 pub thread: Account<'info, Thread>,
28
29 #[account(mut)]
32 pub target: UncheckedAccount<'info>,
33
34 #[account(mut)]
37 pub source: UncheckedAccount<'info>,
38
39 pub fiber_program: Program<'info, antegen_fiber_program::program::AntegenFiber>,
41}
42
43pub fn fiber_swap(ctx: Context<FiberSwap>, source_fiber_index: u8) -> Result<()> {
44 let thread = &mut ctx.accounts.thread;
45
46 thread.sign(|seeds| {
48 antegen_fiber_program::cpi::swap(CpiContext::new_with_signer(
49 ctx.accounts.fiber_program.key(),
50 antegen_fiber_program::cpi::accounts::Swap {
51 thread: thread.to_account_info(),
52 target: ctx.accounts.target.to_account_info(),
53 source: ctx.accounts.source.to_account_info(),
54 },
55 &[seeds],
56 ))
57 })?;
58
59 thread.fiber_ids.retain(|&x| x != source_fiber_index);
61
62 if thread.fiber_cursor == source_fiber_index {
64 if thread.fiber_ids.is_empty() {
65 thread.fiber_cursor = 0;
66 } else {
67 thread.fiber_cursor = thread.fiber_ids[0];
68 }
69 }
70
71 Ok(())
72}