clockwork_network/instructions/
initialize.rs

1use {
2    crate::state::*,
3    anchor_lang::{
4        prelude::*, 
5        solana_program::{instruction::Instruction, system_program}
6    },
7    anchor_spl::token::Mint,
8    clockwork_crank::state::{Trigger, SEED_QUEUE},
9    std::mem::size_of,
10};
11
12#[derive(Accounts)]
13pub struct Initialize<'info> {
14    #[account(mut)]
15    pub admin: Signer<'info>,
16
17    #[account(
18        init,
19        seeds = [SEED_AUTHORITY],
20        bump,
21        payer = admin,
22        space = 8 + size_of::<Authority>(),
23    )]
24    pub authority: Account<'info, Authority>,
25
26    #[account(address = clockwork_crank::ID)]
27    pub clockwork_program: Program<'info, clockwork_crank::program::ClockworkCrank>,
28
29    #[account(
30        init,
31        seeds = [SEED_CONFIG],
32        bump,
33        payer = admin,
34        space = 8 + size_of::<Config>(),
35    )]
36    pub config: Account<'info, Config>,
37    
38    #[account(
39        init,
40        seeds = [SEED_ROTATOR],
41        bump,
42        payer = admin,
43        space = 8 + size_of::<Rotator>(),
44    )]
45    pub rotator: Account<'info, Rotator>,
46
47    #[account()]
48    pub mint: Account<'info, Mint>,
49
50    #[account(
51        init,
52        seeds = [SEED_REGISTRY],
53        bump,
54        payer = admin,
55        space = 8 + size_of::<Registry>(),
56    )]
57    pub registry: Account<'info, Registry>,
58
59    #[account(
60        init,
61        seeds = [
62            SEED_SNAPSHOT, 
63            (0 as u64).to_be_bytes().as_ref()
64        ],
65        bump,
66        payer = admin,
67        space = 8 + size_of::<Snapshot>(),
68    )]
69    pub snapshot: Account<'info, Snapshot>,
70
71    #[account(
72        seeds = [
73            SEED_QUEUE, 
74            authority.key().as_ref(), 
75            "snapshot".as_bytes()
76        ], 
77        seeds::program = clockwork_crank::ID,
78        bump
79    )]
80    pub snapshot_queue: SystemAccount<'info>,
81
82    #[account(address = system_program::ID)]
83    pub system_program: Program<'info, System>,    
84}
85
86pub fn handler<'info>(ctx: Context<'_, '_, '_, 'info, Initialize<'info>>) -> Result<()> {
87    // Get accounts
88    let admin = &ctx.accounts.admin;
89    let authority = &ctx.accounts.authority;
90    let clockwork_program = &ctx.accounts.clockwork_program;
91    let config = &mut ctx.accounts.config;
92    let rotator = &mut ctx.accounts.rotator;
93    let mint = &ctx.accounts.mint;
94    let registry = &mut ctx.accounts.registry;
95    let snapshot = &mut ctx.accounts.snapshot;
96    let snapshot_queue = &ctx.accounts.snapshot_queue;
97    let system_program = &ctx.accounts.system_program;
98
99    // Initialize accounts
100    config.init(admin.key(), mint.key())?;
101    registry.init()?;
102    rotator.init()?;
103
104    // Setup the first snapshot
105    registry.new_snapshot(snapshot)?;
106    registry.rotate_snapshot(None, snapshot)?;
107
108    // Create a queue to take snapshots of the registry
109    let bump = *ctx.bumps.get("authority").unwrap();
110    let snapshot_kickoff_ix = Instruction {
111        program_id: crate::ID,
112        accounts: vec![
113            AccountMeta::new_readonly(authority.key(), false),
114            AccountMeta::new(registry.key(), false),
115            AccountMeta::new_readonly(snapshot_queue.key(), true),
116        ],
117        data: clockwork_crank::anchor::sighash("snapshot_kickoff").into(),
118    };
119    clockwork_crank::cpi::queue_create(
120        CpiContext::new_with_signer(
121            clockwork_program.to_account_info(),
122            clockwork_crank::cpi::accounts::QueueCreate {
123                authority: authority.to_account_info(),
124                payer: admin.to_account_info(),
125                queue: snapshot_queue.to_account_info(),
126                system_program: system_program.to_account_info(),
127            },
128            &[&[SEED_AUTHORITY, &[bump]]]
129        ),
130        "snapshot".into(),
131        snapshot_kickoff_ix.into(),
132        Trigger::Cron { schedule: "0 * * * * * *".into() }
133    )?;
134
135    Ok(())
136}
137