Chain HelpersProgram (Solana)

Program (Solana)

The Program helper and its SvmInstruction type for Solana programs, plus the TokenProgram and Token2022Program artifacts under wative-core/artifacts/svm.

Program wraps a Solana IDL and turns an instruction name plus arguments and accounts into an SvmInstruction — the plain instruction shape the library's SVM transaction builder consumes. It can also build a complete SvmTransaction in one step. The class is on the main wative-core entry; the ready-made TokenProgram and Token2022Program instances are on wative-core/artifacts/svm.

Constructing a Program

Pass a name and an IDL. The name is used for lookups and error messages; the IDL is stored as-is.

program.ts
import { Program } from "wative-core";

const myProgram = new Program("MyProgram", myIdl);

The constructor throws PARAMETER_ERROR if name is not a non-empty string. Every constructed Program is registered by name, so Program.load(name) returns it later.

Identity and lookup

MemberTypeNotes
namestringRead-only; set at construction
idlunknownRead-only; the IDL you passed in
Program.load(name)static (name: string) => Program | nullReturns a previously constructed program, or null

Methods

encodeInstruction(instructionName, args, accounts)

Encodes a single instruction into an SvmInstruction.

encode-instruction.ts
const ix = myProgram.encodeInstruction(
  "transfer",
  { amount: 1_000_000n },
  { source: srcAta, destination: dstAta, authority: ownerPubkey },
);
ParameterTypeNotes
instructionNamestringThe instruction to encode
argsReadonly<Record<string, unknown>>Instruction arguments, by name
accountsReadonly<Record<string, string>>Account name → base58 pubkey

Encoding routes on the IDL's metadata.encoding field:

  • "spl-native" — uses the native SPL Token encoder (a single-byte discriminator plus a packed, little-endian argument layout). This is what the bundled TokenProgram / Token2022Program IDLs declare.
  • anything else — uses @coral-xyz/anchor's BorshInstructionCoder. The Anchor path resolves each account's signer/writable privilege from the IDL's own account list (accepting both legacy isMut / isSigner and modern writable / signer), and defaults an absent flag to the safe read-only, non-signer privilege rather than elevating it.

For the Anchor path, an IDL that lacks account metadata for the instruction, or a accounts map missing a required account, throws TX_BUILD_FAILED.

decodeInstruction(instructionName, encoded)

Not implemented on this build — calling it throws UNSUPPORTED_OP. Program is encoding-only here.

call(from, instructionName, args, accounts, opts?)

Builds a complete SvmTransaction carrying the single encoded instruction, binding the address so the transaction can sign, send, and simulate.

call.ts
const svm = acc.wallets[0].svm; // an SVM Address (SvmSigner)

const tx = myProgram.call(
  svm,
  "transfer",
  { amount: 1_000_000n },
  { source: srcAta, destination: dstAta, authority: svm.publicKey },
);
ParameterTypeNotes
fromAddressMust be an SVM address (from.vm === "svm"); otherwise UNSUPPORTED_OP
instructionNamestringEncoded via encodeInstruction above
argsReadonly<Record<string, unknown>>Instruction arguments
accountsReadonly<Record<string, string>>Account name → base58 pubkey
optsPartial<SvmTxBuildParams>Optional overrides

opts accepts the SvmTxBuildParams fields — recentBlockhash, feePayer, computeUnitLimit, computeUnitPrice, memo, rpcUrl, and further instructions (appended after the encoded one). The returned SvmTransaction is bound to from.

SvmInstruction

The instruction shape encodeInstruction returns and the SVM transaction builder consumes. Re-exported from wative-core.

import type { SvmInstruction } from "wative-core";
FieldTypeNotes
programIdstringThe program's base58 address
accountsReadonlyArray<{ pubkey: string; isSigner: boolean; isWritable: boolean }>Ordered account metas
dataUint8ArrayThe encoded instruction data

The TokenProgram and Token2022Program artifacts

TokenProgram (legacy SPL Token) and Token2022Program (SPL Token-2022) are ready-made Program instances under wative-core/artifacts/svm. Both declare the "spl-native" encoding, so encodeInstruction routes through the native SPL encoder; the legacy instruction set produces byte-identical data under either program, and only the programId differs.

token-program.ts
import { TokenProgram, Token2022Program } from "wative-core/artifacts/svm";

// Legacy SPL Token transfer.
const ix = TokenProgram.encodeInstruction(
  "transfer",
  { amount: 1_000_000n },
  { source: srcAta, destination: dstAta, authority: ownerPubkey },
);

// Same wire bytes under the Token-2022 program id.
const ix2 = Token2022Program.encodeInstruction(
  "transfer",
  { amount: 1_000_000n },
  { source: srcAta, destination: dstAta, authority: ownerPubkey },
);

The supported native instruction names are: initializeMint, initializeAccount, transfer, transferChecked, approve, revoke, mintTo, mintToChecked, burn, burnChecked, closeAccount, freezeAccount, thawAccount, and syncNative. Any other name throws UNSUPPORTED_OP.

Program ids and the low-level encoder

The subpath also re-exports the well-known program-id constants — TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, NATIVE_SOL_MINT — alongside splTokenEncodeInstruction, the native encoder the Token programs route through. Call it directly when you want an SvmInstruction without going through a Program:

spl-encode.ts
import { splTokenEncodeInstruction, TOKEN_2022_PROGRAM_ID } from "wative-core/artifacts/svm";

const ix = splTokenEncodeInstruction(
  "transfer",
  { amount: 1_000_000n },
  { source: srcAta, destination: dstAta, authority: ownerPubkey },
  { programId: TOKEN_2022_PROGRAM_ID }, // defaults to TOKEN_PROGRAM_ID
);

Its args and accounts shapes are the exported types SplTokenArgs and SplTokenAccountSet. Which account keys and arguments are required depends on the instruction — for example transfer reads amount and the source / destination / authority accounts, while a *Checked variant additionally requires decimals and a mint account. A missing account or argument throws PARAMETER_ERROR.

Last updated on