1//! Register a holder (simulated KYC). The transfer hook requires a holder record on both sides, so only
2//! registered wallets can hold bonds. A holder registered after some record moments starts at zero for them.
3
4use anchor_lang::prelude::*;
5
6use crate::constants::*;
7use crate::events::HolderRegistered;
8use crate::state::{Bond, HolderRecord, PositionHistory};
9
10#[derive(Accounts)]
11#[instruction(owner: Pubkey)]
12pub struct RegisterHolder<'info> {
13 #[account(mut)]
14 pub registrar: Signer<'info>,
15
16 #[account(has_one = registrar)]
17 pub bond: Box<Account<'info, Bond>>,
18
19 #[account(
20 init,
21 payer = registrar,
22 space = 8 + HolderRecord::INIT_SPACE,
23 seeds = [HOLDER_SEED, bond.mint.as_ref(), owner.as_ref()],
24 bump,
25 )]
26 pub holder: Box<Account<'info, HolderRecord>>,
27
28 pub system_program: Program<'info, System>,
29}
30
31pub fn handle_register_holder(ctx: Context<RegisterHolder>, owner: Pubkey) -> Result<()> {
32 let bond = &ctx.accounts.bond;
33 let passed = bond.passed_record_moments(bond.now()?)?;
34
35 let holder = &mut ctx.accounts.holder;
36 holder.bond = bond.key();
37 holder.owner = owner;
38 holder.position = PositionHistory::new(passed);
39 holder.paid = 0;
40 holder.locked = 0;
41 holder.redeemed = 0;
42 holder.bump = ctx.bumps.holder;
43 emit!(HolderRegistered { bond: bond.key(), owner });
44 Ok(())
45}