For the complete documentation index, see llms.txt. This page is also available as Markdown.

Revenue Interactions

FAF token staking and the three claimable balances it unlocks — staking rewards, protocol revenue share, and referral rebates. This page covers staking, unstaking, and claiming each balance through Fl

Three claimable balances, three calls:

  • Staking rewardscollectTokenRewardWithAction (your FAF staking yield).

  • Protocol revenuecollectRevenueWithAction (a slice of protocol fees distributed to FAF stakers).

  • Referral rebatescollectRebateWithAction (trading rebates for referrers / stakers).

Each pays out 0 and simply closes if nothing is owed, so they're safe to call speculatively.

Set up flashClient and poolConfig as shown on the Flash SDK v2 landing page. The FAF (governance) token mint and the revenue/rebate token accounts live on poolConfig:

poolConfig.tokenMint           // FAF / governance staking mint
poolConfig.revenueTokenAccount // holds the revenue payout mint (read on-chain)
poolConfig.rebateTokenAccount  // holds the rebate payout mint (read on-chain)

The flow model

The claim flows (collect*WithAction, depositTokenStakeWithAction, withdrawTokenWithAction) are program-driven: you submit one *WithAction transaction with sendAndConfirmTransaction, and the program runs the remaining steps automatically, closing a receipt account. You submit the transaction and poll the receipt until it closes. Everything on this page is signed by your walletKeypair (session keys apply only to trading).

Stake FAF

Stakes FAF into your token_stake account. Stake level (your fee/rebate tier) and revenue eligibility derive from the staked amount.

import { BN } from '@coral-xyz/anchor'
import { getAssociatedTokenAddressSync, createAssociatedTokenAccountIdempotentInstruction } from '@solana/spl-token'
import { findTokenStakeDepositReceiptAddress } from '@flash_trade/flash-sdk-v2'

const stakeFaf = async (amount: BN) => {
  const owner = flashClient.wallet
  const fafMint = poolConfig.tokenMint
  const fundingAccount = getAssociatedTokenAddressSync(fafMint, owner)
  const [receipt] = findTokenStakeDepositReceiptAddress(owner, flashClient.programId)

  const res = await flashClient.depositTokenStakeWithAction({
    tokenMint: fafMint,
    fundingAccount,
    depositAmount: amount,
    token22: false, // true if FAF is a Token-2022 mint
  })
  // Ensure the funding ATA exists (idempotent).
  res.instructions.unshift(
    createAssociatedTokenAccountIdempotentInstruction(owner, fundingAccount, owner, fafMint),
  )

  await flashClient.sendAndConfirmTransaction(res.instructions, {
    additionalSigners: res.additionalSigners,
    skipPreflight: true,
  })

  // Wait for the settle step to close the receipt.
  await pollClosed(receipt) // see LP Interactions for the poller helper
}

await stakeFaf(new BN(1_000_000))

Unstake (begin the unlock)

Appends an entry to your withdraw_request array. The amount matures after the vault's unlock_period, after which you withdraw it. Sent with sendAndConfirmErTransaction, signed by your wallet keypair.

Cancel a pending unstake

Withdraw a matured unstake

Once a request has matured, settle it to return FAF to your ATA.

Reading your stake & claimable balances

TokenStakeAccount exposes your stake level, lock table, and the three claimable balances:

Fetching tokenStake throws if the account doesn't exist (the wallet has never staked). Guard with a try/catch or check existence first.

Claim staking rewards

Claim protocol revenue

A slice of protocol fees is distributed to FAF stakers. The payout mint is whatever the pool's revenueTokenAccount holds — read it on-chain rather than assuming.

If no revenue is owed, the settle step pays 0 and just closes the receipt — the call is a safe no-op. Check tokenStake.unclaimedRevenueAmount first if you want to skip the transaction entirely.

Claim referral rebates

Referrers and stakers accrue trading rebates. Same shape as revenue, reading the mint from poolConfig.rebateTokenAccount (typically USDC).

To register the wallet under a referrer (so the referrer earns rebates on your trades), build the standalone createReferral instruction.

This creates your referral PDA (["referral", owner]) and links it to the referrer's stake. Once linked, pass Privilege.Referral on your trades so the rebate accrues.

Last updated

Was this helpful?