Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
Quando CPI é a ferramenta certa
Um programa personalizado faz sentido quando o swap precisa acontecer atomicamente com outras mudanças de estado on-chain que apenas o seu programa pode fazer. Casos comuns:- Programas de escrow / limite de ordem — o usuário deposita um mint no seu escrow, seu programa monitora uma condição de preço e, quando acionada, seu programa faz um swap atômico através do Raydium e credita a conta do usuário.
- Proxies de agregador — uma instrução única que roteia um swap através do Raydium + um ou mais outros DEXes, com todos os hops sob uma verificação de slippage único controlada pelo seu programa.
- Vaults com autocompounding — deposite LP ou farm stake no seu vault, o vault colhe recompensas em um cronograma, reabastece liquidez e emite tokens de participação.
- Vaults de estratégia — posições LP alavancadas que se rebalanceiam fazendo swaps através de CLMM; liquidadores que fecham posições e fazem swap de colateral em uma única transação.
- Plataformas de lançamento de tokens com vesting personalizado — seu programa mantém tokens em vesting e os libera em um pool Raydium em um cronograma.
Padrões de composição
Padrão 1: Proxy fino
Seu programa expõe uma instrução única que valida alguma política (por exemplo, pares de mint na lista de permissão, desconto de taxa para usuários verificados) e depois encaminha para o Raydium.Padrão 2: Escrow
Seu programa possui um PDA que mantém o mint de entrada do usuário. Ao acionar, o PDA assina um CPI para Raydium fazer swap de seu próprio saldo.CpiContext::new_with_signer. Veja Sementes de assinador PDA.
Padrão 3: Multi-hop composto
Seu programa emite múltiplos CPIs em uma instrução, aplicando um limite de slippage único em todos eles. As instruções de swap do Raydium têm cada uma seu própriominimum_amount_out, mas você os define como 0 (ou um limite muito solto) e aplica um mínimo final rigoroso você mesmo após o último hop.
Padrão 4: Vault / estratégia
Seu programa mantém tokens LP ou farm stake em um PDA. Um keeper (ou o usuário) chamacompound(), que:
- Colhe recompensas do farm.
- Faz swap de recompensas por tokens de pool (CPI em CPMM ou CLMM).
- Deposita os rendimentos de volta no LP (outro CPI).
- Faz stake do novo LP (outro CPI).
Construção da lista de contas
A structAccounts do programa chamador espelha a ordem de contas do programa Raydium, mas a maioria das contas do lado do Raydium são UncheckedAccount porque o Raydium as valida por si só. Você só adiciona restrições às contas que você possui:
UncheckedAccount nas do Raydium — não é preguiça. O receptor valida as suas; validar duas vezes no chamador apenas queima CU e arrisca ficar desatualizado quando o Raydium lança um novo campo de layout de struct.
A chamada CPI em si
Sementes de assinador PDA
O CPI só é bem-sucedido se o PDA passado comoauthority corresponde à derivação que o chamador afirma. Os dois devem concordar em:
- A sequência de bytes da semente (aqui
[b"escrow", user.key().as_ref()]). - O bump.
- O ID do programa chamador (seu programa, não o do Raydium).
authority cubra a transação e que o ATA de entrada seja propriedade dessa autoridade. A validação acontece em anchor_spl::token::transfer: o campo authority do ATA deve ser igual ao assinador.
Bug comum: passar user como a autoridade (e transferir de escrow_input_ata que é propriedade do PDA de escrow). O programa SPL Token rejeita com owner mismatch. Sempre faça o campo authority corresponder ao proprietário do ATA.
Contas restantes
Várias instruções do Raydium aceitam uma lista de comprimento variável de contas anexadas após as fixas — contas restantes.- CLMM
SwapV2: 1–8 contasTickArrayStatepara os arrays de tick que o swap pode atravessar, na direção do swap. - Farm v6
Deposit/Harvest/Withdraw: pares(reward_vault, user_reward_ata), um par por slot de recompensa ativa. - Mints de gancho de transferência Token-2022: o programa do gancho de transferência mais quaisquer contas que o gancho necessite.
Orçamento de compute para chamadas compostas
Um CPI custa ~1.500 CU para o próprio frame de chamada; o uso de CU do receptor se empilha no topo. Orçamento aproximado por CPI do Raydium:| Chamada | CU (SPL Token) | CU (Token-2022) |
|---|---|---|
| CPMM swap_base_input | ~150.000 | ~200.000 |
| CLMM swap_v2 (array de tick único) | ~180.000 | ~230.000 |
| CLMM swap_v2 (atravessa 2 ticks) | ~220.000 | ~270.000 |
| Farm v6 deposit | ~120.000 | ~150.000 |
| Farm v6 harvest (por slot de recompensa) | +30.000 | +40.000 |
| AMM v4 swap_base_in | ~140.000 | n/a |
harvest → swap A → swap B → deposit LP → stake LP facilmente atinge 700k CU.
Sempre defina um ComputeBudgetProgram::set_compute_unit_limit explícito:
Propagação de erro
Os programas do Raydium retornam erros do Anchor com códigos estáveis. Seu programa chamador os vê comoErr(ProgramError::Custom(code)). Propague por padrão:
sdk-api/anchor-idl); novos códigos se anexam ao final, códigos existentes nunca mudam de significado.
Exemplo completo trabalhado: escrow de ordem de limite
Fluxo:open_order— o usuário depositaamount_indeinput_mintno PDA de escrow; registre o alvomin_amount_oute expiração.execute_order— qualquer um (keeper) chama com as contas de pool atuais. O programa verifica a cotação atual ≥min_amount_out, depois faz CPI no swap do Raydium e mantém a saída em escrow.claim— o usuário retira o mint de saída do escrow.
Testes
Puxar programas Raydium para um validador local para testes de integração (doAnchor.toml):
anchor test as busca da mainnet na inicialização. Veja sdk-api/rust-cpi.
Armadilhas específicas da composição
Reentrância
Solana não tem verdadeira reentrância — um CPI não pode chamar de volta para o programa originador na mesma invocação. Mas você ainda pode se construir em uma reentrância lógica: um CPI que lê seu estado, depois seu código o lê novamente assumindo que o CPI não o mudou. Para Raydium, os CPIs não tocam seu estado, então isso é menos preocupação do que, por exemplo, contextos de flash-loan. Mas se você compor Raydium com um protocolo de empréstimo, esteja ciente.Desvio de mutabilidade de conta
Se seu programa passa uma conta comomut mas o Raydium espera somente leitura (ou vice-versa), o runtime rejeita a invocação com InvalidAccountData. Sempre verifique a mutabilidade esperada da instrução do Raydium no IDL; anchor_cp_swap::cpi::accounts::Swap a impõe via seus tipos de campo.
Campo do programa Token-2022
Os mints de entrada e saída podem estar sob diferentes programas de token — um SPL Token, um Token-2022. O CPI tem camposinput_token_program e output_token_program separados por esse motivo. Sempre verifique o campo owner de cada mint e roteia o programa correto em cada slot.
Transações versionadas
Uma tx composta que faz 2+ CPIs do Raydium mais uma criação de ATA raramente cabe em uma transação herdada (v0 sem LUT). Use V0 com tabelas de lookup de endereço; puxe os LUTs públicos do Raydium viaraydium.getRaydiumLutAddresses().
Referências
sdk-api/rust-cpi— mecânica de CPI de baixo nível.integration-guides/priority-fee-tuning— dimensionamento de orçamento de compute.products/cpmm/code-demos,products/clmm/code-demos,products/farm-staking/code-demos— trechos de CPI por produto.

