chain-signer

by kevthetech143

Not rated
GitHub

About

Pre-signature security suite for AI agents: flags wallet drains, permit-phishing, and risky actions before signing across EVM chains. Non-custodial.

Details

Author
kevthetech143
Categories
Other, Security, AI

Setup

Install chain-signer in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/kevthetech143/chain-signer

Follow the installation instructions in the repository README, then restart your MCP client.

A security suite for AI agents — the seatbelt that catches the dangerous thing BEFORE it happens. Three guards, each callable on its own (and as MCP tools), pairing with any wallet or identity stack:

- preflight(tx)— decode an unsigned transaction and flag drains before signing (unlimited/large approval, approve-all, token & NFT transferFrom, proxy upgrade, on-chain permit, on-chain Permit2 approve/permit/transferFrom, approvals hidden in multicall incl. Uniswap router batches and Multicall3 aggregate/aggregate3/aggregate3Value (the batch helper on every EVM chain), approvals wrapped in ERC-4337/smart-account execute/executeBatch, Gnosis Safe multiSend/execTransaction and DSProxy execute, drains routed through the Uniswap Universal Router (Permit2 permit/transferFrom commands incl. sub-plans), 1inch AggregationRouter v5 swap() with redirected output or zero slippage, 0x ExchangeProxy transformERC20() with zero slippage, EIP-7702 account delegation, will-revert).
- inspect_typed_data(td)— catch permit-phishing in an EIP-712 message before the agent signs it (ERC-2612, Uniswap Permit2 incl. SignatureTransfer + witness variants, DAI-style permits) and Seaport orders that give assets away — zero consideration, proceeds routed to a third party, or hidden in a BulkOrder tree.
- check_action(action, policy)— enforce allow/forbid + value/recipient limits before the agent acts.

All three fail safe and are guards, not guarantees. Also bundled: a non-custodial multi-chain wallet (burner, balance, send, swap) — the agent holds its own key and signs locally. No MetaMask, no account, no custody.

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 support is optional:pip install "chain-signer[all]".

Quickstart (10 seconds — offline, no key, no funds, no network)

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

That's the wedge: the drain gets flagged before you'd ever sign it — no key, no funds, no network.

Bundled wallet (optional — the guards pair with any wallet)

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

Full runnable demos are in the repo:examples/agent_safety_demo.py(all three guards stop three real attacks) andexamples/quickstart.py(wallet) — clone to run them, or just import as above.

Before an agent signs, hand the unsigned tx topreflight()— it decodes the calldata and returns the risks, or useassert_safe()to hard-stop on a HIGH flag. Offline, no network, never raises.

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

What it flags today: unlimited/large approval,increaseAllowance,setApprovalForAll, ERC-20transferFrom+ ERC-721/1155safeTransferFrom(token & NFT drains), ERC-777authorizeOperator/operatorSend(operator-grant + operator-pull drains), on-chain ERC-2612 and DAI-stylepermit, on-chain Permit2approve/permit/transferFrom(singleandbatch — the dominant approval router: unlimited uint160 allowance + drain pull) plus Permit2 SignatureTransferpermit(Witness)TransferFrom(the one-shot signed-permit pull intent/filler protocols use), proxyupgradeTo/upgradeToAndCall, approvals hidden insidemulticall(all router variants, nested)and Multicall3aggregate/aggregate3/aggregate3Value(the canonical batch helper deployed at one address on every EVM chain), approvals wrapped in ERC-4337/smart-accountexecute/executeBatch, Gnosis SafemultiSend/execTransaction, or DSProxyexecute(target,data)/execute(code,data)(decoded and recursed), drains routed through the UniswapUniversal Router(execute(commands,inputs)— Permit2permit/transferFromcommands, batch andEXECUTE_SUB_PLAN), EIP-7702 account delegation (the "wallet upgrade" drainer), large native value, opaque calldata, malformed calls, and will-revert (with a sim hook). Honest limits (read these): this is STATIC analysis — it decodes calldata and matches known drain patterns. It is NOT a transaction simulator: it won't catch a novel/obfuscated drain it can't decode (those get a low-severity "unknown" flag, not a block), and simulation-based scanners go deeper there. Safety coverage is EVM-only today (no Solana/Bitcoin tx analysis). And it is not yet field-proven at scale. A first-line guard for known patterns — not a guarantee. Pair it with simulation + human review for high-value actions.

