Banner de versão. Todas as demos em TypeScript têm como alvo
@raydium-io/raydium-sdk-v2@0.2.64-alpha; elas foram executadas pela última vez com 0.2.42-alpha (2026-04), e as assinaturas de chamada foram verificadas novamente contra o código-fonte de 0.2.64-alpha em 2026-09-09, na mainnet-beta da Solana. O esqueleto de CPI em Rust no final tem como alvo raydium-clmm na branch master, com Anchor 1.0.2, a mesma versão fixada da página do CPMM, para que as duas possam coexistir no mesmo crate. Os IDs dos programas vêm de reference/program-addresses por meio do SDK.Configuração
raydium-sdk-V2-demo/src/clmm; o link do GitHub fica ao lado de cada seção. A inicialização segue o config.ts.template do repositório de demos (fonte). Para qualquer integração não trivial, recomenda-se disableFeatureCheck: true:
Criar um pool CLMM
Fonte:src/clmm/createPool.ts
- Ordena
mint1/mint2pela ordem dos bytes antes da derivação. - Calcula
sqrt_price_x64 = floor(sqrt(initialPrice × 10^(dB−dA)) × 2^64). - Cria as contas
observationetick_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
OpenPosition* aloca sozinha um tick array que esteja faltando, às custas do pagador.
Aumentar a liquidez de uma posição existente
Fonte:src/clmm/increaseLiquidity.ts
Reduzir a liquidez (e coletar taxas ao mesmo tempo)
Fonte:src/clmm/decreaseLiquidity.ts e src/clmm/closePosition.ts
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 para fora — esta é a única forma de coletar qualquer um dos dois.
Para fechar a posição por completo depois de zerar a liquidez e as taxas, passe ownerInfo: { closePosition: true } na última chamada de decreaseLiquidity. O SDK adiciona ClosePosition e queima o NFT.
Para um cliente Anchor direto, mantenha as contas declaradas inalteradas e anexe o pool:
poolId em todo fechamento. A CLMM só o lê quando positionNftAccount estiver congelada, o que mantém um único caminho no cliente compatível com posições antigas e novas.
Coletar recompensa(s)
Fonte:src/clmm/harvestAllRewards.ts
harvestAllRewards percorre cada posição de cada pool recebido, agrupa as chamadas DecreaseLiquidity de liquidez zero que liquidam taxas e recompensas (além de eventuais UpdateRewardInfos) e as divide entre transações quando necessário.
Swap
Fonte:src/clmm/swap.ts
Este exemplo espelha src/clmm/swap.ts, que simula a operação com swapInternal em vez de PoolUtils.computeAmountOutFormat.
amountCalculated) junto com a lista exata de contas que a swap vai acessar (accounts).
Sempre passe o remainingAccounts retornado pela simulação: se faltarem contas, a swap é revertida no meio do percurso com NotEnoughTickArrayAccount; se forem contas desatualizadas, você só desperdiça compute.
PoolUtils.computeAmountOutFormat ainda existe, mas exige um ComputeClmmPoolInfo (o
computePoolInfo retornado por getPoolInfoFromRpc, e não um objeto de pool da API), além de dois
argumentos obrigatórios a mais — tickarrayBitmapExtension e blockTimestamp. Além disso, não existe
o método raydium.clmm.fetchTickArrays (fetchTickArrays é uma função independente; os auxiliares
no nível do 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 as opções de taxa dinâmica e de taxa de lado único no momento da criação do pool. Ele recebe a mesma estrutura de createPool, com dois campos adicionais:
createPool continua funcionando para o caminho de taxa padrão, sem taxa dinâmica. Use createCustomizablePool sempre que precisar de qualquer uma dessas opções. Para a lista de contas on-chain, consulte /pt/products/clmm/instructions.
Ordens limitadas
Uma ordem limitada deposita o valor do usuário em um único tick e é preenchida em FIFO quando uma swap atravessa esse tick. Os valores de saída são enviados para o ATA do dono no momento da liquidação; o dono não precisa estar online para que a ordem seja preenchida.Abrir uma ordem limitada
Não existe uma conta de configuração de ordens limitadas por pool, nem um auxiliargetClmmLimitOrderConfigs() — as ordens são identificadas pelo tick.
LimitOrderState a partir de (owner, nonce PDA, order nonce), incrementa o LimitOrderNonce da carteira e insere a ordem na coorte FIFO daquele tick.
Aumentar / reduzir uma ordem aberta
decreaseLimitOrder só pode remover a parte não preenchida da ordem; a parte preenchida fica bloqueada até a liquidação. Ambas as instruções são revertidas com InvalidOrderPhase se a ordem já tiver sido totalmente preenchida.
Liquidar uma ordem preenchida
settleLimitOrder lê o unfilled_ratio_x64 da ordem em relação ao rastreador da coorte, calcula a saída preenchida e a transfere para o ATA do dono. O próprio dono pode chamar essa função; o limit_order_admin (um keeper operacional off-chain) também pode chamá-la em nome do dono — a saída continua indo para o dono.
Para fechar ordens totalmente liquidadas e recuperar o rent, use closeLimitOrder (uma por vez) ou closeAllLimitOrder (em lote). Para liquidar várias ordens de uma vez, settleAllLimitOrder agrupa quantas chamadas de SettleLimitOrder couberem em uma transação v0.
Listar as ordens ativas de uma carteira (off-chain)
totalAmount / filledAmount / pendingSettle distinguem as fases). Para o histórico de ordens fechadas, use /limit-order/history/order/list-by-user?wallet=… (por carteira, paginado por nextPageId); para o log completo de eventos de uma ordem específica, use /limit-order/history/event/list-by-pda?pda=….
Esqueleto de CPI em Rust
remaining accounts) para SwapV2:
Armadilhas comuns
- Extremos de tick fora do espaçamento →
TickAndSpacingNotMatch. Sempre ajuste os valores comTickUtil.getPriceAndTick(no singular,TickUtil). - Não fornecer tick arrays suficientes no
SwapV2→NotEnoughTickArrayAccount. Obtenha a lista a partir deswapInternal(...).accounts. - Posição de faixa total sem a extensão do bitmap → a PDA da extensão precisa ser gravável; o SDK faz isso automaticamente.
- Confundir
sqrt_price_x64comprice→ um erro de fator 2 aqui é especialmente problemático. Na dúvida, deixe o SDK calcular o valor a partir de um preço legível. - Coletar recompensas com frequência excessiva → cada coleta é um
DecreaseLiquiditycom liquidez zero e custa uma transação. Agrupe as coletas comharvestAllRewardsem várias posições e lembre-se de que oexecutedela precisa de{ sequentially: true }. - Fechar as contas de NFT manualmente →
ClosePositionqueima o NFT e fecha seu ATA. Ele também fecha um mint de NFT Token-2022; já um mint do SPL Token clássico permanece com supply zero, pois esse programa não consegue fechar mints. Não feche as contas suportadas separadamente, ou a instrução será revertida. - Abrir uma ordem limite em um tick fora do espaçamento →
TickAndSpacingNotMatch. Sempre quantize o valor com o helper exportadogetOrderTick. - Chamar
decreaseLimitOrderem uma ordem totalmente preenchida →InvalidOrderPhase. UsesettleLimitOrdere, em seguida,closeLimitOrder. - Esperar uma flag
enableDynamicFee→ ela não existe. OmitirdynamicFeeConfigsimplesmente cria um pool de taxa estática, sem aviso e sem erro. Se você quiser taxas dinâmicas, passe oPublicKeyda conta de configuração, escolhido em/pt/main/clmm-dynamic-config.
Próximos passos
sdk-api/typescript-sdk— superfície completa do SDK.sdk-api/rest-api— endpoints de cotação e metadados de pools.user-flows/create-clmm-pool— passo a passo sem código.integration-guides/aggregator— roteamento de CLMM como parte de um caminho de swap.

