4

Similar to ABI files for EVM, Solana programs (hopefully) have IDLs that describe the structure of their contracts. What's the best way to obtain the IDL of a Solana Program?

3 Answers 3

5

As far as I know, there are currently a few ways to get the IDL:

  1. Through the source code of the Program, if it's open source.
  2. Through Anchor CLI via anchor idl.
  3. Metaplex Shank: https://github.com/metaplex-foundation/shank.
  4. Anchor Program Registry: apr.dev.
  5. Reverse engineering via client-side JS.
1
  • 2
    These are ways, but any walkthroughs using one?
    – Jacob Creech
    Commented Jul 15, 2022 at 19:52
2

The easiest way that I know of is fetching the IDLs that Anchor generates (if the program you're interested in uses Anchor)

See this example code snippet:

const anchor = require('@project-serum/anchor');
const solana = require('@solana/web3.js');


async function main() {
  const connection = new solana.Connection(solana.clusterApiUrl('mainnet-beta'))
  const keypair = anchor.web3.Keypair.generate()
  const wallet = new anchor.Wallet(keypair)
  const provider = new anchor.AnchorProvider(connection, wallet)
  const candyMachineV2Program = new solana.PublicKey('cndy3Z4yapfJBmL3ShUp5exZKqR3z33thTzeNMm2gRZ');
  const idl = await anchor.Program.fetchIdl(candyMachineV2Program, provider);
  const program = new anchor.Program(idl, candyMachineV2Program, provider);
  const accounts = await program.account.candyMachine.fetch('9tQLFyLeaUwQ1PN2YDiFztZDxu4KT6px8CBYEapkshAD')
  console.log(accounts)
}
main()

Here this code is setting up the anchor and solana connections, and then we grab the idl of the Candy Machine V2 Program, we use it to create the program interface. Then, we are able to fetch the accountInfo of an arbitrary candy machine address.(9tQLFyLeaUwQ1PN2YDiFztZDxu4KT6px8CBYEapkshAD)

What you see logged out is the account info for that particular account.

You could use this to then get all of the NFTs for this particular project if you wanted to take things a step further.

2
  • thanks for the answer! why does anchor need a wallet to generate a provider? e.g. solana web3 doesn't need a registered wallet to perform read queries
    – Sun Lee
    Commented Jul 27, 2022 at 23:10
  • 1
    @SunLee I don't know honestly, I just know it expects the wallet. I would guess it was a design decision so that you don't have to pass wallets into arguments, and instead the client handles it since you provided it upon initialization, but that's speculation on my part, I'm not 100% sure.
    – NHeinDev
    Commented Aug 4, 2022 at 17:13
1

For "Vanilla" (non-anchor) Solana programs, you can use Native to Anchor to create an Anchor compatible IDL.

Example on how to do this for the Feature Proposal program

  1. Clone the repo:
git clone https://github.com/acheroncrypto/native-to-anchor.git
cd native-to-anchor
  1. Copy the feature proposal instructions into the instructions/ directory.

  2. Run the program.

cargo run

The IDL would be generated in the idl/ directory.

Generated IDL:

{
  "version": "0.1.0",
  "name": "feature_program",
  "instructions": [
    {
      "name": "propose",
      "accounts": [
        {
          "name": "fundingAddress",
          "isMut": true,
          "isSigner": true
        },
        {
          "name": "featureProposalAddress",
          "isMut": true,
          "isSigner": true
        },
        {
          "name": "mintAddress",
          "isMut": true,
          "isSigner": false
        },
        {
          "name": "distributorTokenAddress",
          "isMut": true,
          "isSigner": false
        },
        {
          "name": "acceptanceTokenAddress",
          "isMut": true,
          "isSigner": false
        },
        {
          "name": "feature",
          "isMut": true,
          "isSigner": false
        },
        {
          "name": "systemProgram",
          "isMut": false,
          "isSigner": false
        },
        {
          "name": "tokenProgram",
          "isMut": false,
          "isSigner": false
        },
        {
          "name": "rent",
          "isMut": false,
          "isSigner": false
        }
      ],
      "args": [
        {
          "name": "tokensToMint",
          "type": "u64"
        },
        {
          "name": "acceptanceCriteria",
          "type": {
            "defined": "AcceptanceCriteria"
          }
        }
      ]
    },
    {
      "name": "tally",
      "accounts": [
        {
          "name": "featureProposalAddress",
          "isMut": true,
          "isSigner": false
        },
        {
          "name": "acceptanceTokenAddress",
          "isMut": false,
          "isSigner": false
        },
        {
          "name": "feature",
          "isMut": true,
          "isSigner": false
        },
        {
          "name": "systemProgram",
          "isMut": false,
          "isSigner": false
        },
        {
          "name": "clock",
          "isMut": false,
          "isSigner": false
        }
      ],
      "args": []
    }
  ]
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.