LogoAnchor Docs

Rust

Learn how to use Anchor's Rust client library to interact with Solana programs

The anchor-client crate is the Rust client library for interacting with Anchor programs. You can find the source code here.

Example

The example below demonstrates how to use the anchor-client crate to interact with a simple Anchor program. The program client can be automatically generated from the program's IDL using the declare_program! macro. This macro generates dependency free modules that enable you to interact with the program's instructions and accounts.

The program has two instructions:

  • initialize – Creates and initializes a counter account to store a value
  • increment – Increments the value stored on the counter account
lib.rs
use anchor_lang::prelude::*;   declare_id!("6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC");   #[program] pub mod example {  use super::*;    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {  let counter = &ctx.accounts.counter;  msg!("Counter account created! Current count: {}", counter.count);  Ok(())  }    pub fn increment(ctx: Context<Increment>) -> Result<()> {  let counter = &mut ctx.accounts.counter;  msg!("Previous counter: {}", counter.count);    counter.count += 1;  msg!("Counter incremented! Current count: {}", counter.count);  Ok(())  } }   #[derive(Accounts)] pub struct Initialize<'info> {  #[account(mut)]  pub payer: Signer<'info>,    #[account(  init,  payer = payer,  space = 8 + 8  )]  pub counter: Account<'info, Counter>,  pub system_program: Program<'info, System>, }   #[derive(Accounts)] pub struct Increment<'info> {  #[account(mut)]  pub counter: Account<'info, Counter>, }   #[account] pub struct Counter {  pub count: u64, }

Below is an example folder structure for a Rust client that interacts with the Anchor program:

example.json
main.rs
Cargo.toml

The program IDL must be in a /idls folder. The declare_program! macro searches for the IDL in the /idls folder to generate the client modules.

idls/example.json
{  "address": "6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC",  "metadata": {  "name": "example",  "version": "0.1.0",  "spec": "0.1.0",  "description": "Created with Anchor"  },  "instructions": [  {  "name": "increment",  "discriminator": [11, 18, 104, 9, 104, 174, 59, 33],  "accounts": [  {  "name": "counter",  "writable": true  }  ],  "args": []  },  {  "name": "initialize",  "discriminator": [175, 175, 109, 31, 13, 152, 155, 237],  "accounts": [  {  "name": "payer",  "writable": true,  "signer": true  },  {  "name": "counter",  "writable": true,  "signer": true  },  {  "name": "system_program",  "address": "11111111111111111111111111111111"  }  ],  "args": []  }  ],  "accounts": [  {  "name": "Counter",  "discriminator": [255, 176, 4, 245, 188, 253, 124, 25]  }  ],  "types": [  {  "name": "Counter",  "type": {  "kind": "struct",  "fields": [  {  "name": "count",  "type": "u64"  }  ]  }  }  ] }

Below is the src/main.rs file for interacting with the program:

  1. The declare_program! macro - Generates client modules for the program using the IDL file

  2. The anchor_client crate - Provides utilities for interacting with the program, including:

    • Building program instructions
    • Sending transactions
    • Fetching program accounts
src/main.rs
use anchor_client::{  solana_client::rpc_client::RpcClient,  solana_sdk::{  commitment_config::CommitmentConfig, native_token::LAMPORTS_PER_SOL, signature::Keypair,  signer::Signer, system_program,  },  Client, Cluster, }; use anchor_lang::prelude::*; use std::rc::Rc;   declare_program!(example); use example::{accounts::Counter, client::accounts, client::args};   #[tokio::main] async fn main() -> anyhow::Result<()> {  let connection = RpcClient::new_with_commitment(  "http://127.0.0.1:8899", // Local validator URL  CommitmentConfig::confirmed(),  );    // Generate Keypairs and request airdrop  let payer = Keypair::new();  let counter = Keypair::new();  println!("Generated Keypairs:");  println!(" Payer: {}", payer.pubkey());  println!(" Counter: {}", counter.pubkey());    println!("\nRequesting 1 SOL airdrop to payer");  let airdrop_signature = connection.request_airdrop(&payer.pubkey(), LAMPORTS_PER_SOL)?;    // Wait for airdrop confirmation  while !connection.confirm_transaction(&airdrop_signature)? {  std::thread::sleep(std::time::Duration::from_millis(100));  }  println!(" Airdrop confirmed!");    // Create program client  let provider = Client::new_with_options(  Cluster::Localnet,  Rc::new(payer),  CommitmentConfig::confirmed(),  );  let program = provider.program(example::ID)?;    // Build and send instructions  println!("\nSend transaction with initialize and increment instructions");  let initialize_ix = program  .request()  .accounts(accounts::Initialize {  counter: counter.pubkey(),  payer: program.payer(),  system_program: system_program::ID,  })  .args(args::Initialize)  .instructions()?  .remove(0);    let increment_ix = program  .request()  .accounts(accounts::Increment {  counter: counter.pubkey(),  })  .args(args::Increment)  .instructions()?  .remove(0);    let signature = program  .request()  .instruction(initialize_ix)  .instruction(increment_ix)  .signer(&counter)  .send()  .await?;  println!(" Transaction confirmed: {}", signature);    println!("\nFetch counter account data");  let counter_account: Counter = program.account::<Counter>(counter.pubkey()).await?;  println!(" Counter value: {}", counter_account.count);  Ok(()) }

Below are the dependencies for the Cargo.toml file:

Cargo.toml
[package] name = "rs" version = "0.1.0" edition = "2021"   [dependencies] anchor-client = { version = "0.32.1", features = ["async"] } anchor-lang = "0.32.1" anyhow = "1.0.93" tokio = { version = "1.0", features = ["full"] }

On this page

Edit on GitHub