TypeScript SDK
The official TypeScript SDK for interacting with the rFlow protocol. Full type safety, PDA helpers, and comprehensive error handling.
Installation#
Install the SDK and its peer dependencies:
Terminal
$npm install @rflow/sdk @coral-xyz/anchor @solana/web3.js @solana/spl-token
Peer Dependencies
The SDK requires
@coral-xyz/anchor ^0.32.0 and @solana/web3.js ^1.95.0 as peer dependencies.Quick Start#
Initialize the client and start interacting with the protocol:
example.ts
1import { RFlowClient, SourceProtocol } from "@rflow/sdk";2import { Connection, PublicKey } from "@solana/web3.js";34// Create a read-only client (no wallet needed)5const connection = new Connection("https://api.devnet.solana.com");6const client = RFlowClient.readOnly(connection);78// Get all available yield deals9const deals = await client.yieldDeals.getAvailableDeals();10console.log(`Found ${deals.length} available deals`);1112// Get protocol configuration13const config = await client.getConfig();14console.log(`Protocol fee: ${config?.feeBps / 100}%`);1516// For write operations, pass a wallet17import { useWallet } from "@solana/wallet-adapter-react";18const { publicKey, signTransaction, signAllTransactions } = useWallet();1920const clientWithWallet = new RFlowClient({21 connection,22 wallet: { publicKey, signTransaction, signAllTransactions },23});2425// Create a new deal26const instructions = await clientWithWallet.yieldDeals.createDeal({27 receiptTokenMint: new PublicKey("..."),28 receiptTokensAmount: 10_000_000_000, // 10,000 tokens (6 decimals)29 principalValueAtLock: 10_000_000_000,30 expectedYield: 150_000_000,31 sellingPrice: 125_000_000,32 durationDays: 90,33 sourceProtocol: SourceProtocol.Kamino,34 exchangeRateAtLock: 1_050_000, // 1.0535});Yield Deals#
The YieldDealClient provides methods for interacting with yield deals (receipt tokens like kUSDC, mSOL, jitoSOL).
Read Operations
typescript
1// Get a deal by ID2const deal = await client.yieldDeals.getDeal(42);34// Get a deal by PDA5const dealByPda = await client.yieldDeals.getDealByPda(dealPda);67// Get all deals with optional filters8const allDeals = await client.yieldDeals.getAllDeals({9 status: DealStatus.Active,10 sourceProtocol: SourceProtocol.Kamino,11});1213// Get available deals (status = Created)14const available = await client.yieldDeals.getAvailableDeals();1516// Get deals by seller17const myDeals = await client.yieldDeals.getDealsBySeller(myWallet);1819// Get deals by buyer20const myInvestments = await client.yieldDeals.getDealsByBuyer(myWallet);Write Operations
All write operations return TransactionInstruction[] that you can include in a transaction:
typescript
1// Create a deal2const createIxs = await client.yieldDeals.createDeal({3 receiptTokenMint: kUsdcMint,4 receiptTokensAmount: 10_000_000_000,5 principalValueAtLock: 10_000_000_000,6 expectedYield: 150_000_000,7 sellingPrice: 125_000_000,8 durationDays: 90,9 sourceProtocol: SourceProtocol.Kamino,10 exchangeRateAtLock: 1_050_000,11});1213// Buy a deal14const buyIxs = await client.yieldDeals.buyDeal(15 dealId,16 sellerPaymentAccount,17 treasuryAccount18);1920// Cancel a deal (seller only, before purchase)21const cancelIxs = await client.yieldDeals.cancelDeal(dealId);2223// Settle a deal (after expiry)24const settleIxs = await client.yieldDeals.settleDeal(dealId, currentTokenValue);2526// Buyback a deal (seller early exit with penalty)27const buybackIxs = await client.yieldDeals.buybackDeal(dealId, currentTokenValue);2829// Build and send transaction30const tx = new Transaction().add(...createIxs);31const signature = await sendTransaction(tx, connection);Meteora LP Deals#
The MeteoraLpDealClient provides methods for Meteora CP-AMM LP fee deals. Lock your Position NFT and sell future fees.
Read Operations
typescript
1// Same API as YieldDealClient2const deal = await client.meteoraDeals.getDeal(dealId);3const available = await client.meteoraDeals.getAvailableDeals();4const myDeals = await client.meteoraDeals.getDealsBySeller(myWallet);Write Operations
typescript
1// Create a Meteora LP deal2const createIxs = await client.meteoraDeals.createDeal({3 positionNftMint: positionNftMint,4 positionAccount: meteoraPositionPda,5 pool: meteoraPoolPda,6 tokenAMint: usdcMint,7 tokenBMint: solMint,8 feeAAtLock: 0,9 feeBAtLock: 0,10 expectedFeeA: 500_000_000, // Expected USDC fees11 expectedFeeB: 1_000_000_000, // Expected SOL fees12 expectedFeeValueUsdc: 650_000_000, // Total value in USDC13 sellingPrice: 500_000_000,14 durationDays: 90,15});1617// Buy a Meteora LP deal18const buyIxs = await client.meteoraDeals.buyDeal(19 dealId,20 sellerPaymentAccount,21 treasuryAccount22);2324// Claim fees (buyer only, during active deal)25const claimIxs = await client.meteoraDeals.claimFees({26 dealId,27 meteoraProgram: METEORA_PROGRAM_ID,28 meteoraPosition: positionPda,29 meteoraPool: poolPda,30 poolTokenAVault: tokenAVault,31 poolTokenBVault: tokenBVault,32});3334// Settle after expiry (returns NFT to seller)35const settleIxs = await client.meteoraDeals.settleDeal(dealId);3637// Withdraw liquidity (seller only, after settlement)38const withdrawIxs = await client.meteoraDeals.withdrawLiquidity({39 dealId,40 meteoraProgram: METEORA_PROGRAM_ID,41 meteoraPosition: positionPda,42 meteoraPool: poolPda,43 poolTokenAVault: tokenAVault,44 poolTokenBVault: tokenBVault,45 poolAuthority: poolAuthorityPda,46 eventAuthority: eventAuthorityPda,47 tokenAProgram: TOKEN_PROGRAM_ID,48 tokenBProgram: TOKEN_PROGRAM_ID,49 tokenAAmountThreshold: 0,50 tokenBAmountThreshold: 0,51});5253// Split position (before creating a deal, to sell partial position)54const splitIxs = await client.meteoraDeals.splitPosition({55 sourceNftMint: sourcePositionNft,56 sourcePosition: sourcePositionPda,57 targetNftMint: newPositionNft,58 targetPosition: newPositionPda,59 meteoraPool: poolPda,60 meteoraProgram: METEORA_PROGRAM_ID,61 eventAuthority: eventAuthorityPda,62 unlockedLiquidityPercentage: 50,63 permanentLockedLiquidityPercentage: 50,64 feeAPercentage: 50,65 feeBPercentage: 50,66 reward0Percentage: 50,67 reward1Percentage: 50,68});PDA Helpers#
Helper functions to derive Program Derived Addresses:
typescript
1import {2 findProtocolConfigPDA,3 findYieldDealPDA,4 findVaultPDA,5 findMeteoraLpDealPDA,6 findMeteoraVaultPDA,7 PROGRAM_ID,8} from "@rflow/sdk";910// Protocol config PDA11const [configPda, configBump] = findProtocolConfigPDA(PROGRAM_ID);1213// Yield deal PDA14const [dealPda, dealBump] = findYieldDealPDA(dealId, PROGRAM_ID);1516// Token vault PDA (for locked receipt tokens)17const [vaultPda, vaultBump] = findVaultPDA(dealPda, PROGRAM_ID);1819// Meteora LP deal PDA20const [meteoraDealPda] = findMeteoraLpDealPDA(dealId, PROGRAM_ID);2122// Meteora NFT vault PDA23const [nftVaultPda] = findMeteoraVaultPDA(meteoraDealPda, PROGRAM_ID);Error Handling#
The SDK provides typed errors for better error handling:
typescript
1import {2 RFlowError,3 FetchError,4 DealNotFoundError,5 InvalidInputError,6 InvalidDurationError,7 parseAnchorError,8 isAccountNotFoundError,9 ERROR_CODES,10} from "@rflow/sdk";1112try {13 const deal = await client.yieldDeals.getDeal(999);14} catch (error) {15 if (error instanceof DealNotFoundError) {16 console.log("Deal not found:", error.dealId);17 } else if (error instanceof InvalidInputError) {18 console.log("Invalid input:", error.message);19 } else if (error instanceof InvalidDurationError) {20 console.log("Invalid duration:", error.duration, "days");21 console.log("Valid durations:", error.validDurations);22 }23}2425// Parse Anchor program errors26try {27 await sendTransaction(tx);28} catch (error) {29 const rflowError = parseAnchorError(error);30 if (rflowError) {31 console.log("Program error:", rflowError.code, rflowError.message);32 }33}3435// Check if account doesn't exist36if (isAccountNotFoundError(error)) {37 console.log("Account not found on chain");38}Types#
The SDK exports comprehensive TypeScript types:
typescript
1import type {2 // Deal types3 YieldDeal,4 MeteoraLpDeal,5 ProtocolConfig,67 // Input types8 CreateYieldDealInput,9 CreateMeteoraLpDealInput,10 ClaimMeteoraFeesInput,11 DealFilters,1213 // Enums14 DealStatus,15 SourceProtocol,16} from "@rflow/sdk";1718// Deal status enum19enum DealStatus {20 Created = 0, // Waiting for buyer21 Active = 1, // Purchased, in progress22 Settled = 2, // Ended, distributions complete23 Cancelled = 3, // Cancelled before purchase24 BoughtBack = 4 // Seller did early buyback25}2627// Source protocol enum28enum SourceProtocol {29 // Lending30 Kamino = 0,31 MarginFi = 1,32 Solend = 2,33 Save = 3,34 // Liquid Staking35 Marinade = 4,36 Jito = 5,37 Blaze = 6,38 Sanctum = 7,39 Lido = 8,40 // LP (Phase 2)41 RaydiumLp = 9,42 MeteoraLp = 10,43 OrcaLp = 11,44 // Fee Streams (Phase 3)45 FeeStream = 12,46}Full Type Safety
The SDK is fully typed with TypeScript. Use your IDE's autocomplete to explore all available methods and types.