hydra/processors/init/
init_parent.rs1use crate::error::HydraError;
2use crate::state::{Fanout, MembershipModel};
3use anchor_lang::prelude::*;
4use anchor_spl::token::{Mint, Token};
5
6#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
7pub struct InitializeFanoutArgs {
8 pub bump_seed: u8,
9 pub native_account_bump_seed: u8,
10 pub name: String,
11 pub total_shares: u64,
12}
13
14#[derive(Accounts)]
15#[instruction(args: InitializeFanoutArgs)]
16pub struct InitializeFanout<'info> {
17 #[account(mut)]
18 pub authority: Signer<'info>,
19 #[account(
20 init,
21 space = 300,
22 seeds = [b"fanout-config", args.name.as_bytes()],
23 bump,
24 payer = authority
25 )]
26 pub fanout: Account<'info, Fanout>,
27 #[account(
28 init,
29 space = 1,
30 seeds = [b"fanout-native-account", fanout.key().as_ref()],
31 bump,
32 payer = authority
33 )
34 ]
35 pub holding_account: UncheckedAccount<'info>,
37 pub system_program: Program<'info, System>,
38 #[account(mut)]
39 pub membership_mint: Account<'info, Mint>,
40 pub rent: Sysvar<'info, Rent>,
41 pub token_program: Program<'info, Token>,
42}
43pub fn init(
44 ctx: Context<InitializeFanout>,
45 args: InitializeFanoutArgs,
46 model: MembershipModel,
47) -> Result<()> {
48 let membership_mint = &ctx.accounts.membership_mint;
49 let fanout = &mut ctx.accounts.fanout;
50 fanout.authority = ctx.accounts.authority.to_account_info().key();
51 fanout.account_key = ctx.accounts.holding_account.to_account_info().key();
52 fanout.name = args.name;
53 fanout.total_shares = args.total_shares;
54 fanout.total_available_shares = args.total_shares;
55 fanout.total_inflow = 0;
56 fanout.last_snapshot_amount = fanout.total_inflow;
57 fanout.bump_seed = args.bump_seed;
58 fanout.membership_model = model;
59 fanout.membership_mint = if membership_mint.key() == spl_token::native_mint::id() {
60 None
61 } else {
62 Some(membership_mint.key())
63 };
64 match fanout.membership_model {
65 MembershipModel::Wallet | MembershipModel::NFT => {
66 fanout.membership_mint = None;
67 fanout.total_staked_shares = None;
68 }
69 MembershipModel::Token => {
70 fanout.total_shares = membership_mint.supply;
71 fanout.total_available_shares = 0;
72 if fanout.membership_mint.is_none() {
73 return Err(HydraError::MintAccountRequired.into());
74 }
75 let mint = &ctx.accounts.membership_mint;
76 fanout.total_staked_shares = Some(0);
77 if !mint.is_initialized {
78 let cpi_program = ctx.accounts.token_program.to_account_info();
79 let accounts = anchor_spl::token::InitializeMint {
80 mint: mint.to_account_info(),
81 rent: ctx.accounts.rent.to_account_info(),
82 };
83 let cpi_ctx = CpiContext::new(cpi_program, accounts);
84 anchor_spl::token::initialize_mint(
85 cpi_ctx,
86 0,
87 &ctx.accounts.authority.to_account_info().key(),
88 Some(&ctx.accounts.authority.to_account_info().key()),
89 )?;
90 }
91 }
92 };
93
94 Ok(())
95}