swap-tokens
DEX(分散型取引所)でトークンをスワップする Skill です。デフォルトは dry-run(シミュレーション) であり、--broadcast を明示した場合のみ実際のトランザクションが送信されます。AI エージェントが「USDC を ETH にスワップして」「100 USDC を WETH に交換して」といった指示を受けたとき、このSkillが起動します。
このページは
packages/skills/skills/swap-tokens/の実装に基づきます。
実装ステータス: 利用可能 — Uniswap V3 + Permit2 + Universal Router 経由 (ADR-042)。Coinbase agentic wallet 同等の UX。registered token symbol・native ETH・任意 ERC-20 contract address 直接指定に対応 (address 直入力は ADR-051)。
トリガー条件
以下のような自然言語の指示でこの Skill が呼び出されます。
- “USDC を ETH にスワップして”
- “100 USDC を WETH に交換して”
- “Polygon で USDC を WETH にスワップ”
- “ステーブルコイン同士を交換して”
実行されるコマンド
kova swap --name <wallet> --from <symbol|address> --to <symbol|address> --amount <amount> \
[--slippage <percent>] [--chain <chain>] [--owner] \
[--unlimited-approve] [--recipient <address>] [--broadcast]--from / --to には registered token symbol (USDC / WETH / native ETH 等) のほか、
未登録 ERC-20 の contract address (0x...) を直接渡せます。address 直入力時は decimals / symbol を
on-chain から取得し、symbol() は信用せず address を canonical identity として扱います (偽トークン対策)。
Permit2 セットアップ (重要)
Agent モードで swap を実行する前に、sign_allowlist policy に Permit2 typed data entry を登録する必要があります (DEV-864 default-deny 解除)。
{
"type": "sign_allowlist",
"domain": {
"name": "Permit2",
"verifyingContract": "0x000000000022D473030F116dDEE9F6B43aC78BA3",
"chainId": 8453
},
"primaryType": "PermitSingle",
"spender": "0x6ff5693b99212da76ad316178a184ab56d299b43",
"maxValue": "1000000"
}上の例は Base (chainId 8453) で Universal Router V2.0 (0x6ff5...e9de5) に対する PermitSingle 署名のうち details.amount <= 1,000,000 のものを許可します。
重要: maxValue は raw amount cap であり、token-specific 制限ではありません。USDC (6 decimals) で 1,000,000 は 1 USDC 相当ですが、同じ cap は WETH (18 decimals) では 10⁻¹² 単位として評価されます。トークン別に上限を分けたい場合は別 rule entry を追加してください (現状の rule schema では details.token を評価しないため、「Permit2 + chain + spender + raw amount cap」の組み合わせのみで gate します)。
未登録のまま broadcast すると POLICY_DENIED で fail-closed します。
オプション
| オプション | 説明 | デフォルト |
|---|---|---|
--name | ウォレット名(必須) | - |
--from | 元トークンの symbol または ERC-20 address(必須) | - |
--to | 受取トークンの symbol または ERC-20 address(必須) | - |
--amount | スワップ額(必須) | - |
--slippage | 許容スリッページ(%) | 0.5 |
--chain | チェーン名 | base |
--owner | ローカル passphrase で署名 (OWS API key を使わない) | false |
--unlimited-approve | Permit2 max approve + 1 年 expiry の opt-in (UX 改善 / blast radius 増) | false |
--recipient | swap 出力の受取アドレス | sender |
--broadcast | 実際にトランザクションを送信する | false(dry-run) |
入力バリデーション
CLI にコマンドを渡す前に、すべてのユーザー入力を検証します。未検証の入力は絶対にコマンドに渡しません。
| パラメータ | ルール |
|---|---|
name | 英数字とハイフンのみ |
from | registered token symbol または ERC-20 contract address (0x...) |
to | registered token symbol または ERC-20 contract address。from とは解決後 address で異なること |
amount | ^\d+(\.\d+)?$ 形式のみ。負の値・指数表記・シェルメタキャラクタは拒否。小数桁は token decimals 以下、base-unit 変換後 0 は拒否 |
slippage | 0.1 から 50.0 の範囲 |
chain | サポートされているチェーン名のみ |
対応チェーンとトークン
registered token は symbol、未登録 ERC-20 は contract address 直接指定で swap できます。native swap は ETH-native chain (Base / Ethereum / Arbitrum / Optimism) の ETH のみ対応 (Polygon の native POL は未対応)。
| Chain | registered token symbol | native |
|---|---|---|
| Base | USDC, WETH (+ USDbC) | ETH |
| Ethereum | USDC, USDT, WETH, JPYC | ETH |
| Polygon | USDC, USDT, WETH, JPYC | — (native POL swap は未対応。ETH は WETH alias) |
| Arbitrum | USDC, USDT, USDC.e, WETH | ETH |
| Optimism | USDC, USDT, USDC.e, WETH | ETH |
registered 一覧に無いトークンは
--from 0x.../--to 0x...で address 直接指定できます。symbol()は信用せず address を canonical identity として扱い、未検証トークンには警告が出力されます。fee-on-transfer / rebase トークンは Permit2 制約で非対応です (ADR-051 既知制限)。
出力例
dry-run(見積もり)
{
"ok": true,
"data": {
"dryRun": true,
"swap": {
"from": { "token": "USDC", "amount": "100.0" },
"to": {
"token": "WETH",
"estimatedAmount": "0.025",
"minimumAmount": "0.024875"
},
"route": ["USDC", "WETH"],
"dex": "Uniswap V3 (via Universal Router)",
"gasEstimate": "180000",
"slippage": "0.5%"
},
"permit2": {
"address": "0x000000000022D473030F116dDEE9F6B43aC78BA3",
"needsApprove": true
}
}
}broadcast(実際のスワップ)
{
"ok": true,
"data": {
"dryRun": false,
"txHash": "0xabcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
"explorerUrl": "https://basescan.org/tx/0xabcdef...",
"swap": {
"from": { "token": "USDC", "amount": "100.0" },
"to": {
"token": "WETH",
"estimatedAmount": "0.025",
"minimumAmount": "0.024875"
},
"route": ["USDC", "WETH"],
"dex": "Uniswap V3 (via Universal Router)"
},
"gasSponsored": false
}
}エラーハンドリング
残高不足
{
"ok": false,
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "Insufficient USDC balance: required 100, available 50"
}
}check-balance Skill でスワップ元トークンの残高を確認してください。
ガス不足
{
"ok": false,
"error": {
"code": "INSUFFICIENT_GAS",
"message": "Insufficient ETH for gas"
}
}スワップにはネイティブトークン(ETH, POL 等)のガス代が必要です。残高を確認して補充してください。
スリッページ超過
{
"ok": false,
"error": {
"code": "SLIPPAGE_EXCEEDED",
"message": "Price moved beyond slippage tolerance"
}
}--slippage を増やすか、市場が落ち着くのを待って再実行してください。
ルートが見つからない
{
"ok": false,
"error": {
"code": "NO_ROUTE_FOUND",
"message": "No swap route found for TOKEN_A → TOKEN_B"
}
}中間トークン(USDC など)を経由するか、別のチェーンを試してください。
使用例
推奨ワークフロー:残高確認 → dry-run → broadcast
# 1. 残高確認
kova balance
# 2. dry-run で見積もりを確認
kova swap \
--name my-wallet \
--from USDC \
--to WETH \
--amount 100 \
--chain base
# 3. 見積もりに問題なければ broadcast
kova swap \
--name my-wallet \
--from USDC \
--to WETH \
--amount 100 \
--chain base \
--broadcastスリッページのカスタマイズ
# ステーブルコイン同士は低めに
kova swap \
--name my-wallet \
--from USDC \
--to USDT \
--amount 1000 \
--slippage 0.1 \
--chain base \
--broadcast
# ボラティリティが高い時は広めに
kova swap \
--name my-wallet \
--from WETH \
--to USDC \
--amount 0.1 \
--slippage 1.0 \
--chain base \
--broadcastPermit2 Approve の挙動
- デフォルトでは最小権限を優先し、ERC-20
approve(Permit2, amountIn)が不足している場合だけ approve tx を送信します。 - 次回 swap 額に対して ERC-20 allowance to Permit2 が足りなければ、再度 approve が必要です。
- Permit2 signed permit のデフォルトは、必要 amount + 24 時間 expiry です。
--unlimited-approveは ERC-20 approve / Permit2 signed permit ともに max amount + 1 年 expiry にする opt-in です。allowance / expiry が十分な間、ERC-20 approve と PermitSingle 署名を skip しやすくなりますが、blast radius は大きくなります。
スリッページの目安
| 状況 | 推奨値 |
|---|---|
| ステーブルコイン同士 | 0.1% – 0.3% |
| 通常の市場 | 0.5% – 1.0% |
| ボラティリティが高い | 1.0% – 3.0% |
| 流動性が低いペア | 3.0% – 5.0% |
プライスインパクトの目安
| プライスインパクト | 評価 |
|---|---|
| < 1% | 影響小(良好) |
| 1% – 3% | 中程度(許容範囲) |
| > 3% | 影響大(分割を検討) |
関連項目
- Skills 概要 — 全 Skill の一覧とセキュリティ仕様
- check-balance — スワップ前の残高確認
- send-tokens — スワップ後の送金
- manage-config — デフォルトチェーン・ウォレットの設定