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 →
CPI (“cross-program invocation”) es el mecanismo mediante el cual un programa de Solana invoca a otro. La mayoría de los programas de Raydium incluyen crates de envoltura CPI basadas en Anchor que hacen que el sitio de llamada se parezca a una llamada de función tipada, con estructuras de cuenta que tienen nombres de campo validados y ayudantes
cpi::<ix>(). Esta página documenta el patrón general una sola vez, luego las diferencias por programa. Para TypeScript ejecutable, consulta la página code-demos de cada capítulo de producto.Qué patrón se aplica a cada programa
Si estás integrando CPMM, CLMM o LaunchLab, lee primero el patrón general, luego salta a la sección de tu programa para la lista de cuentas y cualquier diferencia. Farm v6 y AMM v4 son lo suficientemente diferentes como para justificar leer sus secciones de forma independiente.
Dependencias de Cargo
branch = "master" rastrea la fuente publicada más reciente; fija a un rev = "<commit>" específico si necesitas una compilación reproducible. Esto se recomienda una vez que hayas pasado la fase de prototipado, ya que un cambio de diseño de cuenta ascendente en master romperá tu compilación sin previo aviso.
La bandera de característica cpi hace que los crates se compilen solo a la superficie de CPI (estructuras de cuenta + invocadores) en lugar del programa completo, por lo que tu binario se mantiene pequeño.
anchor-lang / anchor-spl debe coincidir con lo que fija el crate de destino:
Para ejemplos de CPI funcionales que cablean las estructuras de cuenta de extremo a extremo, consulta
raydium-io/raydium-cpi-example (cubre AMM v4, CPMM y CLMM). Su rama más nueva es anchor-0.31.0 — aún no hay rama de Anchor 1.x, así que trata ese repositorio como la referencia para el cableado de estructura de cuenta, no para los pines de versión que esta página ordena.
El patrón general de CPI en Anchor
Esta sección recorre CPMM de principio a fin como ejemplo práctico: structAccounts, CpiContext, cpi::<ix>(). CLMM sigue la misma estructura, con una lista de cuentas diferente y un requisito de remaining-accounts. LaunchLab sigue la misma mecánica, pero su lista de cuentas incluye varias cuentas sin equivalente en CPMM/CLMM (global_config, platform_config, event_authority, program), así que trátalo como el mismo patrón, no la misma forma. Consulta la sección de cada programa en lugar de asumir que la lista de cuentas de este tutorial se transfiere directamente.
Construcción de la lista de cuentas
Cada CPI de Raydium requiere un structAccounts en el programa que realiza la llamada. Sus campos son las cuentas que tu instrucción necesita, con validadores a nivel de campo; el orden de su declaración no tiene que coincidir con el orden de cuentas de la instrucción de Raydium, ya que tu cliente generado por IDL las direcciona por nombre, no por posición:
UncheckedAccount porque el programa llamado (Raydium) es responsable de la validación. Tu programa que realiza la llamada solo valida estrictamente las cuentas que tú posees, como las ATAs del usuario y tus propios PDAs. El comentario de documentación /// CHECK: suprime la advertencia de Anchor sobre validaciones faltantes. La única excepción del lado de Raydium es cpmm_program en sí: es el programa que se invoca en lugar de una cuenta de datos que Raydium valida internamente, así que se tipifica como Program<T> y obtiene la verificación automática de dirección de Anchor en lugar de un /// CHECK: manual. Esta forma mayormente UncheckedAccount, donde Raydium valida sus propias cuentas, es la misma para CLMM y LaunchLab. Este ejemplo asume que ambos mints son Token SPL clásico; si cualquiera de los lados puede ser un mint Token-2022, añade un campo token_program_2022: Program<'info, anchor_spl::token_2022::Token2022> y pásalo como input_token_program/output_token_program de ese lado en la llamada CPI de abajo en lugar de token_program.
Construcción de la llamada CPI
Anchor genera un helper por instrucción, junto con un struct de cuentas CPI (cpi::accounts::Swap, aliasado como CpmmSwap abajo). A diferencia de tu struct MyProxySwap anterior, los nombres y el orden de los campos de este están fijados por el IDL propio de raydium-cp-swap y tienen que coincidir exactamente:
cpi::swap_base_input se genera a partir del IDL; su lista de argumentos refleja la lista de argumentos de la instrucción de Anchor. Cada programa de Raydium basado en Anchor confirmado (CPMM, CLMM, LaunchLab) genera sus helpers cpi::<ix>() de la misma manera, con el nombre de la función coincidiendo con el nombre de la instrucción en snake_case. Si esto se extiende a Farm v6 no está confirmado; consulta su sección.
Signer seeds (CPI firmado por PDA)
Cuando tu programa firma el CPI en nombre de un PDA (común para bóvedas, depósitos en garantía, etc.), usaCpiContext::new_with_signer:
authority (o rol de firmante similar), el runtime de Solana verifica que el PDA firme a través de estos seeds.
Remaining accounts
Algunas instrucciones de Raydium toman remaining accounts, una lista de longitud variable añadida después de las cuentas fijas. Los helpers CPI de Anchor no verifican el tipo de remaining accounts; pásalos a través de.with_remaining_accounts(...):
- CLMM
SwapV2: tick arrays, ordenados direccionalmente. - Farm v6: pares
(reward_vault, user_reward_ata), pero solo a partir del segundo flujo de recompensas en adelante; consulta Farm v6 para ver qué muestra la decodificación de una transacción real.
Aplicar el patrón: CLMM
SwapV2 sigue el patrón general anterior con una lista de cuentas diferente y un requisito de remaining-accounts para tick arrays. El módulo #[program] del crate se llama raydium_clmm, que también es su ruta de use en Rust.
TickArrayNotFound (consulta products/clmm/instructions para la tabla de cuentas completa y la lista de errores). Pásalos en la dirección del recorrido de precios: primer array en dirección de swap primero.
Aplicar el patrón: LaunchLab
LaunchLab está basado en Anchor e IDL publicado:raydium_launchpad/raydium_launchpad.json en el repositorio público raydium-idl. El identificador de metadatos interno de ese IDL es raydium_launchpad, un nombre técnico para el programa subyacente, no un nombre alternativo para el producto. A diferencia de CPMM y CLMM, sin embargo, el código fuente del programa no está disponible públicamente (ver reference/program-addresses). No hay una dependencia git = "..." a la que apuntar con Cargo, ni código fuente para confirmar cuál sería la ruta use real de Rust en un crate.
Genera bindings desde el IDL publicado usando la macro declare_program! de Anchor. Guarda el JSON del IDL como idls/raydium_launchpad.json en tu crate (Cargo busca un directorio idls/ relativo a CARGO_MANIFEST_DIR), luego declare_program!(raydium_launchpad); genera structs raydium_launchpad::cpi::accounts::<Ix> y funciones cpi::<ix>() directamente desde el IDL, sin necesidad del código fuente del programa. El nombre del struct de cuentas generado siempre es el nombre de la instrucción en PascalCase (buy_exact_in → BuyExactIn), y los nombres de los campos coinciden exactamente con los nombres de las cuentas del IDL, la misma lista de cuentas ya utilizada en MyProxyBuy a continuación.
La forma del CPI sigue el patrón general. La lista de cuentas y los argumentos a continuación provienen de la instrucción buy_exact_in del IDL en cadena, no de products/launchlab/instructions.mdx:
pool_state.migrate_type, que según products/launchlab/accounts.mdx se establece en el momento de Initialize. Tu lista de cuentas CPI tiene que estar preparada para cualquiera de los dos, o necesitas leer migrate_type de PoolState primero y ramificarte.
Propagación de errores
Cada programa Raydium basado en Anchor devuelve su propio enum de error; Anchor los envuelve, por lo que tu programa llamador los ve comoErr(ProgramError::Custom(code)). Para manejar errores específicos:
raydium_clmm::error::ErrorCode para CLMM, y así sucesivamente). Los números de código de error son estables según la política del IDL (sdk-api/anchor-idl), por lo que puedes probar contra códigos específicos comparando contra el valor numérico. Tablas de errores completas: CPMM, CLMM, AMM v4, Farm v6, y LaunchLab.
Presupuesto de cómputo en CPIs compuestos
Cada frame de CPI tiene sobrecarga, y el consumo de CU propio del programa llamado se suma al tuyo, por lo que una transacción que llama a Raydium desde dentro de tu programa necesita un presupuesto de cómputo explícito en lugar de depender del default de 200k CU.Medido, no estimado. Un
swap_base_input de CPMM en mainnet consume ~23,000 CU en el programa CPMM mismo — muestreado el 2026-09-09 en ocho swaps en vivo en un pool de alto volumen (22,721–23,052), leído de la línea de log Program CPMMoo8… consumed N of M compute units. Para comparación: swap de AMM v4 ~26,000; swap de CLMM ~41,000; swap_v2 de CLMM ~48,000 (43,838–52,887), aumentando con cada cruce de tick.Una revisión anterior de esta página reportaba ~47,700 CU para un CPI de proxy-swap. Esa cifra era la transacción completa (computeUnitsConsumed), que incluye tu propio programa, el frame de CPI y cualquier configuración de ATA — no el costo del programa llamado. Ambos son útiles, pero no son el mismo número, así que compara lo similar con lo similar. Mide tu propia transacción en lugar de presupuestar basándote en ninguno de los dos.remaining_accounts, agregando CU por array), pero solo la cifra de CPMM anterior es un valor medido. Siempre establece un límite explícito ComputeBudgetProgram::set_compute_unit_limit(...) dimensionado a partir de tu propia medición, no un número copiado de la documentación, ya que el límite default de 200k CU se agotará silenciosamente y los costos por instrucción cambian a medida que los programas se actualizan.
AMM v4: construcción manual de Instruction
AMM v4 es anterior a Anchor y no tiene un crate de CPI, lo que lo convierte en el único programa en este documento que no sigue el patrón general anterior. Construye laInstruction manualmente:
products/amm-v4/code-demos para la lista completa de cuentas.
Farm v6
Usa el SDK de TS si esa es una opción para tu integración.raydium.farm.deposit(...) (ver products/farm-staking/code-demos) está ejercitado por demos reales y no depende de si existe un crate Anchor de Rust para este programa.
Si necesitas CPI de Rust de todas formas, por ejemplo componiendo desde otro programa en cadena, construye la Instruction manualmente, de la misma manera que AMM v4: deriva la lista de cuentas real y los discriminadores de instrucción de forma independiente, por ejemplo decodificando los layouts de TypeScript del SDK (raydium-sdk-V2’s farm module), decodificando transacciones reales directamente (ver a continuación), o volcando y desensambland el programa desplegado.
Para la forma de instrucción de cero argumentos consistente con una llamada de harvest o claim, el orden de cuentas real es un prefijo fijo (token_program, la cuenta de estado del farm, un PDA de autoridad de bóveda, la primera bóveda de recompensas de ese PDA, un segundo PDA, el llamador, y el ATA del llamador para ese primer mint de recompensa), seguido de pares (reward_vault_i, user_reward_ata_i) en remaining_accounts para cada stream de recompensa después del primero. La convención de emparejamiento es real, pero solo comienza en el segundo stream de recompensa: la bóveda y ATA del primer stream son cuentas fijas, no adyacentes entre sí, y no son parte de remaining_accounts en absoluto.
Prueba de un flujo CPI
El desarrollo local requiere que los programas de Raydium estén disponibles en tu validador de prueba. Tienes tres opciones:anchor testcon clonación de programa. Extrae el bytecode desplegado en mainnet hacia tu validador local; consulta Clonación de programas en un validador local más abajo para la configuración deAnchor.tomly dos cosas que suelen causar problemas en las pruebas de creación de pools.- Devnet. Raydium despliega la mayoría de programas en devnet, pero con IDs de programa diferentes a los de mainnet para cada uno (CPMM, CLMM, AMM v4, Stable AMM y LaunchLab tienen direcciones distintas en devnet; consulta la tabla de Devnet en
reference/program-addresses). Farm v3/v5/v6 no se publican de forma confiable en devnet; la API en vivo (https://api-v3-devnet.raydium.io/main/info) tiene la información actual. Si usas las constantesDEVNET_PROGRAM_IDincluidas enraydium_clmm(o equivalentes en otros crates), no asumas que un ID de mainnet también funciona en devnet. Ejecutaanchor test --provider.cluster devnetpara probar el código en vivo una vez que tengas las direcciones correctas. - Despliegue local. Clona los repositorios de Raydium (CPMM, CLMM; el código fuente de LaunchLab no está disponible para esta opción) y ejecuta
anchor deployen un validador local. Añade sobrecarga al ciclo de prueba pero te permite modificar el programa llamado para depuración.
anchor test, o primero anchor build y luego anchor test --skip-build si estás iterando sobre el archivo de prueba sin cambiar el programa.
Clonación de programas en un validador local
reference/program-addresses es la fuente de verdad para cada dirección aquí.
Referencias
products/cpmm/code-demos,products/clmm/code-demos,products/amm-v4/code-demos,products/farm-staking/code-demos,products/launchlab/code-demos: ejemplos de CPI y TypeScript específicos del producto.sdk-api/anchor-idl: recuperación de IDL y regeneración de cliente, incluyendo la ruta de codegen de IDL para LaunchLab.integration-guides/cpi-integration: patrones de integración de nivel superior como depósitos en garantía, bóvedas y composición de agregadores.
- raydium-cp-swap
- raydium-clmm
- raydium-idl: IDL de LaunchLab (el código fuente del programa en sí es cerrado)
- Documentación de CPI de Anchor

