Token Berbunga

Apa Itu Mint Berbunga?

Ekstensi mint InterestBearingConfig pada Token Extensions Program memungkinkan mint menyimpan tingkat bunga tahunan secara langsung di onchain.

Token berbunga tidak menambahkan lebih banyak token ke token account dari waktu ke waktu. Jumlah token yang tersimpan di setiap token account tetap sama hingga ada instruksi program token yang mengubahnya, seperti minting, transfer, atau burning.

Seiring berjalannya waktu, jumlah UI yang dihitung dengan bunga dapat meningkat meskipun jumlah token dan pasokan token tetap sama.

Bagaimana Perubahan Tingkat Historis Dihitung

  • InterestBearingConfig menyimpan initialization_timestamp, pre_update_average_rate, last_update_timestamp, dan current_rate.
  • amount_to_ui_amount menghitung jumlah UI dalam dua langkah: pertama menghitung bunga dari inisialisasi hingga last_update_timestamp menggunakan pre_update_average_rate, kemudian menghitung bunga dari last_update_timestamp hingga timestamp saat ini menggunakan current_rate.
  • Ketika UpdateRate dijalankan, process_update_rate memanggil time_weighted_average_rate dan memperbarui pre_update_average_rate menjadi rata-rata historis tertimbang waktu yang baru, kemudian mencatat last_update_timestamp dan current_rate yang baru.
  • Setelah perubahan tingkat dari waktu ke waktu, perubahan yang lebih awal direpresentasikan oleh pre_update_average_rate, sementara periode dari last_update_timestamp hingga waktu saat ini dihitung dengan current_rate.

Cara Membuat dan Menggunakan Token Berbunga

Untuk membuat dan menggunakan token berbunga:

  1. Hitung ukuran mint account dan rent yang diperlukan untuk mint dan ekstensi InterestBearingConfig.
  2. Buat mint account dengan CreateAccount, inisialisasi InterestBearingConfig, dan inisialisasi mint dengan InitializeMint.
  3. Mint token seperti biasa.
  4. Gunakan UpdateRate untuk mengubah tingkat saat ini dari mint dari waktu ke waktu.
  5. Konversi jumlah token menjadi jumlah UI dengan bunga menggunakan AmountToUiAmount atau metode helper yang mengambil mint account dan clock sysvar, kemudian menghitung jumlah UI tanpa mengirim transaksi.

Konversi Jumlah UI Offchain dan Onchain

Jalur helper offchain mengambil mint account dan clock sysvar, lalu menghitung jumlah UI secara lokal tanpa mengirim transaksi. Jalur onchain menggunakan AmountToUiAmount, yang berjalan di Token Program dan mengembalikan jumlah UI dalam data return transaksi. AmountToUiAmount dapat dikirim dalam transaksi atau disimulasikan.

Hitung ukuran akun

Hitung ukuran mint account untuk base mint ditambah ekstensi InterestBearingConfig. Ini adalah ukuran yang digunakan dalam CreateAccount.

Hitung rent

Hitung rent menggunakan ukuran yang diperlukan untuk mint ditambah ekstensi InterestBearingConfig.

Buat mint account

Buat mint account dengan ruang dan lamport yang telah dihitung.

Inisialisasi InterestBearingConfig

Inisialisasi ekstensi InterestBearingConfig pada mint.

Inisialisasi mint

Inisialisasi mint dengan InitializeMint dalam transaksi yang sama.

Buat token account dan mint token

Buat token account untuk mint, lalu mint token ke token account tersebut.

Hitung jumlah UI dengan bantuan offchain

Ambil akun mint dan clock sysvar, lalu hitung jumlah UI tanpa mengirim transaksi.

Hitung ukuran akun

Hitung ukuran mint account untuk base mint ditambah ekstensi InterestBearingConfig. Ini adalah ukuran yang digunakan dalam CreateAccount.

Hitung rent

Hitung rent menggunakan ukuran yang diperlukan untuk mint ditambah ekstensi InterestBearingConfig.

Buat mint account

Buat mint account dengan ruang dan lamport yang telah dihitung.

Inisialisasi InterestBearingConfig

Inisialisasi ekstensi InterestBearingConfig pada mint.

Inisialisasi mint

