Skip to Content
ReferenceSkillsswap-tokens

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 のものを許可します。

重要: maxValueraw 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-approvePermit2 max approve + 1 年 expiry の opt-in (UX 改善 / blast radius 増)false
--recipientswap 出力の受取アドレスsender
--broadcast実際にトランザクションを送信するfalse(dry-run)

入力バリデーション

CLI にコマンドを渡す前に、すべてのユーザー入力を検証します。未検証の入力は絶対にコマンドに渡しません。

パラメータルール
name英数字とハイフンのみ
fromregistered token symbol または ERC-20 contract address (0x...)
toregistered token symbol または ERC-20 contract address。from とは解決後 address で異なること
amount^\d+(\.\d+)?$ 形式のみ。負の値・指数表記・シェルメタキャラクタは拒否。小数桁は token decimals 以下、base-unit 変換後 0 は拒否
slippage0.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 は未対応)。

Chainregistered token symbolnative
BaseUSDC, WETH (+ USDbC)ETH
EthereumUSDC, USDT, WETH, JPYCETH
PolygonUSDC, USDT, WETH, JPYC— (native POL swap は未対応。ETH は WETH alias)
ArbitrumUSDC, USDT, USDC.e, WETHETH
OptimismUSDC, USDT, USDC.e, WETHETH

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 \ --broadcast

Permit2 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%影響大(分割を検討)

関連項目

Last updated on