Anchor
Token2022 з Anchor

Token2022 з Anchor

Розширення з нарахуванням відсотків

Розширення InterestBearing є розширенням облікового запису Mint, яке дозволяє користувачам застосовувати відсоткову ставку до своїх токенів і отримувати оновлену загальну суму, включаючи відсотки, у будь-який момент.

Initializing the Mint Account

Оскільки Anchor не має макросів для розширення interest_bearing, ми створимо обліковий запис Mint за допомогою необроблених CPI.

Ось як створити емісію з розширенням Transfer Fee:

rust
use anchor_lang::prelude::*;
use anchor_lang::system_program::{create_account, CreateAccount};
use anchor_spl::{
    token_2022::{
        initialize_mint2,
        spl_token_2022::{extension::ExtensionType, pod::PodMint},
        InitializeMint2,
    },
    token_interface::{
        interest_bearing_mint_initialize, InterestBearingMintInitialize, Mint, Token2022,
    },
};
 
#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(mut)]
    pub mint_account: Signer<'info>,
    pub token_program: Program<'info, Token2022>,
    pub system_program: Program<'info, System>,
}
 
pub fn initialize_interest_bearing_config(
    ctx: Context<Initialize>,
    rate: i16
) -> Result<()> {
    // Calculate space required for mint and extension data
    let mint_size =
        ExtensionType::try_calculate_account_len::<PodMint>(&[ExtensionType::InterestBearingConfig])?;
 
    // Calculate minimum lamports required for size of mint account with extensions
    let lamports = (Rent::get()?).minimum_balance(mint_size);
 
    // Invoke System Program to create new account with space for mint and extension data
    create_account(
        CpiContext::new(
            ctx.accounts.system_program.to_account_info(),
            CreateAccount {
                from: ctx.accounts.payer.to_account_info(),
                to: ctx.accounts.mint_account.to_account_info(),
            },
        ),
        lamports,                          // Lamports
        mint_size as u64,                  // Space
        &ctx.accounts.token_program.key(), // Owner Program
    )?;
 
    // Initialize the InterestBearingConfig extension
    // This instruction must come before the instruction to initialize the mint data
    interest_bearing_mint_initialize(
        CpiContext::new(
            ctx.accounts.token_program.to_account_info(),
            InterestBearingMintInitialize {
                token_program_id: ctx.accounts.token_program.to_account_info(),
                mint: ctx.accounts.mint_account.to_account_info(),
            },
        ),
        Some(ctx.accounts.payer.key()),
        rate,
    )?;
 
    // Initialize the standard mint account data
    initialize_mint2(
        CpiContext::new(
            ctx.accounts.token_program.to_account_info(),
            InitializeMint2 {
                mint: ctx.accounts.mint_account.to_account_info(),
            },
        ),
        2,                               // decimals
        &ctx.accounts.payer.key(),       // mint authority
        Some(&ctx.accounts.payer.key()), // freeze authority
    )?;
 
    Ok(())
}

Calculating the Interest

Розширення InterestBearing не генерує нові токени; відображена сума просто включає накопичені відсотки через функцію amount_to_ui_amount, що робить зміну суто естетичною.

Тож після unpacking облікового запису Token, для якого ми хочемо обчислити відсотки, легко отримати всю інформацію, необхідну для виконання розрахунку суми відсотків.

На щастя, нам навіть не потрібно цього робити, оскільки ми можемо використовувати функцію amountToUiAmount таким чином:

ts
const tokenInfo = await getAccount(
    connection,
    tokenAccount,
    undefined,
    TOKEN_2022_PROGRAM_ID,
);
 
console.log("Token Amount: ", tokenInfo.amount);
    
const uiAmount = await amountToUiAmount(
    connection,
    keypair,
    mint.publicKey,
    tokenInfo.amount,
    TOKEN_2022_PROGRAM_ID,
);
    
console.log("UI Amount: ", uiAmount);

Updating the Interest Bearing Extension

З розширенням InterestBearing можливо змінювати відсотки, що нараховуються на токен-рахунок, завдяки структурі його даних:

rust
pub struct InterestBearing {
    pub rate_authority: Pubkey,
    pub initialization_timestamp: i64,
    pub pre_update_average_rate: u16,
    pub last_update_timestamp: i64,
    pub current_rate: u16,
}

Для цього ми можемо використовувати інструкцію interest_bearing_mint_update_rate() таким чином:

ts
interest_bearing_mint_update_rate(
    CpiContext::new(
        ctx.accounts.token_program.to_account_info(),
        InterestBearingMintUpdateRate {
            token_program_id: ctx.accounts.token_program.to_account_info(),
            mint: ctx.accounts.mint_account.to_account_info(),
            rate_authority: ctx.accounts.authority.to_account_info(),
        },
    ),
    rate,
)?;

І якщо ми хочемо, ми можемо змінити повноваження щодо встановлення відсотків за допомогою функції set_authority(), передавши правильний AuthorityType таким чином:

ts
set_authority(
    CpiContext::new(
        ctx.accounts.token_program.to_account_info(),
        SetAuthority {
            current_authority: ctx.accounts.authority.to_account_info,
            account_or_mint: ctx.accounts.mint.to_account_info,
        }
    ),
    spl_token_2022::instruction::AuthorityType::InterestRate,
    new_authority,
)?;
Blueshift © 2025Commit: 6d01265
Blueshift | Token2022 з Anchor | Розширення нарахування відсотків