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

Flash SDK V2

Introduction

Flash SDK v2 (@flash_trade/flash-sdk-v2) is the TypeScript client for Flash, covering trading, liquidity provisioning, and FAF staking with instant, gasless execution.

Use Flash SDK v2 for all new integrations. The older Flash SDK (flash-sdk) is being deprecated and will be retired shortly — new builds should target v2.

How it works

You give the client two RPC endpoints and call the instruction builders:

  • A standard Solana RPC — bring your own from a provider like Triton or Helius.

  • The Flash ER_RPC — Flash's trading endpoint, provided by Flash; trading and order execution run here.

There are two kinds of operations, and the rest of these docs are organized around them:

  • Trading — open/close positions, adjust collateral, and place or edit orders. Each is built and sent in a single transaction with sendAndConfirmErTransaction.

  • Setup, deposits, liquidity, and staking — sent with sendAndConfirmTransaction. The liquidity and staking operations are multi-step flows: you submit a transaction, then poll a receipt for the result (covered on each page).

Install

npm install @flash_trade/flash-sdk-v2
# or
yarn add @flash_trade/flash-sdk-v2

The SDK already depends on @coral-xyz/anchor, @solana/web3.js, and @solana/spl-token, so they're installed for you. The examples here import directly from those three (for BN, PublicKey, Keypair, ATA helpers, etc.) — if you do the same, it's good practice to add them to your own package.json so the versions stay pinned and types resolve cleanly under strict package managers (pnpm, Yarn PnP):

npm install @coral-xyz/anchor @solana/web3.js @solana/spl-token

The main export is FlashPerpetualsClient. Everything you call hangs off one instance of it.

Setting up the client

Create a single shared module and import the client (and your keypair) everywhere:

PoolConfig.fromIdsByName(...) reads a pool/token snapshot bundled into the npm package — frozen at the version you installed. To pick up new pools, token listings, custody changes, and oracle updates without waiting for an SDK release, fetch the live config from Flash's CDN instead — see Dynamic Pool & Token Data.

Sending transactions

You build instructions with the client, then send them one of two ways:

  • flashClient.sendAndConfirmTransaction(ixs, opts?) — for one-time setup, deposits, liquidity, and staking. opts accepts { additionalSigners, skipPreflight, alts }.

  • flashClient.sendAndConfirmErTransaction(ixs, signers) — for trading (positions and orders) and for the commit step of liquidity/staking flows. signers[0] is the fee payer and signs the transaction — your owner keypair for a bot, or a session key if you've set one up.

Large setup/liquidity transactions forward a big account set inline — attach the pool's address lookup tables so they fit:

Session keys (optional — for UIs)

If you're building a UI, a session key lets users trade without a wallet pop-up on every transaction: authorize a fresh keypair once, then sign trades with it locally.

Bots and scripts don't need session keys. Sign trades directly with your owner keypair (sendAndConfirmErTransaction(ixs, [walletKeypair])). Session keys only affect trading instructions; everything else is always signed by the owner.

Receipts: how liquidity & staking flows report their outcome

Liquidity and staking operations return a receipt account. After your transaction confirms, the program runs the remaining steps and closes the receipt. Two helpers wait on it:

Reading accounts

Fetch typed account wrappers. Position/pool/custody reads use client.accounts; your basket (which holds your open positions and orders) is read from client.erAccounts:

Wrappers expose decoded fields directly (e.g. pool.lpSupply, position.sizeAmount) plus .publicKey and helpers. Your open positions and orders are embedded in the basket (basket.positions, basket.orders) — there's no separate per-position account. See Trader Interactions → Reading positions & orders.

To stream updates, subscribe to the basket with onAccountChange and decode with the program coder:

Quotes & views

Pricing math runs on-chain — the SDK simulates it and decodes the typed result, so you never re-implement fee/PnL math. Views live under flashClient.views.*:

Each interaction page lists the views relevant to it.

Troubleshooting

On-chain failures come back as {"InstructionError":[i,{"Custom":N}]}. Decode N by range: 20002999 are Anchor framework constraints; ≥ 6000 are the perpetuals program's own errors (offset from 6000); small codes like 0x1 are SPL Token; 0x0 from the System program means an account already exists.

Error
Cause
Fix

Custom 2006 — Anchor ConstraintSeeds

A passed PDA doesn't match what the program re-derives — most often the wrong collateral symbol for the market (the market PDA is keyed by target + collateral + side).

Resolve the market and use its collateralSymbol (Resolving the market); don't hardcode. Confirm cluster/pool/program id agree.

Custom 6023MinLeverage

sizeAmount is in target-token base units, not USD, so a USD-looking number lands far below the minimum leverage.

Derive sizeAmount from getOpenPositionQuoteEr at your target leverage (BPS) instead of passing a raw size.

Custom 6021MaxLeverage

Same size↔collateral unit confusion, other direction.

Same fix — derive the size from a quote.

SPL Token 0x1 — insufficient funds

The funding account is empty/underfunded; for trades, collateral isn't in the deposit ledger yet.

Fund the ATA, and run the one-time setup to deposit collateral before trading.

System 0x0 — account in use

A receipt from a half-finished liquidity/staking flow is still open.

Resume that receipt rather than resubmitting — see Reading the outcome / resuming.

Account-not-found on getPnl / getPositionData

The base getPnl / getPositionData views target the old standalone position model, not the basket.

Use the *Er variants — your positions live in the basket.

Next steps

  • Trader Interactions — basket setup, open/close/modify positions, limit & trigger orders, quotes, reading positions.

  • LP Interactions — add/remove liquidity (FLP & sFLP), migrations, and the receipt-driven flow.

  • Revenue Interactions — FAF staking, claiming staking rewards, protocol revenue, and referral rebates.

  • Dynamic Pool & Token Data — fetch the live pool/token config from Flash's CDN and hot-reload it in long-running bots, instead of relying on the bundled snapshot.

Last updated

Was this helpful?