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(
31 mut,
32 constraint = target.thread.eq(&thread.key()) @ AntegenThreadError::InvalidFiberAccount,
33 )]
34 pub target: Account<'info, antegen_fiber_program::state::FiberState>,
35
36 #[account(
38 mut,
39 constraint = source.thread.eq(&thread.key()) @ AntegenThreadError::InvalidFiberAccount,
40 )]
41 pub source: Account<'info, antegen_fiber_program::state::FiberState>,
42
43 pub fiber_program: Program<'info, antegen_fiber_program::program::AntegenFiber>,
45}
46
47pub fn fiber_swap(ctx: Context<FiberSwap>, source_fiber_index: u8) -> Result<()> {
48 let thread = &mut ctx.accounts.thread;
49
50 thread.sign(|seeds| {
52 antegen_fiber_program::cpi::swap_fiber(CpiContext::new_with_signer(
53 ctx.accounts.fiber_program.key(),
54 antegen_fiber_program::cpi::accounts::FiberSwap {
55 thread: thread.to_account_info(),
56 target: ctx.accounts.target.to_account_info(),
57 source: ctx.accounts.source.to_account_info(),
58 },
59 &[seeds],
60 ))
61 })?;
62
63 thread.fiber_ids.retain(|&x| x != source_fiber_index);
65
66 if thread.fiber_cursor == source_fiber_index {
68 if thread.fiber_ids.is_empty() {
69 thread.fiber_cursor = 0;
70 } else {
71 thread.fiber_cursor = thread.fiber_ids[0];
72 }
73 }
74
75 Ok(())
76}