高级方法:使用账户密钥获取优先费用估算,适用于交易前分析、批量操作和账户模式研究等特殊用例。

概述

当您需要快速费用估算或在构建完整交易之前估算费用时,账户密钥方法提供了一种比交易序列化更简单的替代方案。

高级用例

  • 交易前分析
  • 批量账户操作
  • 市场研究和模式
  • 专用架构

权衡

  • 准确性低于序列化交易
  • 无指令特定分析
  • 最适合账户级模式
建议:对于大多数应用程序,请使用序列化交易方法。此账户密钥方法适用于需要账户级分析或交易前规划的特殊用例。

何时使用账户密钥

交易前规划

在构建完整交易之前获取费用估算

简化集成

当您的架构使交易序列化变得困难时

快速市场分析

分析特定账户的费用模式而无需构建交易

多账户分析

独立了解多个账户的费用模式

快速开始

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

实施指南

核心功能

这是一个用于获取优先费用估算的可重用函数:
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;
}

具有多个优先级别的完整示例

账户类型与策略

高交易量的程序账户通常由于竞争而显示更高的优先费用。
// 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`);
预期行为:由于高交易量和竞争导致更高的费用。

高级配置选项

账户选择的最佳实践

包含可写账户

优先级:关注将被修改的账户
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");

限制与注意事项

基于账户的方法限制:
  1. 对只读账户的准确性较低 - 算法侧重于可写账户
  2. 无指令特定分析 - 无法考虑特定操作
  3. 账户活动依赖性 - 对于不活跃账户准确性较低
  4. 不考虑交易大小 - 不考虑交易复杂性
何时升级到序列化交易:
  • 需要最高准确性的生产应用
  • 包含多个指令的复杂交易
  • 当指令特定的费用模式很重要时
  • 性能关键的应用

相关资源