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