利息承載擴展
InterestBearing 擴展是一個 Mint 賬戶擴展,讓用戶可以為其代幣應用利率,並在任何時刻檢索包括利息在內的更新總額。
初始化鑄幣賬戶
由於 Anchor 沒有任何針對 interest_bearing 擴展的宏,我們將使用原始 CPI 創建一個 Mint 賬戶。
以下是如何使用轉賬費用擴展創建鑄幣的方法:
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(())
}計算利息
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);更新利息承載擴展
通過 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,
)?;