mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-18 04:41:56 +00:00
feat(skills): merge blockchain/base into blockchain/evm; salvage PR #2010
Salvages the closed PR #2010 (Mibayy's EVM multi-chain skill) and folds the existing optional-skills/blockchain/base/ skill into it, so we ship one unified EVM skill instead of two overlapping ones. Pulled in from base/: - 8 missing Base-specific tokens (AERO, DEGEN, TOSHI, BRETT, WELL, cbETH, cbBTC, wstETH, rETH) added to KNOWN_TOKENS['base'] — base/ had 11, evm/ only had 3 (USDC/DAI/WETH). - L1 data-fee pitfall note for rollups (Base, Arbitrum, Optimism, zkSync). - Batch-size chunking in rpc_batch (Base RPC caps batches at 10 calls per JSON-RPC request; adding more known tokens tripped that limit and broke 'wallet --chain base' with a 'list index out of range' error). Ported the chunking pattern from base/_rpc_batch_chunk. Latent bugs found and fixed while smoke-testing the merge: - cmd_multichain and cmd_allowance both iterated KNOWN_TOKENS[chain] with 'for contract, (symbol, _name) in known.items()' — but the dict shape is {symbol: contract_str}, not {addr: (sym, name)}. This raised 'too many values to unpack (expected 2)' on every non-zero balance. Now iterates as 'for symbol, contract in known.items()'. - Input validation: added is_valid_address / is_valid_txhash / require_address / require_txhash helpers and wired them into cmd_wallet, cmd_tx, cmd_token, cmd_activity, cmd_allowance, cmd_decode, cmd_contract, cmd_multichain. Fails fast with exit 2 on malformed input instead of burning an RPC round-trip on garbage. Documentation: - SKILL.md now flags that this skill supersedes optional-skills/blockchain/base. - Pitfalls expanded for ENS (single-endpoint dependency on ensideas.com), tx decoding (single-endpoint dependency on 4byte.directory), and rollup L1 fees. - Regenerated website/docs/user-guide/skills/optional/blockchain/ blockchain-evm.md and removed the old blockchain-base.md page; catalog updated. Removed: - optional-skills/blockchain/base/SKILL.md - optional-skills/blockchain/base/scripts/base_client.py - website/docs/user-guide/skills/optional/blockchain/blockchain-base.md Smoke-tested live against Base mainnet: stats, price, token, wallet (vitalik.eth — 3.12 ETH + 13.88 USDC + 4.23 DAI + 0.06 WETH on Base) and allowance (ethereum, 7 unlimited approvals to Uniswap/Permit2). Original PR #2010 author: Mibayy. Original base/ skill author: youssefea.
This commit is contained in:
parent
aa1e2edd35
commit
e3fc081499
7 changed files with 354 additions and 1521 deletions
|
|
@ -1,232 +0,0 @@
|
|||
---
|
||||
name: base
|
||||
description: Query Base (Ethereum L2) blockchain data with USD pricing — wallet balances, token info, transaction details, gas analysis, contract inspection, whale detection, and live network stats. Uses Base RPC + CoinGecko. No API key required.
|
||||
version: 0.1.0
|
||||
author: youssefea
|
||||
license: MIT
|
||||
platforms: [linux, macos, windows]
|
||||
metadata:
|
||||
hermes:
|
||||
tags: [Base, Blockchain, Crypto, Web3, RPC, DeFi, EVM, L2, Ethereum]
|
||||
related_skills: []
|
||||
---
|
||||
|
||||
# Base Blockchain Skill
|
||||
|
||||
Query Base (Ethereum L2) on-chain data enriched with USD pricing via CoinGecko.
|
||||
8 commands: wallet portfolio, token info, transactions, gas analysis,
|
||||
contract inspection, whale detection, network stats, and price lookup.
|
||||
|
||||
No API key needed. Uses only Python standard library (urllib, json, argparse).
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
- User asks for a Base wallet balance, token holdings, or portfolio value
|
||||
- User wants to inspect a specific transaction by hash
|
||||
- User wants ERC-20 token metadata, price, supply, or market cap
|
||||
- User wants to understand Base gas costs and L1 data fees
|
||||
- User wants to inspect a contract (ERC type detection, proxy resolution)
|
||||
- User wants to find large ETH transfers (whale detection)
|
||||
- User wants Base network health, gas price, or ETH price
|
||||
- User asks "what's the price of USDC/AERO/DEGEN/ETH?"
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The helper script uses only Python standard library (urllib, json, argparse).
|
||||
No external packages required.
|
||||
|
||||
Pricing data comes from CoinGecko's free API (no key needed, rate-limited
|
||||
to ~10-30 requests/minute). For faster lookups, use `--no-prices` flag.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
RPC endpoint (default): https://mainnet.base.org
|
||||
Override: export BASE_RPC_URL=https://your-private-rpc.com
|
||||
|
||||
Helper script path: ~/.hermes/skills/blockchain/base/scripts/base_client.py
|
||||
|
||||
```
|
||||
python3 base_client.py wallet <address> [--limit N] [--all] [--no-prices]
|
||||
python3 base_client.py tx <hash>
|
||||
python3 base_client.py token <contract_address>
|
||||
python3 base_client.py gas
|
||||
python3 base_client.py contract <address>
|
||||
python3 base_client.py whales [--min-eth N]
|
||||
python3 base_client.py stats
|
||||
python3 base_client.py price <contract_address_or_symbol>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Procedure
|
||||
|
||||
### 0. Setup Check
|
||||
|
||||
```bash
|
||||
python3 --version
|
||||
|
||||
# Optional: set a private RPC for better rate limits
|
||||
export BASE_RPC_URL="https://mainnet.base.org"
|
||||
|
||||
# Confirm connectivity
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py stats
|
||||
```
|
||||
|
||||
### 1. Wallet Portfolio
|
||||
|
||||
Get ETH balance and ERC-20 token holdings with USD values.
|
||||
Checks ~15 well-known Base tokens (USDC, WETH, AERO, DEGEN, etc.)
|
||||
via on-chain `balanceOf` calls. Tokens sorted by value, dust filtered.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
wallet 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
|
||||
```
|
||||
|
||||
Flags:
|
||||
- `--limit N` — show top N tokens (default: 20)
|
||||
- `--all` — show all tokens, no dust filter, no limit
|
||||
- `--no-prices` — skip CoinGecko price lookups (faster, RPC-only)
|
||||
|
||||
Output includes: ETH balance + USD value, token list with prices sorted
|
||||
by value, dust count, total portfolio value in USD.
|
||||
|
||||
Note: Only checks known tokens. Unknown ERC-20s are not discovered.
|
||||
Use the `token` command with a specific contract address for any token.
|
||||
|
||||
### 2. Transaction Details
|
||||
|
||||
Inspect a full transaction by its hash. Shows ETH value transferred,
|
||||
gas used, fee in ETH/USD, status, and decoded ERC-20/ERC-721 transfers.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
tx 0xabc123...your_tx_hash_here
|
||||
```
|
||||
|
||||
Output: hash, block, from, to, value (ETH + USD), gas price, gas used,
|
||||
fee, status, contract creation address (if any), token transfers.
|
||||
|
||||
### 3. Token Info
|
||||
|
||||
Get ERC-20 token metadata: name, symbol, decimals, total supply, price,
|
||||
market cap, and contract code size.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
||||
```
|
||||
|
||||
Output: name, symbol, decimals, total supply, price, market cap.
|
||||
Reads name/symbol/decimals directly from the contract via eth_call.
|
||||
|
||||
### 4. Gas Analysis
|
||||
|
||||
Detailed gas analysis with cost estimates for common operations.
|
||||
Shows current gas price, base fee trends over 10 blocks, block
|
||||
utilization, and estimated costs for ETH transfers, ERC-20 transfers,
|
||||
and swaps.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py gas
|
||||
```
|
||||
|
||||
Output: current gas price, base fee, block utilization, 10-block trend,
|
||||
cost estimates in ETH and USD.
|
||||
|
||||
Note: Base is an L2 — actual transaction costs include an L1 data
|
||||
posting fee that depends on calldata size and L1 gas prices. The
|
||||
estimates shown are for L2 execution only.
|
||||
|
||||
### 5. Contract Inspection
|
||||
|
||||
Inspect an address: determine if it's an EOA or contract, detect
|
||||
ERC-20/ERC-721/ERC-1155 interfaces, resolve EIP-1967 proxy
|
||||
implementation addresses.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
contract 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
||||
```
|
||||
|
||||
Output: is_contract, code size, ETH balance, detected interfaces
|
||||
(ERC-20, ERC-721, ERC-1155), ERC-20 metadata, proxy implementation
|
||||
address.
|
||||
|
||||
### 6. Whale Detector
|
||||
|
||||
Scan the most recent block for large ETH transfers with USD values.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
whales --min-eth 1.0
|
||||
```
|
||||
|
||||
Note: scans the latest block only — point-in-time snapshot, not historical.
|
||||
Default threshold is 1.0 ETH (lower than Solana's default since ETH
|
||||
values are higher).
|
||||
|
||||
### 7. Network Stats
|
||||
|
||||
Live Base network health: latest block, chain ID, gas price, base fee,
|
||||
block utilization, transaction count, and ETH price.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py stats
|
||||
```
|
||||
|
||||
### 8. Price Lookup
|
||||
|
||||
Quick price check for any token by contract address or known symbol.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price ETH
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price USDC
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price AERO
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price DEGEN
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
||||
```
|
||||
|
||||
Known symbols: ETH, WETH, USDC, cbETH, AERO, DEGEN, TOSHI, BRETT,
|
||||
WELL, wstETH, rETH, cbBTC.
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **CoinGecko rate-limits** — free tier allows ~10-30 requests/minute.
|
||||
Price lookups use 1 request per token. Use `--no-prices` for speed.
|
||||
- **Public RPC rate-limits** — Base's public RPC limits requests.
|
||||
For production use, set BASE_RPC_URL to a private endpoint
|
||||
(Alchemy, QuickNode, Infura).
|
||||
- **Wallet shows known tokens only** — unlike Solana, EVM chains have no
|
||||
built-in "get all tokens" RPC. The wallet command checks ~15 popular
|
||||
Base tokens via `balanceOf`. Unknown ERC-20s won't appear. Use the
|
||||
`token` command for any specific contract.
|
||||
- **Token names read from contract** — if a contract doesn't implement
|
||||
`name()` or `symbol()`, these fields may be empty. Known tokens have
|
||||
hardcoded labels as fallback.
|
||||
- **Gas estimates are L2 only** — Base transaction costs include an L1
|
||||
data posting fee (depends on calldata size and L1 gas prices). The gas
|
||||
command estimates L2 execution cost only.
|
||||
- **Whale detector scans latest block only** — not historical. Results
|
||||
vary by the moment you query. Default threshold is 1.0 ETH.
|
||||
- **Proxy detection** — only EIP-1967 proxies are detected. Other proxy
|
||||
patterns (EIP-1167 minimal proxy, custom storage slots) are not checked.
|
||||
- **Retry on 429** — both RPC and CoinGecko calls retry up to 2 times
|
||||
with exponential backoff on rate-limit errors.
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Should print Base chain ID (8453), latest block, gas price, and ETH price
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py stats
|
||||
```
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -25,6 +25,11 @@ Optimism, Avalanche (C-Chain), zkSync Era.
|
|||
No API key needed. Zero external dependencies — Python standard library only
|
||||
(urllib, json, argparse, threading).
|
||||
|
||||
> **Supersedes the standalone `base` skill.** Base-specific tokens (AERO, DEGEN,
|
||||
> TOSHI, BRETT, WELL, cbETH, cbBTC, wstETH, rETH) and all Base RPC functionality
|
||||
> previously living under `optional-skills/blockchain/base/` have been folded
|
||||
> into this skill. Pass `--chain base` to any command for Base coverage.
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
|
@ -188,8 +193,10 @@ Shows gwei price + USD cost for: transfer, ERC-20 transfer, approve, swap, NFT m
|
|||
- `wallet` and `allowance` only check known token list (~30 tokens per chain). Use a block explorer for complete token discovery.
|
||||
- `activity` scans recent blocks only (max 200). For full history, use Etherscan API.
|
||||
- `multichain` runs 8 parallel threads — can trigger rate limits on public RPCs.
|
||||
- ENS requires internet access to ensideas.com.
|
||||
- Tx decode requires internet access to 4byte.directory.
|
||||
- ENS resolution depends on a single public endpoint (ensideas.com / ens.vitalik.ca) with no fallback. If that endpoint is down, `ens` will fail — re-run later or use a block explorer.
|
||||
- Tx decoding depends on a single public endpoint (4byte.directory) with no fallback. Selectors not in their database show up as `unknown`.
|
||||
- **L2 gas estimates are L2-execution only.** On rollups like Base, Arbitrum, Optimism, and zkSync, the actual transaction cost also includes an L1 data-posting fee that depends on calldata size and current L1 gas prices. The `gas` command does not estimate that L1 component. For Base specifically, see the network's L1 fee oracle (contract `0x420000000000000000000000000000000000000F`).
|
||||
- Address / tx-hash inputs are validated for 0x-prefix + correct length + hex, but EIP-55 checksum casing is **not** enforced (RPC endpoints accept any-case hex).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -137,9 +137,21 @@ KNOWN_TOKENS: Dict[str, Dict[str, str]] = {
|
|||
"DOGE": "0xbA2aE424d960c26247Dd6c32edC70B295c744C43",
|
||||
},
|
||||
"base": {
|
||||
"USDC": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
||||
"DAI": "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
||||
"WETH": "0x4200000000000000000000000000000000000006",
|
||||
# Stables + wrapped
|
||||
"USDC": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
||||
"DAI": "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
||||
"WETH": "0x4200000000000000000000000000000000000006",
|
||||
# Liquid-staked ETH variants
|
||||
"cbETH": "0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cF0DEc22",
|
||||
"wstETH": "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
|
||||
"rETH": "0xB6fe221Fe9EeF5aBa221c348bA20A1Bf5e73624c",
|
||||
"cbBTC": "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
|
||||
# Base-native DeFi + meme tokens (carried over from the standalone base/ skill)
|
||||
"AERO": "0x940181a94A35A4569E4529A3CDfB74e38FD98631",
|
||||
"DEGEN": "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed",
|
||||
"TOSHI": "0xAC1Bd2486aAf3B5C0fc3Fd868558b082a531B2B4",
|
||||
"BRETT": "0x532f27101965dd16442E59d40670FaF5eBB142E4",
|
||||
"WELL": "0xA88594D404727625A9437C3f886C7643872296AE",
|
||||
},
|
||||
"arbitrum": {
|
||||
"USDC": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
||||
|
|
@ -226,9 +238,73 @@ def hex_to_int(h: str) -> int:
|
|||
return 0
|
||||
return int(h, 16)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Input validation
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def is_valid_address(s: str) -> bool:
|
||||
"""Return True if `s` looks like a 20-byte hex Ethereum address.
|
||||
|
||||
Does NOT validate EIP-55 checksum — RPC endpoints accept any-case hex.
|
||||
Just guards against typos / wrong-length input before we burn an RPC call.
|
||||
"""
|
||||
if not isinstance(s, str):
|
||||
return False
|
||||
if not s.startswith("0x") and not s.startswith("0X"):
|
||||
return False
|
||||
if len(s) != 42:
|
||||
return False
|
||||
try:
|
||||
int(s, 16)
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_valid_txhash(s: str) -> bool:
|
||||
"""Return True if `s` looks like a 32-byte hex transaction hash."""
|
||||
if not isinstance(s, str):
|
||||
return False
|
||||
if not s.startswith("0x") and not s.startswith("0X"):
|
||||
return False
|
||||
if len(s) != 66:
|
||||
return False
|
||||
try:
|
||||
int(s, 16)
|
||||
except ValueError:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def require_address(s: str, *, field: str = "address") -> str:
|
||||
"""Return `s` lowercased if valid, else exit with an error message.
|
||||
|
||||
Centralizing validation here means every subcommand fails fast on bad input
|
||||
instead of bubbling up an opaque RPC error 30 seconds later.
|
||||
"""
|
||||
if not is_valid_address(s):
|
||||
sys.stderr.write(
|
||||
f"error: invalid {field} {s!r}: expected 0x-prefixed 40-hex-char address\n"
|
||||
)
|
||||
sys.exit(2)
|
||||
return s.lower()
|
||||
|
||||
|
||||
def require_txhash(s: str, *, field: str = "tx hash") -> str:
|
||||
"""Return `s` lowercased if valid, else exit with an error message."""
|
||||
if not is_valid_txhash(s):
|
||||
sys.stderr.write(
|
||||
f"error: invalid {field} {s!r}: expected 0x-prefixed 64-hex-char tx hash\n"
|
||||
)
|
||||
sys.exit(2)
|
||||
return s.lower()
|
||||
|
||||
|
||||
def wei_to_native(wei: int, decimals: int = 18) -> float:
|
||||
return wei / (10 ** decimals)
|
||||
|
||||
|
||||
def gwei_from_wei(wei: int) -> float:
|
||||
return wei / 1e9
|
||||
|
||||
|
|
@ -326,25 +402,36 @@ def rpc_call(chain: str, method: str, params: List[Any], req_id: int = 1) -> Any
|
|||
raise RuntimeError(f"RPC error: {resp['error']}")
|
||||
return resp.get("result")
|
||||
|
||||
def rpc_batch(chain: str, calls: List[Tuple[str, List[Any]]]) -> List[Any]:
|
||||
"""Send a batch of JSON-RPC calls; returns list of results in same order."""
|
||||
def rpc_batch(chain: str, calls: List[Tuple[str, List[Any]]], batch_limit: int = 10) -> List[Any]:
|
||||
"""Send a batch of JSON-RPC calls; returns list of results in same order.
|
||||
|
||||
Auto-chunks at `batch_limit` (default 10) so we stay under per-RPC limits.
|
||||
Base's public RPC caps batches at 10 — exceeding that returns a single error
|
||||
dict instead of a results list, which would mask all our calls.
|
||||
"""
|
||||
url = get_rpc_url(chain)
|
||||
payload = [
|
||||
|
||||
# Build the full payload, preserving order via JSON-RPC `id`
|
||||
items = [
|
||||
{"jsonrpc": "2.0", "id": i, "method": m, "params": p}
|
||||
for i, (m, p) in enumerate(calls)
|
||||
]
|
||||
resp = _http_post(url, payload)
|
||||
if isinstance(resp, list):
|
||||
# Sort by id to preserve order
|
||||
resp_sorted = sorted(resp, key=lambda x: x.get("id", 0))
|
||||
results = []
|
||||
for r in resp_sorted:
|
||||
if "error" in r:
|
||||
results.append(None)
|
||||
else:
|
||||
results.append(r.get("result"))
|
||||
return results
|
||||
return [resp.get("result")]
|
||||
|
||||
out: List[Any] = [None] * len(items)
|
||||
for start in range(0, len(items), batch_limit):
|
||||
chunk = items[start:start + batch_limit]
|
||||
resp = _http_post(url, chunk)
|
||||
if not isinstance(resp, list):
|
||||
# Single error response (e.g. batch-too-large) — leave this chunk as None
|
||||
continue
|
||||
for r in resp:
|
||||
rid = r.get("id")
|
||||
if isinstance(rid, int) and 0 <= rid < len(out):
|
||||
if "error" in r:
|
||||
out[rid] = None
|
||||
else:
|
||||
out[rid] = r.get("result")
|
||||
return out
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ABI encoding helpers (minimal, for ERC-20 calls)
|
||||
|
|
@ -556,7 +643,7 @@ def cmd_stats(args: argparse.Namespace) -> None:
|
|||
|
||||
|
||||
def cmd_wallet(args: argparse.Namespace) -> None:
|
||||
address = args.address
|
||||
address = require_address(args.address)
|
||||
chain = args.chain
|
||||
limit = args.limit
|
||||
no_prices = args.no_prices
|
||||
|
|
@ -633,7 +720,7 @@ def cmd_wallet(args: argparse.Namespace) -> None:
|
|||
|
||||
|
||||
def cmd_tx(args: argparse.Namespace) -> None:
|
||||
tx_hash = args.hash
|
||||
tx_hash = require_txhash(args.hash)
|
||||
chain = args.chain
|
||||
cfg = CHAINS[chain]
|
||||
|
||||
|
|
@ -702,7 +789,7 @@ def cmd_tx(args: argparse.Namespace) -> None:
|
|||
|
||||
|
||||
def cmd_token(args: argparse.Namespace) -> None:
|
||||
contract = args.contract
|
||||
contract = require_address(args.contract, field="contract address")
|
||||
chain = args.chain
|
||||
|
||||
# Batch all ERC-20 metadata calls
|
||||
|
|
@ -744,7 +831,7 @@ def cmd_token(args: argparse.Namespace) -> None:
|
|||
|
||||
|
||||
def cmd_activity(args: argparse.Namespace) -> None:
|
||||
address = args.address
|
||||
address = require_address(args.address)
|
||||
chain = args.chain
|
||||
limit = args.limit
|
||||
cfg = CHAINS[chain]
|
||||
|
|
@ -1000,7 +1087,7 @@ def cmd_multichain(args: argparse.Namespace) -> None:
|
|||
"""Scan same wallet across all 8 chains simultaneously."""
|
||||
import threading
|
||||
|
||||
address = args.address
|
||||
address = require_address(args.address)
|
||||
results: Dict[str, Any] = {}
|
||||
lock = threading.Lock()
|
||||
|
||||
|
|
@ -1019,9 +1106,10 @@ def cmd_multichain(args: argparse.Namespace) -> None:
|
|||
"tokens": [],
|
||||
"total_usd": native_usd or 0.0,
|
||||
}
|
||||
# Check known tokens for this chain
|
||||
# Check known tokens for this chain.
|
||||
# KNOWN_TOKENS[chain] maps {symbol: contract_address}, not {addr: (sym, name)}.
|
||||
known = KNOWN_TOKENS.get(chain, {})
|
||||
for contract, (symbol, _name) in known.items():
|
||||
for symbol, contract in known.items():
|
||||
raw = eth_call_erc20(chain, contract, "balanceOf(address)", address)
|
||||
if not raw or raw == "0x":
|
||||
continue
|
||||
|
|
@ -1067,7 +1155,7 @@ def cmd_multichain(args: argparse.Namespace) -> None:
|
|||
|
||||
def cmd_allowance(args: argparse.Namespace) -> None:
|
||||
"""Check dangerous ERC-20 approvals for a wallet (known spenders)."""
|
||||
address = args.address
|
||||
address = require_address(args.address)
|
||||
chain = args.chain
|
||||
|
||||
# Well-known spender contracts (DEXes, bridges, etc.)
|
||||
|
|
@ -1085,7 +1173,8 @@ def cmd_allowance(args: argparse.Namespace) -> None:
|
|||
known = KNOWN_TOKENS.get(chain, {})
|
||||
approvals = []
|
||||
|
||||
for contract, (symbol, _name) in known.items():
|
||||
# KNOWN_TOKENS[chain] is {symbol: contract_address}, not {addr: (sym, name)}.
|
||||
for symbol, contract in known.items():
|
||||
for spender_addr, spender_name in KNOWN_SPENDERS.items():
|
||||
# allowance(owner, spender) = 0xdd62ed3e
|
||||
owner_pad = address.lower().replace("0x", "").zfill(64)
|
||||
|
|
@ -1127,7 +1216,7 @@ def cmd_allowance(args: argparse.Namespace) -> None:
|
|||
def cmd_decode(args: argparse.Namespace) -> None:
|
||||
"""Decode transaction input data using 4byte.directory."""
|
||||
chain = args.chain
|
||||
tx_hash = args.hash
|
||||
tx_hash = require_txhash(args.hash)
|
||||
|
||||
tx = rpc_call(chain, "eth_getTransactionByHash", [tx_hash])
|
||||
if not tx:
|
||||
|
|
@ -1212,7 +1301,7 @@ def cmd_ens(args: argparse.Namespace) -> None:
|
|||
def cmd_contract(args: argparse.Namespace) -> None:
|
||||
"""Inspect a smart contract: bytecode size, proxy detection, creation info."""
|
||||
chain = args.chain
|
||||
address = args.address
|
||||
address = require_address(args.address)
|
||||
|
||||
# Get bytecode
|
||||
code_hex = rpc_call(chain, "eth_getCode", [address, "latest"])
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ hermes skills uninstall <skill-name>
|
|||
|
||||
| Skill | Description |
|
||||
|-------|-------------|
|
||||
| [**base**](/docs/user-guide/skills/optional/blockchain/blockchain-base) | Query Base (Ethereum L2) blockchain data with USD pricing — wallet balances, token info, transaction details, gas analysis, contract inspection, whale detection, and live network stats. Uses Base RPC + CoinGecko. No API key required. |
|
||||
| [**evm**](/docs/user-guide/skills/optional/blockchain/blockchain-evm) | Query EVM blockchain data across 8 chains — wallet portfolios, ERC-20 tokens, transactions, gas tracker, whale detection, multi-chain scan, ENS resolution, allowance checker, contract inspection, and tx decoder. Supports Ethereum, BNB Chain, Base, Arbitrum, Polygon, Optimism, Avalanche, zkSync. Uses public RPCs + CoinGecko. No API key required. |
|
||||
| [**solana**](/docs/user-guide/skills/optional/blockchain/blockchain-solana) | Query Solana blockchain data with USD pricing — wallet balances, token portfolios with values, transaction details, NFTs, whale detection, and live network stats. Uses Solana RPC + CoinGecko. No API key required. |
|
||||
|
||||
## communication
|
||||
|
|
|
|||
|
|
@ -1,249 +0,0 @@
|
|||
---
|
||||
title: "Base"
|
||||
sidebar_label: "Base"
|
||||
description: "Query Base (Ethereum L2) blockchain data with USD pricing — wallet balances, token info, transaction details, gas analysis, contract inspection, whale detect..."
|
||||
---
|
||||
|
||||
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
||||
|
||||
# Base
|
||||
|
||||
Query Base (Ethereum L2) blockchain data with USD pricing — wallet balances, token info, transaction details, gas analysis, contract inspection, whale detection, and live network stats. Uses Base RPC + CoinGecko. No API key required.
|
||||
|
||||
## Skill metadata
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Source | Optional — install with `hermes skills install official/blockchain/base` |
|
||||
| Path | `optional-skills/blockchain/base` |
|
||||
| Version | `0.1.0` |
|
||||
| Author | youssefea |
|
||||
| License | MIT |
|
||||
| Platforms | linux, macos, windows |
|
||||
| Tags | `Base`, `Blockchain`, `Crypto`, `Web3`, `RPC`, `DeFi`, `EVM`, `L2`, `Ethereum` |
|
||||
|
||||
## Reference: full SKILL.md
|
||||
|
||||
:::info
|
||||
The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active.
|
||||
:::
|
||||
|
||||
# Base Blockchain Skill
|
||||
|
||||
Query Base (Ethereum L2) on-chain data enriched with USD pricing via CoinGecko.
|
||||
8 commands: wallet portfolio, token info, transactions, gas analysis,
|
||||
contract inspection, whale detection, network stats, and price lookup.
|
||||
|
||||
No API key needed. Uses only Python standard library (urllib, json, argparse).
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
- User asks for a Base wallet balance, token holdings, or portfolio value
|
||||
- User wants to inspect a specific transaction by hash
|
||||
- User wants ERC-20 token metadata, price, supply, or market cap
|
||||
- User wants to understand Base gas costs and L1 data fees
|
||||
- User wants to inspect a contract (ERC type detection, proxy resolution)
|
||||
- User wants to find large ETH transfers (whale detection)
|
||||
- User wants Base network health, gas price, or ETH price
|
||||
- User asks "what's the price of USDC/AERO/DEGEN/ETH?"
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The helper script uses only Python standard library (urllib, json, argparse).
|
||||
No external packages required.
|
||||
|
||||
Pricing data comes from CoinGecko's free API (no key needed, rate-limited
|
||||
to ~10-30 requests/minute). For faster lookups, use `--no-prices` flag.
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
RPC endpoint (default): https://mainnet.base.org
|
||||
Override: export BASE_RPC_URL=https://your-private-rpc.com
|
||||
|
||||
Helper script path: ~/.hermes/skills/blockchain/base/scripts/base_client.py
|
||||
|
||||
```
|
||||
python3 base_client.py wallet <address> [--limit N] [--all] [--no-prices]
|
||||
python3 base_client.py tx <hash>
|
||||
python3 base_client.py token <contract_address>
|
||||
python3 base_client.py gas
|
||||
python3 base_client.py contract <address>
|
||||
python3 base_client.py whales [--min-eth N]
|
||||
python3 base_client.py stats
|
||||
python3 base_client.py price <contract_address_or_symbol>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Procedure
|
||||
|
||||
### 0. Setup Check
|
||||
|
||||
```bash
|
||||
python3 --version
|
||||
|
||||
# Optional: set a private RPC for better rate limits
|
||||
export BASE_RPC_URL="https://mainnet.base.org"
|
||||
|
||||
# Confirm connectivity
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py stats
|
||||
```
|
||||
|
||||
### 1. Wallet Portfolio
|
||||
|
||||
Get ETH balance and ERC-20 token holdings with USD values.
|
||||
Checks ~15 well-known Base tokens (USDC, WETH, AERO, DEGEN, etc.)
|
||||
via on-chain `balanceOf` calls. Tokens sorted by value, dust filtered.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
wallet 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
|
||||
```
|
||||
|
||||
Flags:
|
||||
- `--limit N` — show top N tokens (default: 20)
|
||||
- `--all` — show all tokens, no dust filter, no limit
|
||||
- `--no-prices` — skip CoinGecko price lookups (faster, RPC-only)
|
||||
|
||||
Output includes: ETH balance + USD value, token list with prices sorted
|
||||
by value, dust count, total portfolio value in USD.
|
||||
|
||||
Note: Only checks known tokens. Unknown ERC-20s are not discovered.
|
||||
Use the `token` command with a specific contract address for any token.
|
||||
|
||||
### 2. Transaction Details
|
||||
|
||||
Inspect a full transaction by its hash. Shows ETH value transferred,
|
||||
gas used, fee in ETH/USD, status, and decoded ERC-20/ERC-721 transfers.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
tx 0xabc123...your_tx_hash_here
|
||||
```
|
||||
|
||||
Output: hash, block, from, to, value (ETH + USD), gas price, gas used,
|
||||
fee, status, contract creation address (if any), token transfers.
|
||||
|
||||
### 3. Token Info
|
||||
|
||||
Get ERC-20 token metadata: name, symbol, decimals, total supply, price,
|
||||
market cap, and contract code size.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
||||
```
|
||||
|
||||
Output: name, symbol, decimals, total supply, price, market cap.
|
||||
Reads name/symbol/decimals directly from the contract via eth_call.
|
||||
|
||||
### 4. Gas Analysis
|
||||
|
||||
Detailed gas analysis with cost estimates for common operations.
|
||||
Shows current gas price, base fee trends over 10 blocks, block
|
||||
utilization, and estimated costs for ETH transfers, ERC-20 transfers,
|
||||
and swaps.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py gas
|
||||
```
|
||||
|
||||
Output: current gas price, base fee, block utilization, 10-block trend,
|
||||
cost estimates in ETH and USD.
|
||||
|
||||
Note: Base is an L2 — actual transaction costs include an L1 data
|
||||
posting fee that depends on calldata size and L1 gas prices. The
|
||||
estimates shown are for L2 execution only.
|
||||
|
||||
### 5. Contract Inspection
|
||||
|
||||
Inspect an address: determine if it's an EOA or contract, detect
|
||||
ERC-20/ERC-721/ERC-1155 interfaces, resolve EIP-1967 proxy
|
||||
implementation addresses.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
contract 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
||||
```
|
||||
|
||||
Output: is_contract, code size, ETH balance, detected interfaces
|
||||
(ERC-20, ERC-721, ERC-1155), ERC-20 metadata, proxy implementation
|
||||
address.
|
||||
|
||||
### 6. Whale Detector
|
||||
|
||||
Scan the most recent block for large ETH transfers with USD values.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py \
|
||||
whales --min-eth 1.0
|
||||
```
|
||||
|
||||
Note: scans the latest block only — point-in-time snapshot, not historical.
|
||||
Default threshold is 1.0 ETH (lower than Solana's default since ETH
|
||||
values are higher).
|
||||
|
||||
### 7. Network Stats
|
||||
|
||||
Live Base network health: latest block, chain ID, gas price, base fee,
|
||||
block utilization, transaction count, and ETH price.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py stats
|
||||
```
|
||||
|
||||
### 8. Price Lookup
|
||||
|
||||
Quick price check for any token by contract address or known symbol.
|
||||
|
||||
```bash
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price ETH
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price USDC
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price AERO
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price DEGEN
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py price 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
|
||||
```
|
||||
|
||||
Known symbols: ETH, WETH, USDC, cbETH, AERO, DEGEN, TOSHI, BRETT,
|
||||
WELL, wstETH, rETH, cbBTC.
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- **CoinGecko rate-limits** — free tier allows ~10-30 requests/minute.
|
||||
Price lookups use 1 request per token. Use `--no-prices` for speed.
|
||||
- **Public RPC rate-limits** — Base's public RPC limits requests.
|
||||
For production use, set BASE_RPC_URL to a private endpoint
|
||||
(Alchemy, QuickNode, Infura).
|
||||
- **Wallet shows known tokens only** — unlike Solana, EVM chains have no
|
||||
built-in "get all tokens" RPC. The wallet command checks ~15 popular
|
||||
Base tokens via `balanceOf`. Unknown ERC-20s won't appear. Use the
|
||||
`token` command for any specific contract.
|
||||
- **Token names read from contract** — if a contract doesn't implement
|
||||
`name()` or `symbol()`, these fields may be empty. Known tokens have
|
||||
hardcoded labels as fallback.
|
||||
- **Gas estimates are L2 only** — Base transaction costs include an L1
|
||||
data posting fee (depends on calldata size and L1 gas prices). The gas
|
||||
command estimates L2 execution cost only.
|
||||
- **Whale detector scans latest block only** — not historical. Results
|
||||
vary by the moment you query. Default threshold is 1.0 ETH.
|
||||
- **Proxy detection** — only EIP-1967 proxies are detected. Other proxy
|
||||
patterns (EIP-1167 minimal proxy, custom storage slots) are not checked.
|
||||
- **Retry on 429** — both RPC and CoinGecko calls retry up to 2 times
|
||||
with exponential backoff on rate-limit errors.
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Should print Base chain ID (8453), latest block, gas price, and ETH price
|
||||
python3 ~/.hermes/skills/blockchain/base/scripts/base_client.py stats
|
||||
```
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
---
|
||||
title: "Evm"
|
||||
sidebar_label: "Evm"
|
||||
description: "Query EVM blockchain data across 8 chains — wallet portfolios, ERC-20 tokens, transactions, gas tracker, whale detection, multi-chain scan, ENS resolution, a..."
|
||||
---
|
||||
|
||||
{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}
|
||||
|
||||
# Evm
|
||||
|
||||
Query EVM blockchain data across 8 chains — wallet portfolios, ERC-20 tokens, transactions, gas tracker, whale detection, multi-chain scan, ENS resolution, allowance checker, contract inspection, and tx decoder. Supports Ethereum, BNB Chain, Base, Arbitrum, Polygon, Optimism, Avalanche, zkSync. Uses public RPCs + CoinGecko. No API key required.
|
||||
|
||||
## Skill metadata
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| Source | Optional — install with `hermes skills install official/blockchain/evm` |
|
||||
| Path | `optional-skills/blockchain/evm` |
|
||||
| Version | `1.0.0` |
|
||||
| Author | Mibayy |
|
||||
| License | MIT |
|
||||
| Tags | `EVM`, `Ethereum`, `BNB`, `BSC`, `Base`, `Arbitrum`, `Polygon`, `Optimism`, `Avalanche`, `zkSync`, `Blockchain`, `Crypto`, `Web3`, `DeFi`, `NFT`, `ENS`, `Whale`, `Security` |
|
||||
| Related skills | [`solana`](/docs/user-guide/skills/optional/blockchain/blockchain-solana) |
|
||||
|
||||
## Reference: full SKILL.md
|
||||
|
||||
:::info
|
||||
The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active.
|
||||
:::
|
||||
|
||||
# EVM Blockchain Skill
|
||||
|
||||
Query EVM-compatible blockchain data across 8 chains with USD pricing.
|
||||
14 commands: wallet portfolio, token info, transactions, activity, gas tracker,
|
||||
network stats, price lookup, multi-chain scan, whale detection, ENS resolution,
|
||||
allowance checker, contract inspector, and transaction decoder.
|
||||
|
||||
Supports 8 chains: Ethereum, BNB Chain (BSC), Base, Arbitrum One, Polygon,
|
||||
Optimism, Avalanche (C-Chain), zkSync Era.
|
||||
|
||||
No API key needed. Zero external dependencies — Python standard library only
|
||||
(urllib, json, argparse, threading).
|
||||
|
||||
> **Supersedes the standalone `base` skill.** Base-specific tokens (AERO, DEGEN,
|
||||
> TOSHI, BRETT, WELL, cbETH, cbBTC, wstETH, rETH) and all Base RPC functionality
|
||||
> previously living under `optional-skills/blockchain/base/` have been folded
|
||||
> into this skill. Pass `--chain base` to any command for Base coverage.
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
- User asks for a wallet balance or portfolio on any EVM chain
|
||||
- User wants to check the same wallet across ALL chains at once
|
||||
- User wants to inspect a transaction by hash (or decode what it did)
|
||||
- User wants ERC-20 token metadata, price, supply, or market cap
|
||||
- User wants recent transaction history for an address
|
||||
- User wants current gas prices or to compare fees across chains
|
||||
- User wants to find large whale transfers in recent blocks
|
||||
- User asks to resolve an ENS name (vitalik.eth) or reverse-lookup an address
|
||||
- User wants to check if a contract has dangerous token approvals
|
||||
- User wants to inspect a smart contract (proxy? ERC-20? ERC-721? bytecode size?)
|
||||
- User wants to compare gas costs across chains before a transaction
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
Python 3.8+ standard library only. No pip installs required.
|
||||
Pricing: CoinGecko free API (rate-limited, ~10-30 req/min).
|
||||
ENS: ensideas.com public API.
|
||||
Tx decoding: 4byte.directory public API.
|
||||
|
||||
Override RPC endpoint: `export EVM_RPC_URL=https://your-rpc.com`
|
||||
|
||||
Helper script path: `~/.hermes/skills/blockchain/evm/scripts/evm_client.py`
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
```
|
||||
SCRIPT=~/.hermes/skills/blockchain/evm/scripts/evm_client.py
|
||||
|
||||
# Network & prices
|
||||
python3 $SCRIPT stats # Ethereum stats
|
||||
python3 $SCRIPT stats --chain arbitrum # Arbitrum stats
|
||||
python3 $SCRIPT compare # Gas + prices ALL 8 chains
|
||||
|
||||
# Wallet
|
||||
python3 $SCRIPT wallet 0xd8dA...96045 # Portfolio (ETH + ERC-20)
|
||||
python3 $SCRIPT wallet 0xd8dA...96045 --chain bsc
|
||||
python3 $SCRIPT multichain 0xd8dA...96045 # Same wallet on ALL chains
|
||||
|
||||
# Tokens & prices
|
||||
python3 $SCRIPT price ETH
|
||||
python3 $SCRIPT price 0xdAC1...1ec7 # By contract address
|
||||
python3 $SCRIPT token 0xdAC1...1ec7 # ERC-20 metadata + market cap
|
||||
|
||||
# Transactions
|
||||
python3 $SCRIPT tx 0x5c50...f060 # Transaction details
|
||||
python3 $SCRIPT decode 0x5c50...f060 # Decode input data (4byte.directory)
|
||||
python3 $SCRIPT activity 0xd8dA...96045 # Recent transactions
|
||||
|
||||
# Gas
|
||||
python3 $SCRIPT gas # Gas prices + cost estimates
|
||||
python3 $SCRIPT gas --chain optimism
|
||||
|
||||
# Security
|
||||
python3 $SCRIPT allowance 0xd8dA...96045 # Dangerous ERC-20 approvals
|
||||
python3 $SCRIPT contract 0xdAC1...1ec7 # Contract inspection (proxy? standards?)
|
||||
|
||||
# ENS
|
||||
python3 $SCRIPT ens vitalik.eth # Name -> address + profile
|
||||
python3 $SCRIPT ens 0xd8dA...96045 # Address -> ENS name
|
||||
|
||||
# Whale detection
|
||||
python3 $SCRIPT whale # Large transfers (last 20 blocks, >$10k)
|
||||
python3 $SCRIPT whale --blocks 50 --min-usd 100000 --chain arbitrum
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Procedure
|
||||
|
||||
### 0. Setup Check
|
||||
```bash
|
||||
python3 --version # 3.8+ required
|
||||
python3 ~/.hermes/skills/blockchain/evm/scripts/evm_client.py stats
|
||||
```
|
||||
|
||||
### 1. Wallet Portfolio
|
||||
Native balance + known ERC-20 tokens, sorted by USD value.
|
||||
```bash
|
||||
python3 $SCRIPT wallet 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
|
||||
python3 $SCRIPT wallet 0xd8dA... --chain bsc --no-prices # faster
|
||||
```
|
||||
|
||||
### 2. Multi-Chain Scan
|
||||
Scans all 8 chains simultaneously for the same address using threads.
|
||||
```bash
|
||||
python3 $SCRIPT multichain 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
|
||||
```
|
||||
Output: per-chain native balance + token holdings + grand total USD.
|
||||
|
||||
### 3. Compare (Gas + Prices)
|
||||
All 8 chains queried in parallel. Shows cheapest/most expensive chain.
|
||||
```bash
|
||||
python3 $SCRIPT compare
|
||||
```
|
||||
|
||||
### 4. Transaction Details & Decode
|
||||
```bash
|
||||
python3 $SCRIPT tx 0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060
|
||||
python3 $SCRIPT decode 0x5c504ed... # Shows human-readable function signature
|
||||
```
|
||||
Decode uses 4byte.directory to translate 0xa9059cbb -> transfer(address,uint256).
|
||||
|
||||
### 5. ENS Resolution
|
||||
```bash
|
||||
python3 $SCRIPT ens vitalik.eth # -> 0xd8dA... + avatar + social links
|
||||
python3 $SCRIPT ens 0xd8dA...96045 # -> vitalik.eth
|
||||
```
|
||||
|
||||
### 6. Allowance Checker (Security)
|
||||
Checks ERC-20 approvals granted to known DEX/bridge contracts.
|
||||
```bash
|
||||
python3 $SCRIPT allowance 0xYourWallet
|
||||
```
|
||||
Flags UNLIMITED approvals as HIGH risk.
|
||||
|
||||
### 7. Contract Inspector
|
||||
```bash
|
||||
python3 $SCRIPT contract 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 # USDC (proxy)
|
||||
python3 $SCRIPT contract 0xdAC17F958D2ee523a2206206994597C13D831ec7 # USDT (ERC-20)
|
||||
```
|
||||
Detects: proxy (EIP-1967/EIP-1167), ERC-20, ERC-721, ERC-165. Shows bytecode size and implementation address for proxies.
|
||||
|
||||
### 8. Whale Detection
|
||||
```bash
|
||||
python3 $SCRIPT whale # ETH, last 20 blocks, >$10k
|
||||
python3 $SCRIPT whale --blocks 50 --min-usd 50000 --chain bsc
|
||||
```
|
||||
|
||||
### 9. Gas Tracker
|
||||
```bash
|
||||
python3 $SCRIPT gas
|
||||
python3 $SCRIPT gas --chain polygon
|
||||
```
|
||||
Shows gwei price + USD cost for: transfer, ERC-20 transfer, approve, swap, NFT mint, NFT transfer.
|
||||
|
||||
---
|
||||
|
||||
## Supported Chains
|
||||
| Key | Name | Native | Chain ID |
|
||||
|-----------|----------------|--------|----------|
|
||||
| ethereum | Ethereum | ETH | 1 |
|
||||
| bsc | BNB Chain | BNB | 56 |
|
||||
| base | Base | ETH | 8453 |
|
||||
| arbitrum | Arbitrum One | ETH | 42161 |
|
||||
| polygon | Polygon | POL | 137 |
|
||||
| optimism | Optimism | ETH | 10 |
|
||||
| avalanche | Avalanche C | AVAX | 43114 |
|
||||
| zksync | zkSync Era | ETH | 324 |
|
||||
|
||||
---
|
||||
|
||||
## Pitfalls
|
||||
- CoinGecko free tier: ~10-30 req/min. Use `--no-prices` for faster wallet scans.
|
||||
- Public RPCs may throttle. Set EVM_RPC_URL to a private endpoint for production.
|
||||
- `wallet` and `allowance` only check known token list (~30 tokens per chain). Use a block explorer for complete token discovery.
|
||||
- `activity` scans recent blocks only (max 200). For full history, use Etherscan API.
|
||||
- `multichain` runs 8 parallel threads — can trigger rate limits on public RPCs.
|
||||
- ENS resolution depends on a single public endpoint (ensideas.com / ens.vitalik.ca) with no fallback. If that endpoint is down, `ens` will fail — re-run later or use a block explorer.
|
||||
- Tx decoding depends on a single public endpoint (4byte.directory) with no fallback. Selectors not in their database show up as `unknown`.
|
||||
- **L2 gas estimates are L2-execution only.** On rollups like Base, Arbitrum, Optimism, and zkSync, the actual transaction cost also includes an L1 data-posting fee that depends on calldata size and current L1 gas prices. The `gas` command does not estimate that L1 component. For Base specifically, see the network's L1 fee oracle (contract `0x420000000000000000000000000000000000000F`).
|
||||
- Address / tx-hash inputs are validated for 0x-prefix + correct length + hex, but EIP-55 checksum casing is **not** enforced (RPC endpoints accept any-case hex).
|
||||
|
||||
---
|
||||
|
||||
## Verification
|
||||
```bash
|
||||
# Should print current block, gas price, ETH price
|
||||
python3 ~/.hermes/skills/blockchain/evm/scripts/evm_client.py stats
|
||||
|
||||
# Should resolve vitalik.eth to 0xd8dA...
|
||||
python3 ~/.hermes/skills/blockchain/evm/scripts/evm_client.py ens vitalik.eth
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue