> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript Client

> 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.

<Note>
  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`.
</Note>

## Installation

Install the Anchor client library along with Solana web3.js:

<CodeGroup>
  ```bash npm theme={null}
  npm install @anchor-lang/core @solana/web3.js
  ```

  ```bash yarn theme={null}
  yarn add @anchor-lang/core @solana/web3.js
  ```

  ```bash pnpm theme={null}
  pnpm add @anchor-lang/core @solana/web3.js
  ```
</CodeGroup>

## Core Concepts

The Anchor TypeScript client is built around three main concepts:

<CardGroup cols={3}>
  <Card title="Program" icon="code">
    The main interface for interacting with on-chain programs
  </Card>

  <Card title="Provider" icon="plug">
    Combines connection and wallet for signing and sending transactions
  </Card>

  <Card title="Workspace" icon="folder-tree">
    Auto-discovers programs in Anchor projects (Node.js only)
  </Card>
</CardGroup>

## Creating a Program Instance

To interact with an Anchor program, you need to create a `Program` instance using the program's IDL file.

### Constructor Signature

```typescript theme={null}
new Program<IDL>(
  idl: IDL,
  provider?: Provider,
  coder?: Coder
)
```

### Frontend/React Example

When integrating with a frontend using the [Solana wallet adapter](https://github.com/anza-xyz/wallet-adapter):

```typescript theme={null}
import { Program, AnchorProvider } from "@anchor-lang/core";
import { useAnchorWallet, useConnection } from "@solana/wallet-adapter-react";
import type { MyProgram } from "./idl-type";
import idl from "./idl.json";

const { connection } = useConnection();
const wallet = useAnchorWallet();

// Create provider
const provider = new AnchorProvider(connection, wallet, {
  preflightCommitment: "processed"
});

// Create program instance
const program = new Program<MyProgram>(idl, provider);
```

### Without Wallet

You can create a `Program` instance without a wallet for read-only operations:

```typescript theme={null}
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 });
```

### Fetch IDL from Chain

If an IDL has been deployed to the blockchain using `anchor idl init`:

```typescript theme={null}
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 chain
const program = await Program.at(programId, { connection });
```

## AnchorProvider

The `AnchorProvider` combines a Solana connection and wallet to handle transaction signing and sending.

### API

```typescript theme={null}
class AnchorProvider {
  constructor(
    readonly connection: Connection,
    readonly wallet: Wallet,
    readonly opts: ConfirmOptions
  )

  // Create provider from local filesystem keypair (Node.js only)
  static local(url?: string, opts?: ConfirmOptions): AnchorProvider

  // Create provider from ANCHOR_PROVIDER_URL env variable (Node.js only)
  static env(): AnchorProvider

  // Send and confirm transaction
  sendAndConfirm(
    tx: Transaction | VersionedTransaction,
    signers?: Signer[],
    opts?: ConfirmOptions
  ): Promise<TransactionSignature>

  // Send multiple transactions
  sendAll(
    txWithSigners: { tx: Transaction; signers?: Signer[] }[],
    opts?: ConfirmOptions
  ): Promise<TransactionSignature[]>

  // Simulate transaction
  simulate(
    tx: Transaction | VersionedTransaction,
    signers?: Signer[],
    commitment?: Commitment
  ): Promise<SimulatedTransactionResponse>
}
```

### Example: Node.js Provider

```typescript theme={null}
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 URL
const provider = AnchorProvider.local("https://api.devnet.solana.com");

// Or use environment variable
const provider = AnchorProvider.env();
```

## Workspace (Node.js Only)

In Anchor projects, you can use the `workspace` object to automatically discover and load programs:

```typescript theme={null}
import * as anchor from "@anchor-lang/core";
import { Program } from "@anchor-lang/core";
import { MyProgram } from "../target/types/my_program";

// Configure provider
anchor.setProvider(anchor.AnchorProvider.env());

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

// Now you can call program methods
const tx = await program.methods.initialize().rpc();
```

The workspace automatically:

* Reads IDL files from `target/idl/`
* Parses `Anchor.toml` for program configuration
* Creates typed `Program` instances

## Invoking Instructions

The `program.methods` namespace provides a builder API for creating and sending transactions.

### Builder Pattern

<Steps>
  <Step title="Start with .methods">
    Call the instruction name with its arguments

    ```typescript theme={null}
    program.methods.initialize(arg1, arg2)
    ```
  </Step>

  <Step title="Provide accounts with .accounts()">
    Pass required accounts (PDAs and common accounts are often auto-resolved)

    ```typescript theme={null}
    .accounts({ account1: publicKey1, account2: publicKey2 })
    ```
  </Step>

  <Step title="Add signers with .signers() (optional)">
    Include additional signers beyond the wallet

    ```typescript theme={null}
    .signers([keypair1, keypair2])
    ```
  </Step>

  <Step title="Execute">
    Choose how to execute: `.rpc()`, `.transaction()`, or `.instruction()`
  </Step>
</Steps>

### Execution Methods

<Tabs>
  <Tab title=".rpc()">
    Builds, signs, and sends the transaction in one call. Returns the transaction signature.

    ```typescript theme={null}
    const signature = await program.methods
      .initialize(new BN(42))
      .accounts({
        counter: counterKeypair.publicKey,
        user: wallet.publicKey,
        systemProgram: SystemProgram.programId,
      })
      .signers([counterKeypair])
      .rpc();

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

    **Best for:** Simple, single-instruction transactions
  </Tab>

  <Tab title=".transaction()">
    Builds a `Transaction` object without sending it. Useful for combining multiple instructions.

    ```typescript theme={null}
    const transaction = await program.methods
      .initialize(new BN(42))
      .accounts({
        counter: counterKeypair.publicKey,
        user: wallet.publicKey,
      })
      .transaction();

    // Add more instructions
    transaction.add(anotherInstruction);

    // Send manually
    const signature = await provider.connection.sendTransaction(
      transaction,
      [wallet.payer, counterKeypair]
    );
    ```

    **Best for:** Combining multiple instructions in one transaction
  </Tab>

  <Tab title=".instruction()">
    Builds a `TransactionInstruction` for maximum control.

    ```typescript theme={null}
    const instruction = await program.methods
      .initialize(new BN(42))
      .accounts({
        counter: counterKeypair.publicKey,
        user: wallet.publicKey,
      })
      .instruction();

    // Build transaction manually
    const transaction = new Transaction().add(instruction);

    const signature = await provider.connection.sendTransaction(
      transaction,
      [wallet.payer, counterKeypair]
    );
    ```

    **Best for:** Advanced use cases requiring full control
  </Tab>

  <Tab title=".simulate()">
    Simulates the transaction without sending it. Useful for testing and viewing logs.

    ```typescript theme={null}
    const simulation = await program.methods
      .initialize(new BN(42))
      .accounts({
        counter: counterKeypair.publicKey,
        user: wallet.publicKey,
      })
      .simulate();

    console.log("Logs:", simulation.logs);
    console.log("Events:", simulation.events);
    ```

    **Best for:** Testing and debugging
  </Tab>
</Tabs>

### Additional Options

The methods builder supports additional configuration:

```typescript theme={null}
await program.methods
  .initialize()
  .accounts({ /* ... */ })
  .signers([keypair])
  .preInstructions([/* instructions to run before */])
  .postInstructions([/* instructions to run after */])
  .remainingAccounts([/* additional AccountMeta[] */])
  .rpc({
    skipPreflight: false,
    commitment: "confirmed",
    maxRetries: 3,
  });
```

## Fetching Accounts

The `program.account` namespace provides methods to fetch and deserialize program accounts.

### Fetch Single Account

```typescript theme={null}
const counterAccount = await program.account.counter.fetch(counterAddress);
console.log("Count:", counterAccount.count.toString());
```

### Fetch Multiple Accounts

```typescript theme={null}
const accounts = await program.account.counter.fetchMultiple([
  address1,
  address2,
  address3,
]);

accounts.forEach((account, index) => {
  if (account) {
    console.log(`Account ${index}:`, account.count.toString());
  }
});
```

### Fetch All Accounts

```typescript theme={null}
const allCounters = await program.account.counter.all();

allCounters.forEach(({ publicKey, account }) => {
  console.log(`${publicKey.toString()}: ${account.count.toString()}`);
});
```

### Fetch with Filters

Use `memcmp` (memory compare) to filter accounts. Remember: the first 8 bytes are the account discriminator.

```typescript theme={null}
// Filter accounts where a u64 field at offset 8 equals a specific value
const 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),
    },
  },
]);
```

## Event Listeners

