viem-integration

Integrate EVM blockchains using viem for TypeScript/JavaScript applications.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "viem-integration" with this command: npx skills add uniswap/uniswap-ai/uniswap-uniswap-ai-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

  • viem Documentation

  • wagmi Documentation

  • viem GitHub

  • wagmi GitHub

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

swap-integration

No summary provided by upstream source.

Repository SourceNeeds Review
General

swap-planner

No summary provided by upstream source.

Repository SourceNeeds Review
General

liquidity-planner

No summary provided by upstream source.

Repository SourceNeeds Review
General

deployer

No summary provided by upstream source.

Repository SourceNeeds Review