Skip to main content
Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.Ver versão em inglês →
Banner de versão. Todos os demos TypeScript visam @raydium-io/raydium-sdk-v2@0.2.64-alpha; foram executados pela última vez contra 0.2.42-alpha (2026-04) e suas assinaturas de chamada foram verificadas novamente contra a fonte 0.2.64-alpha em 2026-09-09, contra Solana mainnet-beta. O esqueleto Rust CPI no final visa raydium-clmm no branch chore/upgrade-anchor, Anchor 1.0.2, o mesmo pin da página CPMM, para que os dois possam conviver em um crate. master ainda fixa 0.32.1. Os IDs de programa vêm de reference/program-addresses via o SDK.

Configuração

Cada demo nesta página espelha um arquivo em raydium-sdk-V2-demo/src/clmm; o link do GitHub fica ao lado de cada seção. O bootstrap segue o config.ts.template do repositório de demo (fonte) — disableFeatureCheck: true é a configuração recomendada para qualquer integração não trivial:

Criar um pool CLMM

Fonte: src/clmm/createPool.ts
O SDK:
  • Ordena mint1/mint2 por ordem de bytes antes da derivação.
  • Calcula sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64).
  • Cria as contas observation e tick_array_bitmap_extension.
  • Paga a taxa de criação do pool definida por ammConfig.

Abrir uma posição em um intervalo escolhido

Fonte: src/clmm/createPosition.ts
O SDK calcula quais arrays de tick o intervalo toca e os passa como contas. Não precisa agrupar nenhuma instrução init — não há instrução init-tick-array; OpenPosition* aloca um array de tick ausente por si só, à custa do pagador.

Aumentar liquidez em uma posição existente

Fonte: src/clmm/increaseLiquidity.ts

Diminuir liquidez (e coletar taxas ao mesmo tempo)

Fonte: src/clmm/decreaseLiquidity.ts e src/clmm/closePosition.ts
Para coletar apenas taxas e recompensas, chame decreaseLiquidity com liquidity = new BN(0). O efeito colateral da instrução é liquidar token_fees_owed_{0,1} e reward_amount_owed e transferi-los — esta é a única forma de coletar qualquer um deles. Para fechar a posição inteiramente após zerar liquidez e taxas, passe ownerInfo: { closePosition: true } na chamada final de decreaseLiquidity. O SDK anexa ClosePosition e queima o NFT.
Posições de emissor restrito requerem um construtor de fechamento compatível. Essas posições têm uma conta de token NFT congelada. ClosePosition deve anexar o ID do pool da posição como a primeira conta restante para que CLMM possa descongelar a conta antes de queimá-la. O branch de fonte do programa não inclui uma mudança de SDK. Confirme que sua versão do SDK suporta explicitamente o caminho de fechamento congelado antes de ativar a criação de posição de emissor restrito.
Para um cliente Anchor direto, mantenha as contas declaradas inalteradas e anexe o pool:
Você pode passar poolId em cada fechamento. CLMM o lê apenas quando positionNftAccount está congelada, o que mantém um caminho de cliente compatível com posições antigas e novas.

Coletar recompensa(s)

Fonte: src/clmm/harvestAllRewards.ts
harvestAllRewards percorre cada posição em cada pool passado, agrupa as chamadas DecreaseLiquidity de liquidez zero que liquidam taxas e recompensas (mais qualquer UpdateRewardInfos), e as divide entre transações se necessário.

Swap

Fonte: src/clmm/swap.ts
A simulação percorre o mapa de tick off-chain com a mesma lógica do programa on-chain e retorna a quantidade de saída (amountCalculated) mais a lista exata de contas que o swap tocará (accounts). Sempre passe o remainingAccounts que a simulação retorna: muito poucos e o swap reverte no meio da caminhada com NotEnoughTickArrayAccount; os obsoletos apenas desperdiçam computação.
PoolUtils.computeAmountOutFormat ainda existe, mas precisa de um ComputeClmmPoolInfo (o computePoolInfo de getPoolInfoFromRpc, não um objeto de pool de API) mais dois argumentos obrigatórios — tickarrayBitmapExtension e blockTimestamp — e não há método raydium.clmm.fetchTickArrays (fetchTickArrays é uma função livre; os helpers de nível de módulo são PoolUtils.fetchMultiplePoolTickArrays e o tickData / tickArrays retornados por getPoolInfoFromRpc).

Criar um pool CLMM personalizável

