diff --git a/modules/sdk-coin-sol/src/lib/iface.ts b/modules/sdk-coin-sol/src/lib/iface.ts index eea56eec9a..6f90308470 100644 --- a/modules/sdk-coin-sol/src/lib/iface.ts +++ b/modules/sdk-coin-sol/src/lib/iface.ts @@ -108,7 +108,9 @@ export interface StakingAuthorize { export interface SetPriorityFee { type: InstructionBuilderTypes.SetPriorityFee; - params: Record; + params: { + fee: number | bigint; + }; } export interface AtaInit { diff --git a/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts b/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts index 2c723b7c52..b076bc09df 100644 --- a/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts +++ b/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts @@ -13,6 +13,7 @@ import { StakeProgram, SystemInstruction, TransactionInstruction, + ComputeBudgetInstruction, } from '@solana/web3.js'; import { NotSupported, TransactionType } from '@bitgo/sdk-core'; @@ -195,9 +196,12 @@ function parseSendInstructions( instructionData.push(ataClose); break; case ValidInstructionTypesEnum.SetPriorityFee: + const setComputeUnitPriceParams = ComputeBudgetInstruction.decodeSetComputeUnitPrice(instruction); const setPriorityFee: SetPriorityFee = { type: InstructionBuilderTypes.SetPriorityFee, - params: {}, + params: { + fee: setComputeUnitPriceParams.microLamports, + }, }; instructionData.push(setPriorityFee); break; diff --git a/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts b/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts index 70adbbb52a..308a8154bd 100644 --- a/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts +++ b/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts @@ -94,10 +94,8 @@ function advanceNonceInstruction(data: Nonce): TransactionInstruction[] { } function fetchPriorityFeeInstruction(instructionToBuild: SetPriorityFee): TransactionInstruction[] { - // 200k * 10000000 microlamports => prio fee - // https://www.quicknode.com/gas-tracker/solana const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ - microLamports: 10000000, + microLamports: instructionToBuild.params.fee, }); return [addPriorityFee]; diff --git a/modules/sdk-coin-sol/src/lib/tokenTransferBuilder.ts b/modules/sdk-coin-sol/src/lib/tokenTransferBuilder.ts index 0cae453157..4f4934645f 100644 --- a/modules/sdk-coin-sol/src/lib/tokenTransferBuilder.ts +++ b/modules/sdk-coin-sol/src/lib/tokenTransferBuilder.ts @@ -142,7 +142,9 @@ export class TokenTransferBuilder extends TransactionBuilder { ); const addPriorityFeeInstruction: SetPriorityFee = { type: InstructionBuilderTypes.SetPriorityFee, - params: {}, + params: { + fee: this._priorityFee, + }, }; // order is important, createAtaInstructions must be before sendInstructions this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions]; diff --git a/modules/sdk-coin-sol/src/lib/transactionBuilder.ts b/modules/sdk-coin-sol/src/lib/transactionBuilder.ts index 3af1b18fb7..524883fcb9 100644 --- a/modules/sdk-coin-sol/src/lib/transactionBuilder.ts +++ b/modules/sdk-coin-sol/src/lib/transactionBuilder.ts @@ -41,6 +41,7 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { protected _signers: KeyPair[] = []; protected _memo?: string; protected _feePayer?: string; + protected _priorityFee: number; constructor(_coinConfig: Readonly) { super(_coinConfig); @@ -245,6 +246,11 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder { return this; } + setPriorityFee(feeOptions: FeeOptions): this { + this._priorityFee = Number(feeOptions.amount); + return this; + } + feePayer(feePayer: string): this { this._feePayer = feePayer; return this; diff --git a/modules/sdk-coin-sol/src/lib/transferBuilderV2.ts b/modules/sdk-coin-sol/src/lib/transferBuilderV2.ts index 77831efcb9..8863ba05a8 100644 --- a/modules/sdk-coin-sol/src/lib/transferBuilderV2.ts +++ b/modules/sdk-coin-sol/src/lib/transferBuilderV2.ts @@ -176,7 +176,9 @@ export class TransferBuilderV2 extends TransactionBuilder { ) { addPriorityFeeInstruction = { type: InstructionBuilderTypes.SetPriorityFee, - params: {}, + params: { + fee: this._priorityFee, + }, }; this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions]; } else { diff --git a/modules/sdk-coin-sol/test/unit/transactionBuilder/tokenTransferBuilder.ts b/modules/sdk-coin-sol/test/unit/transactionBuilder/tokenTransferBuilder.ts index 86a3861a91..40d5226009 100644 --- a/modules/sdk-coin-sol/test/unit/transactionBuilder/tokenTransferBuilder.ts +++ b/modules/sdk-coin-sol/test/unit/transactionBuilder/tokenTransferBuilder.ts @@ -2,6 +2,7 @@ import { getBuilderFactory } from '../getBuilderFactory'; import { KeyPair, Utils } from '../../../src'; import should from 'should'; import * as testData from '../../resources/sol'; +import { FeeOptions } from '@bitgo/sdk-core'; describe('Sol Token Transfer Builder', () => { let ataAddress; @@ -26,6 +27,10 @@ describe('Sol Token Transfer Builder', () => { const owner = testData.tokenTransfers.owner; const walletPK = testData.associatedTokenAccounts.accounts[0].pub; const walletSK = testData.associatedTokenAccounts.accounts[0].prv; + const prioFeeMicroLamports = '10000000'; + const priorityFee: FeeOptions = { + amount: prioFeeMicroLamports, + }; describe('Succeed', () => { before(async () => { ataAddress = await Utils.getAssociatedTokenAccountAddress(mintUSDC, otherAccount.pub); @@ -37,6 +42,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -60,6 +66,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.nonce(recentBlockHash, { walletNonceAddress: nonceAccount.pub, authWalletAddress: walletPK }); txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -89,6 +96,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -112,6 +120,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.nonce(recentBlockHash); txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -140,6 +149,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); txBuilder.sign({ key: walletSK }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.id.should.not.equal(undefined); tx.inputs.length.should.equal(1); @@ -177,6 +187,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.send({ address: account5.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); txBuilder.sign({ key: authAccount.prv }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(6); tx.inputs[0].should.deepEqual({ @@ -259,6 +270,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.send({ address: account1.pub, amount, tokenName: nameUSDC }); txBuilder.send({ address: account2.pub, amount, tokenName: nameSRM }); txBuilder.send({ address: account3.pub, amount, tokenName: nameRAY }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(4); tx.inputs[0].should.deepEqual({ @@ -325,6 +337,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.nonce(recentBlockHash); txBuilder.sender(owner); txBuilder.send({ address: account1.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.outputs.should.deepEqual([ @@ -343,6 +356,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -399,6 +413,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC }); txBuilder.createAssociatedTokenAccount({ ownerAddress: account1.pub, tokenName: nameUSDC }); txBuilder.createAssociatedTokenAccount({ ownerAddress: account2.pub, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(3); tx.inputs[0].should.deepEqual({ @@ -503,6 +518,7 @@ describe('Sol Token Transfer Builder', () => { txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC }); txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC }); txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(3); tx.inputs[0].should.deepEqual({ diff --git a/modules/sdk-coin-sol/test/unit/transactionBuilder/transferBuilderV2.ts b/modules/sdk-coin-sol/test/unit/transactionBuilder/transferBuilderV2.ts index 6b01f586e7..6920c1d8f7 100644 --- a/modules/sdk-coin-sol/test/unit/transactionBuilder/transferBuilderV2.ts +++ b/modules/sdk-coin-sol/test/unit/transactionBuilder/transferBuilderV2.ts @@ -2,6 +2,7 @@ import { getBuilderFactory } from '../getBuilderFactory'; import { KeyPair, Utils } from '../../../src'; import * as testData from '../../resources/sol'; import should from 'should'; +import { FeeOptions } from '@bitgo/sdk-core'; describe('Sol Transfer Builder V2', () => { let ataAddress; @@ -20,7 +21,10 @@ describe('Sol Transfer Builder V2', () => { const owner = testData.tokenTransfers.owner; const walletPK = testData.associatedTokenAccounts.accounts[0].pub; const walletSK = testData.associatedTokenAccounts.accounts[0].prv; - + const prioFeeMicroLamports = '10000000'; + const priorityFee: FeeOptions = { + amount: prioFeeMicroLamports, + }; const transferBuilderV2 = () => { const txBuilder = factory.getTransferBuilderV2(); txBuilder.nonce(recentBlockHash); @@ -287,6 +291,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -311,6 +316,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.feePayer(feePayerAccount.pub); txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -341,6 +347,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -365,6 +372,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.feePayer(feePayerAccount.pub); txBuilder.sender(walletPK); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(1); tx.inputs[0].should.deepEqual({ @@ -394,6 +402,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); txBuilder.sign({ key: walletSK }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.id.should.not.equal(undefined); tx.inputs.length.should.equal(1); @@ -425,6 +434,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.memo(memo); txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC }); txBuilder.sign({ key: walletSK }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.id.should.not.equal(undefined); tx.inputs.length.should.equal(1); @@ -485,6 +495,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.send({ address: account5.pub, amount, tokenName: nameUSDC }); txBuilder.memo(memo); txBuilder.sign({ key: authAccount.prv }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(6); tx.inputs[0].should.deepEqual({ @@ -568,6 +579,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.send({ address: account1.pub, amount, tokenName: nameUSDC }); txBuilder.send({ address: account2.pub, amount, tokenName: nameSRM }); txBuilder.send({ address: account3.pub, amount, tokenName: nameRAY }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(4); tx.inputs[0].should.deepEqual({ @@ -658,6 +670,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.sender(authAccount.pub); txBuilder.send({ address: otherAccount.pub, amount }); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(2); tx.inputs[0].should.deepEqual({ @@ -694,6 +707,7 @@ describe('Sol Transfer Builder V2', () => { txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC }); + txBuilder.setPriorityFee(priorityFee); const tx = await txBuilder.build(); tx.inputs.length.should.equal(4); tx.inputs[0].should.deepEqual({