From 71749a226262e97b75e72002c8ad185c7695d1e5 Mon Sep 17 00:00:00 2001 From: nickkelly1 Date: Wed, 20 Nov 2024 20:39:36 -0600 Subject: [PATCH 1/2] fix: dropped jupiter sol swap transactions --- packages/swap/src/providers/jupiter/index.ts | 15 ++++-- packages/swap/src/providers/jupiter/types.ts | 9 +++- packages/swap/src/utils/solana.ts | 52 ++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/packages/swap/src/providers/jupiter/index.ts b/packages/swap/src/providers/jupiter/index.ts index ef92eb65d..50ff8b9cf 100644 --- a/packages/swap/src/providers/jupiter/index.ts +++ b/packages/swap/src/providers/jupiter/index.ts @@ -616,7 +616,7 @@ async function getJupiterTokens(abortable?: { const url = JUPITER_TOKENS_URL; let failed = false; let tokens: JupiterTokenInfo[]; - const backoff = [0, 100, 500, 1000, 2_500, 5_000]; + const backoff = [0, 100, 500, 1000, 2_000, 4_000]; let backoffi = 0; let errRef: undefined | { err: Error }; @@ -795,7 +795,7 @@ async function getJupiterQuote( let failed = false; let quote: JupiterQuoteResponse; - const backoff = [0, 100, 500, 1000, 2_500, 5_000]; + const backoff = [0, 100, 500, 1000, 2_000, 4_000]; let backoffi = 0; let errRef: undefined | { err: Error }; @@ -936,12 +936,19 @@ async function getJupiterSwap( feeAccount: referrerATAPubkey?.toBase58(), quoteResponse: quote, destinationTokenAccount: dstATAPubkey?.toBase58(), + prioritizationFeeLamports: { + /** + * The automatic fee seems low and frequently causes transactions + * to be dropped when traffic is high + */ + autoMultiplier: 3, + }, }; const url = `${JUPITER_API_URL}swap`; let failed = false; let swap: JupiterSwapResponse; - const backoff = [0, 100, 500, 1000, 2_500, 5_000]; + const backoff = [0, 100, 500, 1000, 2_000, 4_000]; let backoffi = 0; let errRef: undefined | { err: Error }; @@ -1197,6 +1204,6 @@ function sleep( clearTimeout(timeout); } abortable?.signal?.addEventListener("abort", onAbortDuringSleep); - const timeout = setTimeout(onTimeout); + const timeout = setTimeout(onTimeout, duration); }); } diff --git a/packages/swap/src/providers/jupiter/types.ts b/packages/swap/src/providers/jupiter/types.ts index c776f6c14..614ac217d 100644 --- a/packages/swap/src/providers/jupiter/types.ts +++ b/packages/swap/src/providers/jupiter/types.ts @@ -87,7 +87,14 @@ export type JupiterSwapParams = { trackingAccount?: string; /** Integer */ computeUnitPriceMicroLamports?: number; - prioritizationFeeLamports?: number; + /** Integer */ + prioritizationFeeLamports?: + | number + | "auto" + | { + /** Integer */ + autoMultiplier: number; + }; /** Default: false */ asLegacyTransaction?: boolean; /** Default: false */ diff --git a/packages/swap/src/utils/solana.ts b/packages/swap/src/utils/solana.ts index e0e43aa3f..863d22671 100644 --- a/packages/swap/src/utils/solana.ts +++ b/packages/swap/src/utils/solana.ts @@ -118,6 +118,58 @@ export function extractComputeBudget( ); } +/** + * @see https://solana.com/docs/core/fees#prioritization-fees + */ +export function extractComputeUnitPriceMicroLamports( + tx: VersionedTransaction, +): undefined | number | bigint { + /** Compute unit price */ + let computeUnitPriceMicroLamports: undefined | number | bigint; + + // eslint-disable-next-line no-restricted-syntax, no-labels + instructionLoop: for ( + let i = 0, len = tx.message.compiledInstructions.length; + i < len; + i++ + ) { + const instr = tx.message.compiledInstructions[i]; + const program = tx.message.staticAccountKeys[instr.programIdIndex]; + if (!ComputeBudgetProgram.programId.equals(program)) continue; + + const keys = instr.accountKeyIndexes.map( + (accountKeyIndex): AccountMeta => ({ + pubkey: tx.message.staticAccountKeys[accountKeyIndex], + isSigner: tx.message.isAccountSigner(accountKeyIndex), + isWritable: tx.message.isAccountWritable(accountKeyIndex), + }), + ); + + // Decompile the instruction + const instruction = new TransactionInstruction({ + keys, + programId: program, + data: Buffer.from(instr.data), + }); + + const type = ComputeBudgetInstruction.decodeInstructionType(instruction); + switch (type) { + case "SetComputeUnitPrice": { + // Compute limit + const command = + ComputeBudgetInstruction.decodeSetComputeUnitPrice(instruction); + computeUnitPriceMicroLamports = command.microLamports; + // eslint-disable-next-line no-labels + break instructionLoop; + } + default: /** noop */ + break; + } + } + + return computeUnitPriceMicroLamports; +} + /** * Insert new instructions at the start of a transaction, after compute budget and compute limit instructions */ From 10dfeb06fead876f0cccc5d201765b7c467bba65 Mon Sep 17 00:00:00 2001 From: nickkelly1 Date: Thu, 21 Nov 2024 14:01:08 -0600 Subject: [PATCH 2/2] fix: increase jupiter swap priority fee multiplier --- packages/swap/src/providers/jupiter/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/swap/src/providers/jupiter/index.ts b/packages/swap/src/providers/jupiter/index.ts index 50ff8b9cf..2e1023006 100644 --- a/packages/swap/src/providers/jupiter/index.ts +++ b/packages/swap/src/providers/jupiter/index.ts @@ -936,12 +936,16 @@ async function getJupiterSwap( feeAccount: referrerATAPubkey?.toBase58(), quoteResponse: quote, destinationTokenAccount: dstATAPubkey?.toBase58(), + /** @see https://station.jup.ag/api-v6/post-swap */ prioritizationFeeLamports: { /** * The automatic fee seems low and frequently causes transactions * to be dropped when traffic is high + * + * This number has been arbitrary selected from manual testing @ 2024-11-21 + * where there's been a bunch of network activity causing dropped transactions */ - autoMultiplier: 3, + autoMultiplier: 6, }, };