Home/区块链与 Web3/viem-integration
V

viem-integration

by @uniswapv
4.5(11)

Integrates EVM blockchains into TypeScript/JavaScript applications using viem, providing a quick decision guide.

ViemWeb3.jsEthereum DevelopmentSmart Contract InteractionBlockchain IntegrationGitHub
Installation
npx skills add uniswap/uniswap-ai --skill viem-integration
compare_arrows

Before / After Comparison

1
Before

In the past, when integrating EVM blockchains into TypeScript/JavaScript applications, developers often had to deal with complex Web3 libraries, encountering issues like inconsistent APIs and missing type definitions. This led to low development efficiency, lengthy decision-making processes, and a higher propensity for errors.

After

By using viem, developers can integrate EVM blockchains into TypeScript/JavaScript applications more lightly and efficiently. viem offers clear APIs and type safety, along with a quick decision-making guide, significantly simplifying the development process and accelerating the construction of Web3 applications.

description SKILL.md

viem-integration

viem Integration

Integrate EVM blockchains using viem for TypeScript/JavaScript applications.

Quick Decision Guide

Building... Use This

Node.js script/backend viem with http transport

React/Next.js frontend wagmi hooks (built on viem)

Real-time event monitoring viem with webSocket transport

Browser wallet integration wagmi or viem custom transport

Installation

# Core library
npm install viem

# For React apps, also install wagmi
npm install wagmi viem @tanstack/react-query

Core Concepts

Clients

viem uses two client types:

Client Purpose Example Use

PublicClient Read-only operations Get balances, read contracts, fetch logs

WalletClient Write operations Send transactions, sign messages

Transports

Transport Use Case

http() Standard RPC calls (most common)

webSocket() Real-time event subscriptions

custom() Browser wallets (window.ethereum)

Chains

viem includes 50+ chain definitions. Import from viem/chains:

import { mainnet, arbitrum, optimism, base, polygon } from 'viem/chains';

Input Validation Rules

Before interpolating ANY user-provided value into generated TypeScript code:

  • Ethereum addresses: MUST match ^0x[a-fA-F0-9]{40}$ — use viem's isAddress() for validation

  • Chain IDs: MUST be from viem's supported chain definitions

  • Private keys: MUST NEVER be hardcoded — always use process.env.PRIVATE_KEY with runtime validation

  • RPC URLs: MUST use https:// or wss:// protocols only

  • ABI inputs: Validate types match expected Solidity types before encoding

Quick Start Examples

Read Balance

import { createPublicClient, http, formatEther } from 'viem';
import { mainnet } from 'viem/chains';

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

const balance = await client.getBalance({
  address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
});

console.log(`Balance: ${formatEther(balance)} ETH`);

Read Contract

import { createPublicClient, http, parseAbi } from 'viem';
import { mainnet } from 'viem/chains';

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

const abi = parseAbi([
  'function balanceOf(address) view returns (uint256)',
  'function decimals() view returns (uint8)',
]);

const balance = await client.readContract({
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
  abi,
  functionName: 'balanceOf',
  args: ['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'],
});

Send Transaction

import { createWalletClient, http, parseEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const client = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
});

const hash = await client.sendTransaction({
  to: '0x...',
  value: parseEther('0.1'),
});

console.log(`Transaction hash: ${hash}`);

Write to Contract

import { createWalletClient, createPublicClient, http, parseAbi, parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
});

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

const abi = parseAbi(['function transfer(address to, uint256 amount) returns (bool)']);

// Simulate first to catch errors
const { request } = await publicClient.simulateContract({
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  abi,
  functionName: 'transfer',
  args: ['0x...', parseUnits('100', 6)],
  account,
});

// Execute the transaction
const hash = await walletClient.writeContract(request);

// Wait for confirmation
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log(`Confirmed in block ${receipt.blockNumber}`);

Reference Documentation

For deeper coverage of specific topics:

Topic Reference File

Client setup, transports, chains Clients & Transports

Reading blockchain data Reading Data

Sending transactions Writing Transactions

Private keys, HD wallets Accounts & Keys

ABI handling, multicall Contract Patterns

React/wagmi hooks Wagmi React

Related Plugins

Once you're comfortable with viem basics, the uniswap-trading plugin provides comprehensive Uniswap swap integration:

  • Uniswap Trading API integration

  • Universal Router SDK usage

  • Token swap implementations

Install it with: claude plugin add @uniswap/uniswap-trading

Common Utilities

Unit Conversion

import { parseEther, formatEther, parseUnits, formatUnits } from 'viem';

// ETH
parseEther('1.5'); // 1500000000000000000n (wei)
formatEther(1500000000000000000n); // "1.5"

// Tokens (e.g., USDC with 6 decimals)
parseUnits('100', 6); // 100000000n
formatUnits(100000000n, 6); // "100"

Address Utilities

import { getAddress, isAddress } from 'viem';

isAddress('0x...'); // true/false
getAddress('0x...'); // checksummed address

Hashing

import { keccak256, toHex } from 'viem';

keccak256(toHex('hello')); // 0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8

Error Handling

viem throws typed errors that can be caught and handled:

import { ContractFunctionExecutionError, InsufficientFundsError } from 'viem'

try {
  await client.writeContract(...)
} catch (error) {
  if (error instanceof ContractFunctionExecutionError) {
    console.error('Contract call failed:', error.shortMessage)
  }
  if (error instanceof InsufficientFundsError) {
    console.error('Not enough ETH for gas')
  }
}

Resources

Weekly Installs274Repositoryuniswap/uniswap-aiGitHub Stars177First SeenFeb 12, 2026Security AuditsGen Agent Trust HubPassSocketPassSnykWarnInstalled oncodex260opencode259gemini-cli254github-copilot252cursor250kimi-cli249

forumUser Reviews (0)

Write a Review

Effect
Usability
Docs
Compatibility

No reviews yet

Statistics

Installs349
Rating4.5 / 5.0
Version
Updated2026年3月17日
Comparisons1

User Rating

4.5(11)
5
0%
4
0%
3
0%
2
0%
1
0%

Rate this Skill

0.0

Compatible Platforms

🔧Claude Code
🔧OpenClaw
🔧OpenCode
🔧Codex
🔧Gemini CLI
🔧GitHub Copilot
🔧Amp
🔧Kimi CLI

Timeline

Created2026年3月17日
Last Updated2026年3月17日