Skip to main content
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 →
Banner de versión. Todos los demostraciones de TypeScript apuntan a @raydium-io/raydium-sdk-v2@0.2.64-alpha; se ejecutaron por última vez contra 0.2.42-alpha (2026-04) y sus firmas de llamada se verificaron nuevamente contra la fuente 0.2.64-alpha el 2026-09-09, contra Solana mainnet-beta. El esqueleto de CPI en Rust al final apunta a raydium-clmm en master, que fija Anchor =0.32.1 — no el 1.0.2 que usa la página CPMM; los dos no pueden coexistir en un crate. Los ID de programa provienen de reference/program-addresses a través del SDK.

Configuración

Cada demostración en esta página refleja un archivo en raydium-sdk-V2-demo/src/clmm; el enlace de GitHub se encuentra junto a cada sección. El arranque sigue el config.ts.template del repositorio de demostración (fuente) — disableFeatureCheck: true es la configuración recomendada para cualquier integración no trivial:

Crear un pool CLMM

Fuente: src/clmm/createPool.ts
El SDK:
  • Ordena mint1/mint2 por orden de bytes antes de la derivación.
  • Calcula sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Crea las cuentas observation y tick_array_bitmap_extension.
  • Paga la comisión de creación del pool definida por ammConfig.

Abrir una posición en un rango elegido

Fuente: src/clmm/createPosition.ts
El SDK calcula qué arrays de tick toca el rango y los pasa como cuentas. No necesita agrupar ninguna instrucción de inicialización — no hay instrucción de inicialización de array de tick; OpenPosition* asigna un array de tick faltante por sí solo, a expensas del pagador.

Aumentar liquidez en una posición existente

Fuente: src/clmm/increaseLiquidity.ts

Disminuir liquidez (y cobrar comisiones al mismo tiempo)

Fuente: src/clmm/decreaseLiquidity.ts y src/clmm/closePosition.ts
Para cobrar solo comisiones y recompensas, llama a decreaseLiquidity con liquidity = new BN(0). El efecto secundario de la instrucción es liquidar token_fees_owed_{0,1} y reward_amount_owed y transferirlos — esta es la única forma de cobrar cualquiera de ellos. Para cerrar la posición completamente después de poner la liquidez y comisiones en cero, pasa ownerInfo: { closePosition: true } en la llamada final a decreaseLiquidity. El SDK añade ClosePosition y quema el NFT.
Las posiciones de emisor restringido requieren un constructor de cierre compatible. Estas posiciones tienen una cuenta de token NFT congelada. ClosePosition debe añadir el ID del pool de la posición como la primera cuenta restante para que CLMM pueda descongelar la cuenta antes de quemarla. La rama de fuente del programa no incluye un cambio de SDK. Confirma que tu versión de SDK soporta explícitamente la ruta de cierre congelado antes de habilitar la creación de posiciones de emisor restringido.
Para un cliente Anchor directo, mantén las cuentas declaradas sin cambios y añade el pool:
Puedes pasar poolId en cada cierre. CLMM lo lee solo cuando positionNftAccount está congelada, lo que mantiene una ruta de cliente compatible con posiciones antiguas y nuevas.

Cobrar recompensa(s)

Fuente: src/clmm/harvestAllRewards.ts
harvestAllRewards recorre cada posición en cada pool pasado, agrupa las llamadas DecreaseLiquidity de liquidez cero que liquidan comisiones y recompensas (más cualquier UpdateRewardInfos), y las divide entre transacciones si es necesario.

Swap

Fuente: src/clmm/swap.ts
La simulación recorre el mapa de tick fuera de la cadena con la misma lógica que el programa en la cadena y devuelve la cantidad de salida (amountCalculated) más la lista exacta de cuentas que el swap tocará (accounts). Siempre pasa los remainingAccounts que devuelve la simulación: muy pocos y el swap se revierte a mitad de camino con NotEnoughTickArrayAccount; los obsoletos simplemente desperdician cómputo.
PoolUtils.computeAmountOutFormat aún existe, pero necesita un ComputeClmmPoolInfo (el computePoolInfo de getPoolInfoFromRpc, no un objeto de pool de API) más dos argumentos requeridos más — tickarrayBitmapExtension y blockTimestamp — y no hay método raydium.clmm.fetchTickArrays (fetchTickArrays es una función libre; los ayudantes a nivel de módulo son PoolUtils.fetchMultiplePoolTickArrays y el tickData / tickArrays devueltos por getPoolInfoFromRpc).

Crear un pool CLMM personalizable

