Skip to content

Commit 90628d4

Browse files
feat(sdk-coin-sol): add prio fees for token txns
Ticket: CR-1224
1 parent 345584c commit 90628d4

File tree

12 files changed

+116
-54
lines changed

12 files changed

+116
-54
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export enum ValidInstructionTypesEnum {
2727
Assign = 'Assign',
2828
Split = 'Split',
2929
Authorize = 'Authorize',
30+
SetPriorityFee = 'SetPriorityFee',
3031
}
3132

3233
// Internal instructions types
@@ -43,6 +44,7 @@ export enum InstructionBuilderTypes {
4344
TokenTransfer = 'TokenTransfer',
4445
StakingAuthorize = 'Authorize',
4546
StakingDelegate = 'Delegate',
47+
SetPriorityFee = 'SetPriorityFee',
4648
}
4749

4850
export const VALID_SYSTEM_INSTRUCTION_TYPES: ValidInstructionTypes[] = [
@@ -62,6 +64,7 @@ export const VALID_SYSTEM_INSTRUCTION_TYPES: ValidInstructionTypes[] = [
6264
ValidInstructionTypesEnum.Assign,
6365
ValidInstructionTypesEnum.Split,
6466
ValidInstructionTypesEnum.Authorize,
67+
ValidInstructionTypesEnum.SetPriorityFee,
6568
];
6669

6770
/** Const to check the order of the Wallet Init instructions when decode */

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type InstructionParams =
2929
| Nonce
3030
| Memo
3131
| WalletInit
32+
| SetPriorityFee
3233
| Transfer
3334
| StakingActivate
3435
| StakingDeactivate
@@ -105,6 +106,11 @@ export interface StakingAuthorize {
105106
};
106107
}
107108

