mcpbeat Sign in

Orca Agent Skill

Complete guide for Orca - Solana's leading concentrated liquidity AMM (CLMM). Covers Whirlpools SDK for swaps, liquidity provision, pool creation, position management, and fee harvesting on Solana and Eclipse networks.

30k tokens
context cost
the whole folder, loaded on every use
10
files
ships runnable scripts
0
copies elsewhere
how many repositories repackaged it
122
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/sendaifun/skills --skill orca

What comes with it

103 300 bytes besides the instruction
docs/troubleshooting.md
examples/liquidity/harvest-fees.ts
examples/liquidity/manage-position.ts
examples/liquidity/open-position.ts
examples/pools/create-pool.ts
examples/swap/token-swap.ts
resources/api-reference.md
resources/program-addresses.md
templates/setup.ts

The instruction itself

40 sections, as written by the author

Orca Whirlpools Development Guide

Orca is the most trusted DEX on Solana and Eclipse, built on a concentrated liquidity automated market maker (CLMM) called Whirlpools. This guide covers the Whirlpools SDK for building trading, liquidity provision, and pool management applications.

Overview

Orca Whirlpools provides:

  • Token Swaps - Efficient token exchanges with low slippage and competitive rates
  • Concentrated Liquidity - Provide liquidity within custom price ranges for higher capital efficiency
  • Splash Pools - Simple full-range liquidity provision for beginners
  • Position Management - Open, increase, decrease, and close liquidity positions
  • Fee Harvesting - Collect trading fees and rewards from positions
  • Pool Creation - Permissionless creation of new liquidity pools

Program IDs

| Network | Program ID |

|---------|------------|

| Solana Mainnet | whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc |

| Solana Devnet | whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc |

| Eclipse Mainnet | whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc |

| Eclipse Testnet | whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc |

Quick Start

Installation

New SDK (Solana Web3.js v2):

npm install @orca-so/whirlpools @solana/kit

Legacy SDK (Solana Web3.js v1):

npm install @orca-so/whirlpools-sdk @orca-so/common-sdk @coral-xyz/[email protected] @solana/web3.js @solana/spl-token decimal.js

Core Utilities (optional):

npm install @orca-so/whirlpools-core @orca-so/whirlpools-client

Basic Setup (New SDK)

import {
  setWhirlpoolsConfig,
  setRpc,
  setPayerFromBytes
} from "@orca-so/whirlpools";
import { createSolanaRpc, devnet } from "@solana/kit";
import fs from "fs";

// Configure for Solana Devnet
await setWhirlpoolsConfig("solanaDevnet");
await setRpc("https://api.devnet.solana.com");

// Load wallet from keypair file
const keyPairBytes = new Uint8Array(
  JSON.parse(fs.readFileSync("./keypair.json", "utf8"))
);
const wallet = await setPayerFromBytes(keyPairBytes);

// Create RPC connection
const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

console.log("Wallet:", wallet.address);

Basic Setup (Legacy SDK)

import { WhirlpoolContext, buildWhirlpoolClient, ORCA_WHIRLPOOL_PROGRAM_ID } from "@orca-so/whirlpools-sdk";
import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
import { Connection, Keypair } from "@solana/web3.js";
import fs from "fs";

// Setup connection
const connection = new Connection("https://api.mainnet-beta.solana.com", "confirmed");

// Load wallet
const secretKey = JSON.parse(fs.readFileSync("./keypair.json", "utf8"));
const wallet = new Wallet(Keypair.fromSecretKey(new Uint8Array(secretKey)));

// Create provider and context
const provider = new AnchorProvider(connection, wallet, {});
const ctx = WhirlpoolContext.from(connection, wallet, ORCA_WHIRLPOOL_PROGRAM_ID);
const client = buildWhirlpoolClient(ctx);

console.log("Wallet:", wallet.publicKey.toString());

Token Swaps

Swap with New SDK

import { swap, swapInstructions, setWhirlpoolsConfig } from "@orca-so/whirlpools";
import { address } from "@solana/kit";

await setWhirlpoolsConfig("solanaMainnet");

const poolAddress = address("POOL_ADDRESS_HERE");
const inputMint = address("INPUT_TOKEN_MINT");
const amount = 1_000_000n; // Amount in smallest units
const slippageTolerance = 100; // 100 bps = 1%

// Option 1: Use the simple swap function (builds and sends)
const txId = await swap(
  rpc,
  { inputAmount: amount, mint: inputMint },
  poolAddress,
  slippageTolerance,
  wallet
);

console.log("Swap transaction:", txId);