createCustomizablePool es el punto de entrada que expone los toggles de comisión dinámica y comisión de un solo lado en el momento de la creación del pool. Toma la forma de createPool más dos adiciones:
No hay bandera enableDynamicFee ni parámetro dynamicFeeConfigId, y no hay startTime. Suministrar dynamicFeeConfig es lo que habilita comisiones dinámicas — omítelo y obtendrás un pool de comisión estática, sin error. Ten en cuenta también que los miembros del enum del SDK son TokenOnlyA / TokenOnlyB, mientras que el enum Rust en la cadena los deletrea Token0Only / Token1Only; los valores numéricos coinciden (FromInput = 0).
createPool continúa funcionando para la ruta de comisión predeterminada, sin comisión dinámica. Usa createCustomizablePool siempre que necesites cualquiera de los dos controles. Ver products/clmm/instructions para la lista de cuentas en la cadena.

Órdenes limitadas

Una orden limitada estaciona la entrada del usuario en un único tick y se completa FIFO cuando un swap cruza ese tick. Las salidas se envían al ATA del propietario en el momento de la liquidación; el propietario no necesita estar en línea para ser completado.

Abrir una orden limitada

El SDK deriva el PDA LimitOrderState de (owner, nonce PDA, order nonce), incrementa el LimitOrderNonce por billetera, e inserta la orden en la cohorte FIFO en ese tick.

Aumentar / disminuir una orden abierta

decreaseLimitOrder solo puede eliminar de la porción no completada de la orden; la porción completada está bloqueada hasta la liquidación. Ambas instrucciones se revierten con InvalidOrderPhase si la orden ya ha sido completada totalmente.

Liquidar una orden completada

settleLimitOrder lee el unfilled_ratio_x64 de la orden contra el rastreador de cohorte, calcula la salida completada, y la transfiere al ATA del propietario. El propietario puede llamar a esto por sí mismo; limit_order_admin (un guardián operacional fuera de la cadena) también puede llamarlo en nombre del propietario — la salida aún va al propietario. Para cerrar órdenes completadas totalmente para recuperar renta, usa closeLimitOrder (individual) o closeAllLimitOrder (lote). Para liquidar muchas a la vez, settleAllLimitOrder empaqueta tantas llamadas SettleLimitOrder como quepan en una tx v0.

Listar órdenes estacionadas de una billetera (fuera de la cadena)

El endpoint de órdenes activas devuelve órdenes no completadas y parcialmente completadas en un solo payload (totalAmount / filledAmount / pendingSettle distinguen las fases). Para historial de órdenes cerradas usa /limit-order/history/order/list-by-user?wallet=… (por billetera, paginado por nextPageId); para el registro de eventos completo de una orden específica usa /limit-order/history/event/list-by-pda?pda=….

Esqueleto de CPI en Rust

Orden de cuenta restante para SwapV2:
Si el swap nunca necesita la extensión, omítela; de lo contrario, es la primera cuenta restante.

Errores comunes

  • Endpoints de tick fuera de espaciado → TickAndSpacingNotMatch. Siempre ajusta vía TickUtil.getPriceAndTick (singular TickUtil).
  • No hay suficientes arrays de tick suministrados en SwapV2 → NotEnoughTickArrayAccount. Toma la lista de swapInternal(...).accounts.
  • Posición de rango completo sin la extensión de bitmap → el PDA de extensión debe ser escribible; el SDK lo maneja automáticamente.
  • Confundir sqrt_price_x64 con price → una confusión de factor-2 aquí es particularmente dolorosa. Cuando dudes, deja que el SDK lo calcule desde un precio legible por humanos.
  • Cobrar recompensas demasiado ansiosamente → cada cobro es un DecreaseLiquidity de liquidez cero y cuesta una transacción. Agrupa vía harvestAllRewards entre muchas posiciones, y recuerda que su execute necesita { sequentially: true }.
  • Cerrar cuentas NFT por ti mismo → ClosePosition quema el NFT y cierra su ATA. También cierra un mint de NFT Token-2022; un mint de Token SPL clásico permanece en suministro cero porque ese programa no puede cerrar mints. No cierres cuentas soportadas por separado o la instrucción se revertirá.
  • Abrir una orden limitada en un tick no espaciado → TickAndSpacingNotMatch. Siempre cuantiza vía el ayudante exportado getOrderTick.
  • Llamar a decreaseLimitOrder en una orden completada totalmente → InvalidOrderPhase. Usa settleLimitOrder luego closeLimitOrder en su lugar.
  • Esperando una bandera enableDynamicFee → no hay ninguna. Omitir dynamicFeeConfig simplemente crea un pool de comisión estática, silenciosamente y sin error. Si querías comisiones dinámicas, pasa el PublicKey de la cuenta de configuración, elegido de /main/clmm-dynamic-config.

Dónde ir a continuación

Fuentes: