5

In the anchor-lang docs it says,

The features = ["cpi"] is used so we can not only use puppet's types but also its instruction builders and cpi functions. Without those, we would have to use low level solana syscalls. Fortunately, anchor provides abstractions on top of those. By enabling the cpi feature, the puppet-master program gets access to the puppet::cpi module. Anchor generates this module automatically and it contains tailor-made instructions builders and cpi helpers for the program.

https://www.anchor-lang.com/docs/cross-program-invocations

In the examples I've found, the programs to CPI into are also included and you have to specify the path in Cargo.toml.

[dependencies] 
callee = { path = "../callee", features = ["cpi"] }

https://github.com/coral-xyz/anchor/blob/master/tests/cpi-returns/programs/caller/Cargo.toml#L20

[dependencies]
puppet = { path = "../puppet", features = ["cpi"] }

https://github.com/coral-xyz/anchor/blob/master/examples/tutorial/basic-3/programs/puppet-master/Cargo.toml#L18

  • Does features = ["cpi"] only work if you also having both programs?
  • Can the feature be used with Anchor programs that you don't have the code to?
  • Does the feature only work with Anchor programs, or can it also work with Native programs?

For example, is there a way to use the features = ["cpi"] with programs cloned in Anchor.toml for to make CPIs to for testing?

[test.validator]
url = "https://api.mainnet-beta.solana.com"

[[test.validator.clone]]
address = "7NL2qWArf2BbEBBH1vTRZCsoNqFATTddH6h8GkVvrLpG"

More generally, I'm trying to figure out how to make CPIs with CpiContext to programs other than the Token program using the anchor_spl crate.

1 Answer 1

6

The cpi feature simply toggles whether the cpi module is generated or not.

Probably the most significant generated item is the cpi::<your instruction>() function that takes a CpiContext and:

  1. Creates an instruction: serialises instruction data and constructs an AccountInfo list, and
  2. Sends the instruction to the downstream program, e.g. invoke_signed().

(Shameless plug: I blogged about this very topic already Anatomy of Solana Program Invocations using Anchor)

This should make the answers to your other questions more obvious: You will have access to the cpi module of a downstream program if: a) you have access to its source code, or b) it was included in its published crate, c) the IDL is available.

Since this is generated by Anchor macros, it is typically only available in Anchor programs and not plain Solana programs.

As you have noted, Anchor provides a wrapper for a few common programs like SPL token, Serum, etc. (the full list is here) to provide a similar experience to the generated cpi feature for non-Anchor programs.

Another notable tool is native-to-anchor CLI which parses the Solana code and attempts to create the Anchor IDL and client package for it. For some SPL programs that it cannot support, they also have provided the Anchor client separately.

If there is an Anchor IDL available, then you still have some recourse to generate the CPI stuff:

4
  • Appreciate the thorough response! For clarification, in order to generate the cpi module for an Anchor program to CPI into, I either have to 1) have access to the source code or 2) use a published crate. In other words, there's no way to generate the cpi module using only the programId of the program to CPI into? Awesome blog post, very concise and diagrams were super helpful
    – john
    Commented Sep 10, 2022 at 7:57
  • 1
    If the program publishes an IDL on-chain (i.e. can be fetched using anchor idl fetch), then you can still generate it something. I had a crack at this myself a while ago: github.com/labeleven-dev/anchorgen and Saber guys had another try later github.com/saber-hq/anchor-gen
    – sohrab
    Commented Sep 10, 2022 at 8:01
  • I've updated it in the answer for posterity.
    – sohrab
    Commented Sep 10, 2022 at 8:07
  • this is cool! the saber-hq one actually didn't work for me so I used yours and it worked great! Commented Nov 1, 2023 at 1:20

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.