Esta página fue traducida automáticamente por IA. La versión en inglés es la fuente autorizada.Ver versión en inglés →
sdk-api/rust-cpi cubre la mecánica de bajo nivel para invocar cada programa de Raydium. Esta página es la acompañante de nivel superior: por qué compondrías Raydium en tu propio programa, qué patrón se ajusta a tu caso de uso, y el código de integración completo que necesitas de principio a fin.
Cuándo CPI es la herramienta correcta
Un programa personalizado tiene sentido cuando el intercambio debe ocurrir de forma atómica con otros cambios de estado on-chain que solo tu programa puede hacer. Casos comunes:- Programas de depósito en garantía / órdenes limitadas — el usuario deposita un mint en tu depósito en garantía, tu programa observa una condición de precio, y cuando se activa, tu programa intercambia atómicamente a través de Raydium y acredita la cuenta del usuario.
- Proxies agregadores — una única instrucción que enruta un intercambio a través de Raydium + uno o más DEXes adicionales, con todos los saltos bajo una única verificación de slippage propiedad de tu programa.
- Bóvedas de auto-compounding — deposita LP o participación en granja en tu bóveda, la bóveda cosecha recompensas en un cronograma, re-suministra liquidez, emite tokens de participación.
- Bóvedas de estrategia — posiciones LP apalancadas que se reequilibran intercambiando a través de CLMM; liquidadores que cierran posiciones e intercambian garantía en una transacción.
- Plataformas de lanzamiento de tokens con vesting personalizado — tu programa mantiene tokens de vesting y los libera en un pool de Raydium en un cronograma.
Patrones de composición
Patrón 1: Proxy delgado
Tu programa expone una única instrucción que valida alguna política (p. ej. pares de mint en lista blanca, descuento de tarifa para usuarios verificados) y luego reenvía a Raydium.Patrón 2: Depósito en garantía
Tu programa posee un PDA que mantiene el mint de entrada del usuario. Al activarse, el PDA firma un CPI a Raydium para intercambiar su propio saldo.CpiContext::new_with_signer. Ver Semillas de firmante PDA.
Patrón 3: Multi-salto compuesto
Tu programa emite múltiples CPIs en una instrucción, aplicando un único límite de slippage en todos ellos. Las instrucciones de intercambio de Raydium tienen cada una su propiominimum_amount_out, pero estableces esos en 0 (o un piso muy flexible) y aplicas un mínimo final estricto después del último salto.
Patrón 4: Bóveda / estrategia
Tu programa mantiene tokens LP o participación en granja en un PDA. Un guardián (o el usuario) llama acompound(), que:
- Cosecha recompensas de la granja.
- Intercambia recompensas por tokens de pool (CPI en CPMM o CLMM).
- Deposita los ingresos de vuelta en el LP (otro CPI).
- Participa en el nuevo LP (otro CPI).
Construcción de lista de cuentas
La estructuraAccounts del programa que llama refleja el orden de cuentas del programa de Raydium, pero la mayoría de las cuentas del lado de Raydium son UncheckedAccount porque Raydium las valida a sí mismo. Solo añades restricciones en cuentas que tú posees:
UncheckedAccount en las de Raydium — no es pereza. El receptor valida las suyas; validar dos veces en el llamador solo quema CU y arriesga desincronización cuando Raydium envía un nuevo campo de diseño de struct.
La llamada CPI en sí
Semillas de firmante PDA
El CPI solo tiene éxito si el PDA pasado comoauthority coincide con la derivación que el llamador afirma. Los dos deben estar de acuerdo en:
- La secuencia de bytes de semilla (aquí
[b"escrow", user.key().as_ref()]). - El bump.
- El ID del programa que llama (tu programa, no el de Raydium).
authority de CPMM es su propio PDA de bóveda — una cuenta fija de todo el programa que deriva y firma a sí mismo, y que tu programa ni controla ni sustituye. La cuenta con la que tus semillas PDA tienen que alinearse es payer: la verificación ocurre dentro del ayudante transfer_from_user_to_pool_vault propio de CPMM, que requiere que la cuenta pasada como payer sea la propietaria de input_token_account.
Error común: pasar user como payer mientras escrow_input_ata es propiedad del PDA de depósito en garantía. El programa SPL Token rechaza con owner mismatch. Siempre haz que payer sea el propietario del ATA — y firma por él con new_with_signer cuando ese propietario es un PDA.
Cuentas restantes
Varias instrucciones de Raydium toman una lista de longitud variable de cuentas añadidas después de las fijas — cuentas restantes.- CLMM
SwapV2: 1–8 cuentasTickArrayStatepara los arrays de tick que el intercambio puede atravesar, en dirección de intercambio. - Farm v6
Deposit/Harvest/Withdraw: pares(reward_vault, user_reward_ata), un par por ranura de recompensa activa. - Mints de transfer-hook de Token-2022: el programa de transfer-hook más cualquier cuenta que el hook necesite.
Presupuesto de cómputo para llamadas compuestas
Un CPI cuesta ~1,500 CU por el marco de llamada en sí; el uso de CU propio del llamado se apila encima. Las figuras del llamado abajo se midieron de transacciones mainnet en vivo en pools de alto volumen el 2026-09-09, leídas de la línea de logProgram <id> consumed N of M compute units para la propia invocación del programa de Raydium (así que incluyen sus CPIs internos de programa de token):
Añade ~1,500 por cada marco CPI y la sobrecarga de tu propio programa encima. El costo de intercambio CLMM se escala con cruces de tick, así que trata su figura como un piso. Los mints de Token-2022 añaden el costo de manejo de extensión de la transferencia en sí; mídelo para tus propios mints en lugar de aplicar un multiplicador plano.
Siempre establece un
ComputeBudgetProgram::set_compute_unit_limit explícito:
Propagación de errores
Los programas de Raydium devuelven errores de Anchor con códigos de error estables. Tu programa que llama los ve comoErr(ProgramError::Custom(code)). Propágalos por defecto:
ERROR_CODE_OFFSET: las variantes #[error_code] se emiten comenzando en 6000, así que comparar contra el discriminante de enum desnudo nunca coincide. (No hay ayudante is_err en anchor-lang o en raydium_cp_swap — revisiones anteriores de esta página usaban uno que no existe.)
La asignación de código de error a significado es estable según la política de IDL (sdk-api/anchor-idl); nuevos códigos se añaden al final, códigos existentes nunca cambian de significado.
Ejemplo completo trabajado: escrow de orden limitada
Flujo:open_order— el usuario depositaamount_indeinput_minten el PDA de depósito en garantía; registramin_amount_outobjetivo y vencimiento.execute_order— cualquiera (guardián) llama con las cuentas de pool actuales. El programa verifica que la cotización actual ≥min_amount_out, luego CPI intercambia Raydium y mantiene la salida en depósito en garantía.claim— el usuario retira el mint de salida del depósito en garantía.
order firma el CPI como payer, porque posee el ATA de entrada del depósito en garantía; ExecuteOrder por lo tanto también necesita un campo pool_authority: UncheckedAccount<'info> para el PDA de bóveda propio de CPMM. Tanto la verificación de slippage del lado de Raydium como la verificación de delta del propio depósito en garantía aplican el piso — doble seguridad.
Pruebas
Extrayendo programas de Raydium en un validador local para pruebas de integración (desdeAnchor.toml):
anchor test las obtiene de mainnet al inicio. Ver sdk-api/rust-cpi.
Trampas específicas de composición
Reentrancia
Solana no tiene verdadera reentrancia — un CPI no puede llamar de vuelta al programa originador en la misma invocación. Pero aún puedes construirte en una reentrancia lógica: un CPI que lee tu estado, luego tu código lo lee de nuevo asumiendo que el CPI no lo cambió. Para Raydium, los CPIs no tocan tu estado, así que esto es menos una preocupación que p. ej. contextos de flash-loan. Pero si compones Raydium con un protocolo de préstamo, ten cuidado.Deriva de mutabilidad de cuenta
Si tu programa pasa una cuenta comomut pero Raydium la espera de solo lectura (o viceversa), el tiempo de ejecución rechaza la invocación con InvalidAccountData. Siempre verifica la mutabilidad esperada de la instrucción de Raydium en el IDL; raydium_cp_swap::cpi::accounts::Swap establece la mutabilidad de cada cuenta para ti, desde los marcadores #[account(mut)] en la estructura Swap propia de CPMM — los campos derivados son todos AccountInfo<'info> simples, así que es la implementación ToAccountMetas derivada, no los tipos de campo, la que lleva las banderas.
Campo de programa Token-2022
Los mints de entrada y salida pueden estar bajo diferentes programas de token — uno SPL Token, uno Token-2022. El CPI tiene camposinput_token_program y output_token_program separados por esta razón. Siempre verifica el campo owner de cada mint y enruta el programa correcto en cada ranura.
Transacciones versionadas
Una tx compuesta que hace 2+ CPIs de Raydium más una creación de ATA raramente cabe en una transacción heredada (v0-sin-LUT). Usa V0 con tablas de búsqueda de direcciones; extrae los LUTs públicos de Raydium a través deraydium.getRaydiumLutAddresses().
Punteros
sdk-api/rust-cpi— mecánica CPI de bajo nivel.integration-guides/priority-fee-tuning— dimensionamiento de presupuesto de cómputo.products/cpmm/code-demos,products/clmm/code-demos,products/farm-staking/code-demos— fragmentos CPI por producto.