createCustomizablePool é o ponto de entrada que expõe os toggles de taxa dinâmica e taxa unilateral no momento da criação do pool. Leva a forma de createPool mais duas adições:
Não há flag enableDynamicFee e nenhum parâmetro dynamicFeeConfigId, e nenhum startTime. Fornecer dynamicFeeConfig é o que ativa taxas dinâmicas — omita e você obtém um pool de taxa estática, silenciosamente e sem erro. Note também que os membros do enum do SDK são TokenOnlyA / TokenOnlyB, enquanto o enum Rust on-chain os soletra Token0Only / Token1Only; os valores numéricos correspondem (FromInput = 0).
createPool continua funcionando para o caminho padrão de taxa, sem taxa dinâmica. Use createCustomizablePool sempre que precisar de qualquer um dos controles. Veja products/clmm/instructions para a lista de contas on-chain.

Ordens limitadas

Uma ordem limitada estaciona entrada do usuário em um único tick e é preenchida FIFO quando um swap cruza esse tick. As saídas são enviadas para o ATA do proprietário no momento da liquidação; o proprietário não precisa estar online para ser preenchido.

Abrir uma ordem limitada

O SDK deriva o PDA LimitOrderState de (owner, nonce PDA, order nonce), incrementa o LimitOrderNonce por carteira, e insere a ordem na coorte FIFO naquele tick.

Aumentar / diminuir uma ordem aberta

decreaseLimitOrder só pode remover da porção não preenchida da ordem; a porção preenchida fica bloqueada até a liquidação. Ambas as instruções revertem com InvalidOrderPhase se a ordem já foi totalmente preenchida.

Liquidar uma ordem preenchida

settleLimitOrder lê o unfilled_ratio_x64 da ordem contra o rastreador de coorte, calcula a saída preenchida e a transfere para o ATA do proprietário. O proprietário pode chamar isso por si mesmo; limit_order_admin (um mantenedor operacional off-chain) também pode chamar em nome do proprietário — a saída ainda vai para o proprietário. Para fechar ordens totalmente liquidadas para recuperar aluguel, use closeLimitOrder (única) ou closeAllLimitOrder (lote). Para liquidar muitas de uma vez, settleAllLimitOrder empacota quantas chamadas SettleLimitOrder couberem em uma tx v0.

Listar ordens estacionadas de uma carteira (off-chain)

O endpoint de ordens ativas retorna ordens não preenchidas e parcialmente preenchidas em um payload (totalAmount / filledAmount / pendingSettle distinguem as fases). Para histórico de ordem fechada use /limit-order/history/order/list-by-user?wallet=… (por carteira, paginado por nextPageId); para o log de eventos completo de uma ordem específica use /limit-order/history/event/list-by-pda?pda=….

Esqueleto Rust CPI

Ordem de conta restante para SwapV2:
Se o swap nunca precisar da extensão, omita-a; caso contrário, ela é a primeira conta restante.

Armadilhas comuns

  • Endpoints de tick fora do espaçamento → TickAndSpacingNotMatch. Sempre encaixe via TickUtil.getPriceAndTick (singular TickUtil).
  • Não há arrays de tick suficientes fornecidos em SwapV2 → NotEnoughTickArrayAccount. Pegue a lista de swapInternal(...).accounts.
  • Posição de intervalo completo sem a extensão de bitmap → o PDA de extensão deve ser gravável; o SDK lida com isso automaticamente.
  • Confundir sqrt_price_x64 com price → uma confusão de fator-2 aqui é particularmente dolorosa. Em caso de dúvida, deixe o SDK calculá-lo a partir de um preço legível por humanos.
  • Coletar recompensas muito cedo → cada coleta é um DecreaseLiquidity de liquidez zero e custa uma transação. Agrupe via harvestAllRewards em muitas posições, e lembre-se que seu execute precisa de { sequentially: true }.
  • Fechar contas NFT você mesmo → ClosePosition queima o NFT e fecha seu ATA. Também fecha um mint de NFT Token-2022; um mint de Token SPL clássico permanece com suprimento zero porque esse programa não pode fechar mints. Não feche contas suportadas separadamente ou a instrução reverterá.
  • Abrir uma ordem limitada em um tick não espaçado → TickAndSpacingNotMatch. Sempre quantize via o helper getOrderTick exportado.
  • Chamar decreaseLimitOrder em uma ordem totalmente preenchida → InvalidOrderPhase. Use settleLimitOrder depois closeLimitOrder.
  • Esperando uma flag enableDynamicFee → não há nenhuma. Omitir dynamicFeeConfig simplesmente cria um pool de taxa estática, silenciosamente e sem erro. Se você queria taxas dinâmicas, passe a PublicKey da conta de configuração, escolhida de /main/clmm-dynamic-config.

Para onde ir a seguir

Fontes: