use anchor_lang::prelude::*;
use anchor_spl::token::{Token, TokenAccount, Mint};
use anchor_spl::associated_token::AssociatedToken;
const MAX_MEMBERS: usize = 5;
const MEMBER_INFO_SIZE: usize = 32 + 8 + 8 + 32; const TOTAL_MEMBERS_SPACE: usize = MAX_MEMBERS * MEMBER_INFO_SIZE;
#[account]
#[derive(Default, Debug)]
pub struct SplitWallet {
pub authority: Pubkey,
pub tentacles: Pubkey,
pub name: String,
pub mint: Pubkey,
pub total_shares: u64,
pub total_members: u8,
pub last_inflow: u64,
pub total_inflow: u64,
pub token_account: Pubkey,
pub remaining_flow: u64,
pub bump_seed: u8,
pub total_available_shares: u64,
pub disburse_cycles: u64, pub members: Vec<MemberInfo>,
}
impl SplitWallet {
pub fn is_member(&self, member_info: &MemberInfo) -> bool {
self.members.iter().any(|m| m.member == member_info.member)
}
pub fn find_member_index(&self, member_pubkey: &Pubkey) -> Option<usize> {
self.members.iter().position(|m| m.member == *member_pubkey)
}
}
#[derive(Clone, AnchorSerialize, AnchorDeserialize, Debug)]
pub struct MemberInfo {
pub member: Pubkey,
pub shares: u64,
pub disburse_cycles: u64,
pub member_token_account: Pubkey,
}
#[derive(Accounts)]
#[instruction(name: String, bump: u8)]
pub struct InitializeWallet<'info> {
#[account(
init,
payer = authority,
seeds = [b"split_wallet".as_ref(), name.as_bytes()],
bump,
space = 8 + 32 + 32 + 4 + name.len() + 32 + 8 + 1 + 8 + 8 + 32 + 8 + 1 + 8 + TOTAL_MEMBERS_SPACE
)]
pub wallet: Account<'info, SplitWallet>,
#[account(
mut,
constraint = wallet_token_account.owner == wallet.key(),
constraint = wallet_token_account.delegate.is_none(),
constraint = wallet_token_account.close_authority.is_none(),
constraint = wallet_token_account.mint == mint.key(),
)]
pub wallet_token_account: Account<'info, TokenAccount>,
pub mint: Account<'info, Mint>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
pub associated_token_program: Program<'info, AssociatedToken>,
pub token_program: Program<'info, Token>,
}
#[derive(Accounts)]
pub struct AddMember<'info> {
#[account(
mut,
has_one = authority,
)]
pub wallet: Account<'info, SplitWallet>,
pub member: UncheckedAccount<'info>,
#[account(mut)]
pub member_token_account: UncheckedAccount<'info>,
#[account(mut)]
pub authority: Signer<'info>,
pub mint: Account<'info, Mint>,
pub system_program: Program<'info, System>,
pub rent: Sysvar<'info, Rent>,
pub associated_token_program: Program<'info, AssociatedToken>,
pub token_program: Program<'info, Token>,
}
#[derive(Accounts)]
pub struct Distribute<'info> {
#[account(mut)]
pub wallet: Account<'info, SplitWallet>,
pub pda_as_authority: AccountInfo<'info>,
#[account(mut)]
pub wallet_token_account: Account<'info, TokenAccount>,
#[account(mut)]
pub member_token_account: Account<'info, TokenAccount>,
#[account(signer)]
pub wallet_authority: AccountInfo<'info>,
pub token_program: Program<'info, Token>,
pub mint: Account<'info, Mint>,
pub rent: Sysvar<'info, Rent>,
pub system_program: Program<'info, System>,
pub associated_token_program: Program<'info, AssociatedToken>,
}