Signed-message inspector (the off-chain half)

A drain doesn't need a transaction. A dApp can ask the agent tosignan EIP-712 message — most dangerously apermitgranting an unlimited token allowance, whichpreflight(a tx check) can't see.inspect_typed_data()catches it before the agent signs:

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', ...}]

Covers all three major permit shapes:ERC-2612,Uniswap Permit2(PermitSingle/PermitBatch, plus SignatureTransfer and the witness variants intent protocols use), andDAI-style(allowed: true), plusSeaportmarketplace orders that hand assets over for nothing — zero consideration, proceeds routed to a third party while your asset leaves, or the same giveaway buried in a BulkOrder merkle tree. Offline, never raises.

inspect_typed_dataonly protects when the agent remembers to call it first —sign_typed_dataalone will happily sign a permit-phishing message.guarded_sign_typed_data()composes the two so signing is screened bydefault: it inspects, then refuses to sign a HIGH-risk drain.

from chain_signer import guarded_sign_typed_data, SignatureBlocked sig = guarded_sign_typed_data(wallet, domain, types, message, "Permit") # raises SignatureBlocked on a drain

On a clean message the signature is byte-identical tosign_typed_data; passforce=Trueto override.

Action-policy gate (inspect what the agent DOES)

Identity tells youwhothe agent is; it doesn't stop a badaction.check_action()enforces a policy on a proposed tool call before it runs — fail-safe (denies on unreadable input):

from chain_signer import check_action policy = {"forbid_tools": ["bridge"], "max_value_wei": 1018, "allow_recipients": [trusted_addr]} r = check_action({"tool": "send", "args": {"to": addr, "value_wei": 5*1018}}, policy) # {'allowed': False, 'violations': [{'code': 'value_over_limit', ...}]}

All three guards are exposed as MCP tools (preflight,inspect_signature,check_action) — any agent runtime (Claude, Cursor, …) can call them directly, read-only, no key.

What's caught and what isn't — the honest threat-coverage map:docs/THREAT-COVERAGE.md.

- preflight(tx)/assert_safe(tx)— decode an unsigned tx and flag drain patterns before signing.
- inspect_typed_data(td)— flag permit-phishing in an EIP-712 message before the agent signs it.
- guarded_sign_typed_data(w, domain, types, message, primary_type)— screen then sign; refuses a drain.
- check_action(action, policy)— enforce allow/forbid + value/recipient limits before the agent acts.
- burner()— a fresh wallet for a one-off task; discard it when done.
- restore(key)— reload a wallet later from its exported private key (same key → same address).
- send_ether(w, to, amount)— send in ETH (not wei); nonce, gas, and broadcast handled for you.
- get_balance(w)— live balance from the chain (Etherscan v2 indexer, not a flaky public RPC).
- swap(...)— token swaps via 0x/Paraswap.
- Optional Solana + Bitcoin wallets via the
[all]extra.

The private key is generated/loaded locally, used only to sign, and never logged, returned, or stored by this library. You hold the key; we never touch your funds. That is the whole design.

w.private_keyis the keys to the wallet. Treat it like a password:

- NEVER log it, print it in production, or write it into notes/memory/chat. Anyone who has it controls the funds.
- For a burner holding a few dollars this is low-stakes by design — but the rule still holds.
- To reuse a wallet later, store the key in a secret manager / env var, thenrestore(key).
- Better:export_encrypted(w, password)gives a password-protected keystore dict to store at rest;load_encrypted(keystore, password)brings the wallet back. Never store the raw key if you can store the keystore.

