고급 방법: 사전 거래 분석, 배치 작업 및 계정 패턴 연구와 같은 특수한 사용 사례를 위해 account keys로 우선 수수료를 얻습니다.
개요
account keys 방법은 전체 거래를 구성하기 전의 수수료를 빠르게 추정하거나 계산할 때 거래 직렬화에 대한 더 간단한 대안을 제공합니다.고급 사용 사례
- 사전 거래 분석
- 계정 배치 작업
- 시장 조사 및 패턴
- 특수 아키텍처
트레이드 오프
- 직렬화된 거래보다 정확성이 낮음
- 지시사항에 대한 구체적인 분석 불가능
- 계정 수준 패턴에 최적화
권장 사항: 대부분의 애플리케이션에는 직렬화된 거래 방법을 대신 사용하세요. 이 account keys 방법은 계정 수준의 분석이나 사전 거래 계획이 필요한 특수한 사용 사례를 위한 것입니다.
Account Keys 사용 시기
- 이상적인 사용 사례
- 특수한 시나리오
사전 거래 계획
전체 거래를 구성하기 전의 수수료 추정
간편 통합
아키텍처가 거래 직렬화를 어렵게 만드는 경우
빠른 시장 분석
거래를 구성하지 않고 특정 계정의 수수료 패턴 분석
다중 계정 분석
여러 계정에 걸친 수수료 패턴 독립적 이해
연구 및 분석: 다른 계정 및 프로그램에 걸친 수수료 패턴 연구 시배치 작업: 여러 계정에 걸친 수수료 패턴 분석 시사전 계획: 복잡한 거래 워크플로우를 구축하기 전의 비용 추정 시맞춤 아키텍처: 시스템 제약으로 인해 거래 직렬화를 할 수 없을 때
빠른 시작
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 (기본값)일 때, 거래가 없는 슬롯은 제외되지 않고 0수수료로 처리됩니다. 이는 활동이 적은 계정에 대해서도 보다 균형 잡힌 추정을 제공합니다.세부 정보 포함
세부 정보 포함
각 계정의 수수료 패턴에 대한 세부 정보를 요청하세요:이는 각 계정에 대해 수수료가 어떻게 계산되었는지에 대한 추가 정보를 제공합니다.
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 문서 및 매개변수