> For the complete documentation index, see [llms.txt](https://docs.flash.trade/flash-trade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flash.trade/flash-trade/flash-trade-protocol/build-on-flash/flash-sdk/revenue-interactions.md).

# Revenue Interactions

{% hint style="info" %}

#### **Two things to know before you call these helpers:**

* Revenue is **FAF-scoped, not pool-scoped.** The `tokenVault` and `revenueTokenAccount` are shared across every mainnet pool, so any pool config can be the anchor — `Crypto.1` is used in the examples.
* Wallets without an FAF stake account (or with zero eligible amount) will see `revenueAmount == 0`. `claimRevenue` will short-circuit and skip the transaction in that case.
  {% endhint %}

Requires `flash-sdk >= 2.52.1`.

### Setup

Revenue claims use the same `PerpetualsClient` setup as the other SDK examples. If you've already configured a client on the [Flash SDK landing page](/flash-trade/flash-trade-protocol/build-on-flash/flash-sdk.md#install-the-flash-sdk), reuse it — just import `POOL_CONFIGS[0]` (or any pool) as the anchor.

For a standalone script:

```typescript
import dotenv from 'dotenv'
import {
    BN_ZERO,
    nativeToUiDecimals,
    PerpetualsClient,
    PoolConfig,
    USD_DECIMALS,
} from 'flash-sdk'
import { AnchorProvider, BN } from '@coral-xyz/anchor'
import {
    AddressLookupTableAccount,
    ComputeBudgetProgram,
    PublicKey,
    Signer,
    TransactionInstruction,
} from '@solana/web3.js'

dotenv.config()

// Crypto.1 is the canonical anchor — switch to `devnet.1` for devnet testing.
export const POOL_CONFIG = PoolConfig.fromIdsByName('Crypto.1', 'mainnet-beta')

// Revenue is paid in USDC. Override only if a future pool changes this.
const REVENUE_TOKEN_SYMBOL = 'USDC'

// Generous CU budget — matches the flash-main-ui claim flow.
const CU_CLAIM_REVENUE = 200_000

const RPC_URL = process.env.RPC_URL
if (!RPC_URL) throw new Error('RPC_URL is not set')

const provider = AnchorProvider.local(RPC_URL, {
    commitment: 'processed',
    preflightCommitment: 'processed',
    skipPreflight: true,
})

export const flashClient = new PerpetualsClient(
    provider,
    POOL_CONFIG.programId,
    POOL_CONFIG.perpComposibilityProgramId,
    POOL_CONFIG.fbNftRewardProgramId,
    POOL_CONFIG.rewardDistributionProgram.programId,
    { prioritizationFee: 0 },
)
```

### Get claimable revenue

Read-only quote of how much USDC a wallet can currently claim. No transaction is sent. Defaults to the connected wallet when no argument is passed.

```typescript
export const getUserClaimableRevenue = async (wallet?: PublicKey): Promise<BN> => {
    const target = wallet ?? flashClient.provider.publicKey

    await flashClient.loadAddressLookupTable(POOL_CONFIG)

    const revenueAmount = await flashClient.getUserClaimableRevenueAmount(POOL_CONFIG, target)

    console.log(
        'revenueAmount :>> ',
        revenueAmount.toString(),
        `(${nativeToUiDecimals(revenueAmount, USD_DECIMALS)} ${REVENUE_TOKEN_SYMBOL})`,
    )
    return revenueAmount
}

// Check the connected wallet:
const owed = await getUserClaimableRevenue()

// Or check any wallet:
const owed = await getUserClaimableRevenue(new PublicKey('GKTL...MoffMd'))
```

Returns a native `BN` amount in 6-decimal USDC. Use `nativeToUiDecimals(amount, USD_DECIMALS)` for a human-readable value.

### Claim revenue

Submits the claim and sweeps the wallet's eligible USDC balance to its USDC ATA. Auto-creates the receiving ATA if it doesn't exist.

```typescript
export const claimRevenue = async () => {
    // Pre-flight: skip the transaction if there's nothing to claim.
    const owed = await getUserClaimableRevenue()
    if (owed.lte(BN_ZERO)) {
        console.log('Nothing to claim — wallet has no eligible FAF revenue.')
        return
    }

    const setCULimitIx = ComputeBudgetProgram.setComputeUnitLimit({
        units: CU_CLAIM_REVENUE,
    })

    let instructions: TransactionInstruction[] = []
    let additionalSigners: Signer[] = []

    const collectRevenueData = await flashClient.collectRevenue(
        flashClient.provider.publicKey,
        REVENUE_TOKEN_SYMBOL,
        POOL_CONFIG,
        true, // createUserATA — auto-creates the receiving USDC ATA if missing
    )
    instructions.push(...collectRevenueData.instructions)
    additionalSigners.push(...collectRevenueData.additionalSigners)

    const alts: AddressLookupTableAccount[] = (
        await flashClient.getOrLoadAddressLookupTable(POOL_CONFIG)
    ).addressLookupTables

    const trxId = await flashClient.sendTransaction(
        [setCULimitIx, ...instructions],
        { additionalSigners, alts },
    )
    console.log(`https://explorer.solana.com/tx/${trxId}`)
}

await claimRevenue()
```

{% hint style="warning" %}
&#x20;`claimRevenue` fails if the wallet has no FAF token-stake account or zero eligible amount. The `owed.lte(BN_ZERO)` guard above prevents wasted transactions — keep it in place.
{% endhint %}

### Common gotchas

* **`revenueAmount == 0`** — the wallet has no FAF staked, or the stake hasn't accrued any revenue yet. Stake FAF first via `depositFafStake` (see the [FAF token docs](/flash-trade/flash-trade-protocol/faf-token.md)).
* **`claimRevenue` throws on a fresh wallet** — usually because no `token_stake` PDA exists. The pre-flight read prevents this; don't remove it.
* **Wrong pool config?** — any mainnet pool resolves to the same `tokenVault`. `Crypto.1` is just the canonical anchor. For devnet, switch to `devnet.1` and the devnet cluster URL.
* **USDC ATA missing?** — `createUserATA: true` on the `collectRevenue` call handles this. Set it to `false` only if you've already created the ATA out-of-band.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.flash.trade/flash-trade/flash-trade-protocol/build-on-flash/flash-sdk/revenue-interactions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
