chain-signer について
chain-signerは、AIエージェント向けのセキュリティツールキットで、トランザクション、署名メッセージ、実行予定の操作を事前に検査します。3種類のガードをMCPツールとして呼び出せるほか、ローカル署名対応の非カストディアルウォレットも含みます。
主な機能
- 01未署名トランザクションのリスク検出
- 02EIP-712署名の許可フィッシング検査
- 03署名前の型付きデータ検査
- 04ツール、金額、送信先に関するポリシー適用
- 05ローカル署名ウォレットを同梱
- 06コマンドラインとMCPツールのインターフェース
活用シーン
- 01トランザクション署名前に危険な承認を検出
- 02エージェントが署名する許可メッセージを確認
- 03金額や送信先の制限を超える操作を拒否
- 04MCP接続されたエージェントに安全検査を提供
MCP 対応
3種類のガードをpreflight、inspect_signature、check_actionというMCPツールとして公開します。任意のエージェントランタイムから、鍵なしで読み取り専用の呼び出しが可能です。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
9掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| tx | object | はい | 未署名トランザクション:{to, data (hex calldata), value}。 |
| max_value | integer | いいえ | 任意:この値(wei)を超えるネイティブ通貨の金額を検出します。 |
詳細
chain-signer
AI エージェント向けのセキュリティスイートです。危険なことが起きる前に防ぐシートベルトです。 それぞれ単独でも呼び出せる 3 つのガード(MCP ツールとしても呼び出し可能)が、あらゆるウォレットやアイデンティティスタックと連携します。
preflight(tx)— 署名前に未署名トランザクションをデコードし、資金流出につながる操作を検知します(無制限または大規模な承認、全承認、トークンおよび NFT の transferFrom、プロキシのアップグレード、オンチェーン permit、オンチェーン Permit2 の approve/permit/transferFrom、Uniswap ルーターバッチや Multicall3 の aggregate/aggregate3/aggregate3Value(すべての EVM チェーンで使われるバッチヘルパー)を含む multicall 内に隠された承認、ERC-4337/スマートアカウントの execute/executeBatch にラップされた承認、Gnosis Safe の multiSend/execTransaction および DSProxy の execute、Uniswap Universal Router(サブプランを含む Permit2 の permit/transferFrom コマンド)経由の資金流出、出力先を変更またはスリッページをゼロにした 1inch AggregationRouter v5 の swap()、スリッページをゼロにした 0x ExchangeProxy の transformERC20()、EIP-7702 のアカウント委任、実行時にリバートするトランザクション)。inspect_typed_data(td)— エージェントが署名する前に EIP-712 メッセージ内の permit フィッシングを検知します(ERC-2612、SignatureTransfer と witness バリアントを含む Uniswap Permit2、DAI 形式の permit)。また、資産を手放す Seaport 注文(対価がゼロ、第三者への収益の送金、または BulkOrder ツリー内に隠されたもの)も検知します。check_action(action, policy)— エージェントの行動前に、許可/禁止と金額/受取人の制限を適用します。
3 つのガードはすべてフェイルセーフであり、保証ではなく防護策です。また、カストディ不要のマルチチェーンウォレット(burner、残高確認、送金、スワップ)も同梱されています。エージェントは自分のキーを保持し、ローカルで署名します。MetaMask、アカウント、カストディは不要です。
from chain_signer import assert_safe
assert_safe(tx) # raises if the tx is a drain/unlimited-approval/revert — review before signing
インストール
pip install chain-signer
export ETHERSCAN_API_KEY=... # for live balance reads + broadcast (Etherscan v2)
Bitcoin/Solana のサポートはオプションです。pip install "chain-signer[all]" を実行してください。
クイックスタート(10 秒 — オフライン、キー不要、資金不要、ネットワーク不要)
pip install chain-signer
from chain_signer import preflight
spender = "0x" + "22" * 20
tx = {"to": "0x" + "33" * 20, "data": "0x095ea7b3" + spender[2:].rjust(64, "0") + "f" * 64, "value": 0}
print(preflight(tx)) # ok=False — flags unlimited_approval before you'd ever sign
これが導入の決め手です。署名する前に資金流出につながる操作を検知します。キーも資金もネットワークも不要です。
同梱ウォレット(オプション — ガードはあらゆるウォレットと連携します)
from chain_signer import burner, send_ether
from chain_signer.balance import get_balance
w = burner() # fresh throwaway wallet; the agent owns w.private_key
print(w.address, get_balance(w)) # live on-chain balance
send_ether(w, "0x...recipient", 0.001) # auto nonce+gas, signed locally, broadcast
すぐに実行できるデモはリポジトリにあります。examples/agent_safety_demo.py(3 つのガードが実際の攻撃を 3 件阻止)と examples/quickstart.py(ウォレット)です。実行するにはリポジトリをクローンしてください。または、上記のようにインポートするだけで使えます。
安全性の事前チェック(ウェッジ)
エージェントが署名する前に、未署名のトランザクションを preflight() に渡してください。calldata をデコードしてリスクを返します。または assert_safe() を使用して、HIGH フラグがある場合に処理を強制停止できます。オフラインで動作し、ネットワークには接続せず、例外を発生させません。
from chain_signer import preflight, assert_safe
# an unlimited-allowance approve() to a spender — the classic drain setup
tx = {"to": token, "data": "0x095ea7b3" + spender_padded + "f"*64, "value": 0}
report = preflight(tx)
# {'decoded': {...}, 'ok': False,
# 'risk_flags': [{'code': 'unlimited_approval', 'severity': 'HIGH',
# 'detail': 'approve() grants an effectively-unlimited allowance ...'}]}
assert_safe(tx) # raises ValueError on a HIGH flag; pass force=True to override
assert_safe(tx, sim=my_simulator) # optional: also flag will-revert via your simulation hook
現在検出する項目:無制限または大規模な承認、increaseAllowance、setApprovalForAll、ERC-20 transferFrom と ERC-721/1155 safeTransferFrom(トークンおよび NFT の流出)、ERC-777 authorizeOperator/operatorSend(オペレーターへの権限付与とオペレーターによる引き出しの流出)、オンチェーンの ERC-2612 および DAI 形式の permit、オンチェーンの Permit2 approve/permit/transferFrom(単一およびバッチ。主要な承認ルーターであり、無制限の uint160 allowance と引き出しによる流出)、さらに Permit2 SignatureTransfer permit(Witness)TransferFrom(ワンショットの署名付き permit 引き出しインテントで、フィラープロトコルが使用)、プロキシの upgradeTo/upgradeToAndCall、multicall 内に隠された承認(すべてのルーター形式、ネストされたものを含む)、および Multicall3 aggregate/aggregate3/aggregate3Value(すべての EVM チェーンで同じアドレスにデプロイされている標準的なバッチヘルパー)、ERC-4337/スマートアカウントの execute/executeBatch 内にラップされた承認、Gnosis Safe の multiSend/execTransaction、DSProxy の execute(target,data)/execute(code,data)(デコードして再帰的に検査)、Uniswap Universal Router を経由する流出(execute(commands,inputs) — Permit2 permit/transferFrom コマンド、バッチ、EXECUTE_SUB_PLAN)、EIP-7702 アカウント委任(「ウォレットのアップグレード」を利用した資産流出)、大きなネイティブ通貨の送金額、不透明な calldata、不正な呼び出し、実行時にリバートする呼び出し(シミュレーションフックを使用)。
正直な制限事項(ご確認ください):これは静的解析です。calldata をデコードし、既知の流出パターンと照合します。トランザクションシミュレーターではありません。デコードできない新規または難読化された流出は検出できず(ブロックされず、重大度の低い「不明」フラグが付与されます)、シミュレーションベースのスキャナーなら、さらに詳しく検査できます。現在、安全性の検査は EVM のみを対象としています(Solana/Bitcoin のトランザクション解析には対応していません)。また、大規模な環境で実証されたものではありません。既知のパターンに対する最初の防御手段であり、安全を保証するものではありません。高額な操作では、シミュレーションと人間によるレビューを併用してください。
署名メッセージの検査(オフチェーン側)
資産流出にトランザクションは必要ありません。dApp はエージェントに EIP-712 メッセージへの署名を求めることがあります。特に危険なのは、無制限のトークン使用許可を与える permit です。トランザクションのチェックである preflight では検出できません。inspect_typed_data() は、エージェントが署名する前にこれを検出します。
from chain_signer import inspect_typed_data
report = inspect_typed_data(typed_data) # the EIP-712 object you're about to sign
# ok=False, risk_flags=[{'code': 'unlimited_permit_signature', 'severity': 'HIGH', ...}]
主要な permit 形式をすべて検査します。ERC-2612、Uniswap Permit2(PermitSingle/PermitBatch、および SignatureTransfer と、インテントプロトコルが使用する witness 形式)、DAI 形式(allowed: true)、さらに Seaport のマーケットプレイス注文(対価なしで資産を引き渡すもの、売却益が第三者に送られる一方で資産が持ち出されるもの、BulkOrder のマークルツリー内に同じ無償譲渡が隠されているもの)に対応しています。オフラインで動作し、例外を発生させません。
保護付き署名(検査と署名を 1 回で実行)
エージェントが事前に呼び出すことを忘れると、inspect_typed_data だけでは保護されません。sign_typed_data だけなら、permit フィッシングメッセージにもそのまま署名してしまいます。guarded_sign_typed_data() はこの 2 つを組み合わせるため、デフォルトで署名前に検査されます。まず内容を調べ、HIGH リスクの流出があれば署名を拒否します。
from chain_signer import guarded_sign_typed_data, SignatureBlocked
sig = guarded_sign_typed_data(wallet, domain, types, message, "Permit") # raises SignatureBlocked on a drain
問題のないメッセージでは、署名は sign_typed_data とバイト単位で同一です。上書きするには force=True を渡してください。
アクションポリシーのゲート(エージェントの実行内容を検査)
ID によってエージェントが誰であるかはわかりますが、不正なアクションを止めることはできません。check_action() は、提案されたツール呼び出しの実行前にポリシーを適用します。フェイルセーフで動作し、入力を読み取れない場合は拒否します。
from chain_signer import check_action
policy = {"forbid_tools": ["bridge"], "max_value_wei": 10**18, "allow_recipients": [trusted_addr]}
r = check_action({"tool": "send", "args": {"to": addr, "value_wei": 5*10**18}}, policy)
# {'allowed': False, 'violations': [{'code': 'value_over_limit', ...}]}
3 つのガードはすべて MCP ツール(preflight、inspect_signature、check_action)として公開されています。Claude、Cursor など、どのエージェントランタイムからも直接呼び出せます。読み取り専用で、鍵は不要です。
検出できるものとできないものについては、正直な脅威カバレッジマップをご覧ください:docs/THREAT-COVERAGE.md。
利用できる機能
preflight(tx)/assert_safe(tx)— 署名前に未署名のトランザクションをデコードし、資金流出につながるパターンを検出します。inspect_typed_data(td)— エージェントが署名する前に、EIP-712 メッセージの許可フィッシングを検出します。guarded_sign_typed_data(w, domain, types, message, primary_type)— チェックしてから署名し、資金流出につながる場合は拒否します。check_action(action, policy)— エージェントがアクションを実行する前に、許可/禁止と金額/送信先の制限を適用します。burner()— 単発のタスク用に新しいウォレットを作成します。完了したら破棄してください。restore(key)— エクスポートした秘密鍵から後でウォレットを復元します(同じ鍵なら同じアドレスになります)。send_ether(w, to, amount)— ETH 単位(wei ではありません)で送金します。nonce、ガス、ブロードキャストは自動で処理されます。get_balance(w)— チェーン上の最新残高を取得します(不安定なパブリック RPC ではなく、Etherscan v2 インデクサーを使用します)。swap(...)— 0x/Paraswap 経由でトークンをスワップします。[all]エクストラを使用すると、Solana と Bitcoin のウォレットも利用できます。
ノンカストディアルの保証
秘密鍵はローカルで生成または読み込まれ、署名にのみ使用されます。このライブラリによってログに記録、返却、保存されることはありません。鍵を保持するのはあなたです。私たちが資金に触れることはありません。それがこの設計のすべてです。
鍵の取り扱い(必ずお読みください)
w.private_key はウォレットの鍵です。パスワードと同じように扱ってください。
- 絶対にログに記録したり、本番環境で出力したり、メモ/記憶領域/チャットに書き込んだりしないでください。鍵を持つ人は誰でも資金を操作できます。
- 数ドルを入れた使い捨てウォレットなら、リスクは意図的に低く抑えられます。それでも、このルールは守ってください。
- 後でウォレットを再利用するには、鍵をシークレットマネージャーまたは環境変数に保存し、
restore(key)を実行します。 - さらに安全な方法として、
export_encrypted(w, password)を使うと、パスワードで保護されたキーストア辞書を生成して保管できます。load_encrypted(keystore, password)を使うとウォレットを復元できます。キーストアを保存できる場合は、生の鍵を保存しないでください。
署名の慣用的な使い方(web3.py ユーザー向け)
このウォレットには sign_transaction/sign_message メソッドはありません。署名は、ウォレットを渡す関数ヘルパーで行います。たとえば、send_ether(w, to, amount) は署名してブロードキャストし、sign_message(w, "text") は認証/サインインのフロー用の EIP-191 署名を返します(eth_account の Account.recover_message で復元できます)。
PATH 上の CLI
pip install を実行すると、chain-signer スクリプトのディレクトリが PATH に含まれていないという警告が表示される場合があります。ライブラリはそのまま動作します。CLI を直接使うには、そのディレクトリを PATH に追加するか、python -m chain_signer ... を実行してください。
ツールのインターフェース(あらゆる AI/MCP/CLI 向け)
chain_signer.mcp_server は list_tools() と call_tool(name, arguments) を公開します。CLI:
python -m chain_signer list
python -m chain_signer call create_wallet '{"chain":"evm"}'
責任ある利用
汎用のノンカストディアルツールです。適用される法律および利用規約の範囲内で使用する責任は、利用者にあります。利用者の管轄区域で制限または禁止されている取引を目的としたものでも、そのように販売されているものでもありません。
メモ
- 残高の取得とブロードキャストには、Etherscan v2 インデクサー(信頼できる情報源)を使用し、無料のパブリック RPC は使用しません。
- 低レベルの構成要素(
tx.send、call_contract、明示的な nonce/ガス指定)も、高度な用途向けに引き続き利用できます。
x402 API に1回の呼び出しで支払う
from chain_signer import burner, sign_x402_payment
w = burner()
payload = sign_x402_payment(w, token=USDC, to=PAY_TO, value=1000, valid_before=EXPIRES, chain_id=8453)
# -> {"signature", "authorization"} ready for the x402 payment header. Signed locally, no prompt.
x402 が想定する EIP-3009 の認可(「exact」方式)を構築し、署名します。エージェントは、パスワードの入力も、サインアップも、カストディも必要とせず、有料 API に自ら支払います。
型付きデータ(EIP-712)に署名する — エージェントの支払い/x402 向け
from chain_signer import burner, sign_typed_data
w = burner()
sig = sign_typed_data(w, domain, types, message) # EIP-712; for x402 / EIP-3009 authorizations
エージェントは、パスワードの入力やサインアップをせずに、型付きデータにローカルで署名して支払いを承認できます。
MCP サーバーとして実行
chain-signer は Model Context Protocol(MCP)サーバーでもあるため、MCP 対応エージェントから直接利用できます。
pip install chain-signer
chain-signer-mcp # speaks MCP over stdio (JSON-RPC 2.0)
9 個のツールを公開します。3 つのセキュリティガード(要となる機能)は、preflight、inspect_signature、
check_action です。さらに、ノンカストディアルウォレットとして、create_wallet、get_balance、send、call_contract、swap、bridge を利用できます。
mcpServers 設定に追加することで、任意の MCP クライアント(Claude Desktop、Cursor など)に接続できます。
{
"mcpServers": {
"chain-signer": {
"command": "chain-signer-mcp",
"env": { "ETHERSCAN_API_KEY": "your-key-for-live-balance-and-broadcast" }
}
}
}
これで完了です。エージェントは、実行前にすべての tx、署名、アクションをガードでチェックできるようになり、(任意で)自身のウォレットを保持して、ネイティブツールとして残高の読み取り、送金、スワップを行えます。
(ETHERSCAN_API_KEY は任意です。リアルタイムの残高読み取りとブロードキャストを行う場合にのみ必要です。)
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。