clockwork_network/instructions/
node_unstake.rs

1use {
2    crate::state::*,
3    anchor_lang::prelude::*,
4    anchor_spl::token::{transfer, Mint, Token, TokenAccount, Transfer},
5};
6
7#[derive(Accounts)]
8#[instruction(amount: u64)]
9pub struct NodeUnstake<'info> {
10    #[account(mut)]
11    pub authority: Signer<'info>,
12
13    #[account(seeds = [SEED_CONFIG], bump)]
14    pub config: Account<'info, Config>,
15
16    #[account(
17        seeds = [
18            SEED_NODE,
19            node.id.to_be_bytes().as_ref()
20        ],
21        bump,
22        has_one = authority,
23    )]
24    pub node: Account<'info, Node>,
25
26    #[account(
27        mut,
28        associated_token::authority = node,
29        associated_token::mint = mint,
30    )]
31    pub node_stake: Account<'info, TokenAccount>,
32
33    #[account(address = config.mint)]
34    pub mint: Account<'info, Mint>,
35
36    #[account(address = anchor_spl::token::ID)]
37    pub token_program: Program<'info, Token>,
38
39    #[account(
40        mut,
41        associated_token::authority = authority,
42        associated_token::mint = mint,
43    )]
44    pub tokens: Account<'info, TokenAccount>,
45}
46
47pub fn handler(ctx: Context<NodeUnstake>, amount: u64) -> Result<()> {
48    // Get accounts
49    let node = &ctx.accounts.node;
50    let node_stake = &mut ctx.accounts.node_stake;
51    let token_program = &ctx.accounts.token_program;
52    let tokens = &mut ctx.accounts.tokens;
53
54    // Transfer trokens from stake account to authority's stake account
55    let bump = *ctx.bumps.get("node").unwrap();
56    transfer(
57        CpiContext::new_with_signer(
58            token_program.to_account_info(),
59            Transfer {
60                from: node_stake.to_account_info(),
61                to: tokens.to_account_info(),
62                authority: node.to_account_info(),
63            },
64            &[&[SEED_NODE, node.id.to_be_bytes().as_ref(), &[bump]]],
65        ),
66        amount,
67    )?;
68
69    Ok(())
70}