Skip to content

Commit 5e27a5c

Browse files
Merge pull request #5403 from BitGo/get-prio-fees-from-WP
feat(sdk-coin-sol): fetch prio fees from WP
2 parents a3256ba + 7dd8807 commit 5e27a5c

File tree

10 files changed

+96
-40
lines changed

10 files changed

+96
-40
lines changed

modules/sdk-coin-sol/src/lib/iface.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ export interface StakingAuthorize {
108108

109109
export interface SetPriorityFee {
110110
type: InstructionBuilderTypes.SetPriorityFee;
111-
params: Record<string, never>;
111+
params: {
112+
fee: number | bigint;
113+
};
112114
}
113115

114116
export interface AtaInit {

modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
StakeProgram,
1414
SystemInstruction,
1515
TransactionInstruction,
16+
ComputeBudgetInstruction,
1617
} from '@solana/web3.js';
1718

1819
import { NotSupported, TransactionType } from '@bitgo/sdk-core';
@@ -195,9 +196,12 @@ function parseSendInstructions(
195196
instructionData.push(ataClose);
196197
break;
197198
case ValidInstructionTypesEnum.SetPriorityFee:
199+
const setComputeUnitPriceParams = ComputeBudgetInstruction.decodeSetComputeUnitPrice(instruction);
198200
const setPriorityFee: SetPriorityFee = {
199201
type: InstructionBuilderTypes.SetPriorityFee,
200-
params: {},
202+
params: {
203+
fee: setComputeUnitPriceParams.microLamports,
204+
},
201205
};
202206
instructionData.push(setPriorityFee);
203207
break;

modules/sdk-coin-sol/src/lib/solInstructionFactory.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,8 @@ function advanceNonceInstruction(data: Nonce): TransactionInstruction[] {
9494
}
9595

9696
function fetchPriorityFeeInstruction(instructionToBuild: SetPriorityFee): TransactionInstruction[] {
97-
// 200k * 10000000 microlamports => prio fee
98-
// https://www.quicknode.com/gas-tracker/solana
9997
const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
100-
microLamports: 10000000,
98+
microLamports: instructionToBuild.params.fee,
10199
});
102100

103101
return [addPriorityFee];

modules/sdk-coin-sol/src/lib/tokenTransferBuilder.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,17 @@ export class TokenTransferBuilder extends TransactionBuilder {
142142
);
143143
const addPriorityFeeInstruction: SetPriorityFee = {
144144
type: InstructionBuilderTypes.SetPriorityFee,
145-
params: {},
145+
params: {
146+
fee: this._priorityFee ?? BigInt(0),
147+
},
146148
};
147-
// order is important, createAtaInstructions must be before sendInstructions
148-
this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions];
149+
150+
if (!this._priorityFee) {
151+
this._instructionsData = [...createAtaInstructions, ...sendInstructions];
152+
} else {
153+
// order is important, createAtaInstructions must be before sendInstructions
154+
this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions];
155+
}
149156
return await super.buildImplementation();
150157
}
151158
}

