From 307dca3b1728b49954e78dc2bfa56f6e22f22ba5 Mon Sep 17 00:00:00 2001 From: Derek Chen Date: Fri, 7 Nov 2025 14:42:43 -0500 Subject: [PATCH] feat(sdk-coin-sol): support SetComputeUnitLimit instructions Ticket: SC-3899 --- modules/sdk-coin-sol/src/lib/constants.ts | 3 ++ modules/sdk-coin-sol/src/lib/iface.ts | 9 +++++ .../src/lib/instructionParamsFactory.ts | 37 ++++++++++++++++++- .../src/lib/solInstructionFactory.ts | 11 ++++++ modules/sdk-coin-sol/src/lib/transaction.ts | 2 + modules/sdk-coin-sol/src/lib/utils.ts | 4 ++ modules/sdk-coin-sol/test/unit/utils.ts | 21 ++++++++++- 7 files changed, 84 insertions(+), 3 deletions(-) diff --git a/modules/sdk-coin-sol/src/lib/constants.ts b/modules/sdk-coin-sol/src/lib/constants.ts index 8c0d212d2f..f71b3956f9 100644 --- a/modules/sdk-coin-sol/src/lib/constants.ts +++ b/modules/sdk-coin-sol/src/lib/constants.ts @@ -34,6 +34,7 @@ export enum ValidInstructionTypesEnum { Assign = 'Assign', Split = 'Split', Authorize = 'Authorize', + SetComputeUnitLimit = 'SetComputeUnitLimit', SetPriorityFee = 'SetPriorityFee', MintTo = 'MintTo', Burn = 'Burn', @@ -57,6 +58,7 @@ export enum InstructionBuilderTypes { TokenTransfer = 'TokenTransfer', StakingAuthorize = 'Authorize', StakingDelegate = 'Delegate', + SetComputeUnitLimit = 'SetComputeUnitLimit', SetPriorityFee = 'SetPriorityFee', MintTo = 'MintTo', Burn = 'Burn', @@ -83,6 +85,7 @@ export const VALID_SYSTEM_INSTRUCTION_TYPES: ValidInstructionTypes[] = [ ValidInstructionTypesEnum.Assign, ValidInstructionTypesEnum.Split, ValidInstructionTypesEnum.Authorize, + ValidInstructionTypesEnum.SetComputeUnitLimit, ValidInstructionTypesEnum.SetPriorityFee, ValidInstructionTypesEnum.MintTo, ValidInstructionTypesEnum.Burn, diff --git a/modules/sdk-coin-sol/src/lib/iface.ts b/modules/sdk-coin-sol/src/lib/iface.ts index d0bd7b0cd3..c12d8741b3 100644 --- a/modules/sdk-coin-sol/src/lib/iface.ts +++ b/modules/sdk-coin-sol/src/lib/iface.ts @@ -36,6 +36,7 @@ export type InstructionParams = | Nonce | Memo | WalletInit + | SetComputeUnitLimit | SetPriorityFee | Transfer | StakingActivate @@ -188,6 +189,13 @@ export interface StakingAuthorize { }; } +export interface SetComputeUnitLimit { + type: InstructionBuilderTypes.SetComputeUnitLimit; + params: { + units: number; + }; +} + export interface SetPriorityFee { type: InstructionBuilderTypes.SetPriorityFee; params: { @@ -221,6 +229,7 @@ export type ValidInstructionTypes = | 'CloseAssociatedTokenAccount' | DecodedCloseAccountInstruction | 'TokenTransfer' + | 'SetComputeUnitLimit' | 'SetPriorityFee' | 'MintTo' | 'Burn' diff --git a/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts b/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts index f631eb9929..34587efc54 100644 --- a/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts +++ b/modules/sdk-coin-sol/src/lib/instructionParamsFactory.ts @@ -45,6 +45,7 @@ import { TokenTransfer, Transfer, WalletInit, + SetComputeUnitLimit, SetPriorityFee, CustomInstruction, Approve, @@ -138,9 +139,31 @@ function parseSendInstructions( instructions: TransactionInstruction[], instructionMetadata?: InstructionParams[], _useTokenAddressTokenName?: boolean -): Array { +): Array< + | Nonce + | Memo + | Transfer + | TokenTransfer + | AtaInit + | AtaClose + | SetComputeUnitLimit + | SetPriorityFee + | MintTo + | Burn + | Approve +> { const instructionData: Array< - Nonce | Memo | Transfer | TokenTransfer | AtaInit | AtaClose | SetPriorityFee | MintTo | Burn | Approve + | Nonce + | Memo + | Transfer + | TokenTransfer + | AtaInit + | AtaClose + | SetComputeUnitLimit + | SetPriorityFee + | MintTo + | Burn + | Approve > = []; for (const instruction of instructions) { const type = getInstructionType(instruction); @@ -252,6 +275,16 @@ function parseSendInstructions( }; instructionData.push(ataClose); break; + case ValidInstructionTypesEnum.SetComputeUnitLimit: + const setComputeUnitLimitParams = ComputeBudgetInstruction.decodeSetComputeUnitLimit(instruction); + const setComputeUnitLimit: SetComputeUnitLimit = { + type: InstructionBuilderTypes.SetComputeUnitLimit, + params: { + units: setComputeUnitLimitParams.units, + }, + }; + instructionData.push(setComputeUnitLimit); + break; case ValidInstructionTypesEnum.SetPriorityFee: const setComputeUnitPriceParams = ComputeBudgetInstruction.decodeSetComputeUnitPrice(instruction); const setPriorityFee: SetPriorityFee = { diff --git a/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts b/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts index 06d250f8d7..52aea30157 100644 --- a/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts +++ b/modules/sdk-coin-sol/src/lib/solInstructionFactory.ts @@ -40,6 +40,7 @@ import { TokenTransfer, Transfer, WalletInit, + SetComputeUnitLimit, SetPriorityFee, CustomInstruction, Approve, @@ -82,6 +83,8 @@ export function solInstructionFactory(instructionToBuild: InstructionParams): Tr return stakingAuthorizeInstruction(instructionToBuild); case InstructionBuilderTypes.StakingDelegate: return stakingDelegateInstruction(instructionToBuild); + case InstructionBuilderTypes.SetComputeUnitLimit: + return setComputeUnitLimitInstruction(instructionToBuild); case InstructionBuilderTypes.SetPriorityFee: return fetchPriorityFeeInstruction(instructionToBuild); case InstructionBuilderTypes.MintTo: @@ -114,6 +117,14 @@ function advanceNonceInstruction(data: Nonce): TransactionInstruction[] { return [nonceInstruction]; } +function setComputeUnitLimitInstruction(instructionToBuild: SetComputeUnitLimit): TransactionInstruction[] { + const setComputeUnitLimit = ComputeBudgetProgram.setComputeUnitLimit({ + units: instructionToBuild.params.units, + }); + + return [setComputeUnitLimit]; +} + function fetchPriorityFeeInstruction(instructionToBuild: SetPriorityFee): TransactionInstruction[] { const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({ microLamports: instructionToBuild.params.fee, diff --git a/modules/sdk-coin-sol/src/lib/transaction.ts b/modules/sdk-coin-sol/src/lib/transaction.ts index 7aac445fd5..1ddbc53c79 100644 --- a/modules/sdk-coin-sol/src/lib/transaction.ts +++ b/modules/sdk-coin-sol/src/lib/transaction.ts @@ -489,6 +489,8 @@ export class Transaction extends BaseTransaction { break; case InstructionBuilderTypes.StakingDelegate: break; + case InstructionBuilderTypes.SetComputeUnitLimit: + break; case InstructionBuilderTypes.SetPriorityFee: break; case InstructionBuilderTypes.CustomInstruction: diff --git a/modules/sdk-coin-sol/src/lib/utils.ts b/modules/sdk-coin-sol/src/lib/utils.ts index 90e19f2cc2..a632e55dd1 100644 --- a/modules/sdk-coin-sol/src/lib/utils.ts +++ b/modules/sdk-coin-sol/src/lib/utils.ts @@ -27,6 +27,7 @@ import { SystemInstruction, SystemProgram, TransactionInstruction, + ComputeBudgetInstruction, } from '@solana/web3.js'; import assert from 'assert'; import BigNumber from 'bignumber.js'; @@ -403,6 +404,9 @@ export function getInstructionType(instruction: TransactionInstruction): ValidIn ); } case COMPUTE_BUDGET: + if (ComputeBudgetInstruction.decodeInstructionType(instruction) === 'SetComputeUnitLimit') { + return 'SetComputeUnitLimit'; + } return 'SetPriorityFee'; default: return 'CustomInstruction'; diff --git a/modules/sdk-coin-sol/test/unit/utils.ts b/modules/sdk-coin-sol/test/unit/utils.ts index 95cc835e8d..2915d7151e 100644 --- a/modules/sdk-coin-sol/test/unit/utils.ts +++ b/modules/sdk-coin-sol/test/unit/utils.ts @@ -1,7 +1,14 @@ import should from 'should'; import { Utils } from '../../src/lib'; import * as testData from '../resources/sol'; -import { Lockup, PublicKey, StakeProgram, SystemProgram, TransactionInstruction } from '@solana/web3.js'; +import { + ComputeBudgetProgram, + Lockup, + PublicKey, + StakeProgram, + SystemProgram, + TransactionInstruction, +} from '@solana/web3.js'; import { MEMO_PROGRAM_PK, stakingActivateInstructionsIndexes, @@ -244,6 +251,18 @@ describe('SOL util library', function () { }); Utils.getInstructionType(invalidInstruction).should.equal('CustomInstruction'); }); + it('should succeed for ComputeBudget SetComputeUnitLimit instruction', function () { + const setComputeUnitLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit({ + units: 300000, + }); + Utils.getInstructionType(setComputeUnitLimitInstruction).should.equal('SetComputeUnitLimit'); + }); + it('should succeed for ComputeBudget SetComputeUnitPrice instruction', function () { + const setComputeUnitPriceInstruction = ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: 100000, + }); + Utils.getInstructionType(setComputeUnitPriceInstruction).should.equal('SetPriorityFee'); + }); }); describe('validateIntructionTypes', function () {