// Option 2: Get instructions for custom transaction building
const { instructions, quote } = await swapInstructions(
  rpc,
  { inputAmount: amount, mint: inputMint },
  poolAddress,
  slippageTolerance,
  wallet
);

console.log("Expected output:", quote.tokenEstOut);
console.log("Minimum output:", quote.tokenMinOut);
console.log("Price impact:", quote.priceImpact);

Exact Output Swap

// Swap to get exact output amount
const { instructions, quote } = await swapInstructions(
  rpc,
  { outputAmount: 1_000_000n, mint: outputMint },
  poolAddress,
  slippageTolerance,
  wallet
);

console.log("Max input required:", quote.tokenMaxIn);

Swap with Legacy SDK

import { WhirlpoolContext, swapQuoteByInputToken, buildWhirlpoolClient } from "@orca-so/whirlpools-sdk";
import { DecimalUtil, Percentage } from "@orca-so/common-sdk";
import Decimal from "decimal.js";

// Get the pool
const whirlpool = await client.getPool(poolAddress);
const whirlpoolData = whirlpool.getData();

// Get swap quote
const inputAmount = new Decimal("1.0"); // 1 token
const quote = await swapQuoteByInputToken(
  whirlpool,
  whirlpoolData.tokenMintA,
  DecimalUtil.toBN(inputAmount, 9), // 9 decimals
  Percentage.fromFraction(1, 100), // 1% slippage
  ctx.program.programId,
  ctx.fetcher
);

console.log("Estimated output:", quote.estimatedAmountOut.toString());

// Execute swap
const tx = await whirlpool.swap(quote);
const signature = await tx.buildAndExecute();
console.log("Swap signature:", signature);

Liquidity Provision

Position Types

Concentrated Liquidity Position: Provide liquidity within a specific price range for higher capital efficiency.

Full Range Position (Splash Pool): Provide liquidity across the entire price range, similar to traditional AMMs.

Open Concentrated Liquidity Position

import { openPosition, openPositionInstructions } from "@orca-so/whirlpools";
import { address } from "@solana/kit";

const poolAddress = address("POOL_ADDRESS");
const lowerPrice = 0.001;  // Lower bound of price range
const upperPrice = 100.0;  // Upper bound of price range
const slippageTolerance = 100; // 1%

// Specify liquidity by token amount
const param = { tokenA: 1_000_000_000n }; // 1 token with 9 decimals

// Option 1: Simple function that builds and sends
const txId = await openPosition(
  rpc,
  poolAddress,
  param,
  lowerPrice,
  upperPrice,
  slippageTolerance,
  wallet
);

// Option 2: Get instructions for custom transaction
const {
  instructions,
  quote,
  positionMint,
  initializationCost
} = await openPositionInstructions(
  rpc,
  poolAddress,
  param,
  lowerPrice,
  upperPrice,
  slippageTolerance,
  wallet
);

console.log("Position mint:", positionMint);
console.log("Token A required:", quote.tokenEstA);
console.log("Token B required:", quote.tokenEstB);
console.log("Initialization cost:", initializationCost);

Open Full Range Position

import { openFullRangePosition, openFullRangePositionInstructions } from "@orca-so/whirlpools";

const poolAddress = address("POOL_ADDRESS");
const param = { tokenA: 1_000_000_000n };
const slippageTolerance = 100;

const {
  instructions,
  quote,
  positionMint,
  callback: sendTx
} = await openFullRangePositionInstructions(
  rpc,
  poolAddress,
  param,
  slippageTolerance,
  wallet
);

console.log("Position mint:", positionMint);
console.log("Token max B:", quote.tokenMaxB);

// Send the transaction
const txId = await sendTx();
console.log("Transaction:", txId);

Increase Position Liquidity

import { increaseLiquidity, increaseLiquidityInstructions } from "@orca-so/whirlpools";

const positionMint = address("POSITION_MINT");
const param = { tokenA: 500_000_000n }; // Add 0.5 tokens
const slippageTolerance = 100;

const { instructions, quote } = await increaseLiquidityInstructions(
  rpc,
  positionMint,
  param,
  slippageTolerance,
  wallet
);

console.log("Additional Token A:", quote.tokenEstA);
console.log("Additional Token B:", quote.tokenEstB);

Decrease Position Liquidity

import { decreaseLiquidity, decreaseLiquidityInstructions } from "@orca-so/whirlpools";

const positionMint = address("POSITION_MINT");
const param = { liquidity: 1000000n }; // Or use tokenA/tokenB
const slippageTolerance = 100;

const { instructions, quote } = await decreaseLiquidityInstructions(
  rpc,
  positionMint,
  param,
  slippageTolerance,
  wallet
);

