Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
CPI (“cross-program invocation”) é o mecanismo pelo qual um programa Solana chama outro. A maioria dos programas da Raydium fornece crates de wrapper CPI Anchor que fazem o site de chamada parecer uma chamada de função tipada, com structs de conta que têm nomes de campo validados e helpers
cpi::<ix>(). Esta página documenta o padrão geral uma vez, depois as diferenças por programa. Para TypeScript executável, consulte a página code-demos de cada capítulo de produto.Qual padrão se aplica a qual programa
Se você está integrando CPMM, CLMM ou LaunchLab, leia o padrão geral primeiro, depois pule para a seção do seu programa para a lista de contas e quaisquer diferenças. Farm v6 e AMM v4 são diferentes o suficiente para justificar a leitura de suas seções de forma independente.
Dependências do Cargo
branch = "master" rastreia a fonte publicada mais recente; fixe um rev = "<commit>" específico se você precisar de uma compilação reproduzível. Isso é recomendado depois que você passar do protótipo, pois uma mudança de layout de conta upstream em master quebrará sua compilação sem aviso prévio.
O sinalizador de feature cpi faz as crates compilarem apenas para a superfície CPI (structs de conta + invocadores) em vez do programa completo, para que seu binário permaneça pequeno.
anchor-lang / anchor-spl devem corresponder ao que a crate de destino fixa:
Para exemplos CPI funcionais que conectam as structs de conta de ponta a ponta, consulte
raydium-io/raydium-cpi-example (cobre AMM v4, CPMM e CLMM). Seu branch mais recente é anchor-0.31.0 — ainda não há branch Anchor 1.x, então trate esse repo como a referência para fiação de struct de conta, não para os pinos de versão que esta página exige.
O padrão geral de CPI do Anchor
Esta seção percorre o CPMM de ponta a ponta como exemplo prático: structAccounts, CpiContext, cpi::<ix>(). O CLMM segue a mesma forma, com uma lista de contas diferente e um requisito de remaining-accounts. O LaunchLab segue a mesma mecânica, mas sua lista de contas inclui várias contas sem equivalente no CPMM/CLMM (global_config, platform_config, event_authority, program), então trate-o como o mesmo padrão, não a mesma forma. Consulte a seção específica de cada programa em vez de assumir que a lista de contas deste passo a passo se transfere diretamente.
Construção da lista de contas
Toda CPI do Raydium requer uma structAccounts no programa chamador. Seus campos são quaisquer contas que sua instrução precisa, com validadores no nível do campo; sua ordem de declaração não precisa corresponder à ordem de contas da instrução do próprio Raydium, já que seu cliente gerado pelo IDL as endereça por nome, não por posição:
UncheckedAccount porque o programa chamado (Raydium) é responsável pela validação. Seu programa chamador valida estritamente apenas as contas que você possui, como ATAs de usuário e seus próprios PDAs. O comentário de documentação /// CHECK: suprime o aviso do Anchor sobre verificações ausentes. A única exceção do lado do Raydium é o próprio cpmm_program: é o programa sendo invocado, não uma conta de dados que o Raydium valida internamente, então é tipado como Program<T> e recebe a verificação automática de endereço do Anchor em vez de um /// CHECK: manual. Esta forma, principalmente UncheckedAccount, onde o Raydium valida suas próprias contas, é a mesma para CLMM e LaunchLab. Este exemplo assume que ambos os mints são Token SPL clássico; se qualquer um deles puder ser um mint Token-2022, adicione um campo token_program_2022: Program<'info, anchor_spl::token_2022::Token2022> e passe-o como input_token_program/output_token_program desse lado na chamada CPI abaixo em vez de token_program.
Construindo a chamada CPI
O Anchor gera um helper por instrução, junto com uma struct de contas CPI (cpi::accounts::Swap, com alias CpmmSwap abaixo). Diferentemente de sua própria struct MyProxySwap acima, os nomes e a ordem dos campos desta são fixos pelo IDL do próprio raydium-cp-swap e devem corresponder exatamente:
cpi::swap_base_input é gerado a partir do IDL; sua lista de argumentos espelha a lista de argumentos da instrução do Anchor. Todo programa Raydium baseado em Anchor confirmado (CPMM, CLMM, LaunchLab) gera seus helpers cpi::<ix>() da mesma forma, com o nome da função correspondendo ao nome da instrução em snake_case. Se isso se estende ao Farm v6 é não confirmado; consulte sua seção.
Signer seeds (CPI assinada por PDA)
Quando seu programa assina a CPI em nome de um PDA (comum para vaults, escrows, etc.), useCpiContext::new_with_signer:
authority (ou papel de assinante similar), o runtime do Solana verifica que o PDA assina via essas seeds.
Remaining accounts
Algumas instruções do Raydium aceitam remaining accounts, uma lista de comprimento variável anexada após as contas fixas. Os helpers CPI do Anchor não fazem verificação de tipo para remaining accounts; passe-os via.with_remaining_accounts(...):
- CLMM
SwapV2: tick arrays, ordenadas direcionalmente. - Farm v6: pares
(reward_vault, user_reward_ata), mas apenas a partir do segundo fluxo de recompensa em diante; consulte Farm v6 para ver o que a decodificação de uma transação real mostra.
Aplicando o padrão: CLMM
SwapV2 segue o padrão geral acima com uma lista de contas diferente e um requisito de remaining-accounts para tick arrays. O módulo #[program] do crate é nomeado raydium_clmm, que também é seu caminho use do Rust.
TickArrayNotFound (consulte products/clmm/instructions para a tabela de contas completa e lista de erros). Passe-os na direção do caminhar de preço: primeiro array na direção do swap primeiro.
Aplicando o padrão: LaunchLab
LaunchLab é baseado em Anchor e publica um IDL:raydium_launchpad/raydium_launchpad.json no repositório público raydium-idl. O identificador de metadados interno desse IDL é raydium_launchpad, um nome técnico para o programa subjacente, não um nome alternativo para o produto. Diferentemente de CPMM e CLMM, porém, o código-fonte do programa não está disponível publicamente (veja reference/program-addresses). Não há uma dependência git = "..." para apontar o Cargo, e nenhum código-fonte para confirmar qual seria o caminho use real do Rust de um crate.
Gere bindings a partir do IDL publicado usando a macro declare_program! do Anchor. Salve o JSON do IDL como idls/raydium_launchpad.json no seu crate (Cargo procura por um diretório idls/ relativo a CARGO_MANIFEST_DIR), então declare_program!(raydium_launchpad); gera structs raydium_launchpad::cpi::accounts::<Ix> e funções cpi::<ix>() diretamente do IDL, sem precisar do código-fonte do programa. O nome da struct de contas gerada é sempre o nome da instrução em PascalCase (buy_exact_in → BuyExactIn), e os nomes dos campos correspondem exatamente aos nomes de contas do IDL, a mesma lista de contas já usada em MyProxyBuy abaixo.
A forma do CPI segue o padrão geral. A lista de contas e argumentos abaixo vêm da instrução buy_exact_in do IDL on-chain, não de products/launchlab/instructions.mdx:
pool_state.migrate_type, que products/launchlab/accounts.mdx diz ser definido no tempo de Initialize. Sua lista de contas CPI precisa estar preparada para ambos, ou você precisa ler migrate_type de PoolState primeiro e fazer uma ramificação.
Propagação de erros
Cada programa Raydium baseado em Anchor retorna seu próprio enum de erro; Anchor os envolve, então seu programa chamador os vê comoErr(ProgramError::Custom(code)). Para lidar com erros específicos:
raydium_clmm::error::ErrorCode para CLMM, e assim por diante). Os números de código de erro são estáveis conforme a política do IDL (sdk-api/anchor-idl), então você pode testar contra códigos específicos comparando com o valor numérico. Tabelas de erro completas: CPMM, CLMM, AMM v4, Farm v6, e LaunchLab.
Orçamento de computação em CPIs compostos
Cada frame de CPI tem overhead, e o próprio consumo de CU do chamado se acumula sobre o seu, então uma transação que chama Raydium de dentro do seu programa precisa de um orçamento de computação explícito em vez de confiar no padrão de 200k CU.Medido, não estimado. Um
swap_base_input de CPMM na mainnet consome ~23.000 CU no próprio programa CPMM — amostrado em 2026-09-09 em oito swaps ao vivo em um pool de alto volume (22.721–23.052), lido da linha de log Program CPMMoo8… consumed N of M compute units. Para comparação: swap AMM v4 ~26.000; CLMM swap ~41.000; CLMM swap_v2 ~48.000 (43.838–52.887), aumentando com cada cruzamento de tick.Uma revisão anterior desta página relatava ~47.700 CU para um CPI de proxy-swap. Esse número era a transação inteira (computeUnitsConsumed), que inclui o próprio programa do chamador, o frame de CPI e qualquer configuração de ATA — não o custo do chamado. Ambos são úteis, mas não são o mesmo número, então compare como com como. Meça sua própria transação em vez de orçar com base em um ou outro.remaining_accounts, adicionando CU por array), mas apenas o número de CPMM acima é um valor medido. Sempre defina uma instrução ComputeBudgetProgram::set_compute_unit_limit(...) explícita dimensionada a partir de sua própria medição, não um número copiado da documentação, já que o limite padrão de 200k CU se esgotará silenciosamente e os custos por instrução mudam conforme os programas são atualizados.
AMM v4: construção manual de Instruction
AMM v4 é anterior ao Anchor e não possui um crate de CPI, tornando-o o único programa neste documento que não segue o padrão geral acima. Construa aInstruction manualmente:
products/amm-v4/code-demos para a lista completa de contas.
Farm v6
Use o SDK do TypeScript se essa for uma opção para sua integração.raydium.farm.deposit(...) (veja products/farm-staking/code-demos) é exercitado por demos reais e não depende de se um crate Anchor existe para este programa.
Se você precisar de CPI Rust mesmo assim, por exemplo compondo a partir de outro programa on-chain, construa a Instruction manualmente, da mesma forma que AMM v4: derive a lista de contas real e os discriminadores de instrução independentemente, por exemplo decodificando os layouts do TypeScript do SDK (raydium-sdk-V2’s farm module), decodificando transações reais diretamente (veja abaixo), ou despejando e desassemblando o programa implantado.
Para a forma de instrução de argumento zero consistente com uma chamada de harvest ou claim, a ordem de conta real é um prefixo fixo (token_program, a conta de estado do farm, um PDA de autoridade de vault, o primeiro vault de recompensa desse PDA, um segundo PDA, o chamador, e o ATA do chamador para esse primeiro mint de recompensa), seguido por pares (reward_vault_i, user_reward_ata_i) em remaining_accounts para cada fluxo de recompensa após o primeiro. A convenção de emparelhamento é real, mas só começa no segundo fluxo de recompensa: o vault e ATA do primeiro fluxo são contas fixas, não adjacentes um ao outro, e não fazem parte de remaining_accounts em absoluto.
Testando um fluxo de CPI
O desenvolvimento local requer que os programas Raydium estejam disponíveis no seu validador de teste. Três opções:anchor testcom clonagem de programa. Extrai o bytecode implantado da mainnet para seu validador local; veja Clonando programas em um validador local abaixo para a configuraçãoAnchor.tomle duas coisas que costumam causar problemas em testes de criação de pool especificamente.- Devnet. Raydium implanta a maioria dos programas na devnet, mas em IDs de programa diferentes da mainnet para cada programa (CPMM, CLMM, AMM v4, Stable AMM e LaunchLab cada um tem um endereço devnet distinto; veja a tabela Devnet em
reference/program-addresses). Farm v3/v5/v6 não são publicados de forma confiável na devnet; a API ao vivo (https://api-v3-devnet.raydium.io/main/info) tem o panorama atual. Se você usar as constantesDEVNET_PROGRAM_IDincluídas emraydium_clmm(ou o equivalente para outros crates), não assuma que um ID de mainnet também funciona na devnet. Executeanchor test --provider.cluster devnetpara acessar código ao vivo uma vez que você tenha os endereços corretos. - Implantação local. Clone os repositórios Raydium (CPMM, CLMM; o código-fonte do LaunchLab não está disponível para esta opção) e execute
anchor deployem um validador local. Adiciona overhead ao ciclo de teste, mas permite que você modifique o programa chamado para depuração.
anchor test, ou execute anchor build primeiro e anchor test --skip-build depois se estiver iterando no arquivo de teste sem alterar o programa.
Clonando programas em um validador local
reference/program-addresses é a fonte de verdade para cada endereço aqui.
Referências
products/cpmm/code-demos,products/clmm/code-demos,products/amm-v4/code-demos,products/farm-staking/code-demos,products/launchlab/code-demos: exemplos de CPI e TypeScript específicos do produto.sdk-api/anchor-idl: recuperação de IDL e regeneração de cliente, incluindo o caminho de codegen de IDL para LaunchLab.integration-guides/cpi-integration: padrões de integração de nível superior como escrows, vaults e composição de agregadores.
- raydium-cp-swap
- raydium-clmm
- raydium-idl: IDL do LaunchLab (o código-fonte do programa em si é fechado)
- Documentação de CPI do Anchor