Inisialisasi mint dengan InitializeMint dalam transaksi yang sama.

Buat token account dan mint token

Buat token account untuk mint, lalu mint token ke token account tersebut.

Hitung jumlah UI dengan bantuan offchain

Ambil akun mint dan clock sysvar, lalu hitung jumlah UI tanpa mengirim transaksi.

Example
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();
const interestBearingExtension = extension("InterestBearingConfig", {
rateAuthority: client.payer.address,
initializationTimestamp: BigInt(Math.floor(Date.now() / 1000)),
lastUpdateTimestamp: BigInt(Math.floor(Date.now() / 1000)),
preUpdateAverageRate: 30000,
currentRate: 30000
});
const mintSpace = BigInt(getMintSize([interestBearingExtension]));

Urutan Instruksi

InterestBearingMintInstruction::Initialize harus datang sebelum InitializeMint. CreateAccount, InterestBearingMintInstruction::Initialize, dan InitializeMint harus disertakan dalam transaksi yang sama.

Referensi Sumber

ItemDeskripsiSumber
InterestBearingConfigEkstensi mint yang menyimpan otoritas tingkat bunga, timestamp, serta tingkat saat ini dan historis.Sumber
InterestBearingMintInstruction::InitializeInstruksi yang menginisialisasi konfigurasi interest bearing sebelum InitializeMint.Sumber
InterestBearingMintInstruction::UpdateRateInstruksi yang mengubah tingkat bunga saat ini dari mint.Sumber
AmountToUiAmountInstruksi yang mengembalikan string jumlah UI saat ini untuk jumlah token menggunakan konfigurasi aktif mint.Sumber
InterestBearingConfig::amount_to_ui_amountPembantu yang mengonversi jumlah token menjadi jumlah UI dengan bunga untuk timestamp tertentu.Sumber
process_initializeLogika prosesor yang menginisialisasi InterestBearingConfig dan mencatat timestamp serta tingkat awal.Sumber
process_update_rateLogika prosesor yang memperbarui tingkat saat ini, menghitung ulang tingkat rata-rata tertimbang waktu, dan mencatat timestamp pembaruan.Sumber
process_amount_to_ui_amountLogika prosesor yang mengembalikan string jumlah UI menggunakan konfigurasi interest bearing aktif dari mint.Sumber

Typescript

Contoh Kit di bawah ini menggunakan instruksi yang dihasilkan secara langsung. Contoh lama menggunakan @solana/web3.js dan @solana/spl-token disertakan sebagai referensi.

Kit

Instructions
import {
lamports,
createClient,
appendTransactionMessageInstructions,
createTransactionMessage,
generateKeyPairSigner,
getBase64EncodedWireTransaction,
pipe,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
signTransactionMessageWithSigners,
unwrapOption
} from "@solana/kit";
import { solanaRpc, rpcAirdrop } from "@solana/kit-plugin-rpc";
import { generatedPayer, airdropPayer } from "@solana/kit-plugin-signer";
import { getCreateAccountInstruction } from "@solana-program/system";
import {
amountToUiAmountForMintWithoutSimulation,
extension,
fetchMint,
findAssociatedTokenPda,
getAmountToUiAmountInstruction,
getCreateAssociatedTokenInstructionAsync,
getInitializeInterestBearingMintInstruction,
getInitializeMintInstruction,
getMintSize,
getMintToCheckedInstruction,
getUpdateRateInterestBearingMintInstruction,
isExtension,
TOKEN_2022_PROGRAM_ADDRESS
} from "@solana-program/token-2022";
const client = await createClient()
.use(generatedPayer())
.use(
solanaRpc({
rpcUrl: "http://localhost:8899",
rpcSubscriptionsUrl: "ws://localhost:8900"
})
)
.use(rpcAirdrop())
.use(airdropPayer(lamports(1_000_000_000n)));
const mint = await generateKeyPairSigner();
const recipient = await generateKeyPairSigner();
const tokenAmount = 1_000_000_000_000n;
const interestBearingExtension = extension("InterestBearingConfig", {
rateAuthority: client.payer.address,
initializationTimestamp: BigInt(Math.floor(Date.now() / 1000)),
lastUpdateTimestamp: BigInt(Math.floor(Date.now() / 1000)),
preUpdateAverageRate: 30000,
currentRate: 30000
});
const mintSpace = BigInt(getMintSize([interestBearingExtension]));
const mintRent = await client.rpc
.getMinimumBalanceForRentExemption(mintSpace)
.send();
const [tokenAccount] = await findAssociatedTokenPda({
mint: mint.address,
owner: recipient.address,
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS
});
await client.sendTransaction([
getCreateAccountInstruction({
payer: client.payer, // Account funding the new mint account.
newAccount: mint, // New mint account to create.
lamports: mintRent, // Lamports funding the mint account rent.
space: mintSpace, // Account size in bytes for the mint plus InterestBearingConfig.
programAddress: TOKEN_2022_PROGRAM_ADDRESS // Program that owns the mint account.
}),
getInitializeInterestBearingMintInstruction({
mint: mint.address, // Mint account that stores the InterestBearingConfig extension.
rateAuthority: client.payer.address, // Authority allowed to update the interest rate later.
rate: 30000 // Interest rate in basis points.
}),
getInitializeMintInstruction({
mint: mint.address, // Mint account to initialize.
decimals: 0, // Number of decimals for the token.
mintAuthority: client.payer.address, // Authority allowed to mint new tokens.
freezeAuthority: client.payer.address // Authority allowed to freeze token accounts.
})
]);
await client.sendTransaction([
await getCreateAssociatedTokenInstructionAsync({
payer: client.payer, // Account funding the associated token account creation.
mint: mint.address, // Mint for the associated token account.
owner: recipient.address // Owner of the token account.
}),
getMintToCheckedInstruction({
mint: mint.address, // Mint account that issues the tokens.
token: tokenAccount, // Token account receiving the newly minted tokens.
mintAuthority: client.payer, // Signer authorized to mint new tokens.
amount: tokenAmount, // Token amount in base units.
decimals: 0 // Decimals defined on the mint.
})
]);
await new Promise((resolve) => setTimeout(resolve, 2_000));
const calculatedUiAmount = await amountToUiAmountForMintWithoutSimulation(
client.rpc,
mint.address,
tokenAmount
);
const amountToUiInstruction = getAmountToUiAmountInstruction({
mint: mint.address, // Mint whose UI amount conversion is being simulated.
amount: tokenAmount // Token amount in base units.
});
const { value: latestBlockhash } = await client.rpc.getLatestBlockhash().send();
const amountToUiMessage = pipe(
createTransactionMessage({ version: 0 }),
(tx) => setTransactionMessageFeePayerSigner(client.payer, tx),
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
(tx) => appendTransactionMessageInstructions([amountToUiInstruction], tx)
);
const signedAmountToUiMessage =
await signTransactionMessageWithSigners(amountToUiMessage);
const simulation = await client.rpc
.simulateTransaction(
getBase64EncodedWireTransaction(signedAmountToUiMessage),
{
encoding: "base64"
}
)
.send();
const simulatedUiAmount = Buffer.from(
simulation.value.returnData?.data?.[0] ?? "",
"base64"
).toString("utf8");
const updateRateInstruction = getUpdateRateInterestBearingMintInstruction({
mint: mint.address, // Mint account that stores the InterestBearingConfig extension.
rateAuthority: client.payer, // Signer authorized to update the interest rate.
rate: 15000 // New interest rate in basis points.
});
await client.sendTransaction([updateRateInstruction]);
const mintAccount = await fetchMint(client.rpc, mint.address);
const interestBearingConfig = (
unwrapOption(mintAccount.data.extensions) ?? []
).find((item) => isExtension("InterestBearingConfig", item));
console.log("Mint Address:", mint.address);
console.log("Token Account:", tokenAccount);
console.log("Calculated UI Amount:", calculatedUiAmount);
console.log("Simulated UI Amount:", simulatedUiAmount);
console.log("InterestBearingConfig:", interestBearingConfig);
Console
Click to execute the code.

Web3.js

