> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Demonstrações de código do Stable AMM

> Como identificar um pool Stable AMM pela API, fazer swap através dele via o módulo Liquidity (que lida nativamente com pools version=5), e usar os helpers off-chain da curva estável.

<Info>
  **Esta página foi traduzida automaticamente por IA. A versão em inglês é a fonte oficial.**

  [Ver versão em inglês →](/products/stable/code-demos)
</Info>

<Info>
  **Banner de versão.**

  * SDK: `@raydium-io/raydium-sdk-v2@0.2.42-alpha`
  * Cluster: Solana `mainnet-beta`
  * ID do programa Stable AMM: `5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h` (veja [`reference/program-addresses`](/pt/reference/program-addresses))
  * Última verificação: 2026-04

  O módulo `liquidity` do SDK lida nativamente com pools Stable AMM. Pools estáveis aparecem como **`version: 5`** (ou `pooltype: "StablePool"`) em `ApiV3PoolInfoStandardItem`; os mesmos helpers `addLiquidity` / `removeLiquidity` / swap funcionam para eles como para pools de produto constante AMM v4 (`version: 4`) — o SDK detecta a variante e emite as instruções corretas automaticamente. A matemática off-chain da curva estável fica em `src/raydium/liquidity/stable.ts`.
</Info>

## Configuração

```bash theme={null}
npm install @raydium-io/raydium-sdk-v2 @solana/web3.js @solana/spl-token
```

```ts theme={null}
import { Raydium, TxVersion } from "@raydium-io/raydium-sdk-v2";
import { Connection, Keypair, clusterApiUrl } from "@solana/web3.js";
import BN from "bn.js";
import bs58 from "bs58";

const connection = new Connection(clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(bs58.decode(process.env.PRIVATE_KEY!));

const raydium = await Raydium.load({
  connection,
  owner,
  cluster: "mainnet",
  // Opcional: carregue o layout do modelo de curva estável se você pretender chamar
  // helpers de quoting de `liquidity/stable.ts` diretamente. Swap / add / remove
  // no nível do pool fazem isso de forma lazy para você, então a maioria dos
  // chamadores pode pular esta etapa.
});

// Uma única vez: pré-busque o layout de dados do modelo on-chain usado pelos
// helpers off-chain da curva estável. Necessário apenas se você chamar getStablePrice /
// getDxByDyBaseIn / getDyByDxBaseIn diretamente. addLiquidity / removeLiquidity / swap
// não precisam disso.
await raydium.liquidity.initLayout();
```

## Identificando um pool Stable

Dois sinais equivalentes em `ApiV3PoolInfoStandardItem`:

```ts theme={null}
const isStable =
  pool.version === 5 ||
  pool.pooltype.includes("StablePool"); // o SDK usa essa verificação de string internamente

// Alternativamente, por ID do programa:
const STABLE_AMM_PROGRAM_ID = "5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h";
const isStableByProgram = pool.programId === STABLE_AMM_PROGRAM_ID;
```

Tanto AMM v4 (`version: 4`, produto constante) quanto Stable AMM (`version: 5`) fluem através da mesma API `LiquidityModule` no SDK. Internamente o módulo despacha para:

* `InstructionType.AmmV4AddLiquidity` / `AmmV4RemoveLiquidity` para pools v4
* `InstructionType.AmmV5AddLiquidity` / `AmmV5RemoveLiquidity` para pools v5 (Stable)

O `programId` do pool (retornado com as chaves do pool) diz ao SDK qual programa fazer CPI; você não precisa codificá-lo.

## Encontrar um pool por par de mints

```ts theme={null}
import { PublicKey } from "@solana/web3.js";

// Dois mints comuns para usar como exemplo
const mintA = new PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); // USDT
const mintB = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // USDC

const pools = await raydium.api.fetchPoolByMintPair({
  mint1: mintA.toBase58(),
  mint2: mintB.toBase58(),
});

const stablePool = pools.find(
  (p) => p.version === 5 || p.pooltype.includes("StablePool"),
);

if (!stablePool) {
  throw new Error("Nenhum pool Stable existe para este par de mints");
}

console.log("ID do pool Stable:", stablePool.id);
console.log("programId do pool Stable:", stablePool.programId);
console.log("TVL:", stablePool.tvl);
```

