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.
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
| Member | Type | Notes |
|---|---|---|
name | string | Read-only; set at construction |
idl | unknown | Read-only; the IDL you passed in |
Program.load(name) | static (name: string) => Program | null | Returns a previously constructed program, or null |
Methods
encodeInstruction(instructionName, args, accounts)
Encodes a single instruction into an SvmInstruction.
const ix = myProgram.encodeInstruction(
"transfer",
{ amount: 1_000_000n },
{ source: srcAta, destination: dstAta, authority: ownerPubkey },
);| Parameter | Type | Notes |
|---|---|---|
instructionName | string | The instruction to encode |
args | Readonly<Record<string, unknown>> | Instruction arguments, by name |
accounts | Readonly<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 bundledTokenProgram/Token2022ProgramIDLs declare.- anything else — uses
@coral-xyz/anchor'sBorshInstructionCoder. The Anchor path resolves each account's signer/writable privilege from the IDL's own account list (accepting both legacyisMut/isSignerand modernwritable/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.
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 },
);| Parameter | Type | Notes |
|---|---|---|
from | Address | Must be an SVM address (from.vm === "svm"); otherwise UNSUPPORTED_OP |
instructionName | string | Encoded via encodeInstruction above |
args | Readonly<Record<string, unknown>> | Instruction arguments |
accounts | Readonly<Record<string, string>> | Account name → base58 pubkey |
opts | Partial<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.
from is read off a wallet, not constructed directly — acc.wallets[0].svm returns the SvmSigner, which is an Address.
SvmInstruction
The instruction shape encodeInstruction returns and the SVM transaction builder consumes. Re-exported from wative-core.
import type { SvmInstruction } from "wative-core";| Field | Type | Notes |
|---|---|---|
programId | string | The program's base58 address |
accounts | ReadonlyArray<{ pubkey: string; isSigner: boolean; isWritable: boolean }> | Ordered account metas |
data | Uint8Array | The 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.
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.
Token-2022 extension instructions (transfer hooks, confidential transfers, interest-bearing config, non-transferable, and the rest) are not encoded by this build. For those, integrate @solana/spl-token-2022 directly.
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:
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.