The wallet does not exposesign_transaction/sign_messagemethods. Signing is done by function helpers you pass the wallet to — e.g.send_ether(w, to, amount)signs and broadcasts, andsign_message(w, "text")returns an EIP-191 signature for auth / sign-in flows (recoverable via eth_accountAccount.recover_message).

pip installmay warn that thechain-signerscript dir isn't on your PATH. The library works regardless; to use the CLI directly, add that dir to PATH or runpython -m chain_signer ....

chain_signer.mcp_serverexposeslist_tools()andcall_tool(name, arguments). CLI:

python -m chain_signer list python -m chain_signer call create_wallet '{"chain":"evm"}'

General-purpose, non-custodial tooling. You are responsible for using it within the laws and terms of service that apply to you. Not intended or marketed for any restricted or prohibited trading in your jurisdiction.

- Balances/broadcast use the Etherscan v2 indexer (authoritative), never a free public RPC.
- Low-level building blocks (tx.send,call_contract, explicit nonce/gas) remain available for advanced use.

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.

Builds + signs the EIP-3009 authorization x402 expects (the "exact" scheme). Your agent pays a paid API by itself — no password prompt, no signup, no custody.

Sign typed data (EIP-712) — for agent payments / 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

Your agent can authorize a payment by signing typed data locally — no password prompt, no signup.

chain-signer is also a Model Context Protocol (MCP) server, so MCP-aware agents can use it directly:

pip install chain-signer chain-signer-mcp # speaks MCP over stdio (JSON-RPC 2.0)

Exposes 9 tools. The three security guards (the wedge):preflight,inspect_signature,check_action. Plus the non-custodial wallet: create_wallet, get_balance, send, call_contract, swap, bridge.

Wire it into any MCP client (Claude Desktop, Cursor, etc.) by adding it to the client'smcpServersconfig:

{ "mcpServers": { "chain-signer": { "command": "chain-signer-mcp", "env": { "ETHERSCAN_API_KEY": "your-key-for-live-balance-and-broadcast" } } } }

That's all — the agent can now screen every tx, signature, and action through the guards before it acts, and (optionally) hold its own wallet to read balances, send, and swap as native tools. (ETHERSCAN_API_KEYis optional; needed only for live balance reads and broadcasting.)

Non-custodial spending controls for AI agent wallets — enforce limits, allowlists, and kill switches before transactions execute.

Non-custodial spending controls for AI agent crypto wallets — enforce daily limits, per-tx caps, and recipient whitelists.

Universal Contract AI Interface (UCAI) 🔗 ABI to MCP | The open standard for connecting AI agents to blockchain. MCP server generator for smart contracts. Claude + Uniswap, Aave, ERC20, NFTs, DeFi. Python CLI, Web3 integration, transaction simulation. Polygon, Arbitrum, Base, Ethereum EVM chains. Claude, GPT, LLM tooling, Solidity, OpenAI.

Blockchain data across 100+ chains: token prices, NFTs, transfers, simulation, traces, Solana DAS

Perform bulk BNB and BEP20 token transfers on the BNB Smart Chain (BSC).

On-chain automated trading strategies (DEX) for AI agents. Create limit orders, range orders, recurring buy-low-sell-high strategies, and concentrated liquidity positions across Ethereum, Sei, Celo, TAC, and COTI. Unlike traditional AMMs and liquidity pools, Carbon lets you set asymmetric price ranges - your buy and sell orders are independent, not mirrored. Backtest any strategy against historical prices before going on-chain, explore market liquidity, find discount entry points, and swap tokens against Carbon DeFi's maker liquidity. 25 tools. Returns unsigned transactions — agents never hold funds or private keys. Zero gas on fills.

Autonomous DeFi yield for AI agents on Base. Query APY rates, agent status, payment splits. 9 MCP tools.

Give AI agents spending power without giving them your wallet keys. Cloaked creates on-chain spending accounts with enforced constraints that agents cannot bypass - even if jailbroken or compromised.

MCP server for local transaction signing across EVM, UTXO, Tron, and XRP blockchains — no API calls required

AI-powered Solana token rug pull detection with ML ensemble scoring, honeypot detection, and temporal rug stage prediction.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.