Skip to content

Commit

Permalink
[wip]: Add compute unit instructions to JS client
Browse files Browse the repository at this point in the history
  • Loading branch information
lorisleiva committed Jan 23, 2025
1 parent e082342 commit a42905a
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 12 deletions.
1 change: 1 addition & 0 deletions clients/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
},
"dependencies": {
"@iarna/toml": "^2.2.5",
"@solana-program/compute-budget": "^0.6.1",
"@solana-program/system": "^0.6.2",
"chalk": "^4.1.0",
"commander": "^13.0.0",
Expand Down
12 changes: 12 additions & 0 deletions clients/js/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 18 additions & 1 deletion clients/js/src/createMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
PROGRAM_METADATA_PROGRAM_ADDRESS,
} from './generated';
import {
getComputeUnitInstructions,
getDefaultInstructionPlanContext,
getPdaDetails,
InstructionPlan,
Expand All @@ -16,7 +17,7 @@ import {
import { getAccountSize, MetadataInput, MetadataResponse } from './utils';

export const SIZE_THRESHOLD_FOR_INITIALIZING_WITH_BUFFER = 200;
const WRITE_CHUNK_SIZE = 1000;
const WRITE_CHUNK_SIZE = 900;

export async function createMetadata(
input: MetadataInput
Expand Down Expand Up @@ -50,6 +51,10 @@ export function getCreateMetadataInstructionsUsingInstructionData(
return {
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
getTransferSolInstruction({
source: input.payer,
destination: input.metadata,
Expand All @@ -72,6 +77,10 @@ export function getCreateMetadataInstructionsUsingBuffer(
mainPlan.plans.push({
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
getTransferSolInstruction({
source: input.payer,
destination: input.metadata,
Expand All @@ -95,6 +104,10 @@ export function getCreateMetadataInstructionsUsingBuffer(
writePlan.plans.push({
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
getWriteInstruction({
buffer: input.metadata,
authority: input.authority,
Expand All @@ -109,6 +122,10 @@ export function getCreateMetadataInstructionsUsingBuffer(
mainPlan.plans.push({
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
getInitializeInstruction({
...input,
programData: input.isCanonical ? input.programData : undefined,
Expand Down
27 changes: 27 additions & 0 deletions clients/js/src/internals.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import {
getSetComputeUnitLimitInstruction,
getSetComputeUnitPriceInstruction,
} from '@solana-program/compute-budget';
import {
Address,
appendTransactionMessageInstructions,
Expand All @@ -10,6 +14,7 @@ import {
GetMinimumBalanceForRentExemptionApi,
GetSignatureStatusesApi,
IInstruction,
MicroLamports,
pipe,
Rpc,
RpcSubscriptions,
Expand Down Expand Up @@ -193,3 +198,25 @@ async function sendMessageInstructionPlan(
(tx) => signAndSendTransaction(tx, ctx.sendAndConfirm)
);
}

export function getComputeUnitInstructions(input: {
computeUnitPrice?: MicroLamports;
computeUnitLimit?: number;
}) {
const instructions: IInstruction[] = [];
if (input.computeUnitPrice !== undefined) {
instructions.push(
getSetComputeUnitPriceInstruction({
microLamports: input.computeUnitPrice,
})
);
}
if (input.computeUnitLimit !== undefined) {
instructions.push(
getSetComputeUnitLimitInstruction({
units: input.computeUnitLimit,
})
);
}
return instructions;
}
46 changes: 35 additions & 11 deletions clients/js/src/updateMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getWriteInstruction,
} from './generated';
import {
getComputeUnitInstructions,
getDefaultInstructionPlanContext,
getPdaDetails,
InstructionPlan,
Expand Down Expand Up @@ -88,7 +89,15 @@ export function getUpdateMetadataInstructionsUsingInstructionData(
extraRent: Lamports;
}
): MessageInstructionPlan {
const plan: InstructionPlan = { kind: 'message', instructions: [] };
const plan: InstructionPlan = {
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
],
};

if (input.sizeDifference > 0) {
plan.instructions.push(
Expand Down Expand Up @@ -128,7 +137,15 @@ export function getUpdateMetadataInstructionsUsingBuffer(
}
): InstructionPlan {
const mainPlan: InstructionPlan = { kind: 'sequential', plans: [] };
const initialMessage: InstructionPlan = { kind: 'message', instructions: [] };
const initialMessage: InstructionPlan = {
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
],
};

if (input.sizeDifference > 0) {
initialMessage.instructions.push(
Expand Down Expand Up @@ -163,6 +180,10 @@ export function getUpdateMetadataInstructionsUsingBuffer(
writePlan.plans.push({
kind: 'message',
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
getWriteInstruction({
buffer: input.buffer.address,
authority: input.buffer,
Expand All @@ -176,16 +197,19 @@ export function getUpdateMetadataInstructionsUsingBuffer(

const finalizeMessage: InstructionPlan = {
kind: 'message',
instructions: [],
instructions: [
...getComputeUnitInstructions({
computeUnitPrice: input.priorityFees,
computeUnitLimit: 10_000, // TODO: Add max CU for each instruction.
}),
getSetDataInstruction({
...input,
buffer: input.buffer.address,
programData: input.isCanonical ? input.programData : undefined,
data: undefined,
}),
],
};
finalizeMessage.instructions.push(
getSetDataInstruction({
...input,
buffer: input.buffer.address,
programData: input.isCanonical ? input.programData : undefined,
data: undefined,
})
);

if (input.closeBuffer) {
// TODO: Close buffer account.
Expand Down
6 changes: 6 additions & 0 deletions clients/js/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
getStructDecoder,
getU32Decoder,
getU64Decoder,
MicroLamports,
ReadonlyUint8Array,
Rpc,
RpcSubscriptions,
Expand Down Expand Up @@ -65,6 +66,11 @@ export type MetadataInput = {
format: FormatArgs;
dataSource: DataSourceArgs;
data: ReadonlyUint8Array;
/**
* Extra fees to pay in microlamports per CU.
* Defaults to no extra fees.
*/
priorityFees?: MicroLamports;
/**
* Whether to use a buffer for creating or updating a metadata account.
* If a `TransactionSigner` is provided, the provided buffer will be used for updating only.
Expand Down

0 comments on commit a42905a

Please sign in to comment.