Instructions
import {
Connection,
Keypair,
sendAndConfirmTransaction,
SystemProgram,
Transaction,
LAMPORTS_PER_SOL
} from "@solana/web3.js";
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
amountToUiAmountForMintWithoutSimulation,
createAmountToUiAmountInstruction,
createAssociatedTokenAccountInstruction,
createInitializeMintInstruction,
createInitializeInterestBearingMintInstruction,
createMintToCheckedInstruction,
createUpdateRateInterestBearingMintInstruction,
ExtensionType,
getAssociatedTokenAddressSync,
getInterestBearingMintConfigState,
getMint,
getMintLen,
TOKEN_2022_PROGRAM_ID
} from "@solana/spl-token";
const connection = new Connection("http://localhost:8899", "confirmed");
const latestBlockhash = await connection.getLatestBlockhash();
const feePayer = Keypair.generate();
const recipient = Keypair.generate();
const tokenAmount = 1_000_000_000_000n;
const airdropSignature = await connection.requestAirdrop(
feePayer.publicKey,
5 * LAMPORTS_PER_SOL
);
await connection.confirmTransaction({
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
signature: airdropSignature
});
const extensions = [ExtensionType.InterestBearingConfig];
const mint = Keypair.generate();
const mintLength = getMintLen(extensions);
const mintRent = await connection.getMinimumBalanceForRentExemption(mintLength);
const tokenAccount = getAssociatedTokenAddressSync(
mint.publicKey,
recipient.publicKey,
false,
TOKEN_2022_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
);
const createMintAccountInstruction = SystemProgram.createAccount({
fromPubkey: feePayer.publicKey, // Account funding the new mint account.
newAccountPubkey: mint.publicKey, // New mint account to create.
space: mintLength, // Account size in bytes for the mint plus InterestBearingConfig.
lamports: mintRent, // Lamports funding the mint account rent.
programId: TOKEN_2022_PROGRAM_ID // Program that owns the mint account.
});
const initializeInterestBearingInstruction =
createInitializeInterestBearingMintInstruction(
mint.publicKey, // Mint account that stores the InterestBearingConfig extension.
feePayer.publicKey, // Authority allowed to update the interest rate later.
30000, // Interest rate in basis points.
TOKEN_2022_PROGRAM_ID // Token program that owns the mint.
);
const initializeMintInstruction = createInitializeMintInstruction(
mint.publicKey, // Mint account to initialize.
0, // Number of decimals for the token.
feePayer.publicKey, // Authority allowed to mint new tokens.
feePayer.publicKey, // Authority allowed to freeze token accounts.
TOKEN_2022_PROGRAM_ID // Program that owns the mint account.
);
const createTokenAccountInstruction = createAssociatedTokenAccountInstruction(
feePayer.publicKey, // Account funding the associated token account creation.
tokenAccount, // Associated token account address to create.
recipient.publicKey, // Owner of the token account.
mint.publicKey, // Mint for the associated token account.
TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.
ASSOCIATED_TOKEN_PROGRAM_ID // Associated Token Program that creates the account.
);
const mintToTokenAccountInstruction = createMintToCheckedInstruction(
mint.publicKey, // Mint account that issues the tokens.
tokenAccount, // Token account receiving the newly minted tokens.
feePayer.publicKey, // Signer authorized to mint new tokens.
tokenAmount, // Token amount in base units.
0, // Decimals defined on the mint.
[], // Additional multisig signers.
TOKEN_2022_PROGRAM_ID // Token program that owns the mint and token account.
);
await sendAndConfirmTransaction(
connection,
new Transaction({
feePayer: feePayer.publicKey,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight
}).add(
createMintAccountInstruction,
initializeInterestBearingInstruction,
initializeMintInstruction
),
[feePayer, mint]
);
await sendAndConfirmTransaction(
connection,
new Transaction().add(
createTokenAccountInstruction,
mintToTokenAccountInstruction
),
[feePayer]
);
await new Promise((resolve) => setTimeout(resolve, 2_000));
const calculatedUiAmount = await amountToUiAmountForMintWithoutSimulation(
connection,
mint.publicKey,
tokenAmount
);
const amountToUiInstruction = createAmountToUiAmountInstruction(
mint.publicKey, // Mint whose UI amount conversion is being simulated.
tokenAmount, // Token amount in base units.
TOKEN_2022_PROGRAM_ID // Token program that owns the mint.
);
const amountToUiSimulation = await connection.simulateTransaction(
new Transaction().add(amountToUiInstruction),
[feePayer],
false
);
const simulatedUiAmount = Buffer.from(
amountToUiSimulation.value.returnData?.data?.[0] ?? "",
"base64"
).toString("utf8");
const updateRateInstruction = createUpdateRateInterestBearingMintInstruction(
mint.publicKey, // Mint account that stores the InterestBearingConfig extension.
feePayer.publicKey, // Signer authorized to update the interest rate.
15000, // New interest rate in basis points.
[], // Additional multisig signers.
TOKEN_2022_PROGRAM_ID // Token program that owns the mint.
);
await sendAndConfirmTransaction(
connection,
new Transaction().add(updateRateInstruction),
[feePayer]
);
const mintAccount = await getMint(
connection,
mint.publicKey,
"confirmed",
TOKEN_2022_PROGRAM_ID
);
const interestBearingConfig = getInterestBearingMintConfigState(mintAccount);
console.log("Mint Address:", mint.publicKey.toBase58());
console.log("Token Account:", tokenAccount.toBase58());
console.log("Calculated UI Amount:", calculatedUiAmount);
console.log("Simulated UI Amount:", simulatedUiAmount);
console.log("InterestBearingConfig:", interestBearingConfig);
Console
Click to execute the code.