modules/sdk-coin-sol/src/lib/transactionBuilder.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder {
4141
protected _signers: KeyPair[] = [];
4242
protected _memo?: string;
4343
protected _feePayer?: string;
44+
protected _priorityFee: number | bigint;
4445

4546
constructor(_coinConfig: Readonly<CoinConfig>) {
4647
super(_coinConfig);
@@ -245,6 +246,11 @@ export abstract class TransactionBuilder extends BaseTransactionBuilder {
245246
return this;
246247
}
247248

249+
public setPriorityFee(feeOptions: FeeOptions): this {
250+
this._priorityFee = BigInt(feeOptions.amount);
251+
return this;
252+
}
253+
248254
feePayer(feePayer: string): this {
249255
this._feePayer = feePayer;
250256
return this;

modules/sdk-coin-sol/src/lib/transferBuilderV2.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,19 @@ export class TransferBuilderV2 extends TransactionBuilder {
170170

171171
let addPriorityFeeInstruction: SetPriorityFee;
172172
// If there are createAtaInstructions, then token is involved and we need to add a priority fee instruction
173-
if (
173+
if (!this._priorityFee) {
174+
this._instructionsData = [...createAtaInstructions, ...sendInstructions];
175+
} else if (
174176
createAtaInstructions.length !== 0 ||
175177
sendInstructions.some((instruction) => instruction.type === InstructionBuilderTypes.TokenTransfer)
176178
) {
177179
addPriorityFeeInstruction = {
178180
type: InstructionBuilderTypes.SetPriorityFee,
179-
params: {},
181+
params: {
182+
fee: this._priorityFee ?? BigInt(0),
183+
},
180184
};
181185
this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions];
182-
} else {
183-
// order is important, createAtaInstructions must be before sendInstructions
184-
this._instructionsData = [...createAtaInstructions, ...sendInstructions];
185186
}
186187

187188
return await super.buildImplementation();

modules/sdk-coin-sol/test/unit/sol.ts

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,31 +1883,30 @@ describe('SOL:', function () {
18831883
should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
18841884

18851885
const instructionsData = tokenTxnJson.instructionsData as InstructionParams[];
1886-
should.equal(instructionsData.length, 4);
1886+
should.equal(instructionsData.length, 3);
18871887
should.equal(instructionsData[0].type, 'NonceAdvance');
18881888

18891889
const destinationUSDTTokenAccount = await getAssociatedTokenAccountAddress(
18901890
usdtMintAddress,
18911891
testData.keys.destinationPubKey
18921892
);
1893-
should.equal(instructionsData[1].type, 'SetPriorityFee');
1894-
should.equal(instructionsData[2].type, 'CreateAssociatedTokenAccount');
1895-
should.equal((instructionsData[2] as AtaInit).params.mintAddress, usdtMintAddress);
1896-
should.equal((instructionsData[2] as AtaInit).params.ataAddress, destinationUSDTTokenAccount);
1897-
should.equal((instructionsData[2] as AtaInit).params.ownerAddress, testData.keys.destinationPubKey);
1898-
should.equal((instructionsData[2] as AtaInit).params.tokenName, 'tsol:usdt');
1899-
should.equal((instructionsData[2] as AtaInit).params.payerAddress, testData.wrwUser.walletAddress0);
1893+
should.equal(instructionsData[1].type, 'CreateAssociatedTokenAccount');
1894+
should.equal((instructionsData[1] as AtaInit).params.mintAddress, usdtMintAddress);
1895+
should.equal((instructionsData[1] as AtaInit).params.ataAddress, destinationUSDTTokenAccount);
1896+
should.equal((instructionsData[1] as AtaInit).params.ownerAddress, testData.keys.destinationPubKey);
1897+
should.equal((instructionsData[1] as AtaInit).params.tokenName, 'tsol:usdt');
1898+
should.equal((instructionsData[1] as AtaInit).params.payerAddress, testData.wrwUser.walletAddress0);
19001899

19011900
const sourceUSDTTokenAccount = await getAssociatedTokenAccountAddress(
19021901
usdtMintAddress,
19031902
testData.wrwUser.walletAddress0
19041903
);
1905-
should.equal(instructionsData[3].type, 'TokenTransfer');
1906-
should.equal((instructionsData[3] as TokenTransfer).params.fromAddress, testData.wrwUser.walletAddress0);
1907-
should.equal((instructionsData[3] as TokenTransfer).params.toAddress, destinationUSDTTokenAccount);
1908-
should.equal((instructionsData[3] as TokenTransfer).params.amount, '2000000000');
1909-
should.equal((instructionsData[3] as TokenTransfer).params.tokenName, 'tsol:usdt');
1910-
should.equal((instructionsData[3] as TokenTransfer).params.sourceAddress, sourceUSDTTokenAccount);
1904+
should.equal(instructionsData[2].type, 'TokenTransfer');
1905+
should.equal((instructionsData[2] as TokenTransfer).params.fromAddress, testData.wrwUser.walletAddress0);
1906+
should.equal((instructionsData[2] as TokenTransfer).params.toAddress, destinationUSDTTokenAccount);
1907+
should.equal((instructionsData[2] as TokenTransfer).params.amount, '2000000000');
1908+
should.equal((instructionsData[2] as TokenTransfer).params.tokenName, 'tsol:usdt');
1909+
should.equal((instructionsData[2] as TokenTransfer).params.sourceAddress, sourceUSDTTokenAccount);
19111910

19121911
const solCoin = basecoin as any;
19131912
sandBox.assert.callCount(solCoin.getDataFromNode, 7);
@@ -1941,7 +1940,7 @@ describe('SOL:', function () {
19411940
should.equal(tokenTxnJson.numSignatures, testData.SolInputData.durableNonceSignatures);
19421941

19431942
const instructionsData = tokenTxnJson.instructionsData as TokenTransfer[];
1944-
should.equal(instructionsData.length, 3);
1943+
should.equal(instructionsData.length, 2);
19451944
should.equal(instructionsData[0].type, 'NonceAdvance');
19461945

19471946
const sourceUSDTTokenAccount = await getAssociatedTokenAccountAddress(
@@ -1952,13 +1951,12 @@ describe('SOL:', function () {
19521951
usdtMintAddress,
19531952
testData.keys.destinationPubKey2
19541953
);
1955-
should.equal(instructionsData[1].type, 'SetPriorityFee');
1956-
should.equal(instructionsData[2].type, 'TokenTransfer');
1957-
should.equal(instructionsData[2].params.fromAddress, testData.wrwUser.walletAddress0);
1958-
should.equal(instructionsData[2].params.toAddress, destinationUSDTTokenAccount);
1959-
should.equal(instructionsData[2].params.amount, '2000000000');
1960-
should.equal(instructionsData[2].params.tokenName, 'tsol:usdt');
1961-
should.equal(instructionsData[2].params.sourceAddress, sourceUSDTTokenAccount);
1954+
should.equal(instructionsData[1].type, 'TokenTransfer');
1955+
should.equal(instructionsData[1].params.fromAddress, testData.wrwUser.walletAddress0);
1956+
should.equal(instructionsData[1].params.toAddress, destinationUSDTTokenAccount);
1957+
should.equal(instructionsData[1].params.amount, '2000000000');
1958+
should.equal(instructionsData[1].params.tokenName, 'tsol:usdt');
1959+
should.equal(instructionsData[1].params.sourceAddress, sourceUSDTTokenAccount);
19621960

19631961
const solCoin = basecoin as any;
19641962
sandBox.assert.callCount(solCoin.getDataFromNode, 7);

modules/sdk-coin-sol/test/unit/transactionBuilder/tokenTransferBuilder.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getBuilderFactory } from '../getBuilderFactory';
22
import { KeyPair, Utils } from '../../../src';
33
import should from 'should';
44
import * as testData from '../../resources/sol';
5+
import { FeeOptions } from '@bitgo/sdk-core';
56

67
describe('Sol Token Transfer Builder', () => {
78
let ataAddress;
@@ -26,6 +27,10 @@ describe('Sol Token Transfer Builder', () => {
2627
const owner = testData.tokenTransfers.owner;
2728
const walletPK = testData.associatedTokenAccounts.accounts[0].pub;
2829
const walletSK = testData.associatedTokenAccounts.accounts[0].prv;
30+
const prioFeeMicroLamports = '10000000';
31+
const priorityFee: FeeOptions = {
32+
amount: prioFeeMicroLamports,
33+
};
2934
describe('Succeed', () => {
3035
before(async () => {
3136
ataAddress = await Utils.getAssociatedTokenAccountAddress(mintUSDC, otherAccount.pub);
@@ -37,6 +42,7 @@ describe('Sol Token Transfer Builder', () => {
3742
txBuilder.sender(walletPK);
3843
txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC });
3944
txBuilder.memo(memo);
45+
txBuilder.setPriorityFee(priorityFee);
4046
const tx = await txBuilder.build();
4147
tx.inputs.length.should.equal(1);
4248
tx.inputs[0].should.deepEqual({
@@ -60,6 +66,7 @@ describe('Sol Token Transfer Builder', () => {
6066
txBuilder.nonce(recentBlockHash, { walletNonceAddress: nonceAccount.pub, authWalletAddress: walletPK });
6167
txBuilder.sender(walletPK);
6268
txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC });
69+
txBuilder.setPriorityFee(priorityFee);
6370
const tx = await txBuilder.build();
6471
tx.inputs.length.should.equal(1);
6572
tx.inputs[0].should.deepEqual({
@@ -89,6 +96,7 @@ describe('Sol Token Transfer Builder', () => {
8996
txBuilder.sender(walletPK);
9097
txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC });
9198
txBuilder.memo(memo);
99+
txBuilder.setPriorityFee(priorityFee);
92100
const tx = await txBuilder.build();
93101
tx.inputs.length.should.equal(1);
94102
tx.inputs[0].should.deepEqual({
@@ -112,6 +120,7 @@ describe('Sol Token Transfer Builder', () => {
112120
txBuilder.nonce(recentBlockHash);
113121
txBuilder.sender(walletPK);
114122
txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC });
123+
txBuilder.setPriorityFee(priorityFee);
115124
const tx = await txBuilder.build();
116125
tx.inputs.length.should.equal(1);
117126
tx.inputs[0].should.deepEqual({
@@ -140,6 +149,7 @@ describe('Sol Token Transfer Builder', () => {
140149
txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC });
141150
txBuilder.memo(memo);
142151
txBuilder.sign({ key: walletSK });
152+
txBuilder.setPriorityFee(priorityFee);
143153
const tx = await txBuilder.build();
144154
tx.id.should.not.equal(undefined);
145155
tx.inputs.length.should.equal(1);
@@ -177,6 +187,7 @@ describe('Sol Token Transfer Builder', () => {
177187
txBuilder.send({ address: account5.pub, amount, tokenName: nameUSDC });
178188
txBuilder.memo(memo);
179189
txBuilder.sign({ key: authAccount.prv });
190+
txBuilder.setPriorityFee(priorityFee);
180191
const tx = await txBuilder.build();
181192
tx.inputs.length.should.equal(6);
182193
tx.inputs[0].should.deepEqual({
@@ -259,6 +270,7 @@ describe('Sol Token Transfer Builder', () => {
259270
txBuilder.send({ address: account1.pub, amount, tokenName: nameUSDC });
260271
txBuilder.send({ address: account2.pub, amount, tokenName: nameSRM });
261272
txBuilder.send({ address: account3.pub, amount, tokenName: nameRAY });
273+
txBuilder.setPriorityFee(priorityFee);
262274
const tx = await txBuilder.build();
263275
tx.inputs.length.should.equal(4);
264276
tx.inputs[0].should.deepEqual({
@@ -325,6 +337,7 @@ describe('Sol Token Transfer Builder', () => {
325337
txBuilder.nonce(recentBlockHash);
326338
txBuilder.sender(owner);
327339
txBuilder.send({ address: account1.pub, amount, tokenName: nameUSDC });
340+
txBuilder.setPriorityFee(priorityFee);
328341
const tx = await txBuilder.build();
329342

330343
tx.outputs.should.deepEqual([
@@ -343,6 +356,7 @@ describe('Sol Token Transfer Builder', () => {
343356
txBuilder.send({ address: otherAccount.pub, amount, tokenName: nameUSDC });
344357
txBuilder.memo(memo);
345358
txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC });
359+
txBuilder.setPriorityFee(priorityFee);
346360
const tx = await txBuilder.build();
347361
tx.inputs.length.should.equal(1);
348362
tx.inputs[0].should.deepEqual({
@@ -399,6 +413,7 @@ describe('Sol Token Transfer Builder', () => {
399413
txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC });
400414
txBuilder.createAssociatedTokenAccount({ ownerAddress: account1.pub, tokenName: nameUSDC });
401415
txBuilder.createAssociatedTokenAccount({ ownerAddress: account2.pub, tokenName: nameUSDC });
416+
txBuilder.setPriorityFee(priorityFee);
402417
const tx = await txBuilder.build();
403418
tx.inputs.length.should.equal(3);
404419
tx.inputs[0].should.deepEqual({
@@ -503,6 +518,7 @@ describe('Sol Token Transfer Builder', () => {
503518
txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC });
504519
txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC });
505520
txBuilder.createAssociatedTokenAccount({ ownerAddress: otherAccount.pub, tokenName: nameUSDC });
521+
txBuilder.setPriorityFee(priorityFee);
506522
const tx = await txBuilder.build();
507523
tx.inputs.length.should.equal(3);
508524
tx.inputs[0].should.deepEqual({

modules/sdk-coin-sol/test/unit/transactionBuilder/transactionBuilder.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import should from 'should';
22
import * as bs58 from 'bs58';
33

44
import { getBuilderFactory } from '../getBuilderFactory';
5-
import { KeyPair } from '../../../src';
6-
import { Eddsa, TransactionType } from '@bitgo/sdk-core';
5+
import { KeyPair, TokenTransferBuilder } from '../../../src';
6+
import { Eddsa, FeeOptions, TransactionType } from '@bitgo/sdk-core';
77
import * as testData from '../../resources/sol';
88
import BigNumber from 'bignumber.js';
99
import { Ed25519Bip32HdTree } from '@bitgo/sdk-lib-mpc';
@@ -160,7 +160,14 @@ describe('Sol Transaction Builder', async () => {
160160
});
161161

162162
it('build a send from raw token transaction', async () => {
163-
const txBuilder = factory.from(testData.TOKEN_TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE);
163+
const txBuilder = factory.from(
164+
testData.TOKEN_TRANSFER_SIGNED_TX_WITH_MEMO_AND_DURABLE_NONCE
165+
) as TokenTransferBuilder;
166+
const prioFeeMicroLamports = '10000000';
167+
const priorityFee: FeeOptions = {
168+
amount: prioFeeMicroLamports,
169+
};
170+
txBuilder.setPriorityFee(priorityFee);
164171
const builtTx = await txBuilder.build();
165172
should.equal(builtTx.type, TransactionType.Send);
166173
should.equal(
@@ -188,9 +195,12 @@ describe('Sol Transaction Builder', async () => {
188195
walletNonceAddress: '8Y7RM6JfcX4ASSNBkrkrmSbRu431YVi9Y3oLFnzC2dCh',
189196
authWalletAddress: testData.associatedTokenAccounts.accounts[0].pub,
190197
});
198+
const priorityFeeBigInt = BigInt(prioFeeMicroLamports);
191199
jsonTx.instructionsData.should.deepEqual([
192200
{
193-
params: {},
201+
params: {
202+
fee: priorityFeeBigInt,
203+
},
194204
type: 'SetPriorityFee',
195205
},
196206
{

0 commit comments

Comments
 (0)