Subscribe to program events emitted via logs:

```typescript theme={null}
// Subscribe to events
const listenerId = program.addEventListener(
  "CounterUpdated",
  (event, slot, signature) => {
    console.log("Event:", event);
    console.log("Slot:", slot);
    console.log("Signature:", signature);
  }
);

// Unsubscribe when done
await program.removeEventListener(listenerId);
```

## Program Properties

The `Program` instance exposes useful properties:

```typescript theme={null}
// Program ID
const programId: PublicKey = program.programId;

// IDL (camelCased)
const idl = program.idl;

// Raw IDL (original format)
const rawIdl = program.rawIdl;

// Provider
const provider = program.provider;

// Coder for encoding/decoding
const coder = program.coder;
```

## Complete Example

Here's a complete example demonstrating common operations:

```typescript example.ts theme={null}
import {
  Connection,
  Keypair,
  LAMPORTS_PER_SOL,
  SystemProgram,
} from "@solana/web3.js";
import { Program, AnchorProvider, BN } from "@anchor-lang/core";
import type { Counter } from "./idl-type";
import idl from "./idl.json";

async function main() {
  // Setup
  const connection = new Connection("http://127.0.0.1:8899", "confirmed");
  const payer = Keypair.generate();
  const counter = Keypair.generate();

  // Airdrop SOL
  const signature = await connection.requestAirdrop(
    payer.publicKey,
    LAMPORTS_PER_SOL
  );
  await connection.confirmTransaction(signature);

  // Create program instance
  const wallet = {
    publicKey: payer.publicKey,
    signTransaction: async (tx) => {
      tx.partialSign(payer);
      return tx;
    },
    signAllTransactions: async (txs) => {
      return txs.map((tx) => {
        tx.partialSign(payer);
        return tx;
      });
    },
  };

  const provider = new AnchorProvider(connection, wallet, {});
  const program = new Program<Counter>(idl, provider);

  // Initialize counter
  const initTx = await program.methods
    .initialize()
    .accounts({
      counter: counter.publicKey,
      payer: payer.publicKey,
      systemProgram: SystemProgram.programId,
    })
    .signers([counter])
    .rpc();
  console.log("Initialize tx:", initTx);

  // Increment counter
  const incrementTx = await program.methods
    .increment()
    .accounts({
      counter: counter.publicKey,
    })
    .rpc();
  console.log("Increment tx:", incrementTx);

  // Fetch account
  const counterAccount = await program.account.counter.fetch(counter.publicKey);
  console.log("Counter value:", counterAccount.count.toString());
}

main();
```

## TypeScript Type Safety

When you run `anchor build`, Anchor generates TypeScript types in `target/types/`:

```typescript theme={null}
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 checking
const 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 typed
const account = await program.account.myAccount.fetch(address);
console.log(account.field1); // TypeScript knows the account structure
```

## API Reference

### Program Class

| Property/Method                     | Description                          |
| ----------------------------------- | ------------------------------------ |
| `program.methods.<instruction>()`   | Builder for invoking instructions    |
| `program.account.<account>.fetch()` | Fetch and deserialize single account |
| `program.account.<account>.all()`   | Fetch all accounts of a type         |
| `program.addEventListener()`        | Subscribe to program events          |
| `program.programId`                 | The program's public key             |
| `program.provider`                  | The provider instance                |
| `program.idl`                       | The program's IDL                    |

### MethodsBuilder Class

| Method                         | Description                       |
| ------------------------------ | --------------------------------- |
| `.accounts(accounts)`          | Specify instruction accounts      |
| `.signers(signers)`            | Add additional signers            |
| `.remainingAccounts(accounts)` | Add remaining accounts            |
| `.preInstructions(ixs)`        | Instructions to execute before    |
| `.postInstructions(ixs)`       | Instructions to execute after     |
| `.rpc(opts?)`                  | Build, sign, and send transaction |
| `.transaction()`               | Build transaction without sending |
| `.instruction()`               | Build instruction only            |
| `.simulate()`                  | Simulate transaction              |

## Next Steps

<CardGroup cols={2}>
  <Card title="Rust Client" icon="rust" href="/clients/rust">
    Learn about the Rust client library
  </Card>

  <Card title="Program IDL" icon="file-code" href="/concepts/idl">
    Understand the IDL format
  </Card>
</CardGroup>