console.log("Token A received:", quote.tokenEstA);
console.log("Token B received:", quote.tokenEstB);

Harvest Fees and Rewards

import { harvestPosition, harvestPositionInstructions, harvestAllPositionFees } from "@orca-so/whirlpools";

// Harvest single position
const positionMint = address("POSITION_MINT");

const { instructions, feesQuote, rewardsQuote } = await harvestPositionInstructions(
  rpc,
  positionMint,
  wallet
);

console.log("Fee Token A:", feesQuote.feeOwedA);
console.log("Fee Token B:", feesQuote.feeOwedB);
console.log("Rewards:", rewardsQuote);

// Harvest all positions at once
const { instructions: harvestAllIx, fees, rewards } = await harvestAllPositionFees(
  rpc,
  wallet.address
);

Close Position

import { closePosition, closePositionInstructions } from "@orca-so/whirlpools";

const positionMint = address("POSITION_MINT");
const slippageTolerance = 100;

const { instructions, quote, feesQuote } = await closePositionInstructions(
  rpc,
  positionMint,
  slippageTolerance,
  wallet
);

console.log("Token A returned:", quote.tokenEstA);
console.log("Token B returned:", quote.tokenEstB);
console.log("Fees collected:", feesQuote);

Pool Management

Create Splash Pool (Full Range)

import { createSplashPool, createSplashPoolInstructions } from "@orca-so/whirlpools";
import { address } from "@solana/kit";

const tokenMintA = address("TOKEN_A_MINT");
const tokenMintB = address("TOKEN_B_MINT");
const initialPrice = 1.5; // Price of token B in terms of token A

const {
  instructions,
  poolAddress,
  initializationCost
} = await createSplashPoolInstructions(
  rpc,
  tokenMintA,
  tokenMintB,
  initialPrice,
  wallet
);

console.log("Pool address:", poolAddress);
console.log("Initialization cost:", initializationCost, "lamports");

Create Concentrated Liquidity Pool

import { createConcentratedLiquidityPool, createConcentratedLiquidityPoolInstructions } from "@orca-so/whirlpools";

const tokenMintA = address("TOKEN_A_MINT");
const tokenMintB = address("TOKEN_B_MINT");
const tickSpacing = 64; // Common values: 1, 8, 64, 128
const initialPrice = 1.5;

const {
  instructions,
  poolAddress,
  initializationCost
} = await createConcentratedLiquidityPoolInstructions(
  rpc,
  tokenMintA,
  tokenMintB,
  tickSpacing,
  initialPrice,
  wallet
);

console.log("Pool address:", poolAddress);

Fetch Pool Data

import {
  fetchSplashPool,
  fetchConcentratedLiquidityPool,
  fetchWhirlpoolsByTokenPair
} from "@orca-so/whirlpools";

// Fetch specific pool
const pool = await fetchConcentratedLiquidityPool(rpc, poolAddress);
console.log("Current price:", pool.price);
console.log("Liquidity:", pool.liquidity);
console.log("Fee rate:", pool.feeRate);

// Fetch all pools for a token pair
const pools = await fetchWhirlpoolsByTokenPair(rpc, tokenMintA, tokenMintB);
for (const pool of pools) {
  console.log("Pool:", pool.address, "Tick spacing:", pool.tickSpacing);
}

Fetch Positions

import { fetchPositionsForOwner, fetchPositionsInWhirlpool } from "@orca-so/whirlpools";

// Get all positions owned by a wallet
const positions = await fetchPositionsForOwner(rpc, wallet.address);
for (const position of positions) {
  console.log("Position:", position.positionMint);
  console.log("Liquidity:", position.liquidity);
  console.log("Lower tick:", position.tickLowerIndex);
  console.log("Upper tick:", position.tickUpperIndex);
}

// Get all positions in a specific pool
const poolPositions = await fetchPositionsInWhirlpool(rpc, poolAddress);

SDK Configuration

Network Configuration

import { setWhirlpoolsConfig } from "@orca-so/whirlpools";

// Built-in presets
await setWhirlpoolsConfig("solanaMainnet");
await setWhirlpoolsConfig("solanaDevnet");
await setWhirlpoolsConfig("eclipseMainnet");
await setWhirlpoolsConfig("eclipseTestnet");

// Custom configuration
await setWhirlpoolsConfig({
  whirlpoolsConfigAddress: address("CUSTOM_CONFIG_ADDRESS"),
  // ... other custom settings
});

Transaction Settings