109+
export interface SetPriorityFee {
110+
type: InstructionBuilderTypes.SetPriorityFee;
111+
params: Record<string, never>;
112+
}
113+
108114
export interface AtaInit {
109115
type: InstructionBuilderTypes.CreateAssociatedTokenAccount;
110116
params: { mintAddress: string; ataAddress: string; ownerAddress: string; payerAddress: string; tokenName: string };
@@ -122,7 +128,8 @@ export type ValidInstructionTypes =
122128
| 'InitializeAssociatedTokenAccount'
123129
| 'CloseAssociatedTokenAccount'
124130
| DecodedCloseAccountInstruction
125-
| 'TokenTransfer';
131+
| 'TokenTransfer'
132+
| 'SetPriorityFee';
126133

127134
export type StakingAuthorizeParams = {
128135
stakingAddress: string;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
TokenTransfer,
3434
Transfer,
3535
WalletInit,
36+
SetPriorityFee,
3637
} from './iface';
3738
import { getInstructionType } from './utils';
3839

@@ -114,8 +115,8 @@ function parseWalletInitInstructions(instructions: TransactionInstruction[]): Ar
114115
*/
115116
function parseSendInstructions(
116117
instructions: TransactionInstruction[]
117-
): Array<Nonce | Memo | Transfer | TokenTransfer | AtaInit | AtaClose> {
118-
const instructionData: Array<Nonce | Memo | Transfer | TokenTransfer | AtaInit | AtaClose> = [];
118+
): Array<Nonce | Memo | Transfer | TokenTransfer | AtaInit | AtaClose | SetPriorityFee> {
119+
const instructionData: Array<Nonce | Memo | Transfer | TokenTransfer | AtaInit | AtaClose | SetPriorityFee> = [];
119120
for (const instruction of instructions) {
120121
const type = getInstructionType(instruction);
121122
switch (type) {
@@ -193,6 +194,13 @@ function parseSendInstructions(
193194
};
194195
instructionData.push(ataClose);
195196
break;
197+
case ValidInstructionTypesEnum.SetPriorityFee:
198+
const setPriorityFee: SetPriorityFee = {
199+
type: InstructionBuilderTypes.SetPriorityFee,
200+
params: {},
201+
};
202+
instructionData.push(setPriorityFee);
203+
break;
196204
default:
197205
throw new NotSupported(
198206
'Invalid transaction, instruction type not supported: ' + getInstructionType(instruction)

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
SystemProgram,
1414
Transaction,
1515
TransactionInstruction,
16+
ComputeBudgetProgram,
1617
} from '@solana/web3.js';
1718
import assert from 'assert';
1819
import BigNumber from 'bignumber.js';
@@ -31,6 +32,7 @@ import {
3132
TokenTransfer,
3233
Transfer,
3334
WalletInit,
35+
SetPriorityFee,
3436
} from './iface';
3537

3638
/**
@@ -65,6 +67,8 @@ export function solInstructionFactory(instructionToBuild: InstructionParams): Tr
6567
return stakingAuthorizeInstruction(instructionToBuild);
6668
case InstructionBuilderTypes.StakingDelegate:
6769
return stakingDelegateInstruction(instructionToBuild);
70+
case InstructionBuilderTypes.SetPriorityFee:
71+
return fetchPriorityFeeInstruction(instructionToBuild);
6872
default:
6973
throw new Error(`Invalid instruction type or not supported`);
7074
}
@@ -89,6 +93,16 @@ function advanceNonceInstruction(data: Nonce): TransactionInstruction[] {
8993
return [nonceInstruction];
9094
}
9195

96+
function fetchPriorityFeeInstruction(instructionToBuild: SetPriorityFee): TransactionInstruction[] {
97+
// 200k * 10000000 microlamports => prio fee
98+
// https://www.quicknode.com/gas-tracker/solana
99+
const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
100+
microLamports: 10000000,
101+
});
102+
103+
return [addPriorityFee];
104+
}
105+
92106
/**
93107
* Construct Memo Solana instructions
94108
*

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
validateOwnerAddress,
1111
} from './utils';
1212
import { InstructionBuilderTypes } from './constants';
13-
import { AtaInit, TokenAssociateRecipient, TokenTransfer } from './iface';
13+
import { AtaInit, TokenAssociateRecipient, TokenTransfer, SetPriorityFee } from './iface';
1414
import assert from 'assert';
1515
import { TransactionBuilder } from './transactionBuilder';
1616
import _ from 'lodash';
@@ -140,8 +140,12 @@ export class TokenTransferBuilder extends TransactionBuilder {
140140
};
141141
})
142142
);
143+
const addPriorityFeeInstruction: SetPriorityFee = {
144+
type: InstructionBuilderTypes.SetPriorityFee,
145+
params: {},
146+
};
143147
// order is important, createAtaInstructions must be before sendInstructions
144-
this._instructionsData = [...createAtaInstructions, ...sendInstructions];
148+
this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions];
145149
return await super.buildImplementation();
146150
}
147151
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,8 @@ export class Transaction extends BaseTransaction {
365365
break;
366366
case InstructionBuilderTypes.StakingDelegate:
367367
break;
368+
case InstructionBuilderTypes.SetPriorityFee:
369+
break;
368370
}
369371
}
370372
this._outputs = outputs;

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from './utils';
1212
import { BaseCoin as CoinConfig, SolCoin } from '@bitgo/statics';
1313
import assert from 'assert';
14-
import { AtaInit, TokenAssociateRecipient, TokenTransfer, Transfer } from './iface';
14+
import { AtaInit, TokenAssociateRecipient, TokenTransfer, Transfer, SetPriorityFee } from './iface';
1515
import { InstructionBuilderTypes } from './constants';
1616
import _ from 'lodash';
1717

@@ -167,8 +167,20 @@ export class TransferBuilderV2 extends TransactionBuilder {
167167
};
168168
})
169169
);
170-
// order is important, createAtaInstructions must be before sendInstructions
171-
this._instructionsData = [...createAtaInstructions, ...sendInstructions];
170+
171+
let addPriorityFeeInstruction: SetPriorityFee;
172+
// If there are createAtaInstructions, then token is involved and we need to add a priority fee instruction
173+
if (createAtaInstructions.length !== 0) {
174+
addPriorityFeeInstruction = {
175+
type: InstructionBuilderTypes.SetPriorityFee,
176+
params: {},
177+
};
178+
this._instructionsData = [addPriorityFeeInstruction, ...createAtaInstructions, ...sendInstructions];
179+
} else {
180+
// order is important, createAtaInstructions must be before sendInstructions
181+
this._instructionsData = [...createAtaInstructions, ...sendInstructions];
182+
}
183+
172184
return await super.buildImplementation();
173185
}
174186
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { ValidInstructionTypes } from './iface';
5151
const DECODED_BLOCK_HASH_LENGTH = 32; // https://docs.solana.com/developing/programming-model/transactions#blockhash-format
5252
const DECODED_SIGNATURE_LENGTH = 64; // https://docs.solana.com/terminology#signature
5353
const BASE_58_ENCONDING_REGEX = '[1-9A-HJ-NP-Za-km-z]';
54+
const COMPUTE_BUDGET = 'ComputeBudget111111111111111111111111111111';
5455

5556
/** @inheritdoc */
5657
export function isValidAddress(address: string): boolean {
@@ -343,6 +344,8 @@ export function getInstructionType(instruction: TransactionInstruction): ValidIn
343344
'Invalid transaction, instruction program id not supported: ' + instruction.programId.toString()
344345
);
345346
}
347+
case COMPUTE_BUDGET:
348+
return 'SetPriorityFee';
346349
default:
347350
throw new NotSupported(
348351
'Invalid transaction, instruction program id not supported: ' + instruction.programId.toString()

0 commit comments

Comments
 (0)