-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8007fbe
commit 2bac879
Showing
4 changed files
with
144 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { | ||
Connection, | ||
Transaction, | ||
TransactionInstruction, | ||
PublicKey, | ||
ComputeBudgetProgram, | ||
} from '@solana/web3.js'; | ||
|
||
// Add priority fee according to 50th percentile of recent fees paid | ||
const DEFAULT_FEE_PERCENTILE = 0.5; | ||
|
||
export async function addComputeBudget( | ||
connection: Connection, | ||
transaction: Transaction, | ||
lockedWritableAccounts: PublicKey[] = [], | ||
): Promise<void> { | ||
const ixs = await determineComputeBudget( | ||
connection, | ||
transaction, | ||
lockedWritableAccounts, | ||
); | ||
transaction.add(...ixs); | ||
} | ||
|
||
export async function determineComputeBudget( | ||
connection: Connection, | ||
transaction: Transaction, | ||
lockedWritableAccounts: PublicKey[] = [], | ||
feePercentile: number = DEFAULT_FEE_PERCENTILE, | ||
): Promise<TransactionInstruction[]> { | ||
let computeBudget = 250_000; | ||
let priorityFee = 1; | ||
|
||
try { | ||
const simulateResponse = await connection.simulateTransaction(transaction); | ||
|
||
if (simulateResponse?.value?.unitsConsumed) { | ||
// Set compute budget to 120% of the units used in the simulated transaction | ||
computeBudget = Math.round(simulateResponse.value.unitsConsumed * 1.2); | ||
} | ||
|
||
priorityFee = await determinePriorityFee( | ||
connection, | ||
lockedWritableAccounts, | ||
feePercentile, | ||
); | ||
} catch (e) { | ||
console.error(`Failed to get compute budget for Solana transaction: ${e}`); | ||
} | ||
|
||
console.info(`Setting Solana compute unit budget to ${computeBudget} units`); | ||
console.info( | ||
`Setting Solana compute unit price to ${priorityFee} microLamports`, | ||
); | ||
|
||
return [ | ||
ComputeBudgetProgram.setComputeUnitLimit({ | ||
units: computeBudget, | ||
}), | ||
ComputeBudgetProgram.setComputeUnitPrice({ | ||
microLamports: priorityFee, | ||
}), | ||
]; | ||
} | ||
|
||
async function determinePriorityFee( | ||
connection: Connection, | ||
lockedWritableAccounts: PublicKey[] = [], | ||
percentile: number, | ||
): Promise<number> { | ||
// https://twitter.com/0xMert_/status/1768669928825962706 | ||
|
||
let fee = 1; // Set fee to 100,000 microlamport by default | ||
|
||
try { | ||
const recentFeesResponse = await connection.getRecentPrioritizationFees({ | ||
lockedWritableAccounts, | ||
}); | ||
|
||
if (recentFeesResponse) { | ||
// Get 75th percentile fee paid in recent slots | ||
const recentFees = recentFeesResponse | ||
.map((dp) => dp.prioritizationFee) | ||
.filter((dp) => dp > 0) | ||
.sort((a, b) => a - b); | ||
|
||
if (recentFees.length > 0) { | ||
const medianFee = | ||
recentFees[Math.floor(recentFees.length * percentile)]; | ||
fee = Math.max(fee, medianFee); | ||
} | ||
} | ||
} catch (e) { | ||
console.error('Error fetching Solana recent fees', e); | ||
} | ||
|
||
return fee; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.