import {
  setRpc,
  setPriorityFeeSetting,
  setJitoTipSetting,
  setComputeUnitMarginMultiplier,
  setDefaultSlippageToleranceBps,
  setDefaultFunder,
  setNativeMintWrappingStrategy
} from "@orca-so/whirlpools";

// Set RPC endpoint
await setRpc("https://api.mainnet-beta.solana.com");

// Configure priority fees
await setPriorityFeeSetting({
  type: "dynamic",
  percentile: 75, // Use 75th percentile of recent fees
});

// Or set fixed priority fee
await setPriorityFeeSetting({
  type: "fixed",
  microLamports: 10000,
});

// Configure Jito tips for MEV protection
await setJitoTipSetting({
  type: "dynamic",
  percentile: 50,
});

// Set compute unit margin (for larger transactions)
await setComputeUnitMarginMultiplier(1.2);

// Set default slippage tolerance (in bps)
await setDefaultSlippageToleranceBps(100); // 1%

// Set default funder for transactions
await setDefaultFunder(wallet);

// Configure SOL wrapping behavior
await setNativeMintWrappingStrategy("ata"); // or "none"

Reset Configuration

import { resetConfiguration } from "@orca-so/whirlpools";

// Reset all settings to defaults
await resetConfiguration();

Tick Spacing Reference

Tick spacing determines the granularity of price ranges:

| Tick Spacing | Use Case | Fee Tier |

|--------------|----------|----------|

| 1 | Stablecoins (e.g., USDC/USDT) | 0.01% |

| 8 | Correlated pairs | 0.04% |

| 64 | Standard pairs | 0.30% |

| 128 | Exotic/volatile pairs | 1.00% |


Best Practices

Security

  • Never expose private keys - Use environment variables or secure key management
  • Verify pool addresses - Always confirm you're interacting with legitimate pools
  • Use slippage protection - Set appropriate slippage tolerance to prevent front-running
  • Test on devnet first - Validate all operations before mainnet deployment

Performance

  • Use priority fees - Essential for mainnet transactions during high congestion
  • Batch operations - Combine multiple instructions when possible
  • Pre-fetch data - Cache pool and position data to reduce RPC calls

Liquidity Provision

  • Monitor positions - Track when positions go out of range
  • Rebalance strategically - Consider gas costs when adjusting positions
  • Harvest regularly - Collect fees and rewards to compound returns
  • Understand impermanent loss - Concentrated positions have amplified IL risk

Error Handling

try {
  const txId = await swap(rpc, swapParams, poolAddress, slippage, wallet);
} catch (error) {
  if (error.message.includes("SlippageExceeded")) {
    console.error("Slippage tolerance exceeded, try increasing slippage");
  } else if (error.message.includes("InsufficientFunds")) {
    console.error("Not enough tokens in wallet");
  } else if (error.message.includes("TickArrayNotInitialized")) {
    console.error("Price range tick arrays not initialized");
  } else {
    throw error;
  }
}

Resources

Official Documentation

GitHub Repositories

NPM Packages

Security Audits

  • Kudelski Security audit
  • Neodyme audit

Skill Structure

orca/
├── SKILL.md                              # This file
├── resources/
│   ├── api-reference.md                  # Complete SDK function reference
│   └── program-addresses.md              # Program IDs and common pool addresses
├── examples/
│   ├── swap/
│   │   └── token-swap.ts                 # Token swap examples
│   ├── liquidity/
│   │   ├── open-position.ts              # Open liquidity positions
│   │   ├── manage-position.ts            # Increase/decrease liquidity
│   │   └── harvest-fees.ts               # Collect fees and rewards
│   └── pools/
│       └── create-pool.ts                # Pool creation examples
├── templates/
│   └── setup.ts                          # Ready-to-use client template
└── docs/
    └── troubleshooting.md                # Common issues and solutions

Other skills for the same job

different authors, same section of the catalogue
MCP Builder
by anthropics
vendor ×13

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

30k tokens scripts
Changelog Generator
by frostant
×9

Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.

774 tokens
Finishing A Development Branch
by ZhanlinCui
×7

Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup

1k tokens
MCP Builder
by JayZeeDesign
×7

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

37k tokens scripts
Vercel React Native Skills
by vercel-labs
vendor ×6

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

39k tokens
Vercel React Best Practices
by ratacat
×5

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

34k tokens
Next Best Practices
by vercel-labs
vendor ×4

Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling

20k tokens
Using Git Worktrees
by ZhanlinCui
×4

Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification

1k tokens

How to use it

Copy the folder

Take sendaifun/orca from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.

Install what it needs

The instructions reference npm. Without those the skill loads but fails at the first command.