Rust

Rust
use anyhow::{anyhow, Result};
use base64::prelude::{Engine as _, BASE64_STANDARD};
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_commitment_config::CommitmentConfig;
use solana_sdk::{
sysvar::clock::{self, Clock},
signature::{Keypair, Signer},
transaction::Transaction,
};
use solana_system_interface::instruction::create_account;
use spl_associated_token_account_interface::{
address::get_associated_token_address_with_program_id,
instruction::create_associated_token_account,
};
use spl_token_2022_interface::{
extension::{
interest_bearing_mint::{
instruction::{
initialize as initialize_interest_bearing_instruction, update_rate,
},
InterestBearingConfig,
},
BaseStateWithExtensions, ExtensionType, StateWithExtensions,
},
instruction::{amount_to_ui_amount, initialize_mint, mint_to_checked},
state::Mint,
ID as TOKEN_2022_PROGRAM_ID,
};
#[tokio::main]
async fn main() -> Result<()> {
let client = RpcClient::new_with_commitment(
String::from("http://localhost:8899"),
CommitmentConfig::confirmed(),
);
let fee_payer = Keypair::new();
let recipient = Keypair::new();
let token_amount = 1_000_000_000_000u64;
let airdrop_signature = client
.request_airdrop(&fee_payer.pubkey(), 5_000_000_000)
.await?;
loop {
let confirmed = client.confirm_transaction(&airdrop_signature).await?;
if confirmed {
break;
}
}
let mint = Keypair::new();
let mint_space =
ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::InterestBearingConfig])?;
let mint_rent = client
.get_minimum_balance_for_rent_exemption(mint_space)
.await?;
let create_mint_account_instruction = create_account(
&fee_payer.pubkey(), // Account funding the new mint account.
&mint.pubkey(), // New mint account to create.
mint_rent, // Lamports funding the mint account rent.
mint_space as u64, // Account size in bytes for the mint plus InterestBearingConfig.
&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.
);
let initialize_interest_bearing_instruction = initialize_interest_bearing_instruction(
&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.
&mint.pubkey(), // Mint account that stores the InterestBearingConfig extension.
Some(fee_payer.pubkey()), // Authority allowed to update the interest rate later.
30000, // Interest rate in basis points.
)?;
let initialize_mint_instruction = initialize_mint(
&TOKEN_2022_PROGRAM_ID, // Program that owns the mint account.
&mint.pubkey(), // Mint account to initialize.
&fee_payer.pubkey(), // Authority allowed to mint new tokens.
Some(&fee_payer.pubkey()), // Authority allowed to freeze token accounts.
0, // Number of decimals for the token.
)?;
let create_mint_transaction = Transaction::new_signed_with_payer(
&[
create_mint_account_instruction,
initialize_interest_bearing_instruction,
initialize_mint_instruction,
],
Some(&fee_payer.pubkey()),
&[&fee_payer, &mint],
client.get_latest_blockhash().await?,
);
client
.send_and_confirm_transaction(&create_mint_transaction)
.await?;
let token_account = get_associated_token_address_with_program_id(
&recipient.pubkey(),
&mint.pubkey(),
&TOKEN_2022_PROGRAM_ID,
);
let create_token_account_instruction = create_associated_token_account(
&fee_payer.pubkey(), // Account funding the associated token account creation.
&recipient.pubkey(), // Owner of the token account.
&mint.pubkey(), // Mint for the associated token account.
&TOKEN_2022_PROGRAM_ID, // Token program that owns the token account.
);
let mint_to_token_account_instruction = mint_to_checked(
&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint and token account.
&mint.pubkey(), // Mint account that issues the tokens.
&token_account, // Token account receiving the newly minted tokens.
&fee_payer.pubkey(), // Signer authorized to mint new tokens.
&[], // Additional multisig signers.
token_amount, // Token amount in base units.
0, // Decimals defined on the mint.
)?;
let create_token_account_transaction = Transaction::new_signed_with_payer(
&[
create_token_account_instruction,
mint_to_token_account_instruction,
],
Some(&fee_payer.pubkey()),
&[&fee_payer],
client.get_latest_blockhash().await?,
);
client
.send_and_confirm_transaction(&create_token_account_transaction)
.await?;
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
let mint_account = client.get_account(&mint.pubkey()).await?;
let mint_state = StateWithExtensions::<Mint>::unpack(&mint_account.data)?;
let interest_bearing_config = mint_state.get_extension::<InterestBearingConfig>()?;
let clock_account = client.get_account(&clock::ID).await?;
let clock: Clock = clock_account.deserialize_data()?;
let calculated_ui_amount = interest_bearing_config
.amount_to_ui_amount(token_amount, mint_state.base.decimals, clock.unix_timestamp)
.ok_or_else(|| anyhow!("Failed to calculate UI amount"))?;
let amount_to_ui_instruction = amount_to_ui_amount(
&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.
&mint.pubkey(), // Mint whose UI amount conversion is being simulated.
token_amount, // Token amount in base units.
)?;
let amount_to_ui_blockhash = client.get_latest_blockhash().await?;
let amount_to_ui_transaction = Transaction::new_signed_with_payer(
&[amount_to_ui_instruction],
Some(&fee_payer.pubkey()),
&[&fee_payer],
amount_to_ui_blockhash,
);
let amount_to_ui_result = client.simulate_transaction(&amount_to_ui_transaction).await?;
let simulated_ui_amount = String::from_utf8(
BASE64_STANDARD.decode(
amount_to_ui_result
.value
.return_data
.ok_or_else(|| anyhow!("Expected AmountToUiAmount return data"))?
.data
.0,
)?,
)?;
let update_rate_instruction = update_rate(
&TOKEN_2022_PROGRAM_ID, // Token program that owns the mint.
&mint.pubkey(), // Mint account that stores the InterestBearingConfig extension.
&fee_payer.pubkey(), // Signer authorized to update the interest rate.
&[], // Additional multisig signers.
15000, // New interest rate in basis points.
)?;
let update_rate_transaction = Transaction::new_signed_with_payer(
&[update_rate_instruction],
Some(&fee_payer.pubkey()),
&[&fee_payer],
client.get_latest_blockhash().await?,
);
client
.send_and_confirm_transaction(&update_rate_transaction)
.await?;
let updated_mint_account = client.get_account(&mint.pubkey()).await?;
let updated_mint_state = StateWithExtensions::<Mint>::unpack(&updated_mint_account.data)?;
let interest_bearing_config = updated_mint_state.get_extension::<InterestBearingConfig>()?;
println!("Mint Address: {}", mint.pubkey());
println!("Token Account: {}", token_account);
println!("Calculated UI Amount: {}", calculated_ui_amount);
println!("Simulated UI Amount: {}", simulated_ui_amount);
println!("InterestBearingConfig: {:#?}", interest_bearing_config);
Ok(())
}
Console
Click to execute the code.

Is this page helpful?

Daftar Isi

Edit Halaman

Dikelola oleh

© 2026 Yayasan Solana.
Semua hak dilindungi.
Terhubung