Se o par de mints tem tanto um pool v4 (produto constante) quanto um pool v5 (estável), a resposta inclui ambos — escolha o que seu fluxo precisa, ou passe-os para o programa [AMM Routing](/pt/products/routing) e deixe-o escolher a melhor rota.

## Fazer swap através de um pool Stable

O fluxo `LiquidityModule.swap` tem a mesma forma que para pools v4 — apenas passe um objeto pool v5:

```ts theme={null}
import { Percent, TokenAmount, toToken } from "@raydium-io/raydium-sdk-v2";

const inputAmount = new TokenAmount(toToken(stablePool.mintA), 1_000_000); // 1 USDT
const slippage = new Percent(50, 10_000); // 0.5%

// Compute expected output usando os helpers de curva estável do SDK internamente.
const { amountOut, minAmountOut } = raydium.liquidity.computeAmountOut({
  poolInfo: stablePool,
  amountIn: inputAmount,
  mintIn:  stablePool.mintA.address,
  mintOut: stablePool.mintB.address,
  slippage,
});

console.log("Saída esperada:", amountOut.toSignificant());
console.log("Saída mínima:", minAmountOut.toSignificant());

// Construa e assine a transação de swap.
const { transaction, execute } = await raydium.liquidity.swap({
  poolInfo: stablePool,
  amountIn:    inputAmount.raw,
  amountOut:   minAmountOut.raw,
  fixedSide:   "in",
  txVersion:   TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Tx de swap Stable:", txId);
```

O SDK lê o `programId` do pool a partir das chaves do pool e despacha para o programa Stable AMM. Nenhum argumento `programId` especial é necessário.

## Adicionar e remover liquidez

`addLiquidity` e `removeLiquidity` funcionam identicamente em pools v4 e v5:

```ts theme={null}
import { Percent, TokenAmount, toToken } from "@raydium-io/raydium-sdk-v2";

const amountInA = new TokenAmount(toToken(stablePool.mintA), 100_000_000); // 100 USDT
const slippage  = new Percent(50, 10_000); // 0.5%

// Compute o valor correspondente de B que a curva requer para este tamanho de A.
const { anotherAmount, minAnotherAmount } = raydium.liquidity.computePairAmount({
  poolInfo: stablePool,
  amount:   amountInA.toSignificant(),
  baseIn:   true,
  slippage,
});

const { execute } = await raydium.liquidity.addLiquidity({
  poolInfo: stablePool,
  amountInA,
  amountInB:      anotherAmount,
  otherAmountMin: minAnotherAmount,
  fixedSide:      "a",
  txVersion:      TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Tx de adição de liquidez:", txId);
```

Internamente o SDK emite `InstructionType.AmmV5AddLiquidity` porque `pooltype.includes("StablePool")` é verdadeiro. O fluxo correspondente de `removeLiquidity` é simétrico — forneça `lpAmount` e os valores mínimos que você aceitará em cada lado.

## Helpers de quote off-chain (stable.ts)

Para quoting do lado do servidor ou backtesting, o SDK expõe a matemática subjacente da curva estável:

```ts theme={null}
import {
  getStablePrice,
  getDxByDyBaseIn,
  getDyByDxBaseIn,
} from "@raydium-io/raydium-sdk-v2";

// Você deve chamar initLayout() uma vez antes de usar estes (carrega o PDA
// `ModelDataInfo` on-chain no cache StableLayout do SDK).
await raydium.liquidity.initLayout();

const modelData = raydium.liquidity.stableLayout;

// Preço spot nas reservas atuais do pool.
const price = getStablePrice(modelData, /* x */, /* y */, /* withFee */);
console.log("Preço spot:", price);

// Quote: dado dx de entrada, quanto dy de saída (sem taxa aplicada)?
const dyOut = getDyByDxBaseIn(modelData, /* x */, /* y */, /* dx */);

// Quote: dado alvo dy de saída, quanto dx de entrada é necessário?
const dxIn  = getDxByDyBaseIn(modelData, /* x */, /* y */, /* dy */);
```

