高度な方法: トランザクション前の分析、バッチ操作、アカウントパターンの研究などの専門的なケースにおいてアカウントキーを使用して優先手数料を取得します。
概要
アカウントキーの方法は、迅速な手数料の見積もりが必要な場合や完全なトランザクションを構築する前に手数料を推定したい場合に、トランザクションシリアル化の簡易な代替手段を提供します。高度な利用ケース
- トランザクション前の分析
- アカウントのバッチ操作
- 市場調査とパターン
- 専門的なアーキテクチャ
トレードオフ
- シリアル化されたトランザクションより精度が低い
- 命令ごとの分析はできない
- アカウントレベルのパターンに最適
推奨: ほとんどのアプリケーションでは、代わりにシリアル化されたトランザクション方法を使用してください。このアカウントキーの方法は、アカウントレベルの分析やトランザクション前の計画が必要な専門的なケースに適しています。
アカウントキーの使用時
- 理想的な使用ケース
- 専門的なシナリオ
トランザクション前の計画
完全なトランザクションを構築する前に手数料を見積もります
簡易統合
アーキテクチャがトランザクションシリアル化を困難にする場合
迅速な市場分析
トランザクションを構築せずに特定のアカウントの手数料パターンを分析
マルチアカウント分析
複数のアカウント間での手数料パターンを独立して理解
研究と分析: 異なるアカウントやプログラムにわたる手数料パターンを調査する場合バッチ操作: 多くのアカウントで手数料パターンを同時に分析する場合事前計画: 複雑なトランザクションワークフローを構築する前のコスト見積もりのためカスタムアーキテクチャ: システムの制約がトランザクションシリアル化を妨げる場合
クイックスタート
1
アカウントの識別
トランザクションに関与するアカウントを決定します
2
APIを呼び出す
アカウントキーと希望の優先レベルでリクエストを行います
3
手数料の適用
推定値を使用してトランザクションの優先手数料を設定します
基本的な例
import { ComputeBudgetProgram } from "@solana/web3.js";
// 1. Identify accounts involved in your transaction
const accountKeys = [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
"YOUR_WALLET_ADDRESS", // Your wallet
"RECIPIENT_ADDRESS" // Recipient
];
// 2. Get priority fee estimate
const priorityFee = await getPriorityFeeEstimate(connection, accountKeys, "Medium");
// 3. Add to your transaction
const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: priorityFee
});
transaction.add(priorityFeeIx);
import requests
# Get priority fee estimate
def get_priority_fee_estimate(account_keys, priority_level="Medium"):
response = requests.post(
"https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY",
json={
"jsonrpc": "2.0",
"id": "1",
"method": "getPriorityFeeEstimate",
"params": [{
"accountKeys": account_keys,
"options": {
"priorityLevel": priority_level,
"recommended": True
}
}]
}
)
return response.json()["result"]["priorityFeeEstimate"]
# Usage
accounts = ["ACCOUNT_1", "ACCOUNT_2", "ACCOUNT_3"]
fee = get_priority_fee_estimate(accounts, "High")
print(f"Priority fee: {fee} micro-lamports")
実装ガイド
コア機能
優先手数料を取得するための再利用可能な関数はこちらです:async function getPriorityFeeEstimate(connection, accountKeys, priorityLevel = "Medium") {
const response = await fetch(connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
priorityLevel: priorityLevel,
recommended: true
}
}]
})
});
const result = await response.json();
if (result.error) {
throw new Error(`Fee estimation failed: ${JSON.stringify(result.error)}`);
}
return result.result.priorityFeeEstimate;
}
複数の優先レベルを含む完全な例
完全な実装を見るには展開
完全な実装を見るには展開
const {
Connection,
PublicKey,
Transaction,
ComputeBudgetProgram
} = require("@solana/web3.js");
// Initialize connection
const connection = new Connection("https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY");
async function analyzeAccountPriorityFees() {
// Define accounts involved in your transaction
const accountKeys = [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
"YOUR_WALLET_ADDRESS", // Your wallet
"TOKEN_ACCOUNT_ADDRESS", // Token account
"RECIPIENT_ADDRESS" // Recipient
];
try {
// Get estimates for different priority levels
const [lowFee, mediumFee, highFee, veryHighFee] = await Promise.all([
getPriorityFeeEstimate(connection, accountKeys, "Low"),
getPriorityFeeEstimate(connection, accountKeys, "Medium"),
getPriorityFeeEstimate(connection, accountKeys, "High"),
getPriorityFeeEstimate(connection, accountKeys, "VeryHigh")
]);
console.log("Priority Fee Estimates:");
console.log(`Low: ${lowFee} micro-lamports`);
console.log(`Medium: ${mediumFee} micro-lamports`);
console.log(`High: ${highFee} micro-lamports`);
console.log(`VeryHigh: ${veryHighFee} micro-lamports`);
// Get all levels at once for comparison
const allLevels = await getAllPriorityLevels(connection, accountKeys);
console.log("\nAll priority levels:", allLevels);
return {
low: lowFee,
medium: mediumFee,
high: highFee,
veryHigh: veryHighFee,
allLevels
};
} catch (error) {
console.error("Error getting priority fees:", error);
throw error;
}
}
// Helper function to get all priority levels
async function getAllPriorityLevels(connection, accountKeys) {
const response = await fetch(connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
includeAllPriorityFeeLevels: true
}
}]
})
});
const result = await response.json();
if (result.error) {
throw new Error(`Fee estimation failed: ${JSON.stringify(result.error)}`);
}
return result.result.priorityFeeLevels;
}
// Run the analysis
analyzeAccountPriorityFees();
アカウントタイプと戦略
- プログラムアカウント
- ユーザウォレット
- トークンアカウント
高トランザクション量のプログラムアカウントは、競争のために通常より高い優先手数料を示します。
// Popular program accounts
const programAccounts = [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", // Associated token program
"M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K" // Metaplex program
];
const programFees = await getPriorityFeeEstimate(connection, programAccounts, "Medium");
console.log(`Program account fees: ${programFees} micro-lamports`);
予想される動作: 高いトランザクション量と競争のために高い手数料。
アクティブなユーザウォレットは、その活動に基づいて異なる手数料パターンを持つ場合があります。
// Active user wallets
const userWallets = [
"USER_WALLET_1", // Active trader
"USER_WALLET_2" // Regular user
];
const walletFees = await getPriorityFeeEstimate(connection, userWallets, "Medium");
console.log(`User wallet fees: ${walletFees} micro-lamports`);
プロのヒント: より正確な見積もりのために送信者と受信者の両方のウォレットを含めます。
特定のトークンアカウントは、トークンの人気に基づいて異なるパターンを示すことがあります。
// Popular token accounts
const tokenAccounts = [
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC mint
"So11111111111111111111111111111111111111112", // SOL mint
"YOUR_TOKEN_ACCOUNT" // Your specific token account
];
const tokenFees = await getPriorityFeeEstimate(connection, tokenAccounts, "Medium");
高度な設定オプション
空スロット評価
空スロット評価
evaluateEmptySlotAsZero オプションは特にアカウントベースの見積もりに便利です:async function compareEmptySlotHandling(accountKeys) {
const withEmptyAsZero = await fetch(connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
priorityLevel: "Medium",
evaluateEmptySlotAsZero: true // Default: true
}
}]
})
});
const withoutEmptyAsZero = await fetch(connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
priorityLevel: "Medium",
evaluateEmptySlotAsZero: false
}
}]
})
});
const result1 = await withEmptyAsZero.json();
const result2 = await withoutEmptyAsZero.json();
console.log(`With empty as zero: ${result1.result.priorityFeeEstimate}`);
console.log(`Without empty as zero: ${result2.result.priorityFeeEstimate}`);
}
true (デフォルト)では、トランザクションのないスロットは除外されるのではなく、ゼロ手数料として扱われます。これは、活動の少ないアカウントに対してよりバランスの取れた見積もりを提供します。詳細を含める
詳細を含める
各アカウントの手数料パターンに関する詳細情報を要求します:これは、各アカウントの手数料がどのように計算されたかについての追加情報を返します。
async function getDetailedFeeEstimate(connection, accountKeys) {
const response = await fetch(connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
includeDetails: true,
priorityLevel: "Medium"
}
}]
})
});
const result = await response.json();
console.log("Detailed fee analysis:", result.result);
return result.result;
}
カスタムリックバック期間
カスタムリックバック期間
手数料の見積もりに分析するスロットの数を調整します:
async function getCustomLookbackEstimate(accountKeys, lookbackSlots = 50) {
const response = await fetch(connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
priorityLevel: "Medium",
lookbackSlots: lookbackSlots // 1-150, default is 150
}
}]
})
});
const result = await response.json();
return result.result.priorityFeeEstimate;
}
// Compare different lookback periods
const shortTerm = await getCustomLookbackEstimate(accountKeys, 50); // Recent trends
const longTerm = await getCustomLookbackEstimate(accountKeys, 150); // Historical average
console.log(`Short-term estimate: ${shortTerm} micro-lamports`);
console.log(`Long-term estimate: ${longTerm} micro-lamports`);
短いリックバック: より最近の、潜在的に変動のあるデータ大きいリックバック: より安定した、歴史的なコンテキスト
アカウント選択のベストプラクティス
書き込み可能なアカウントを含める
優先度: 変更されるアカウントに注目
const writableAccounts = [
"YOUR_WALLET", // Paying fees
"TOKEN_ACCOUNT", // Being modified
"RECIPIENT_ACCOUNT" // Receiving tokens
];
主要プログラムを追加
コンテキスト: 関連するプログラムアカウントを含める
const programAccounts = [
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
"CUSTOM_PROGRAM_ID" // Your program
];
エラー処理とフォールバック
class AccountBasedFeeEstimator {
constructor(connection) {
this.connection = connection;
this.fallbackFee = 10000; // 10k micro-lamports fallback
}
async getEstimate(accountKeys, priorityLevel = "Medium") {
try {
// Primary attempt
const estimate = await this.getPrimaryEstimate(accountKeys, priorityLevel);
return estimate;
} catch (error) {
console.warn("Primary estimate failed:", error.message);
// Fallback to different configuration
try {
return await this.getFallbackEstimate(accountKeys, priorityLevel);
} catch (fallbackError) {
console.warn("Fallback estimate failed:", fallbackError.message);
return this.fallbackFee;
}
}
}
async getPrimaryEstimate(accountKeys, priorityLevel) {
const response = await fetch(this.connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: accountKeys,
options: {
priorityLevel: priorityLevel,
recommended: true
}
}]
})
});
const result = await response.json();
if (result.error) {
throw new Error(result.error.message);
}
return result.result.priorityFeeEstimate;
}
async getFallbackEstimate(accountKeys, priorityLevel) {
// Try with fewer accounts or different settings
const coreAccounts = accountKeys.slice(0, 3); // Take first 3 accounts
const response = await fetch(this.connection.rpcEndpoint, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "1",
method: "getPriorityFeeEstimate",
params: [{
accountKeys: coreAccounts,
options: {
priorityLevel: "Medium", // Use medium as fallback
evaluateEmptySlotAsZero: true
}
}]
})
});
const result = await response.json();
if (result.error) {
throw new Error(result.error.message);
}
return result.result.priorityFeeEstimate;
}
}
// Usage
const estimator = new AccountBasedFeeEstimator(connection);
const fee = await estimator.getEstimate(accountKeys, "High");
async function safeGetPriorityFee(accountKeys, priorityLevel = "Medium") {
try {
return await getPriorityFeeEstimate(connection, accountKeys, priorityLevel);
} catch (error) {
console.warn(`Priority fee estimation failed: ${error.message}`);
// Return reasonable fallback based on priority level
const fallbacks = {
"Low": 1000,
"Medium": 5000,
"High": 15000,
"VeryHigh": 50000
};
return fallbacks[priorityLevel] || 5000;
}
}
制限と考慮事項
アカウントベースの方法の制限:
- 読み取り専用アカウントには精度が低い - アルゴリズムは書き込み可能なアカウントに集中
- 命令ごとの分析はできない - 特定の操作を考慮できない
- アカウント活動依存 - 非アクティブなアカウントには精度が低い
- トランザクションサイズを考慮しない - トランザクションの複雑性を考慮しない
シリアル化されたトランザクションにアップグレードするタイミング:
- 最高の精度を必要とする本番アプリケーション
- 複数の命令を持つ複雑なトランザクション
- 命令ごとの手数料パターンが重要である場合
- パフォーマンスが重要なアプリケーション
関連リソース
シリアル化されたトランザクション
完全なトランザクションシリアル化を使用するより正確な方法
APIリファレンス
完全なAPIドキュメントとパラメータ