Skip to main content

Overview

The Program class is the primary interface for interacting with Anchor programs. It provides a type-safe, IDL-driven API for sending transactions, fetching accounts, and listening to events.
import { Program, AnchorProvider } from "@anchor-lang/anchor";
import { Connection, PublicKey } from "@solana/web3.js";

const program = new Program(idl, provider);

Constructor

constructor
(idl, provider?, coder?, getCustomResolver?) => Program
Creates a new Program instance.

Static Methods

Program.at
async (address, provider?) => Promise<Program>
Fetches the IDL from the blockchain and creates a Program instance.
const program = await Program.at(
  new PublicKey("11111111111111111111111111111111"),
  provider
);
Program.fetchIdl
async (address, provider?) => Promise<Idl | null>
Fetches the IDL from the blockchain without creating a Program instance.
const idl = await Program.fetchIdl(programId, provider);

Properties

programId
PublicKey
The on-chain address of the program.
console.log(program.programId.toString());
idl
IDL
The IDL in camelCase format for TypeScript compatibility.
const instructions = program.idl.instructions;
rawIdl
Idl
The original IDL without camelCase conversion (snake_case from Rust).
const originalIdl = program.rawIdl;
provider
Provider
The wallet and network provider used by this program.
const connection = program.provider.connection;
coder
Coder
The coder used for serializing and deserializing data.
const encoded = program.coder.instruction.encode("initialize", {});

Namespaces

methods

methods
MethodsNamespace<IDL>
The recommended builder API for constructing and sending transactions.
const signature = await program.methods
  .initialize(new anchor.BN(100))
  .accounts({
    myAccount: myAccount.publicKey,
    user: provider.wallet.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .signers([myAccount])
  .rpc();
The methods namespace provides:
  • .accounts() - Set instruction accounts
  • .signers() - Add transaction signers
  • .remainingAccounts() - Add extra accounts
  • .preInstructions() - Add instructions before
  • .postInstructions() - Add instructions after
  • .rpc() - Send and confirm transaction
  • .instruction() - Build TransactionInstruction
  • .transaction() - Build Transaction
  • .simulate() - Simulate transaction
  • .view() - Call read-only instruction

account

account
AccountNamespace<IDL>
Provides access to account clients for fetching and subscribing to account data.
// Fetch a single account
const accountData = await program.account.myAccount.fetch(address);

// Fetch multiple accounts
const accounts = await program.account.myAccount.fetchMultiple([
  address1,
  address2,
]);

// Fetch all accounts of this type
const allAccounts = await program.account.myAccount.all();

// Subscribe to account changes
const listener = program.account.myAccount.subscribe(address);
listener.on("change", (account) => {
  console.log("Account changed:", account);
});
See AccountClient for full details.

rpc (deprecated)

rpc
RpcNamespace<IDL>
Legacy API for sending signed transactions. Use methods instead.
// Deprecated - use program.methods instead
const signature = await program.rpc.initialize({
  accounts: {
    counter: counterAddress,
    authority: provider.wallet.publicKey,
  },
});
The rpc namespace is deprecated. Use program.methods.<method>(...args).rpc() instead.

transaction (deprecated)

transaction
TransactionNamespace<IDL>
Legacy API for building Transaction objects. Use methods instead.
// Deprecated - use program.methods instead
const tx = await program.transaction.initialize({
  accounts: {
    counter: counterAddress,
  },
});
The transaction namespace is deprecated. Use program.methods.<method>(...args).transaction() instead.

simulate (deprecated)

simulate
SimulateNamespace<IDL>
Legacy API for simulating transactions. Use methods instead.
// Deprecated - use program.methods instead
const result = await program.simulate.initialize({
  accounts: {
    counter: counterAddress,
  },
});
The simulate namespace is deprecated. Use program.methods.<method>(...args).simulate() instead.

instruction (deprecated)

instruction
InstructionNamespace<IDL>
Legacy API for building TransactionInstruction objects. Use methods instead.
// Deprecated - use program.methods instead
const ix = await program.instruction.initialize({
  accounts: {
    counter: counterAddress,
  },
});
The instruction namespace is deprecated. Use program.methods.<method>(...args).instruction() instead.

Event Handling

addEventListener
(eventName, callback, commitment?) => number
Subscribe to program events emitted in transaction logs.
const listenerId = program.addEventListener(
  "MyEvent",
  (event, slot, signature) => {
    console.log("Event:", event);
    console.log("Slot:", slot);
    console.log("Signature:", signature);
  },
  "confirmed"
);
removeEventListener
async (listener) => Promise<void>
Unsubscribe from a program event.
await program.removeEventListener(listenerId);

Usage Examples

Basic Initialization

import * as anchor from "@anchor-lang/anchor";
import { Program } from "@anchor-lang/anchor";
import { MyProgram } from "./target/types/my_program";

// Get provider from environment
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);

// Load from workspace
const program = anchor.workspace.MyProgram as Program<MyProgram>;

// Or create with IDL
const program = new Program(idl, provider);

Sending Transactions

const myAccount = anchor.web3.Keypair.generate();

const signature = await program.methods
  .initialize(new anchor.BN(100), "hello")
  .accounts({
    myAccount: myAccount.publicKey,
    user: provider.wallet.publicKey,
    systemProgram: anchor.web3.SystemProgram.programId,
  })
  .signers([myAccount])
  .rpc();

console.log("Transaction signature:", signature);

Fetching Accounts

// Fetch single account
const account = await program.account.myAccount.fetch(accountAddress);
console.log("Balance:", account.balance);

// Fetch all accounts
const allAccounts = await program.account.myAccount.all();
allAccounts.forEach((acc) => {
  console.log("Account:", acc.publicKey.toString());
  console.log("Data:", acc.account);
});

Building Complex Transactions

// Build instruction
const instruction = await program.methods
  .transfer(new anchor.BN(50))
  .accounts({
    from: fromAccount,
    to: toAccount,
  })
  .instruction();

// Add to transaction with other instructions
const transaction = new Transaction()
  .add(someOtherInstruction)
  .add(instruction);

const signature = await provider.sendAndConfirm(transaction);

Listening to Events

// Listen for events
const listener = program.addEventListener(
  "TransferEvent",
  (event, slot) => {
    console.log(`Transfer of ${event.amount} at slot ${slot}`);
  }
);

// Later: remove listener
await program.removeEventListener(listener);

Build docs developers (and LLMs) love