Your agent can own a wallet now — natural language to on-chain swaps on Ethereum, Base, and other EVM chains.
Most agent demos stop at reading the chain. You ask about a token, the model summarizes a blog post, everyone claps, and nothing moves on-chain.
The new defi/evm_tx_handler skill in Skillware is aimed at a different loop: your agent holds its own EVM wallet, turns plain-language trade intent into structured JSON, quotes a Uniswap V2 swap, shows a preview, and — only after confirmation — signs and broadcasts. No MetaMask popup. No pasting calldata into a block explorer. The LLM stays in natural language; the skill stays deterministic Python.
This post walks through what that looks like in practice, how Skillware fits in, and how you might chain it with wallet screening before you send funds anywhere sketchy.
Skillware in a nutshell
Skillware is an open-source Python framework for packaging agent skills the way you’d package a small library: one folder, one contract, works across providers.
Each skill is a bundle:
-
skill.py— deterministic logic (execute()), no hallucinated math -
manifest.yaml— tool schema, env vars, constitution -
instructions.md— how the model should use the tool (flows, edge cases, safety) -
test_skill.py— bundle tests that run in CI
You load a skill once, adapt it for Gemini, Claude, OpenAI, or others via SkillLoader, pass instructions.md as system context, and wire tool calls to skill.execute(...). Same pattern everywhere — see the introduction and agent loops guide.
That separation matters for DeFi: the model parses “Buy 10 DEGEN on Base with USDC”; the skill parses nothing in free text. It only accepts structured action + intent and returns JSON the agent can show to a human.
evm_tx_handler: architecture in plain terms
Registry ID: defi/evm_tx_handler
Issuer: @Hendobox · catalog page
The skill is built around a dedicated agent wallet — not your personal MetaMask, not a treasury. You create a fresh key, fund it lightly, and put it in .env as AGENT_WALLET_PRIVATE_KEY. The constitution is explicit: “Never pass keys in tool args, YAML, or logs.”
Under the hood, EvmTxHandlerSkill loads YAML registries from data/:
-
chains.yaml— today Ethereum mainnet and Base (chain IDs, RPC env keys, verified Uni V2 router addresses) -
tokens.yaml— symbol → contract per chain -
addressbook.yaml— human labels → addresses for transfers
Long-term defaults (default chain, slippage, confirm_before_send, max_trade_usd) live in config.yaml (copy from config.yaml.example).
Agent vs skill (the split that keeps you sane)
From the skill’s instructions.md:
| You (agent) | Skill |
|---|---|
Parse natural language into partial intent JSON |
Merge intent with config and YAML registries |
| Ask for missing fields in plain language | Return missing_fields and suggested_defaults
|
Show preview to the user and obtain approval |
Build on-chain quotes; sign swaps and transfers when confirmed |
Pass confirmed: true after approval |
Approve (if needed), swap, or transfer; return tx hash + receipt |
So the NLP layer is the LLM. The signing layer is Web3.py inside the skill, using the agent wallet key from the environment — not from the chat thread.
Actions you actually call
The manifest defines eight operations: resolve, quote, preview, execute, transfer, balances, wallet_info, update_preferences.
A typical buy flow (from the skill docs):
- User: “Buy 10 Degen on Base with USDC.”
- Agent calls
resolvewith intent like:
{
"side": "buy",
"chain": "base",
"target_asset": "degen",
"amount": 10,
"amount_kind": "target_out",
}
- If
spend_assetis missing, the skill returnsmissing_fields— the agent asks the user, then continues. -
quote/preview— live Uni V2 math, optional USD via CoinGecko if you setCOINGECKO_API_KEY. - User approves in plain language.
-
executewith the same intent andconfirmed: true.
Important nuance (easy to miss): execute re-quotes on-chain at broadcast time. Preview amounts can drift. The skill warns you to call quote or preview immediately before confirmation — not five minutes earlier.
For ERC20 spends, you may get a two-step flow: approve tx, then swap. If the response includes approve_tx_hash, tell the user both hashes landed.
Copy-paste: load the skill and run a Gemini loop
Install Skillware and deps (web3>=6), set RPC URLs and the agent wallet key, then:
import os
import google.genai as genai
from google.genai import types
from skillware.core.env import load_env_file
from skillware.core.loader import SkillLoader
load_env_file()
bundle = SkillLoader.load_skill("defi/evm_tx_handler")
skill = bundle["module"].EvmTxHandlerSkill()
client = genai.Client()
tool = SkillLoader.to_gemini_tool(bundle)
intent = {
"side": "buy",
"chain": "base",
"target_asset": "degen",
"spend_asset": "usdc",
"amount": 10,
"amount_kind": "target_out",
}
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Resolve and quote a buy of 10 DEGEN on Base with USDC.",
config=types.GenerateContentConfig(
tools=[tool],
system_instruction=bundle["instructions"],
),
)
# On function_call: skill.execute({"action": ..., "intent": ...})
# After preview + user approval:
# skill.execute({"action": "execute", "intent": intent, "confirmed": True})
No keys in the prompt. No MetaMask. The model never sees your private key — only the skill reads AGENT_WALLET_PRIVATE_KEY from the environment.
Want to try the flow without mainnet? The repo ships runnable examples:
EVM_TX_HANDLER_EXAMPLE_DEMO=1 python examples/gemini_evm_tx_handler.py
See examples/gemini_evm_tx_handler.py and examples/claude_evm_tx_handler.py in the examples index.
Safety rails (built into the skill, not bolted on later)
A few things the skill enforces so agents don’t YOLO on-chain:
-
confirm_before_send—execute/transferblocked untilconfirmed: true -
Balance pre-checks — insufficient funds return
status: insufficient_balancebefore broadcast -
max_trade_usd— fail closed if USD price unavailable when a cap is set - Constitution — dedicated wallet only, not financial advice, fail closed on missing RPC or registry entries
The skill itself recommends pairing with finance/wallet_screening before large sends to unknown addresses — screening runs locally in one execute() call (sanctions, malicious interaction counts, PnL context). That’s a natural chain: screen a recipient or counterparty wallet first; only if the report looks acceptable, call transfer or execute on the tx handler.
Same agent loop, two tools, one conversation:
- User: “Send 0.5 ETH to 0xABC… but check if it’s safe first.”
- Agent calls
wallet_screeningwith the address. - Agent summarizes
summary.sanctioned_entity_match,summary.malicious_interaction_count, etc. - If clean (and user still wants to proceed), agent calls
evm_tx_handler→transferwith preview → user confirms →confirmed: true.
Both skills load through the same SkillLoader pattern; you’re composing capabilities, not rewriting provider-specific tool JSON from scratch.
Limits (honest ones)
Today this skill is Uniswap V2 only, on Ethereum + Base (see data/chains.yaml). No bridges, no aggregators, no Polygon router in the registry yet — adding chains is a YAML + verification exercise, not magic NLP.
Natural language can still be mis-parsed. Preview drift is real. Market risk is real. The skill gives you structure, signing, and guardrails; it doesn’t replace human judgment on whether a trade makes sense.
Where to go next
- Skill source: skills/defi/evm_tx_handler
- Docs: evm_tx_handler.md · API keys
-
Framework: github.com/ARPAHLS/skillware ·
pip install skillware - Site: skillware.site
If you’ve been wiring one-off Web3 tools per provider, this is the other path: one skill bundle, any agent, one wallet the agent actually controls — with previews, confirmations, and screening chained in when you need them.
Top comments (0)