الرموز المميزة ذات الفائدة

ما هي عملة تحمل الفائدة؟

يتيح امتداد عملة InterestBearingConfig في برنامج Token Extension تخزين معدل فائدة سنوي مباشرة على السلسلة.

الرموز التي تحمل فائدة لا تضيف المزيد من الرموز إلى حسابات الرموز بمرور الوقت. يظل مبلغ الرموز المخزن في كل حساب رموز كما هو حتى تقوم تعليمة برنامج الرموز بتغييره، مثل السك أو النقل أو الحرق.

مع مرور الوقت، يمكن أن يزداد مبلغ واجهة المستخدم المحسوب مع الفائدة حتى لو ظل مبلغ الرموز وإجمالي المعروض من الرموز كما هو.

كيف يتم حساب تغييرات المعدل التاريخية

  • يخزن InterestBearingConfig initialization_timestamp و pre_update_average_rate و last_update_timestamp و current_rate.
  • يحسب amount_to_ui_amount مبلغ واجهة المستخدم على خطوتين: يحسب أولاً الفائدة من التهيئة إلى last_update_timestamp باستخدام pre_update_average_rate، ثم يحسب الفائدة من last_update_timestamp إلى الطابع الزمني الحالي باستخدام current_rate.
  • عند تشغيل UpdateRate، يستدعي process_update_rate time_weighted_average_rate ويحدث pre_update_average_rate إلى متوسط تاريخي جديد موزون بالوقت، ثم يسجل last_update_timestamp و current_rate جديدين.
  • بعد تغيرات المعدل بمرور الوقت، يتم تمثيل التغييرات الأقدم بواسطة pre_update_average_rate، بينما يتم حساب الفترة من last_update_timestamp إلى الوقت الحالي باستخدام current_rate.

كيفية إنشاء واستخدام الرموز التي تحمل فائدة

لإنشاء واستخدام الرموز التي تحمل فائدة:

  1. احسب حجم حساب العملة والإيجار المطلوب للعملة وامتداد InterestBearingConfig.
  2. أنشئ حساب العملة باستخدام CreateAccount، وهيئ InterestBearingConfig، وهيئ العملة باستخدام InitializeMint.
  3. اسك الرموز كالمعتاد.
  4. استخدم UpdateRate لتغيير المعدل الحالي للعملة بمرور الوقت.
  5. حول مبالغ الرموز إلى مبلغ واجهة مستخدم مع الفائدة باستخدام AmountToUiAmount أو الطرق المساعدة التي تجلب حساب العملة ومتغير نظام الساعة، ثم احسب مبلغ واجهة المستخدم دون إرسال معاملة.

تحويل المبلغ بين واجهة المستخدم خارج السلسلة وعلى السلسلة

يقوم مسار المساعد خارج السلسلة بجلب حساب السك وsysvar الخاص بالساعة، ثم يحسب مبلغ واجهة المستخدم محليًا دون إرسال معاملة. يستخدم المسار على السلسلة AmountToUiAmount، والذي يعمل في برنامج الرموز ويُرجع مبلغ واجهة المستخدم في بيانات إرجاع المعاملة. يمكن إرسال AmountToUiAmount في معاملة أو محاكاته.

حساب حجم الحساب

احسب حجم حساب السك للسك الأساسي بالإضافة إلى امتداد InterestBearingConfig. هذا هو الحجم المستخدم في CreateAccount.

حساب الإيجار

احسب الإيجار باستخدام الحجم المطلوب للسك بالإضافة إلى امتداد InterestBearingConfig.

إنشاء حساب السك

أنشئ حساب السك بالمساحة والlamports المحسوبة.

تهيئة InterestBearingConfig

هيّئ امتداد InterestBearingConfig على السك.

تهيئة السك

هيّئ السك باستخدام InitializeMint في نفس المعاملة.

إنشاء حساب رمز وسك الرموز

أنشئ حساب رمز للسك، ثم اسك الرموز إلى حساب الرمز هذا.

احسب مبلغ واجهة المستخدم باستخدام المساعد خارج السلسلة

جلب حساب السك ومتغير النظام للساعة، ثم احسب مبلغ واجهة المستخدم دون إرسال معاملة.

حساب حجم الحساب

احسب حجم حساب السك للسك الأساسي بالإضافة إلى امتداد InterestBearingConfig. هذا هو الحجم المستخدم في CreateAccount.

حساب الإيجار

احسب الإيجار باستخدام الحجم المطلوب للسك بالإضافة إلى امتداد InterestBearingConfig.

إنشاء حساب السك

أنشئ حساب السك بالمساحة والlamports المحسوبة.

تهيئة InterestBearingConfig

هيّئ امتداد InterestBearingConfig على السك.

تهيئة السك

هيّئ السك باستخدام InitializeMint في نفس المعاملة.

إنشاء حساب رمز وسك الرموز

أنشئ حساب رمز للسك، ثم اسك الرموز إلى حساب الرمز هذا.

احسب مبلغ واجهة المستخدم باستخدام المساعد خارج السلسلة

جلب حساب السك ومتغير النظام للساعة، ثم احسب مبلغ واجهة المستخدم دون إرسال معاملة.

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]));

ترتيب التعليمات

يجب أن يأتي InterestBearingMintInstruction::Initialize قبل InitializeMint. يجب تضمين CreateAccount، InterestBearingMintInstruction::Initialize، و InitializeMint في نفس المعاملة.

مرجع المصدر

العنصرالوصفالمصدر
InterestBearingConfigامتداد السك الذي يخزن سلطة معدل الفائدة والطوابع الزمنية والمعدلات الحالية والتاريخية.المصدر
InterestBearingMintInstruction::Initializeتعليمة تهيئ إعدادات السك الحامل للفائدة قبل InitializeMint.المصدر
InterestBearingMintInstruction::UpdateRateتعليمة تغير معدل الفائدة الحالي للسك.المصدر
AmountToUiAmountتعليمة ترجع سلسلة مبلغ واجهة المستخدم الحالي لمبلغ رمز باستخدام إعدادات السك النشطة.المصدر
InterestBearingConfig::amount_to_ui_amountمساعد يحول مبلغ رمز إلى مبلغ واجهة مستخدم مع فائدة لطابع زمني معين.المصدر
process_initializeمنطق المعالج الذي يهيئ InterestBearingConfig ويسجل الطوابع الزمنية والمعدل الأولي.المصدر
process_update_rateمنطق المعالج الذي يحدث المعدل الحالي ويعيد حساب متوسط المعدل المرجح بالوقت ويسجل طابع التحديث الزمني.المصدر
process_amount_to_ui_amountمنطق المعالج الذي يرجع سلسلة مبلغ واجهة المستخدم باستخدام إعدادات السك الحامل للفائدة النشطة.المصدر

تايب سكريبت

يستخدم مثال Kit أدناه التعليمات المُنشأة مباشرة. تم تضمين أمثلة قديمة باستخدام @solana/web3.js و @solana/spl-token للمرجعية.

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?

جدول المحتويات

تعديل الصفحة

تدار بواسطة

© 2026 مؤسسة سولانا.
جميع الحقوق محفوظة.
تواصل معنا