> ## 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 para farm/staking

> Exemplos em TypeScript para criar um farm, fazer stake de LP, coletar recompensas e adicionar orçamento de recompensas no programa farm v6 da Raydium.

<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/farm-staking/code-demos)
</Info>

<Info>
  **Informações de versão.** Todos os exemplos visam `@raydium-io/raydium-sdk-v2@0.2.42-alpha` contra Solana mainnet-beta, verificado em 2026-04. O SDK despacha v3 / v5 / v6 internamente com base no proprietário do programa do farm; os exemplos abaixo assumem um farm v6. Consulte [`reference/program-addresses`](/pt/reference/program-addresses) para os três IDs de programa.
</Info>

## Setup

Os exemplos aqui espelham arquivos em [`raydium-sdk-V2-demo/src/farm`](https://github.com/raydium-io/raydium-sdk-V2-demo/tree/master/src/farm). O bootstrap segue o [`config.ts.template`](https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/config.ts.template) do repositório de demonstração:

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

const connection = new Connection(process.env.RPC_URL ?? clusterApiUrl("mainnet-beta"));
const owner = Keypair.fromSecretKey(
  new Uint8Array(JSON.parse(fs.readFileSync(process.env.KEYPAIR!, "utf8"))),
);
const raydium = await Raydium.load({
  owner,
  connection,
  cluster: "mainnet",
  disableFeatureCheck: true,
  blockhashCommitment: "finalized",
});
export const txVersion = TxVersion.V0;
```

## Buscar um farm por ID

```ts theme={null}
const farmId = new PublicKey("<FARM_ID>");

const farm = await raydium.farm.getFarmById({ farmId });
console.log("Staking mint:", farm.symbolMint.toBase58());
console.log("Total staked:", farm.totalStaked.toString());
console.log("Rewards:");
for (const r of farm.rewardInfos) {
  console.log(
    "  -", r.mint.toBase58(),
    "rate(1e-" + r.decimals + "/s):", r.perSecond.toString(),
    "open:", new Date(r.openTime * 1000).toISOString(),
    "end: ", new Date(r.endTime * 1000).toISOString(),
  );
}
```

`getFarmById` obtém `FarmState` fora da cadeia, decodifica por versão de programa e normaliza a taxa de emissão de ponto fixo para um simples `Decimal` por segundo.

## Fazer stake de tokens LP

Fonte: [`src/farm/stake.ts`](https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/farm/stake.ts)

```ts theme={null}
const amount = new BN(1_000_000_000);   // 1 LP (assumindo 9 decimais)

const { execute } = await raydium.farm.deposit({
  farmInfo: farm,
  amount,
  txVersion: TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Deposit tx:", txId);
```

O SDK lida com a pré-liquidação de qualquer recompensa pendente, então se esta carteira já tiver stake neste farm, a instrução pagará recompensas acumuladas aos ATAs do usuário na mesma transação.

## Apenas coleta (harvest)

Fonte: [`src/farm/harvest.ts`](https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/farm/harvest.ts)

```ts theme={null}
const { execute } = await raydium.farm.harvestAllRewards({
  farmInfoList: [farm],
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
```

`harvestAllRewards` aceita uma lista — para UIs mostrando uma visão de portfólio, agrupe a chamada. Cada farm é coletado em uma instrução separada em uma transação (sujeito ao limite de tamanho de 1232 bytes; para >\~6 farms, divida em múltiplas transações).

Para um único farm em v6, você também pode usar o caminho `Harvest` explícito:

```ts theme={null}
const { execute } = await raydium.farm.withdraw({
  farmInfo: farm,
  amount: new BN(0),        // 0 = caminho harvest-only, mesmo em v6
  txVersion: TxVersion.V0,
});
await execute({ sendAndConfirm: true });
```

Em v3 e v5 o idioma `amount: 0` é necessário; o SDK o despacha corretamente.

## Unstake

Fonte: [`src/farm/unstake.ts`](https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/farm/unstake.ts)

```ts theme={null}
const amount = new BN(500_000_000);   // 0.5 LP

const { execute } = await raydium.farm.withdraw({
  farmInfo: farm,
  amount,
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
```

## Criar um farm v6

Fonte: [`src/farm/createAmmFarm.ts`](https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/farm/createAmmFarm.ts) e [`editAmmFarm.ts`](https://github.com/raydium-io/raydium-sdk-V2-demo/blob/master/src/farm/editAmmFarm.ts)

```ts theme={null}
import { CurveCalculator } from "@raydium-io/raydium-sdk-v2"; // opcional, para planejamento de APR

const stakingMint = new PublicKey("<LP_MINT>");       // ex: um mint LP CPMM
const rewardMint  = new PublicKey("<REWARD_MINT>");   // ex: token do seu projeto

const now      = Math.floor(Date.now() / 1000);
const openTime = now + 60 * 60;                       // começar em 1h
const duration = 60 * 60 * 24 * 30;                   // 30 dias
const endTime  = openTime + duration;

const totalBudget = new BN(1_000_000).mul(new BN(10).pow(new BN(9))); // 1M tokens de recompensa (9 dec)
const perSecond   = totalBudget.div(new BN(duration));                // inteiro, SDK levanta para Q64.64

const { execute, extInfo } = await raydium.farm.create({
  programId: /* ID do programa v6, de reference/program-addresses */,
  poolInfo: { lpMint: { address: stakingMint, decimals: 9, programId: /* SPL Token */ } as any },
  rewardInfos: [
    {
      mint:           rewardMint,
      openTime:       new BN(openTime),
      endTime:        new BN(endTime),
      perSecond,
      rewardSender:   owner.publicKey,    // quem paga o orçamento inicial
      mintProgramId:  /* SPL Token ou Token-2022 */,
    },
  ],
  txVersion: TxVersion.V0,
});

const { txId } = await execute({ sendAndConfirm: true });
console.log("Farm:", extInfo.farmId.toBase58(), "createTx:", txId);
```

Pontos-chave:

* `perSecond` é a taxa de emissão inteira por segundo. O SDK a empacota em Q64.64 antes de enviar. Para uma taxa fracionária, escale e ajuste a duração.
* O orçamento completo (`perSecond × duration`) deve estar presente em seu ATA de recompensa — `create` o move para o vault de recompensa atomicamente.
* Você pode semear até 5 recompensas em uma chamada `create`. A lista de contas cresce por `(reward_mint, reward_vault, sender_ata, token_program)` por fluxo extra; esteja atento ao limite de tamanho de transação de 1232 bytes. Para 4+ recompensas, crie com 1–2 e use `AddReward` em transações subsequentes.

## Adicionar orçamento a um fluxo de recompensa existente

```ts theme={null}
const additionalDays = 30;
const extraSeconds   = 60 * 60 * 24 * additionalDays;
const extraBudget    = perSecond.mul(new BN(extraSeconds));

const { execute } = await raydium.farm.setRewards({
  farmInfo: farm,
  rewardInfos: [
    {
      rewardMint:  rewardMint,
      newEndTime:  new BN(farm.rewardInfos[0].endTime + extraSeconds),
      newPerSecond: perSecond,                   // manter mesma taxa
      payer:        owner.publicKey,
    },
  ],
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
```

`setRewards` estende `end_time` e transfere o orçamento delta. A instrução não pode encurtar um fluxo, não pode baixar `per_second` em um fluxo ativo e não pode alterar o mint de recompensa. Para trocar mints, aguarde `end_time` e use `AddReward` em um slot liberado (se houver), ou crie um novo farm.

## Reiniciar um fluxo terminado

```ts theme={null}
const { execute } = await raydium.farm.restartRewards({
  farmInfo: farm,
  newRewardInfo: {
    rewardMint:   rewardMint,
    openTime:     new BN(Math.floor(Date.now() / 1000) + 60 * 60),
    endTime:      new BN(Math.floor(Date.now() / 1000) + 60 * 60 + 60 * 60 * 24 * 14),
    perSecond:    new BN("1000000000"),
    payer:        owner.publicKey,
  },
  txVersion: TxVersion.V0,
});

await execute({ sendAndConfirm: true });
```

Válido apenas quando o `reward_state == 2` (terminado) do slot alvo. O chamador deve ser o `reward_sender` do slot (v6) ou o proprietário do farm (v5).

## Rust CPI

Diferentemente do AMM v4, o programa farm v6 vem com um crate Anchor (`raydium_farm_v6`) publicado junto com as fontes do frontend e SDK. Um esboço `Deposit` mínimo:

```rust theme={null}
use anchor_lang::prelude::*;
use raydium_farm_v6::{self, cpi::accounts::Deposit as RaydiumDeposit};

#[derive(Accounts)]
pub struct ProxyFarmDeposit<'info> {
    /// CHECK:
    pub farm_program: UncheckedAccount<'info>,
    #[account(mut)] pub user: Signer<'info>,
    #[account(mut)] /// CHECK:
    pub user_ledger: UncheckedAccount<'info>,
    #[account(mut)] /// CHECK:
    pub farm_state: UncheckedAccount<'info>,
    /// CHECK:
    pub farm_authority: UncheckedAccount<'info>,
    #[account(mut)] /// CHECK:
    pub staking_vault: UncheckedAccount<'info>,
    #[account(mut)] /// CHECK:
    pub user_staking_ata: UncheckedAccount<'info>,
    // Seguido em remaining_accounts por pares (reward_vault_i, user_reward_ata_i)
    // para cada fluxo de recompensa ativo no farm.
    pub token_program: UncheckedAccount<'info>,
    pub system_program: Program<'info, System>,
}

pub fn proxy_deposit<'info>(
    ctx: Context<'_, '_, '_, 'info, ProxyFarmDeposit<'info>>,
    amount: u64,
) -> Result<()> {
    let cpi_ctx = CpiContext::new(
        ctx.accounts.farm_program.to_account_info(),
        RaydiumDeposit {
            user:             ctx.accounts.user.to_account_info(),
            user_ledger:      ctx.accounts.user_ledger.to_account_info(),
            farm_state:       ctx.accounts.farm_state.to_account_info(),
            farm_authority:   ctx.accounts.farm_authority.to_account_info(),
            staking_vault:    ctx.accounts.staking_vault.to_account_info(),
            user_staking_ata: ctx.accounts.user_staking_ata.to_account_info(),
            token_program:    ctx.accounts.token_program.to_account_info(),
            system_program:   ctx.accounts.system_program.to_account_info(),
        },
    ).with_remaining_accounts(ctx.remaining_accounts.to_vec());

    raydium_farm_v6::cpi::deposit(cpi_ctx, amount)
}
```

A fatia `remaining_accounts` deve corresponder 1 para 1 aos slots de recompensa ativos do farm (pares de `reward_vault_i`, `user_reward_ata_i` em ordem de índice). Omitir ou desordenar esses produz uma contabilização silenciosamente incorreta — o programa transferirá o valor incorreto.

## Armadilhas comuns

* **Esquecer de coletar antes de sacar.** Inofensivo — `Withdraw` liquida recompensas pendentes primeiro. Mas se sua UI mostrar "coletar" separadamente de "sacar", o usuário pode pensar que ainda há algo a coletar após um `Withdraw`. Não há; tudo acumulado até aquele ponto foi pago.
* **`total_staked = 0` durante emissões.** Emissões acumuladas enquanto nada estava em stake são perdidas (a fórmula de atualização `reward_per_share` divide por 0 e o programa pula a atualização). Para programas com `open_time` agendado, execute um "seed stake" no open\_time para evitar isso.
* **Taxas de transferência Token-2022.** Em farms v6 com mints de recompensa Token-2022, a taxa de transferência se aplica na emissão (vault → usuário). Fatore isso em citações de APR.
* **Pequeno `per_second` em v5.** A taxa `u64` do v5 significa que qualquer `per_second < 1` unidade de token por segundo (em mints com ≥9 decimais esta é frequentemente a taxa desejada) não pode ser expressa — a taxa do fluxo arredonda para 0 e o farm não emite nada. Use v6.

## Próximos passos

* [`products/farm-staking/instructions`](/pt/products/farm-staking/instructions) — referência de instrução subjacente.
* [`products/clmm/fees`](/pt/products/clmm/fees) — comparar com fluxos de recompensa nativos do CLMM.
* [`user-flows/migrate-amm-v4-to-cpmm`](/pt/user-flows/migrate-amm-v4-to-cpmm) — frequentemente associado a iniciar um novo farm CPMM.

Fontes:

* [Raydium SDK v2](https://github.com/raydium-io/raydium-sdk-V2)
* Farm v6 IDL agrupado em [`raydium-io/raydium-sdk-V2`](https://github.com/raydium-io/raydium-sdk-V2) sob `src/raydium/farm/`.
