Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anchor IDL different (incorrect?) from Solana Playground IDL generated #2914

Open
RyanWilkins opened this issue Apr 17, 2024 · 12 comments
Open
Labels
question Further information is requested

Comments

@RyanWilkins
Copy link

I was following this guide to learn anchor: https://www.quicknode.com/guides/solana-development/anchor/transfer-tokens

When deploying the program via Solana Playground (as instructed), everything runs fine. The issue comes from trying to replicate on my local machine using anchor. The code is exactly the same; however I was running into this issue when trying to invoke the transferLamports function:

    'Program log: Instruction: TransferLamports',
    'Program log: AnchorError caused by account: to. Error Code: ConstraintMut. Error Number: 2000. Error Message: A mut constraint was violated.',

After much, much frustration I discovered that the issue is with the IDL that Anchor generates when building the program. Comparing to the one that Solana Playground generates (remember - exact same lib.rs):

Solana Playground

"accounts":[
{"name":"from","isMut":true,"isSigner":true},
{"name":"to","isMut":true,"isSigner":false},
{"name":"systemProgram","isMut":false,"isSigner":false}],
"args":[{"name":"amount","type":"u64"}]}]

Local Anchor

      "accounts": [
        {
          "name": "payer",
          "writable": true,
          "signer": true
        },
        {
          "name": "recipient",
          "writable": true
        },
        {
          "name": "system_program",
          "address": "11111111111111111111111111111111"
        }
      ],
      "args": [
        {
          "name": "amount",
          "type": "u64"
        }
      ]

Pulling down the IDL from Solana Playground and using that in my Typescript module instead allows the code to run just fine.

    const sig = program.methods.transferLamports(new BN(10000)).accounts({
        from: from.publicKey,
        to: to.publicKey,
        system_program: system_program
    })

What is causing anchor to produce a completely different IDL type that isn't compatible with anchor itself?

@acheroncrypto acheroncrypto added the question Further information is requested label Apr 17, 2024
@acheroncrypto
Copy link
Collaborator

This is because the IDL has been rewritten, and it's incompatible with the old IDL.

There is also a new release (v0.30.0) which was released 2 days ago. Solana Playground has not yet upgraded to the latest version, so if you use the IDL generated from there (or any other place), you can use the 0.29.0 version of @coral-xyz/anchor locally (instead of 0.30.0).

@RyanWilkins
Copy link
Author

This is because the IDL has been rewritten, and it's incompatible with the old IDL.

There is also a new release (v0.30.0) which was released 2 days ago. Solana Playground has not yet upgraded to the latest version, so if you use the IDL generated from there (or any other place), you can use the 0.29.0 version of @coral-xyz/anchor locally (instead of 0.30.0).

Hi, appreciate the quick response.

Before I go messing around with all my configuration, can you clarify for me if there is a version of the 'npm' anchor package which can correctly invoke program functions with this new IDL format? Any quick references on syntax?

@acheroncrypto
Copy link
Collaborator

Before I go messing around with all my configuration, can you clarify for me if there is a version of the 'npm' anchor package which can correctly invoke program functions with this new IDL format? Any quick references on syntax?

It will work as long as you use the same Anchor version for all tooling (crates, packages, CLI).

See https://www.anchor-lang.com/release-notes/0.30.0#type-script

@RyanWilkins
Copy link
Author

Adding extra context for anyone else finding this in the future; not quite there yet:

I've updated everything to the most recent version but now I'm getting an error when the final method .rpc() is called.
I've tracked it to the build function in the NamespaceFactory index.js, the issue stems from coder.instruction.encode(ixName, ix):

TypeError: Cannot read properties of undefined (reading 'encode')

I believe this means I've setup my provider wrong? I can't find any changes from 0.26 (the version i had before) and the current version; I did not change any other code. Currently the provider is setup like this:

    const provider = new AnchorProvider(conn, new Wallet(myPK), AnchorProvider.defaultOptions());
    setProvider(provider);

I'm calling the function via

    const sig = await program.methods.transferSol(new BN(10000)).accounts({
        payer: from.publicKey,
        recipient: to.publicKey,
        system_program: system_program
    }).rpc()

@acheroncrypto
Copy link
Collaborator

Always use camelCase in TS package : https://www.anchor-lang.com/release-notes/0.30.0#case-conversion

Instead of system_program use systemProgram. It's also not even necessary to specify program accounts in the new version if you get the correct types from target/types and initialize your program with that type.

@CryptoCooker
Copy link

How to define program with @coral-xyz/anchor 0.30.0 in typescript?

My current code, which is not working.

import * as splStakingIdl from './idl/spl_staking.json';
const program = new anchor.Program(splStakingIdl, provider);

In version 0.29.0, I used to implement it by this:

import {
  IDL as SplStakingIdl ,
  SplStaking,
} from "./idl/spl_staking";
const program = new anchor.Program(SplStakingIdl as SplStaking, programId, provider);

After upgrading to 0.30.0, anchor doesn't generate IDL in target/types.

Is there any example codebase to integrate program with @coral-xyz/anchor 0.30.0 in typescript?

@acheroncrypto
Copy link
Collaborator

All you need is to cast the idl.json's type to the generated camelCased IDL type in target/types. For example:

import * as idl from "./idl/spl_staking.json";
import type { SplStaking } from "./types/spl_staking";

const program = new anchor.Program(idl as unknown as SplStaking, provider);

or

import type { SplStaking } from "./types/spl_staking";

const idl: SplStaking = require("idl/spl_staking.json");
const program = new anchor.Program(idl, provider);

@kharesiddhant
Copy link

kharesiddhant commented Jun 28, 2024

All you need is to cast the idl.json's type to the generated camelCased IDL type in target/types. For example:

import * as idl from "./idl/spl_staking.json";
import type { SplStaking } from "./types/spl_staking";

const program = new anchor.Program(idl as unknown as SplStaking, provider);

or

import type { SplStaking } from "./types/spl_staking";

const idl: SplStaking = require("idl/spl_staking.json");
const program = new anchor.Program(idl, provider);

I tried both of these but they both seem to spew out: Argument of type '<name_of_my_program> is not assignable to the parameter Idl'.

I'm using crates: anchor-lang "0.30.1", anchor-spl "0.30.1"

and package @coral-xyz/anchor "0.30.1". Does the above method only work for 0.30.0?

It also spews out saying it's missing the name and version properties.

@thiruofficalsp
Copy link

I got the missing name and version properties for idl issue as well - still looking for a solution

@acheroncrypto
Copy link
Collaborator

@Sidkjr, @thiruofficalsp

If you get ... is not assignable to the parameter Idl error, it means the TS package and the crate/CLI version used to generate the IDL doesn't match.

It's the same if it says missing name and version properties. You'd get this if you used @coral-xyz/anchor 0.29.0 with a new IDL for example.

@kharesiddhant
Copy link

@acheroncrypto Yep. Got what I was doing wrong.

It's the same if it says missing name and version properties. You'd get this if you used @coral-xyz/anchor 0.29.0 with a new IDL for example.

But eventually decided to revert back to the version of 0.29 for both anchor-lang and anchor-spl crates and it seemed to work perfectly fine.

The old IDL was better😔.

@viandwi24
Copy link

viandwi24 commented Sep 6, 2024

same problem, but i need use new anchor version but want to use solanaFM local idl (to help better debugging), so im try to make tools to convert my new idl to old idl, so now can compatible to use in solanaFM

https://github.com/viandwi24/anchor-idl-converter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants