web3-viem
npx skills add https://github.com/sablier-labs/agent-skills --skill web3-viem
Agent 安装分布
Skill 文档
Viem
Overview
Viem is a TypeScript interface for Ethereum that provides low-level stateless primitives for interacting with the blockchain. It focuses on developer experience, stability, bundle size, and performance.
Key features:
- Automatic type safety and inference
- Tree-shakable lightweight modules
- Optimized encoding/parsing
- Composable APIs
Core Concepts
| Concept | Description |
|---|---|
| Clients | PublicClient, WalletClient, TestClient – entry points |
| Transports | Connection layer (http, webSocket, custom) |
| Actions | Operations like getBlockNumber, sendTransaction |
| Chains | Chain configurations (mainnet, sepolia, arbitrum, etc.) |
Constants
Viem exports useful constants for common values:
import { maxUint256, maxUint128, maxInt256, zeroAddress, zeroHash } from "viem";
// Max values for uint types
maxUint256; // 2n ** 256n - 1n
maxUint128; // 2n ** 128n - 1n
// Zero values
zeroAddress; // 0x0000000000000000000000000000000000000000
zeroHash; // 0x0000000000000000000000000000000000000000000000000000000000000000
Utilities
Unit Conversion
Convert between wei and human-readable values:
import { parseEther, formatEther, parseUnits, formatUnits } from "viem";
// ETH <-> Wei (18 decimals)
parseEther("1"); // 1000000000000000000n
formatEther(1000000000000000000n); // "1"
// Custom decimals (e.g., USDC with 6 decimals)
parseUnits("100", 6); // 100000000n
formatUnits(100000000n, 6); // "100"
ABI Utilities
Parse human-readable ABIs:
import { parseAbi, parseAbiItem } from "viem";
const abi = parseAbi([
"function balanceOf(address owner) view returns (uint256)",
"function transfer(address to, uint256 amount) returns (bool)",
"event Transfer(address indexed from, address indexed to, uint256 amount)",
]);
const item = parseAbiItem("function name() view returns (string)");
Address Utilities
import { getAddress, isAddress, isAddressEqual } from "viem";
// Checksum address
getAddress("0xabc..."); // "0xAbc..." (checksummed)
// Validation
isAddress("0x..."); // true/false
isAddressEqual("0xAbc...", "0xabc..."); // true (case-insensitive)
Clients
Public Client (Read Operations)
For querying blockchain state:
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
const publicClient = createPublicClient({
chain: mainnet,
transport: http(), // or http("https://eth-mainnet.g.alchemy.com/v2/...")
});
// Read operations
const blockNumber = await publicClient.getBlockNumber();
const balance = await publicClient.getBalance({ address: "0x..." });
const block = await publicClient.getBlock();
Wallet Client (Write Operations)
For signing and sending transactions:
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";
const account = privateKeyToAccount("0x...");
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: http(),
});
// Send transaction
const hash = await walletClient.sendTransaction({
to: "0x...",
value: parseEther("0.1"),
});
Browser Wallet Client
For browser environments with injected wallets:
import "viem/window";
import { createWalletClient, custom } from "viem";
import { mainnet } from "viem/chains";
const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum!),
});
// Request accounts
const [address] = await walletClient.requestAddresses();
Extending Clients
Combine capabilities using .extend():
import { createWalletClient, http, publicActions } from "viem";
import { mainnet } from "viem/chains";
const client = createWalletClient({
chain: mainnet,
transport: http(),
}).extend(publicActions);
// Now supports both wallet and public actions
const balance = await client.getBalance({ address: "0x..." });
const hash = await client.sendTransaction({ to: "0x...", value: 1n });
Contract Interactions
Reading from Contracts
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});
const abi = [
{
inputs: [{ name: "owner", type: "address" }],
name: "balanceOf",
outputs: [{ name: "", type: "uint256" }],
stateMutability: "view",
type: "function",
},
] as const;
const balance = await publicClient.readContract({
address: "0x...", // Contract address
abi,
functionName: "balanceOf",
args: ["0x..."], // Owner address
});
Writing to Contracts
const hash = await walletClient.writeContract({
address: "0x...",
abi,
functionName: "transfer",
args: ["0x...", parseUnits("100", 18)],
});
Simulating Before Writing
Simulate a transaction before sending:
const { request } = await publicClient.simulateContract({
address: "0x...",
abi,
functionName: "transfer",
args: ["0x...", parseUnits("100", 18)],
account: "0x...",
});
const hash = await walletClient.writeContract(request);
Account Types
Local Accounts
For server-side or controlled environments:
import { privateKeyToAccount, mnemonicToAccount } from "viem/accounts";
// From private key
const account = privateKeyToAccount("0x...");
// From mnemonic
const account = mnemonicToAccount("legal winner thank year wave sausage ...");
JSON-RPC Accounts
For browser wallets:
import "viem/window";
const [account] = await window.ethereum!.request({
method: "eth_requestAccounts",
});
Chain Configuration
Built-in Chains
import { mainnet, sepolia, arbitrum, optimism, polygon, base } from "viem/chains";
const client = createPublicClient({
chain: arbitrum,
transport: http(),
});
Custom Chains
import { defineChain } from "viem";
const customChain = defineChain({
id: 123456,
name: "My Chain",
nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
rpcUrls: {
default: { http: ["https://rpc.mychain.com"] },
},
blockExplorers: {
default: { name: "Explorer", url: "https://explorer.mychain.com" },
},
});
Documentation
This skill provides a reference for common operations. For comprehensive documentation, fetch the full viem docs using context7 MCP:
Library ID: /wevm/viem
Use context7 to query specific topics:
clients– Client types and configurationactions– Available actions (read, write, wallet)accounts– Local and JSON-RPC accountscontract– Contract interactions (readContract,writeContract)abi– ABI encoding/decoding utilitieschains– Supported chains and custom chain configuration
Fetching Documentation
To fetch viem documentation for a specific topic:
- Resolve the library ID with
mcp__context7__resolve-library-id(or use/wevm/viemdirectly) - Call
mcp__context7__get-library-docswith the topic parameter
Example topics: "getting started", "wallet client", "send transaction", "read contract".