Learn how to use Anchor’s TypeScript client library (@anchor-lang/core) to interact with Solana programs
Anchor provides a TypeScript client library (@anchor-lang/core) that simplifies the process of interacting with Solana programs from JavaScript or TypeScript applications.
The @anchor-lang/core library is only compatible with the legacy version
(v1) of @solana/web3.js and @solana/spl-token. It is not compatible with
the new version (v2) of @solana/web3.js.
You can create a Program instance without a wallet for read-only operations:
import { Connection, clusterApiUrl } from "@solana/web3.js";import { Program } from "@anchor-lang/core";import type { MyProgram } from "./idl-type";import idl from "./idl.json";const connection = new Connection(clusterApiUrl("devnet"), "confirmed");const program = new Program<MyProgram>(idl, { connection });
If an IDL has been deployed to the blockchain using anchor idl init:
import { Program } from "@anchor-lang/core";import { Connection, PublicKey } from "@solana/web3.js";const connection = new Connection("https://api.devnet.solana.com");const programId = new PublicKey("Your1Program2Address3Here");// Fetch IDL from chainconst program = await Program.at(programId, { connection });
import { AnchorProvider } from "@anchor-lang/core";import { Connection } from "@solana/web3.js";// Use local keypair (reads from ~/.config/solana/id.json)const provider = AnchorProvider.local();// Or specify custom URLconst provider = AnchorProvider.local("https://api.devnet.solana.com");// Or use environment variableconst provider = AnchorProvider.env();
In Anchor projects, you can use the workspace object to automatically discover and load programs:
import * as anchor from "@anchor-lang/core";import { Program } from "@anchor-lang/core";import { MyProgram } from "../target/types/my_program";// Configure provideranchor.setProvider(anchor.AnchorProvider.env());// Access program from workspaceconst program = anchor.workspace.MyProgram as Program<MyProgram>;// Now you can call program methodsconst tx = await program.methods.initialize().rpc();
Use memcmp (memory compare) to filter accounts. Remember: the first 8 bytes are the account discriminator.
// Filter accounts where a u64 field at offset 8 equals a specific valueconst value = new BN(42);const valueBuffer = value.toArrayLike(Buffer, "le", 8);const filteredAccounts = await program.account.counter.all([ { memcmp: { offset: 8, // Skip 8-byte discriminator bytes: bs58.encode(valueBuffer), }, },]);
When you run anchor build, Anchor generates TypeScript types in target/types/:
import { Program } from "@anchor-lang/core";import { MyProgram } from "../target/types/my_program";import idl from "../target/idl/my_program.json";const program = new Program<MyProgram>(idl, provider);// TypeScript provides autocomplete and type checkingconst tx = await program.methods .myInstruction(arg1, arg2) // Args are type-checked .accounts({ // Account names are validated account1: publicKey1, account2: publicKey2, }) .rpc();// Account data is properly typedconst account = await program.account.myAccount.fetch(address);console.log(account.field1); // TypeScript knows the account structure