Estas são funções puras — sem RPC, sem assinatura. O `ModelDataInfo` on-chain é buscado uma vez por `initLayout()` e armazenado em cache em `raydium.liquidity.stableLayout`. Passe as reservas atuais (`x`, `y`) e os helpers computam fazendo busca binária na tabela de lookup e interpolação linear entre as duas linhas `DataElement` circundantes. Veja [`products/stable/math`](/pt/products/stable/math) para o algoritmo subjacente.

## Roteamento através do AMM Routing (multi-hop / melhor preço)

Se você não quer escolher um venue você mesmo, o programa [AMM Routing](/pt/products/routing) considerará cada AMM Raydium (v4 / CPMM / CLMM / Stable) e roteará através de qualquer combinação que seja melhor:

```ts theme={null}
const route = await raydium.tradeV2.fetchRoutes({
  inputMint:  mintA,
  outputMint: mintB,
  amount:     new BN(1_000_000),
  slippage,
});

// route.routes[0].poolType diz quais programas a melhor rota usa;
// "Stable" aparece aqui sempre que um pool Stable faz parte do caminho ótimo.
console.log(route.routes[0]);

const { execute } = await raydium.tradeV2.swap({
  inputMint:    mintA,
  outputMint:   mintB,
  inputAmount:  new BN(1_000_000),
  swapResult:   route.routes[0],
  slippage,
  txVersion:    TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
```

Este é o caminho recomendado para swappers e agregadores em produção — você nunca precisa decidir manualmente se um pool Stable existe ou se é o melhor venue hoje.

## Recomendações

1. **Para swaps de usuário final**, prefira o fluxo de roteamento [`tradeV2`](/pt/products/routing). Ele lida com cada tipo de pool Raydium incluindo Stable.
2. **Para operações específicas de pool** (LP add / remove em um pool Stable conhecido), use o `LiquidityModule` diretamente — ele detecta automaticamente pools v5.
3. **Para quoting off-chain / análise**, chame `getStablePrice` / `getDyByDxBaseIn` / `getDxByDyBaseIn` após `initLayout()`. Sem tráfego RPC por quote após o modelo de dados ser armazenado em cache.
4. **Não codifique manualmente instruções `SwapBaseIn` brutas.** A [atualização de 2026-06-22](/pt/reference/changelog) removeu as contas OpenBook mortas, então o novo layout de swap leva **9 contas** (o layout antigo de 18 contas ainda analisa para compatibilidade com versões anteriores). `Deposit` agora é 12 contas (14 antigas compatíveis), `Withdraw` 12 (21/22 antigas compatíveis), e `WithdrawPnl` 10 com **nenhum** caminho de compatibilidade. Os helpers pré-construídos do SDK selecionam o layout e ordenação corretos para você; fazer o seu próprio é propenso a erros. Veja [`products/stable/instructions`](/pt/products/stable/instructions) para as tabelas de contas completas.

## Para onde ir a seguir

* [Math](/pt/products/stable/math) — como funciona a interpolação da tabela de lookup.
* [Instructions](/pt/products/stable/instructions) — referência completa de instruções.
* [AMM Routing](/pt/products/routing) — roteamento multi-pool através de AMM v4, CPMM, CLMM, Stable.

Fontes:

* [`raydium-sdk-V2/src/raydium/liquidity/liquidity.ts`](https://github.com/raydium-io/raydium-sdk-V2/blob/master/src/raydium/liquidity/liquidity.ts) — ponto de entrada do módulo; despacho v4 / v5.
* [`raydium-sdk-V2/src/raydium/liquidity/stable.ts`](https://github.com/raydium-io/raydium-sdk-V2/blob/master/src/raydium/liquidity/stable.ts) — `StableLayout`, `getStablePrice`, `getDxByDyBaseIn`, `getDyByDxBaseIn`.
