Awesome-omni-skill viem

Viem blockchain client patterns for Ethereum interactions, transactions, signing, encoding, and smart contract calls. Triggers on viem, publicClient, walletClient, chain, abi.

install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/development/viem" ~/.claude/skills/diegosouzapw-awesome-omni-skill-viem && rm -rf "$T"
manifest: skills/development/viem/SKILL.md
source content
<objective> Build blockchain interactions using viem for Ethereum clients, transactions, signing, and smart contract interactions. Viem is the modern replacement for ethers.js with better TypeScript support. </objective>

<mcp_first> CRITICAL: Always fetch viem documentation before implementing.

MCPSearch({ query: "select:mcp__plugin_devtools_context7__query-docs" })
// Client patterns
mcp__context7__query_docs({
  context7CompatibleLibraryID: "/wevm/viem",
  topic: "createPublicClient createWalletClient"
})

// Contract interactions
mcp__context7__query_docs({
  context7CompatibleLibraryID: "/wevm/viem",
  topic: "readContract writeContract simulateContract"
})

// Signing
mcp__context7__query_docs({
  context7CompatibleLibraryID: "/wevm/viem",
  topic: "signMessage signTypedData EIP-712"
})

// Encoding
mcp__context7__query_docs({
  context7CompatibleLibraryID: "/wevm/viem",
  topic: "encodeFunctionData decodeFunctionResult encodeAbiParameters"
})

</mcp_first>

<quick_start> Create clients:

import { createPublicClient, createWalletClient, http } from "viem";
import { mainnet } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(),
});

const walletClient = createWalletClient({
  chain: mainnet,
  transport: http(),
  account: privateKeyToAccount("0x..."),
});

Read contract:

const balance = await publicClient.readContract({
  address: "0x...",
  abi: erc20Abi,
  functionName: "balanceOf",
  args: [userAddress],
});

Write contract:

const hash = await walletClient.writeContract({
  address: "0x...",
  abi: erc20Abi,
  functionName: "transfer",
  args: [recipient, amount],
});

const receipt = await publicClient.waitForTransactionReceipt({ hash });

</quick_start>

<client_types>

ClientPurposeExample Use
PublicClient
Reading blockchain data
getBlockNumber()
,
readContract()
WalletClient
Transaction signing/sending
sendTransaction()
,
signMessage()
TestClient
Testing and simulation
mine()
,
setBalance()
BundlerClient
ERC-4337 User Operations
sendUserOperation()
</client_types>
<utilities> **Unit conversions:**
import { parseEther, formatEther, parseUnits, formatUnits } from "viem";

parseEther("1.5");           // 1500000000000000000n
formatEther(1500000000000000000n);  // "1.5"
parseUnits("100", 6);        // 100000000n (USDC)
formatUnits(100000000n, 6);  // "100"

Address utilities:

import { getAddress, isAddress } from "viem";

getAddress("0xabc...");  // Checksummed address
isAddress("0x...");      // Validates format
</utilities> <constraints> **Banned:** SSRF protection for config-sourced URLs (they're developer-controlled)

Required:

  • Lazy initialization for chain resolution
  • Client caching by network name
  • WebSocket cleanup on destroy/refresh
  • Type-safe ABI interactions </constraints>

<success_criteria>

  • Context7 docs fetched for current API
  • Uses lazy chain resolution
  • Caches clients by network name
  • Type-safe ABI interactions
  • Proper error handling for blockchain ops </success_criteria>