mcpField
O
orca

orca

github.com/sendaifun開発130199 回インストール13 週間前に更新
リポジトリ

orca について

orca は、Solana と Eclipse 向けアプリを開発する人のための Orca Whirlpools SDK ガイドです。スワップ、流動性ポジション、プール管理を扱い、新旧両方の SDK の例を掲載しています。

主な機能

  1. 01トークンスワップと見積もり
  2. 02集中型・全範囲の流動性ポジション
  3. 03ポジションの増減、終了、手数料回収
  4. 04プールの作成とデータ取得
  5. 05Solana・Eclipse ネットワーク設定

活用シーン

  1. 01トークンスワップアプリの構築
  2. 02流動性提供とポジション管理機能の開発
  3. 03Whirlpools プールの作成と照会

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sendaifun/skills --skill orca

インストール後、Claude Code で/orcaを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

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

詳細

Orca Whirlpools 開発ガイド

Orca は Solana と Eclipse で最も信頼されている DEX であり、Whirlpools と呼ばれる集中流動性自動マーケットメーカー(CLMM)を基盤としています。このガイドでは、取引、流動性の提供、プール管理アプリケーションを構築するための Whirlpools SDK について説明します。

概要

Orca Whirlpools は以下を提供します。

  • トークンスワップ - スリッページが低く、競争力のあるレートで効率的にトークンを交換できます
  • 集中流動性 - 独自の価格範囲内で流動性を提供し、資本効率を高められます
  • Splash プール - 初心者向けの、シンプルな全範囲流動性の提供方法です
  • ポジション管理 - 流動性ポジションの開設、増加、減少、クローズができます
  • 手数料の獲得 - ポジションから取引手数料と報酬を受け取れます
  • プール作成 - パーミッションレスで新しい流動性プールを作成できます

プログラム ID

ネットワークプログラム ID
Solana MainnetwhirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
Solana DevnetwhirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
Eclipse MainnetwhirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
Eclipse TestnetwhirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc

クイックスタート

インストール

新しい SDK(Solana Web3.js v2):

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

レガシー 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

コアユーティリティ(任意):

npm install @orca-so/whirlpools-core @orca-so/whirlpools-client
基本設定(新しい 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);
基本設定(レガシー 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());

トークンスワップ

新しい 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);
出力数量を指定したスワップ
// 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);
レガシー 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);

流動性の提供

ポジションの種類

集中流動性ポジション:特定の価格範囲内で流動性を提供し、資本効率を高めます。

全範囲ポジション(Splash プール):従来の AMM と同様に、価格範囲全体にわたって流動性を提供します。

集中流動性ポジションを開設する
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);
全範囲ポジションを開設する
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);
ポジションの流動性を増やす
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);
ポジションの流動性を減らす
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);
手数料と報酬を獲得する
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
);
ポジションをクローズする
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);

プール管理

Splash プール(全範囲)を作成する
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");
集中流動性プールを作成する
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);
プールデータを取得する
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);
}
ポジションを取得する
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 の設定

ネットワーク設定
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
});
トランザクション設定
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"
設定をリセットする
import { resetConfiguration } from "@orca-so/whirlpools";

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

ティック間隔のリファレンス

ティック間隔は価格範囲の粒度を決定します。

ティック間隔用途手数料階層
1ステーブルコイン(例:USDC/USDT)0.01%
8相関の高いペア0.04%
64標準的なペア0.30%
128エキゾチック/変動の大きいペア1.00%

ベストプラクティス

セキュリティ
  1. 秘密鍵を決して公開しない - 環境変数または安全な鍵管理を使用してください
  2. プールアドレスを確認する - 正当なプールとやり取りしていることを必ず確認してください
  3. スリッページ保護を使用する - フロントランニングを防ぐため、適切なスリッページ許容度を設定してください
  4. まず Devnet でテストする - Mainnet にデプロイする前に、すべての操作を検証してください
パフォーマンス
  1. 優先手数料を使用する - 混雑が激しいときの Mainnet トランザクションに不可欠です
  2. 操作をまとめる - 可能な場合は複数の命令をまとめてください
  3. データを事前に取得する - RPC 呼び出しを減らすため、プールとポジションのデータをキャッシュしてください
流動性の提供
  1. ポジションを監視する - ポジションが価格範囲外になったタイミングを追跡してください
  2. 戦略的にリバランスする - ポジション調整時にはガス代を考慮してください
  3. 定期的に手数料を獲得する - 手数料と報酬を受け取ってリターンを複利運用してください
  4. インパーマネントロスを理解する - 集中流動性ポジションでは IL のリスクが増幅します
エラー処理
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;
  }
}

リソース

公式ドキュメント
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

コメント