Documentation Index
Fetch the complete documentation index at: https://developers.avacloud.io/llms.txt
Use this file to discover all available pages before exploring further.
Making C-Chain RPC Calls Using Viem
In this guide, you will learn how to make JSON-RPC calls to Avalanche’s C-Chain using viem, a TypeScript interface for Ethereum that works seamlessly with Avalanche’s EVM-compatible C-Chain.
Prerequisites
- Node.js (v14+) installed
- Basic familiarity with TypeScript/JavaScript
- Understanding of Ethereum/EVM concepts
Step 1: Install Dependencies
# Create a new project
mkdir avalanche-viem-example
cd avalanche-viem-example
npm init -y
# Install viem
npm install viem
# Install TypeScript (optional)
npm install -D typescript @types/node tsx
Step 2: Use Built-in Avalanche Chains
Viem includes Avalanche chain definitions out of the box:
import { avalanche, avalancheFuji } from 'viem/chains'
// avalanche = Avalanche Mainnet (Chain ID: 43114)
// avalancheFuji = Avalanche Fuji Testnet (Chain ID: 43113)
Step 3: Reading Blockchain Data
Create a file called readData.ts:
import { createPublicClient, http, formatEther } from 'viem'
import { avalanche } from 'viem/chains'
const client = createPublicClient({
chain: avalanche,
transport: http(),
})
async function readData() {
// Get the latest block
const block = await client.getBlock()
console.log('Latest block:', block.number)
// Get AVAX balance
const balance = await client.getBalance({
address: '0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC'
})
console.log('Balance:', formatEther(balance), 'AVAX')
// Get gas price
const gasPrice = await client.getGasPrice()
console.log('Gas price:', formatEther(gasPrice), 'AVAX')
}
readData()
Step 4: Sending Transactions
Create a file called sendTransaction.ts:
import { createWalletClient, createPublicClient, http, parseEther } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { avalancheFuji } from 'viem/chains'
// Use environment variable for private key
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const walletClient = createWalletClient({
account,
chain: avalancheFuji,
transport: http(),
})
const publicClient = createPublicClient({
chain: avalancheFuji,
transport: http(),
})
async function sendAvax() {
// Send 0.001 AVAX
const hash = await walletClient.sendTransaction({
to: '0x0000000000000000000000000000000000000000',
value: parseEther('0.001'),
})
console.log('Transaction hash:', hash)
// Wait for confirmation
const receipt = await publicClient.waitForTransactionReceipt({ hash })
console.log('Transaction confirmed:', receipt.status)
}
sendAvax()
Step 5: Smart Contract Interaction
Create a file called contractCall.ts:
import { createPublicClient, http, parseAbi, formatUnits } from 'viem'
import { avalanche } from 'viem/chains'
const client = createPublicClient({
chain: avalanche,
transport: http(),
})
// ERC20 ABI (minimal)
const abi = parseAbi([
'function balanceOf(address) view returns (uint256)',
'function decimals() view returns (uint8)',
'function symbol() view returns (string)',
])
async function readToken() {
// USDC on Avalanche
const usdcAddress = '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E'
const userAddress = '0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC'
// Read multiple values at once
const [balance, decimals, symbol] = await Promise.all([
client.readContract({
address: usdcAddress,
abi,
functionName: 'balanceOf',
args: [userAddress],
}),
client.readContract({
address: usdcAddress,
abi,
functionName: 'decimals',
}),
client.readContract({
address: usdcAddress,
abi,
functionName: 'symbol',
}),
])
console.log(`${symbol} Balance:`, formatUnits(balance, decimals))
}
readToken()
Environment Variables
Create a .env file for sensitive data:
PRIVATE_KEY=0x... # Never commit this!
Running the Examples
# Read blockchain data
npx tsx readData.ts
# Send transaction (requires PRIVATE_KEY)
npx tsx sendTransaction.ts
# Read smart contract
npx tsx contractCall.ts
Best Practices
- Security: Never hardcode private keys
- Gas Management: Always estimate gas before sending transactions
- Error Handling: Wrap async operations in try-catch blocks
- Network Selection: Use testnet (Fuji) for development
Conclusion
Viem provides a clean, type-safe interface for Avalanche C-Chain development with:
- Built-in Avalanche chain configurations
- Full EVM compatibility
- Excellent TypeScript support
- Efficient multicall and batching
For P-Chain and X-Chain operations, use the Avalanche SDK.
Resources