bridge-tokens について
Circle の App Kit または Bridge Kit によるクロスチェーントークン転送を実装するスキルです。SDKとウォレットアダプターの選択、経路検証、見積もり、ユーザー確認、復旧を案内します。
主な機能
- 01App KitまたはBridge Kitの選択
- 02USDCと対応するCCTPxトークンの転送
- 03ウォレットとチェーンアダプターの選択
- 04CCTPx転送前の手数料見積もり
- 05転送の追跡とソフトエラーからの再開
活用シーン
- 01ブラウザーまたはサーバーでのクロスチェーン転送フロー構築
- 02EVMチェーン間またはSolanaとのUSDC転送
- 03EVMチェーン間でのレジストリ登録トークンの転送
- 04途中で失敗した転送の復旧
MCP 対応
Circle の App Kit と Bridge Kit を使うブリッジ処理について、ウォレットアダプター、経路見積もり、転送追跡、復旧を案内します。これらのキットがMCPサーバーであるとは記載されていません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ circlefin/ skills --skill bridge-tokensインストール後、Claude Code で/bridge-tokensを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/adapter-browser-wallet.mdadapter-circle-wallets.mdadapter-private-key.mdadapter-wagmi.mdforwarding-events-recovery.mdnon-usdc-cctpx.md詳細
概要
このスキルは、Circle の App Kit または Bridge Kit を使って、チェーン間でトークンをブリッジします。USDC は Crosschain Transfer Protocol(CCTP)を通じて移動します。送信元チェーンでバーンし、宛先チェーンでミントします。CCTPx トークンでは、レジストリのエイリアス(wETH、cirBTC、EURC など)またはレジストリに登録されたトークン ID を使用します。どちらも同じ kit.bridge() 呼び出しで実行されます。エイリアスまたはトークン ID を token として直接渡すと、SDK が自動的にルーティングするため、プロトコルを選択する必要はありません。App Kit(@circle-fin/app-kit)は、ブリッジ、スワップ、送金を 1 つのパッケージで提供する Circle の包括的な SDK です。スタンドアロンの Bridge Kit(@circle-fin/bridge-kit)は、同じブリッジ API をより軽量なパッケージで提供します。ブリッジ機能のみが必要な場合を除き、App Kit を推奨します。ブリッジ操作にキットキーは必要ありません。
どちらの SDK もブラウザーアプリケーションとサーバーアプリケーションで動作します。クライアントコードではブラウザーウォレットのプロバイダーアダプターを使用し、秘密鍵と Circle Wallets の認証情報はサーバーに保管してください。App Kit >=1.11.0 と Bridge Kit >=1.12.2 は、利用者が用意する Node や Buffer のポリフィルなしでブラウザー向けにバンドルできます。CCTPx トークンには App Kit または Bridge Kit >=1.15.0 が必要です。CCTPx トークンをブリッジするブラウザーアプリには、App Kit >=1.15.2 または Bridge Kit >=1.15.1 が必要です。
サポート対象のトークンとルート
レジストリのエイリアスまたはトークン ID を、kit.bridge() と kit.estimateBridge()(App Kit)/kit.estimate()(Bridge Kit)の token として直接渡してください。プロバイダーセレクターオブジェクトでラップしないでください。SDK が適切なプロトコルへ自動的にルーティングします。Solana をサポートするのは USDC のみです。CCTPx のすべてのルートは EVM から EVM へのルートです。エイリアスでは大文字と小文字が区別されます("WETH" ではなく "wETH")。トークン ID は bytes32 の 16 進文字列です(0x の後に 64 個の 16 進文字が続きます)。
| トークンセレクター | サポート対象のチェーン |
|---|---|
USDC | CCTP がサポートするすべてのチェーン(EVM + Solana)――サポート対象のチェーンを参照 |
EURC | メインネットの Ethereum、Base、Arc、および利用可能なテストネットのルート |
wETH | メインネットの Ethereum <-> Arc、および利用可能なテストネットのルート |
cirBTC | メインネットの Ethereum <-> Arc、および利用可能なテストネットのルート |
| レジストリに登録されたトークン ID | CCTPx レジストリにそのトークンが両方のエンドポイントドメインで登録されている EVM ルート |
CCTPx に対応する EVM チェーンは Ethereum、Arc、Base、Arbitrum、Optimism、Polygon、Avalanche です。チェーンが CCTPx に対応していても、すべてのトークンを任意の別のチェーンへルーティングできるとは限りません。SDK は実行時に Circle から CCTPx トークンレジストリを取得し、選択したトークンが両方のエンドポイントに登録されていない場合は INPUT_UNSUPPORTED_ROUTE をスローします。ルートのリストをハードコードしないでください。
前提条件/セットアップ
インストール
ベースキットは **App Kit(推奨)**またはスタンドアロンの Bridge Kit のどちらか 1 つを選び、必要に応じてアダプターを追加してください。
Viem アダプターを使用する App Kit(推奨):
npm install @circle-fin/app-kit @circle-fin/adapter-viem-v2
# Optional: Solana support
npm install @circle-fin/adapter-solana-kit
# Optional: Circle Wallets (developer-controlled) support
npm install @circle-fin/adapter-circle-wallets
または、ブリッジ専用アプリでは、App Kit の代わりにスタンドアロンの Bridge Kit(より軽量なパッケージ)を使用します。
npm install @circle-fin/bridge-kit @circle-fin/adapter-viem-v2
環境変数
PRIVATE_KEY= # EVM wallet private key (hex, 0x-prefixed)
EVM_PRIVATE_KEY= # EVM private key (when also using Solana)
SOLANA_PRIVATE_KEY= # Solana wallet private key (base58)
CIRCLE_API_KEY= # Circle API key (for Circle Wallets adapter)
CIRCLE_ENTITY_SECRET= # Entity secret (for Circle Wallets adapter)
EVM_WALLET_ADDRESS= # Developer-controlled EVM wallet address
SOLANA_WALLET_ADDRESS= # Developer-controlled Solana wallet address
ブリッジ操作に KIT_KEY は必要ありません。ブラウザーウォレットとの連携では、上記の環境変数はどれも必要ありません。秘密鍵、Circle API キー、エンティティシークレット、App Kit の任意の認証情報をクライアントコードに公開しないでください。
SDK の初期化
App Kit(推奨):
import { AppKit } from "@circle-fin/app-kit";
const kit = new AppKit();
Bridge Kit(スタンドアロン):
import { BridgeKit } from "@circle-fin/bridge-kit";
const kit = new BridgeKit();
選択ガイド
コードを書く前に、必ずユーザーと次の質問を順に確認してください。手順を省略したり、回答を決めつけたりしないでください。
SDK の選択
質問 1 -- 将来的にスワップまたは送金機能が必要になりますか?
- はい、または不明 -> App Kit(推奨) -- 1 つの SDK でブリッジ + スワップ + 送金に対応し、後から拡張しやすくなります
- いいえ、ブリッジ専用で、スワップや送金が今後必要になることもありません -> Bridge Kit -- ブリッジ専用の用途に適した、軽量なスタンドアロンパッケージ
ウォレット/アダプターの選択
質問 2 -- ウォレット/キーをどのように管理していますか?
- 自分で秘密鍵を管理している(セルフカストディ、環境変数またはシークレットマネージャーに保存) -> 質問 3
- Circle の開発者管理ウォレットを使用している(Circle がキーの保管と署名を管理) -> Circle Wallets アダプターを使用します。
references/adapter-circle-wallets.mdを参照してください - EVM ブラウザーウォレットを使用している(wagmi、ConnectKit、RainbowKit、または任意の EIP-1193 プロバイダー) -> Viem プロバイダーアダプターを使用します。
references/adapter-wagmi.mdを参照してください - Solana ブラウザーウォレットを使用している(Phantom、Solflare、Backpack などの Wallet Standard プロバイダー) -> Solana プロバイダーアダプターを使用します。
references/adapter-browser-wallet.mdを参照してください
質問 3 -- どのチェーン間でブリッジしますか?
- EVM 間、または EVM と Solana 間 -> Viem および/または Solana Kit アダプターを使用します。
references/adapter-private-key.mdを参照してください
トークンの選択
質問 4 -- どのトークンをブリッジしますか?
- USDC -> 任意の CCTP ルート(EVM または Solana)。
- wETH、cirBTC、EURC、または CCTPx トークン ID -> EVM 間のみ。
references/non-usdc-cctpx.mdを参照してください。宛先が Solana の場合、またはレジストリにルートが記載されていない場合は停止し、swap-tokensを提案してください。別のチェーンペアに置き換えないでください。
ワークフロー
- 意思決定ガイドを確認する -- コードを書く前に、SDK(App Kit と Bridge Kit のどちらか)とウォレット/アダプターをユーザーと決定します。
- インストールして初期化する -- 選択したキットとアダプターをインストールし、キットとアダプターを構築します(前提条件/セットアップを参照)。
- 送金内容を確認する -- トークン、数量、送信元と宛先のチェーン、受取人を確認します。チェーン名とアドレスを検証します。デフォルトではテストネットを使用し、メインネットの前には明示的な確認を求めます。
- CCTPx トークンの場合は、まず見積もりを取得する -- レジストリが選択した EVM ルートに対応していることを確認し、ユーザーと
FASTとSLOWのどちらにするか決定してから、kit.estimateBridge()(App Kit)またはkit.estimate()(Bridge Kit)を呼び出し、実行前に見積もり手数料を提示します。見積もりの再利用はベストエフォートです。結果にQUOTE_NOT_REUSED警告があれば提示します。 - ブリッジを実行する --
kit.bridge({ token, from, to, amount, ... })を、ユーザーが明示的に操作した場合に限り呼び出します(自動的に呼び出さないでください)。正確なコードについては、アダプターのリファレンスを参照してください。 - 追跡して復旧する --
result.state/result.stepsを確認し、kit.on()を使ってサブスクライブします。一時的な失敗が発生した場合は、kit.retryBridge(result, ...)(App Kit)またはkit.retry(result, ...)(Bridge Kit)で再開します。kit.bridge()を最初から再実行しないでください。
コア概念
- CCTP の手順(USDC):すべての USDC ブリッジ転送は、
approve(ERC-20 の使用許容量を設定)、burn(送信元チェーンで USDC を焼却)、fetchAttestation(Circle が焼却証明に署名するまで待機)、mint(宛先チェーンで USDC を発行)の4つの手順を順番に実行します。 - CCTPx 転送:同じ
kit.bridge({ token, from, to, amount })呼び出しを使用します。レジストリーのエイリアスまたはトークン ID をtokenとして直接渡します。手順はapprove -> transfer -> fetchAttestation -> forwardで、手数料が ERC-20 の場合に限り、transferの前にapproveFeeの手順が追加されます(Circle のリレイヤーが宛先で自動的に発行するため、宛先のガスもuseForwarderの切り替えも不要です)。すべての CCTPx 転送で、送信元チェーンのネイティブトークンによるリレイヤー手数料が発生します。FAST(デフォルト)ではファイナリティ到達前の手数料が追加され、SLOWでは送信元チェーンのファイナリティを待ち、追加手数料をスキップします。ブリッジする前にkit.estimateBridge()(App Kit)またはkit.estimate()(Bridge Kit)を呼び出し、見積もられた手数料をユーザーに提示してください。ブリッジ呼び出しは、ユーザーが明示的に確認した後にのみ実行します。完了を確認するにはresult.state === "success"を確認してください。CCTPx ルートでは、カスタム手数料、feePayment: "destination"、useForwarder: falseは使用できません。 - アダプター:App Kit と Bridge Kit はどちらも、ウォレットや署名者の違いを抽象化するアダプターオブジェクトを使用します。各エコシステムには、それぞれ独自のアダプターファクトリー(
createViemAdapterFromPrivateKey、createSolanaKitAdapterFromPrivateKey、createCircleWalletsAdapter)があります。同じエコシステム内でブリッジする場合は、同じアダプターインスタンスを送信元と宛先の両方に使用できます。 - Forwarding Service:宛先で
useForwarder: trueを設定すると、Circle のインフラストラクチャがアテステーションの取得とミントの送信を処理します。これにより、宛先ウォレットやポーリングループが不要になります。転送ごとに手数料が発生し、金額はルートによって異なります(以下を参照)。 - 転送速度:CCTP のファストモード(デフォルト)は約8~20秒で完了します。標準モードでは約15~19分かかります。
- チェーン識別子:どちらの SDK も、
kit.bridge()呼び出しでは数値のチェーン ID ではなく、文字列のチェーン名(例:"Arc"、"Arc_Testnet"、"Base_Sepolia"、"Solana_Devnet")を使用します。 - ブラウザー対応パッケージ:現在の App Kit、Bridge Kit、Solana アダプターには、必要なブラウザー互換機能が内部に含まれています。ブラウザーからのリクエストでは Node 専用ヘッダーが省略され、Solana の操作にコンシューマー側の
Bufferシムは不要です。ポリフィルを追加するのではなく、古いパッケージをアップグレードしてください。
実装パターン
ユーザーのリクエストに対応するリファレンスを読んでください。
references/adapter-private-key.md-- 秘密鍵アダプター(Viem + Solana Kit)を使用した EVM から EVM、および EVM から Solana へのブリッジ。App Kit と Bridge Kit の例を含みます。references/adapter-circle-wallets.md-- Circle の開発者管理ウォレットを使用したブリッジ(任意のチェーンから任意のチェーンへ)。App Kit と Bridge Kit の例を含みます。references/adapter-wagmi.md-- wagmi(ConnectKit、RainbowKit など)を使用したブラウザーウォレットの統合。App Kit と Bridge Kit の例を含みます。references/adapter-browser-wallet.md-- Wallet Standard プロバイダーを使用した Solana ブラウザーウォレットの統合。手動のポリフィルは不要です。references/non-usdc-cctpx.md-- 対応する EVM ルートでの CCTPx レジストリーエイリアスとトークン ID のブリッジ:ルートの検証、見積もり後の確認フロー、FAST/SLOW 転送速度
kit.bridge() のサンプルレスポンス
{
"amount": "25.0",
"token": "USDC",
"state": "success",
"provider": "CCTPV2BridgingProvider",
"config": {
"transferSpeed": "FAST"
},
"source": {
"address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"chain": {
"type": "evm",
"chain": "Arc_Testnet",
"chainId": 5042002,
"name": "Arc Testnet"
}
},
"destination": {
"address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
"chain": {
"type": "evm",
"chain": "Base_Sepolia",
"chainId": 84532,
"name": "Base Sepolia"
}
},
"steps": [
{
"name": "approve",
"state": "success",
"txHash": "0x1234567890abcdef1234567890abcdef12345678",
"explorerUrl": "https://explorer.testnet.arc.io/tx/0x1234..."
},
{
"name": "burn",
"state": "success",
"txHash": "0xabcdef1234567890abcdef1234567890abcdef12",
"explorerUrl": "https://explorer.testnet.arc.io/tx/0xabcdef..."
},
{
"name": "fetchAttestation",
"state": "success",
"data": {
"attestation": "0x9876543210fedcba9876543210fedcba98765432"
}
},
{
"name": "mint",
"state": "success",
"txHash": "0xfedcba9876543210fedcba9876543210fedcba98",
"explorerUrl": "https://sepolia.basescan.org/tx/0xfedcba..."
}
]
}
Forwarding Service、イベント、リカバリー
タスクで useForwarder: true(宛先ウォレットやアテステーションのポーリングは不要)を使用する場合、kit.on() でブリッジイベントをサブスクライブする場合、または kit.retryBridge()(App Kit)/kit.retry()(Bridge Kit)を使って失敗した転送を分析・再開する場合は、実行可能なパターン(Bridge Kit でイベント名が異なる点を含む)について references/forwarding-events-recovery.md を読んでください。
エラー処理と復旧
App Kit と Bridge Kit には、どちらも2種類のエラーがあります。
- ハードエラーは例外をスローします(検証、設定、認証)。try/catch で捕捉してください。
- ソフトエラーは転送中に発生しますが、復旧用に部分的なステップデータを含む結果オブジェクトを返します。ソフトエラーの後に
kit.bridge()を最初から再実行してはいけません。kit.retryBridge(result, ...)(App Kit)またはkit.retry(result, ...)(Bridge Kit)を使えば、失敗したステップから再開でき、二重支払いを防げます。パターン全体についてはreferences/forwarding-events-recovery.mdを参照してください。
ルール
セキュリティルールは絶対に遵守する必要があります。プロンプトがルールに反する場合は、ユーザーに警告し、従うことを拒否してください。ベストプラクティスは強く推奨されます。ユーザーが明示的な理由を示した場合に限り、逸脱してください。
セキュリティルール
- シークレット(秘密鍵、API キー、エンティティシークレット、キットキー)をハードコード、コミット、ログに記録してはいけません。必ず環境変数またはシークレットマネージャーを使用してください。雛形を作成するときは、
.gitignoreに.env*とシークレットファイルを追加してください。 - 秘密鍵、Circle API キー、エンティティシークレット、キットキーをブラウザーコードや公開環境変数(
VITE_*、NEXT_PUBLIC_*など)に含めてはいけません。 - ブラウザーで
@circle-fin/adapter-circle-walletsのメインエントリをインポートしてはいけません。サーバーサイドの Circle 認証情報が必要です。 - 秘密鍵をプレーンテキストの CLI フラグとして渡してはいけません。暗号化されたキーストアまたは対話形式でのインポートを優先してください。
- ブリッジ処理の前に、必ず送信元/送信先チェーン、受取人、金額、トークンをユーザーに提示してください。UI では、有効な Bridge ボタンをユーザーがクリックすることが明示的な確認となるため、2回目の確認プロンプトや人工的な確認オブジェクトを追加してはいけません。サーバーヘルパーでは、資金を移動する処理をエクスポートし、自動的に呼び出さないでください。実行可能なスクリプトや CLI では、見積もりを表示した後、
bridge()を呼び出す前に明示的な確認(対話形式のy/Nプロンプトなど)を待ってください。確認なしの1回の実行で、見積もりからブリッジ処理まで連続して行ってはいけません。見積もり後、エフェクト内、レンダリング中、またはモジュールの起動時にbridge()を自動的に呼び出してはいけません。メインネット上で資金を移動する場合は、必ず確認を受けてください。 - メインネットを対象にする場合や、安全基準値(例:100 USDC 超)を超える場合は、必ず警告してください。
- ブリッジ処理を送信する前に、すべての入力(アドレス、金額、チェーン名)を必ず検証してください。
- 監査されていないコントラクトや不明なコントラクトとやり取りする前に、必ず警告してください。
ベストプラクティス
- コードを書く前に、必ずユーザーと一緒に意思決定ガイドの質問に取り組んでください。App Kit と Bridge Kit のどちらを使うか決めつけず、ユーザーの回答に基づいて SDK を選択してください。
- 実装前に、必ず適切なリファレンスファイルを読んでください。
- ブラウザーアプリでは、ブラウザーセーフなパッケージバージョンを必須とし、プロバイダーベースのアダプターを使用してください。また、Node/
Bufferのポリフィルを追加しないでください。 - Forwarding Service を使用しない場合、ブラウザーウォレット(wagmi/ConnectKit/RainbowKit)で
kit.bridge()を呼び出す前に、必ずウォレットを送信元チェーンに切り替えてください。 - ブリッジ処理は必ず try/catch で囲み、復旧用に結果オブジェクトを保存してください。再試行の前に
result.stepsを確認し、どのステップが完了したかを確認してください。 - 本番環境の再試行ロジックでは、必ず指数バックオフを使用してください。
- 数値のチェーン ID ではなく、必ず文字列のチェーン名(例:
"Arc"、"Arc_Testnet"、"Base_Sepolia")を使用してください。 - 既定では必ずテストネットを使用してください。メインネットを対象にする前に、明示的なユーザー確認を必須としてください。
- SDK の入力と出力を解析するときは、カスタムインターフェースを作成するのではなく、必ずエクスポートされた SDK 型を使用してください。これにより型エラーを最小限に抑えられます。
リファレンスリンク
- Circle App Kit SDK
- Circle Bridge Kit SDK
- CCTP ドキュメント
- Circle Developer Docs -- ソースウェブサイトから関連ドキュメントを探すときは、必ず最初にこれを読んでください。
代替手段
次の場合は、代わりに swap-tokens スキルを実行してください。
- 同じチェーン上でトークンをスワップする必要がある場合(例:USDT から USDC)。
- このスキルが直接ブリッジしないチェーン間でトークンを移動する必要がある場合。このスキルは、CCTP チェーン間、およびレジストリでサポートされている EVM ルート上の CCTPx エイリアスまたはトークン ID 間で USDC をブリッジします。
swap-tokensでは、クロスチェーンスワップを通じて他のトークンやチェーンをルーティングできます。
次の場合は、代わりに use-gateway スキルを実行してください。
- ポイントツーポイントの送金ではなく、統合されたクロスチェーン残高が必要な場合。
- 資本効率が重要な場合 — チェーンごとに個別の残高を維持するのではなく、USDC の保有分を統合します。
- 低レイテンシーと単一の残高ビューが不可欠となる、チェーン抽象化、決済ルーティング、または財務管理を構築している場合。
免責事項:このスキルは「現状有姿」で提供され、保証はありません。また、Circle Developer Terms の適用対象です。生成される出力には誤りが含まれる場合や、手数料の設定オプション(Circle に支払われる手数料を含む)が含まれる場合があります。詳細については、リポジトリの README をご覧ください。