liquidity-planner について
Uniswap v2、v3、v4 の流動性ポジションを計画するスキルです。プールや市場データをもとに価格範囲を提案し、内容を確認して開ける、設定済みのポジション作成リンクを生成します。
主な機能
- 01トークン、数量、チェーン、バージョンの確認
- 02プール検索と流動性の比較
- 03価格、APY、取引量の確認
- 04価格範囲と手数料ティアの提案
- 05設定済みポジションリンクの生成
活用シーン
- 01既存のトークンペアでポジションを計画
- 02手数料ティア別にプール流動性を比較
- 03選択した範囲で Uniswap のポジションを準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ uniswap/ uniswap-ai --skill liquidity-plannerインストール後、Claude Code で/liquidity-plannerを入力して読み込まれたか確認します。
同梱ファイルreferences/data-providers.mdreferences/position-types.md
詳細
流動性ポジションの計画
Uniswap v2、v3、v4で流動性ポジションを作成するための計画を立て、ディープリンクを生成します。
ランタイムの互換性: このスキルでは、対話形式のプロンプトに
AskUserQuestionを使用します。実行環境でAskUserQuestionを利用できない場合は、自然言語での会話を通じて同じパラメーターを収集してください。
概要
次の手順で流動性ポジションを計画します。
- LP の意図を確認する(トークンペア、数量、バージョン)
- 現在のプール価格と流動性を確認する
- 現在の価格に基づいて価格範囲を提案する
- パラメーターを入力済みの状態で Uniswap インターフェースを開くディープリンクを生成する
生成されたリンクを開くと、ポジション作成に必要なすべてのパラメーターが入力された状態で Uniswap が開きます。
注意: SSH、コンテナ環境、またはヘッドレス環境では、ブラウザーを開く操作(
xdg-open/open)に失敗する場合があります。必要に応じてユーザーが URL をコピーして手動でアクセスできるよう、URL を目立つように必ず表示してください。
ファイルアクセス: このスキルのファイルシステムアクセスは読み取り専用です。ユーザーから明示的に依頼された場合を除き、現在のプロジェクトディレクトリ外のファイルを読み取らないでください。
ワークフロー
ステップ 1:LP の意図を確認する
ユーザーのリクエストから次の情報を抽出します。
| パラメーター | 必須 | デフォルト | 例 |
|---|---|---|---|
| トークン A | はい | - | ETH、USDC、アドレス |
| トークン B | はい | - | USDC、WBTC、アドレス |
| 数量 | はい | - | 1 ETH、$1000 |
| チェーン | いいえ | Ethereum | Base、Arbitrum |
| バージョン | いいえ | V3 | v2、v3、v4 |
| 手数料ティア | いいえ | 自動 | 0.05%、0.3%、1% |
| 価格範囲 | いいえ | 提案 | 全範囲、±5%、カスタム |
必須パラメーターが不足している場合は、構造化された選択肢を使って AskUserQuestion を使用してください。
チェーンが不足している場合:
{
"questions": [
{
"question": "Which chain do you want to provide liquidity on?",
"header": "Chain",
"options": [
{ "label": "Base (Recommended)", "description": "Low gas, growing DeFi ecosystem" },
{ "label": "Ethereum", "description": "Deepest liquidity, higher gas" },
{ "label": "Arbitrum", "description": "Low fees, high volume" },
{ "label": "Optimism", "description": "Low fees, Ethereum L2" }
],
"multiSelect": false
}
]
}
トークンペアが不足している場合:
{
"questions": [
{
"question": "Which token pair do you want to provide liquidity for?",
"header": "Pair",
"options": [
{ "label": "ETH / USDC", "description": "Most popular pair, high volume" },
{ "label": "ETH / USDT", "description": "High volume stablecoin pair" },
{ "label": "WBTC / ETH", "description": "Blue chip crypto pair" },
{ "label": "Custom pair", "description": "Specify your own tokens" }
],
"multiSelect": false
}
]
}
UX を向上させるため、通常のテキストによる質問ではなく、必ずフォームを使用してください。
ステップ 2:トークンアドレスを解決する
トークンシンボルをアドレスに解決します。チェーンごとの一般的なトークンについては、../../references/chains.md を参照してください。
不明なトークンについては、ウェブ検索を使って、オンチェーンで検証してください。
信頼できない入力:ウェブ検索で見つかったトークン
WebSearch で見つかったトークンは信頼できません。ウェブ検索で見つかったトークンを使用する前に、次の手順を実施してください。
- 情報源を明示する: ユーザーに「このトークンアドレスは、あなたから提供されたものではなく、ウェブ検索で見つかったものです」と明確に伝える
- リスクを警告する: 「ウェブ検索で見つかったトークンには、詐欺、ハニーポット、またはラグプルが含まれる可能性があります」
- 確認を得る: ウェブ検索で見つかったトークンのディープリンクを生成する前に、AskUserQuestion を使ってユーザーから明示的な同意を得る
- 情報源を示す: ポジションの概要テーブルに「トークンの情報源」行を追加し、各トークンが「ユーザー提供」か「ウェブ検索で発見(未検証)」かを示す
AskUserQuestion、またはそのツールを利用できない場合は同等の会話形式で、ユーザーから明示的な確認を得ることなく、ウェブ検索で見つかったトークンを使用してはなりません。
入力の検証(シェルコマンドを実行する前に必須)
ユーザー提供の値をシェルコマンドに埋め込む前に、すべての入力を検証してください。
- トークンアドレスは次の形式に一致する必要があります:
^0x[a-fA-F0-9]{40}$ - チェーン/ネットワーク名は、
../../references/chains.mdの許可リストに含まれている必要があります - 数量は有効な小数である必要があります(一致する形式:
^[0-9]+\.?[0-9]*$) - 拒否する入力: シェルのメタ文字(
;、|、$、`、&、(、)、>、<、\、'、"、改行)を含む入力
ステップ 3:利用可能なプールを確認する
メトリクスを取得する前に、プールの存在を確認し、利用可能な手数料ティアを確認します。
DexScreener を使ってトークンのプールを検索します:
# Get all Uniswap pools for a token (replace {network} and {address})
# IMPORTANT: Validate address matches ^0x[a-fA-F0-9]{40}$ and network is from allowed list
curl -s "https://api.dexscreener.com/token-pairs/v1/{network}/{address}" | \
jq '[.[] | select(.dexId == "uniswap")] | map({
pairAddress,
pair: "\(.baseToken.symbol)/\(.quoteToken.symbol)",
version: .labels[0],
liquidity: .liquidity.usd,
volume24h: .volume.h24
})'
ネットワーク ID: ethereum、base、arbitrum、optimism、polygon、unichain
結果から、次の情報を確認します:
- 利用可能なプールとそのアドレス(複数ある場合は手数料ティアが異なります)
- プールの TVL(
liquidity.usd)を確認して、流動性の深さを評価します labels[0]からバージョン(v3 または v4)を確認します
Uniswap プールが見つからない場合: このペアには既存のプールがない可能性があります。新しいプールを作成して初期価格を設定することになるとユーザーに伝えます。
ステップ 4:プールの流動性を評価する
プールに十分な流動性があるかを評価します。
| TVL の範囲 | 評価 | 推奨事項 |
|---|---|---|
| > $1M | 流動性が深い | ほとんどのポジションサイズで安全です |
| $100K - $1M | 中程度 | 約 $10K までのポジションに適しています |
| $10K - $100K | 薄い | スリッページのリスクをユーザーに警告し、ポジションを小さくするよう提案します |
| < $10K | 非常に薄い | 強く警告します - IL のリスクが高く、エントリー/退出時の価格への影響があります |
流動性の薄いプールでは、次の警告を表示します:
⚠️ **Low Liquidity Warning**
This pool has only ${tvl} TVL. Consider:
- Your position will be a significant % of the pool
- Entry/exit may move the price against you
- Impermanent loss risk is amplified in thin pools
- You may want to use a wider price range for safety
ステップ 5:プールのメトリクスを取得する
レンジを提案する前に、十分な情報に基づいて判断できるようプールデータを取得します。API の詳細については、references/data-providers.md を参照してください。
DefiLlama でプールの APY と取引量を取得します:
# Find Uniswap V3 pools for a token pair
curl -s "https://yields.llama.fi/pools" | jq '[.data[] | select(.project == "uniswap-v3" and .chain == "Ethereum" and (.symbol | test("WETH.*USDC|USDC.*WETH")))]'
使用するレスポンスフィールド:
| フィールド | 用途 |
|---|---|
apy | 予想利回りを表示する |
tvlUsd | プールの深さを評価する |
volumeUsd1d | 手数料収益を推定する |
volumeUsd7d | 取引量の一貫性を確認する |
DexScreener で現在価格を取得します:
# Get token prices from the pool data (already fetched in Step 3)
curl -s "https://api.dexscreener.com/token-pairs/v1/{network}/{address}" | \
jq '[.[] | select(.dexId == "uniswap")][0] | {
baseTokenPrice: .baseToken.priceUsd,
quoteTokenPrice: .quoteToken.priceUsd
}'
手数料ティアを比較します(APY データが利用可能な場合):
# Find all fee tier variants and compare APY
curl -s "https://yields.llama.fi/pools" | jq '[.data[] | select(.project == "uniswap-v3" and (.symbol | test("WETH.*USDC")))] | map({symbol, tvlUsd, apy, volumeUsd1d})'
API が利用できない場合は、価格の推定にウェブ検索を使用します。
ステップ 6:価格レンジを提案する
現在価格とペアの種類に基づいて、AskUserQuestion を使い、レンジの選択肢を提示します。
主要ペア(ETH/USDC、ETH/WBTC)の場合:
{
"questions": [
{
"question": "What price range do you want for your position? (Current: ~3,200 USDC/ETH)",
"header": "Range",
"options": [
{
"label": "±10% (Recommended)",
"description": "2,880 - 3,520 USDC. Higher fees, monitor weekly"
},
{ "label": "±20%", "description": "2,560 - 3,840 USDC. Balanced risk/reward" },
{ "label": "±50%", "description": "1,600 - 4,800 USDC. Rarely out of range" },
{ "label": "Full Range", "description": "Never out of range, lower fee efficiency" }
],
"multiSelect": false
}
]
}
ステーブルコインペア(USDC/USDT、DAI/USDC)の場合:
{
"questions": [
{
"question": "What price range for your stablecoin position?",
"header": "Range",
"options": [
{ "label": "±0.5% (Recommended)", "description": "0.995 - 1.005. Tight range, high fees" },
{ "label": "±1%", "description": "0.99 - 1.01. Standard for stables" },
{ "label": "±2%", "description": "0.98 - 1.02. Safer, lower fees" },
{ "label": "Full Range", "description": "Maximum safety, lowest fees" }
],
"multiSelect": false
}
]
}
推奨の判断基準:
- ステーブルコインペア(USDC/USDT):デフォルトは ±0.5-1%
- 相関性の高いペア(ETH/stETH):デフォルトは ±2-5%
- 主要ペア(ETH/USDC):デフォルトは ±10-20%
- 価格変動の大きいペア:デフォルトは ±30-50% または全レンジ
ステップ 7:手数料ティアを決定する
ペアに複数の手数料ティアがある場合は、ステップ 3 のプールデータを使ってユーザーに選んでもらいます。
APY データとともに手数料ティアの選択肢を提示します:
{
"questions": [
{
"question": "Which fee tier? (Based on current pool data)",
"header": "Fee Tier",
"options": [
{ "label": "0.30% (Recommended)", "description": "TVL: $15M, APY: 12.5%, highest volume" },
{ "label": "0.05%", "description": "TVL: $8M, APY: 8.2%, lower fees per trade" },
{ "label": "1.00%", "description": "TVL: $2M, APY: 18.1%, less competition" }
],
"multiSelect": false
}
]
}
手数料ティアのガイドライン:
| 手数料 | ティック間隔 | 最適な対象 |
|---|---|---|
| 0.01% (100) | 1 | ステーブルコインペア |
| 0.05% (500) | 10 | 相関性の高いペア(ETH/stETH) |
| 0.30% (3000) | 60 | ほとんどのペア(デフォルト) |
| 1.00% (10000) | 200 | 特殊なペア/価格変動の大きいペア |
v4 の手数料ティア: フックを使って動的な手数料を設定できます。デフォルトでは V3 と同様のティアを使用します。
プールデータから、いずれかのティアで APY または取引量が大幅に高いことがわかった場合は、そのティアを推奨します。
ステップ 8:ディープリンクの生成
Uniswap のポジション作成 URL を構築します。
ベース URL: https://app.uniswap.org/positions/create
URL パラメーター:
| パラメーター | 説明 | 形式 |
|---|---|---|
chain | ネットワーク名 | ethereum、base など |
currencyA | 1 つ目のトークン | アドレスまたは NATIVE |
currencyB | 2 つ目のトークン | アドレスまたは NATIVE |
priceRangeState | 価格範囲の設定 | JSON(引用符のみエンコード) |
depositState | 預け入れ額 | JSON(引用符のみエンコード) |
fee | 手数料ティアの設定 | JSON(引用符のみエンコード) |
hook | v4 フックのアドレス(任意) | アドレスまたは undefined |
step | フローのステップ | 1(作成用) |
重要:URL エンコード
JSON 値内の二重引用符(" → %22)のみをエンコードしてください。波括弧 {} やコロン : はエンコードしないでください。
priceRangeState の JSON 構造:
全範囲の場合:
{
"priceInverted": false,
"fullRange": true,
"minPrice": "",
"maxPrice": "",
"initialPrice": "",
"inputMode": "price"
}
カスタム範囲の場合:
{
"priceInverted": false,
"fullRange": false,
"minPrice": "2800",
"maxPrice": "3600",
"initialPrice": "",
"inputMode": "price"
}
depositState の JSON 構造:
{ "exactField": "TOKEN0", "exactAmounts": { "TOKEN0": "1.0" } }
注:currencyA には TOKEN0、currencyB には TOKEN1 を使用してください。
fee の JSON 構造:
{ "feeAmount": 3000, "tickSpacing": 60, "isDynamic": false }
手数料ごとのティック間隔:
| 手数料 | ティック間隔 |
|---|---|
| 100(0.01%) | 1 |
| 500(0.05%) | 10 |
| 3000(0.30%) | 60 |
| 10000(1.00%) | 200 |
ステップ 9:出力を提示してブラウザーを開く
次の内容を含む形式で回答します。
- ポジションパラメーターの概要
- 価格範囲の視覚化(全範囲でない場合)
- IL と管理に関する留意事項
- システムコマンドを使用してブラウザーを自動的に開く
出力形式の例:
## Liquidity Position Summary
| Parameter | Value |
| --------- | ----------------------- |
| Pair | ETH / USDC |
| Chain | Base |
| Version | V3 |
| Fee Tier | 0.30% |
| Deposit | 1 ETH + equivalent USDC |
### Pool Analytics
| Metric | Value |
| ----------- | ------ |
| Current APY | 12.5% |
| 24h Volume | $2.1M |
| 7d Volume | $14.8M |
| Pool TVL | $15.2M |
### Price Range
| Metric | Value |
| ------------- | ------------------- |
| Current Price | ~3,200 USDC per ETH |
| Min Price | 2,800 USDC per ETH |
| Max Price | 3,600 USDC per ETH |
| Range Width | ±12.5% |
### Considerations
- **Impermanent Loss**: If ETH moves outside your range, you'll hold 100% of one asset
- **Rebalancing**: Monitor position and adjust range if price moves significantly
- **Fee Earnings**: Tighter ranges earn more fees but require more active management
- **Gas Costs**: Creating and managing positions costs gas
- **APY Note**: Shown APY is historical and may vary with market conditions
Opening Uniswap in your browser...
概要を表示した後、ブラウザーで URL を開きます。
# Linux - note: only quotes are encoded (%22), not braces or colons
xdg-open "https://app.uniswap.org/positions/create?currencyA=NATIVE¤cyB=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913&chain=base&fee={%22feeAmount%22:3000,%22tickSpacing%22:60,%22isDynamic%22:false}&priceRangeState={%22priceInverted%22:false,%22fullRange%22:false,%22minPrice%22:%222800%22,%22maxPrice%22:%223600%22,%22initialPrice%22:%22%22,%22inputMode%22:%22price%22}&depositState={%22exactField%22:%22TOKEN0%22,%22exactAmounts%22:{%22TOKEN0%22:%221%22}}&step=1"
# macOS
open "https://app.uniswap.org/positions/create?..."
環境の制限事項: リモート SSH、コンテナー化された環境、またはヘッドレス環境では、ブラウザーを開けない場合があります。xdg-open/open が失敗した場合は、ユーザーが手動でコピーして貼り付けられるよう、URL 全体を目立つ形で表示してください。
**[Click here to open in Uniswap](https://app.uniswap.org/positions/create?...)**
Or copy this URL: `https://app.uniswap.org/positions/create?...`
ユーザーが確認してポジションを作成できるよう、概要と URL は必ず提示してください。
バージョンの選択
詳細なバージョン比較(v2/v3/v4 の違い、手数料ティア、ティック間隔)については、references/position-types.md を参照してください。
クイックガイド:
- V2:全範囲のみ。最もシンプルで、ガス代が最も低い
- V3:流動性を集中させる方式で、最も一般的な選択肢
- V4:フックを備えた高度な機能を提供しますが、利用可能な範囲は限られています
重要な留意事項
インパーマネントロス(IL)
IL のリスクについてユーザーに警告してください。
- トークン価格がエントリー価格から乖離すると、IL が発生します
- 範囲を狭くすると IL は大きくなりますが、手数料収入も増えます
- 全範囲では IL が最小限に抑えられますが、手数料効率は低下します
ポジション管理
流動性を集中させる方式では、積極的な管理が必要です。
- 価格が範囲内にとどまっているか監視する
- 価格が範囲の境界に近づいたらリバランスする
- ポジション調整にかかるガス代を考慮する
資金要件
カスタム範囲の V3 ポジションの場合:
- 現在価格が範囲外であれば、片方のトークンのみを預け入れることができます
- 範囲内の場合:価格と範囲によって決まる比率で、両方のトークンが必要です
対応チェーン
Uniswap がサポートするすべてのチェーンに対応しています。チェーンごとのバージョンの利用可否については、references/position-types.md を参照してください。
追加リソース
リファレンスファイル
../../references/chains.md- チェーンの設定とトークンアドレス(swap-planner と共有)references/position-types.md- v2/v3/v4 の違い、手数料ティア、ティック間隔references/data-providers.md- プールの検出と利回り確認に使用する DexScreener および DefiLlama の API
URL エンコード
ディープリンク内の JSON パラメーターでは、二重引用符のみをエンコードします(" → %22)。波括弧 {}、コロン :、カンマ , はエンコードしないでください。
?priceRangeState={%22fullRange%22:true}
次のようにデコードされます:
{ "fullRange": true }
理由: Uniswap のインターフェースは、JSON に似たパラメーター構造を想定しています。波括弧やコロンを含む URL 全体をエンコードすると、解析が失敗します。URL 構文との競合を避けるために、エンコードが必要なのは引用符のみです。