# Viem

> This skill should be used when the user asks about "viem", "viem client", "viem actions", "TypeScript Ethereum", "createPublicClient", "createWalletClient", "parseEther", "formatEther", "readContract", "writeContract", or mentions using viem for blockchain interactions.

- **Type:** Skill
- **Install:** `agentstack add skill-sablier-labs-agent-skills-viem`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [sablier-labs](https://agentstack.voostack.com/s/sablier-labs)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [sablier-labs](https://github.com/sablier-labs)
- **Source:** https://github.com/sablier-labs/agent-skills/tree/main/skills/viem

## Install

```sh
agentstack add skill-sablier-labs-agent-skills-viem
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 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:

```typescript
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:

```typescript
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:

```typescript
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

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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()`:

```typescript
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

```typescript
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

```typescript
const hash = await walletClient.writeContract({
  address: "0x...",
  abi,
  functionName: "transfer",
  args: ["0x...", parseUnits("100", 18)],
});
```

### Simulating Before Writing

Simulate a transaction before sending:

```typescript
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:

```typescript
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:

```typescript
import "viem/window";

const [account] = await window.ethereum!.request({
  method: "eth_requestAccounts",
});
```

## Chain Configuration

### Built-in Chains

```typescript
import { mainnet, sepolia, arbitrum, optimism, polygon, base } from "viem/chains";

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

### Custom Chains

```typescript
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 configuration
- `actions` - Available actions (read, write, wallet)
- `accounts` - Local and JSON-RPC accounts
- `contract` - Contract interactions (`readContract`, `writeContract`)
- `abi` - ABI encoding/decoding utilities
- `chains` - Supported chains and custom chain configuration

### Fetching Documentation

To fetch viem documentation for a specific topic:

1. Resolve the library ID with `mcp__context7__resolve-library-id` (or use `/wevm/viem` directly)
2. Call `mcp__context7__get-library-docs` with the topic parameter

Example topics: `"getting started"`, `"wallet client"`, `"send transaction"`, `"read contract"`.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [sablier-labs](https://github.com/sablier-labs)
- **Source:** [sablier-labs/agent-skills](https://github.com/sablier-labs/agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-sablier-labs-agent-skills-viem
- Seller: https://agentstack.voostack.com/s/sablier-labs
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
