Understanding IDL
Interface Description Language (IDL) is used to specify the public interface of your programs for consumers to generate client code automatically.
It's important to note that IDLs are used by Anchor, and are not a native Solana concept.
What is an IDL?
You can imagine an IDL to be the menu at the restaurant, telling you what food they're able to make you.
Programs (smart contracts) have some kind of public interface to create accounts, transfer tokens, etc. In order to know about the interface and be able to use it correctly, Anchor provides us with IDLs.
The IDL will be in a human readable JSON form in your target/
directory after you anchor build
. It will include everything the client needs to figure out how to talk to the program.
Solana's dynamism and why IDLs exist
Solana programs have no real guard-rails or requirements, they simply need to parse binary. Beyond that they can really do anything within the constraints of 10MB (largest Program/Account size on Solana).
Because they can do anything, there's an issue with interfacing. It is there to answer the question:
How do we know what we can do with a Solana program?
In the beginning of Solana, you'd have to either communicate with the developer/creator and get them to tell you the schema, or you'd have to parse their binary into something readable so you can understand what their program interface is.
Anchor makes this process much simpler with IDLs, which end up being placed in human-readable JSON in your built projects target directory.
While Anchor uses IDLs to make interfacing with various Programs easier, it is not a native part of Solana and are not guaranteed to be provided. Programs without an IDL can still be interfaced with but you will need to write your own logic to serialize/deserialize the data.
Building a client from an IDL
Anchor lets you build clients directly from an IDL. This skips the hassle of serialization, where you'd have to parse the Program from bytes into something usable.
We have a program source code file found in programs/your-project-name/src/lib.rs
that contains this code:
use anchor_lang::prelude::*;
declare_id!("Do9Dj8Au8LfMQEJs6RPLAaUVd6bSCCvqPnfFQfknejAm");
#[program]
pub mod anchor_rust_test {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
msg!("Greetings from: {:?}", ctx.program_id);
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
When you run anchor build in an Anchor project, the Anchor CLI automatically generates:
- The IDL file (
.json
) in thetarget/idl
folder (ex.target/idl/example.json
) - The TypeScript type definitions (
.ts
) in thetarget/types
folder (ex.target/types/example.ts
)
We will talk to this program in our test, which is acting on our program from the perspective of the client
. In this case we are using javascript to create an instruction we would send in a transaction:
import { Program } from "@coral-xyz/anchor";
import type { Example } from "./idl/example.ts";
import idl from "./idl/example.json";
const program = new Program(idl as Example, {
connection,
});
const initializeInstruction = await program.methods
.initialize()
.accounts({
payer: payer.publicKey,
counter: counter.publicKey,
})
.instruction();
Here we are using the automatically generated IDL file to create a dynamic client that can interface with our program by generating the correct instructions.