SDK Usage
web3agent ships as a standard npm package. Import the functions you need, call them, get typed results back. No MCP server, no CLI, no configuration files required for basic use.
npm install web3agent
# or
pnpm add web3agent
# or
yarn add web3agent
Requirements: Node.js 22+, TypeScript 5+ (optional but recommended).
Package Entry Points
| Import path | What's there |
|---|---|
"web3agent" | All SDK functions, types, schemas, config helpers |
"web3agent/runtime" | createRuntime(), Web3AgentRuntime type |
"web3agent/mcp" | ProxyServer, startServer() |
"web3agent/agdp" | aGDP marketplace client |
"web3agent/x402" | X-402 payment client |
Most projects only need the root import.
Configuration
Before calling any SDK function, tell web3agent which chain and wallet to use. The simplest approach is environment variables:
CHAIN_ID=8453
PRIVATE_KEY=0x...
RPC_URL=https://mainnet.base.org # optional, uses public RPC by default
Or configure programmatically:
import { setConfig, parseEnv } from "web3agent";
// From environment variables (reads process.env)
setConfig(parseEnv());
// Or pass values directly
setConfig({
chainId: 8453,
privateKey: process.env.PRIVATE_KEY,
confirmWrites: false, // skip confirmation queue for autonomous agents
});
Call setConfig() once at startup, before any other SDK calls.
Chain Utilities
import { getChain, listSupportedChains, findChainByName } from "web3agent";
// Get a chain by ID
const base = getChain(8453);
console.log(base.name); // "Base"
console.log(base.nativeCurrency.symbol); // "ETH"
// List all supported chains
const chains = listSupportedChains();
chains.forEach(c => console.log(`${c.id}: ${c.name}`));
// Find by name (case-insensitive)
const arbitrum = findChainByName("arbitrum");
Supported chain IDs: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 10 (Optimism), 137 (Polygon), 59144 (Linea), 56 (BSC), 43114 (Avalanche), 324 (zkSync Era), 534352 (Scroll), 34443 (Mode), 81457 (Blast), 5000 (Mantle), 42220 (Celo), 100 (Gnosis), 11155111 (Sepolia), 84532 (Base Sepolia).
Token Resolution
Canonical tokens (synchronous)
For well-known tokens like USDC, WETH, and USDT, use the synchronous resolver. No network call required.
import { resolveCanonicalTokenSync } from "web3agent";
const usdc = resolveCanonicalTokenSync({ symbol: "USDC", chainId: 8453 });
// { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6, symbol: "USDC" }
const weth = resolveCanonicalTokenSync({ symbol: "WETH", chainId: 8453 });
// { address: "0x4200000000000000000000000000000000000006", decimals: 18, symbol: "WETH" }
Returns null if the token isn't in the canonical registry.
Arbitrary tokens (async)
For tokens not in the canonical list, resolveToken() queries on-chain metadata.
import { resolveToken } from "web3agent";
const degen = await resolveToken({ symbol: "DEGEN", chainId: 8453 });
// { address: "0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed", decimals: 18, symbol: "DEGEN" }
List tokens on a chain
import { listChainTokens } from "web3agent";
const tokens = await listChainTokens({ chainId: 8453 });
tokens.forEach(t => console.log(`${t.symbol}: ${t.address}`));
Swap Operations
Get a quote
import { getSwapQuote } from "web3agent";
const quote = await getSwapQuote({
fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
toToken: "0x4200000000000000000000000000000000000006", // WETH
fromAmount: "10000000", // 10 USDC (6 decimals)
chainId: 8453,
});
console.log(`You'll receive approximately ${quote.toAmount} WETH`);
console.log(`Price impact: ${quote.priceImpact}%`);
console.log(`Route: ${quote.route}`);
Execute a same-chain swap
This signs and broadcasts the transaction using the configured private key. Only use this in server-side or autonomous agent contexts, not in browser apps where the user should sign.
import { executeSameChainSwap } from "web3agent";
const result = await executeSameChainSwap({
fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
toToken: "0x4200000000000000000000000000000000000006",
fromAmount: "10000000",
chainId: 8453,
});
console.log(`Swap complete: ${result.txHash}`);
console.log(`Received: ${result.toAmount} WETH`);
For browser wallet flows where the user signs, see the Browser Wallet Flows guide.
Explorer Functions
The explorer module wraps Blockscout and Etherscan to give indexed blockchain data without running your own node.
import {
getAddressInfo,
getTransactionHistory,
getTokenTransfers,
getContractAbi,
getTokenHolders,
getNftsByAddress,
} from "web3agent";
// Address overview
const info = await getAddressInfo({
address: "0xYourAddress",
chainId: 8453,
});
console.log(`ETH balance: ${info.balance}`);
console.log(`Transaction count: ${info.txCount}`);
// Transaction history
const history = await getTransactionHistory({
address: "0xYourAddress",
chainId: 8453,
page: 1,
limit: 25,
});
history.items.forEach(tx => {
console.log(`${tx.hash}: ${tx.value} ETH`);
});
// ERC-20 token transfers
const transfers = await getTokenTransfers({
address: "0xYourAddress",
chainId: 8453,
tokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
});
// Contract ABI
const abi = await getContractAbi({
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
chainId: 8453,
});
The explorer module has 40+ functions covering accounts, transactions, tokens, NFTs, contracts, and blocks. All functions accept chainId and return typed results.
Market Data
import {
getTokenPrice,
getProtocolTvl,
getTrendingTokens,
getTokenVolume,
getMarketSentiment,
} from "web3agent";
// Token prices (accepts multiple tokens in one call)
const prices = await getTokenPrice({
tokens: [
"8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
"8453:0x4200000000000000000000000000000000000006", // WETH on Base
],
});
console.log(prices["8453:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"].usd); // 1.0
// Protocol TVL
const tvl = await getProtocolTvl({ protocol: "uniswap" });
console.log(`Uniswap TVL: $${tvl.totalUsd.toLocaleString()}`);
// Trending tokens
const trending = await getTrendingTokens({ chainId: 8453, limit: 10 });
trending.forEach(t => console.log(`${t.symbol}: ${t.priceChange24h}%`));
Market data functions pull from DeFiLlama, CoinGecko, and on-chain sources. Results are cached with short TTLs to avoid rate limits.
Research Functions
import {
getTokenSecurityInfo,
getYieldOpportunities,
getGovernanceProposals,
getTokenHolderDistribution,
} from "web3agent";
// Security analysis (honeypot detection, ownership, taxes)
const security = await getTokenSecurityInfo({
address: "0xSomeToken",
chainId: 8453,
});
console.log(`Is honeypot: ${security.isHoneypot}`);
console.log(`Buy tax: ${security.buyTax}%`);
// Yield opportunities
const yields = await getYieldOpportunities({
chainId: 8453,
minApy: 5,
limit: 20,
});
yields.forEach(y => console.log(`${y.protocol} ${y.pool}: ${y.apy}% APY`));
Error Handling
All SDK functions throw Web3AgentError on failure. Always catch unknown and check the type.
import { getSwapQuote, Web3AgentError } from "web3agent";
try {
const quote = await getSwapQuote({
fromToken: "0x...",
toToken: "0x...",
fromAmount: "1", // too small
chainId: 8453,
});
} catch (e: unknown) {
if (e instanceof Web3AgentError) {
console.error(`Error [${e.code}]: ${e.message}`);
// Common codes:
// "INSUFFICIENT_LIQUIDITY" — no route found
// "LOW_DOLLAR_VALUE" — amount below minimum (~$6-10 for swaps)
// "CHAIN_NOT_SUPPORTED" — chainId not in registry
// "TOKEN_NOT_FOUND" — symbol or address not resolvable
} else {
// Re-throw unexpected errors
throw e;
}
}
Web3AgentError has:
code: string— machine-readable error codemessage: string— human-readable descriptioncause?: unknown— original error if wrapping another
Default Runtime and Cleanup
SDK functions share a lazily-created default runtime. It starts on the first call and stays alive. In long-running processes this is fine. In short-lived scripts, shut it down explicitly to avoid hanging.
import { getSwapQuote, shutdownDefaultRuntime } from "web3agent";
async function main() {
try {
const quote = await getSwapQuote({ ... });
console.log(quote);
} finally {
await shutdownDefaultRuntime();
}
}
main();
Without shutdownDefaultRuntime(), the process may not exit cleanly because the runtime holds open connections.
TypeScript Types
All input and output types are exported from the root package:
import type {
Chain,
Token,
SwapQuote,
SwapResult,
ExplorerTransaction,
TokenPrice,
Web3AgentError,
RuntimeBoundOptions,
} from "web3agent";
RuntimeBoundOptions is an optional last argument accepted by most SDK functions. Pass it to override the default runtime for a specific call:
import { createRuntime } from "web3agent/runtime";
import { getSwapQuote } from "web3agent";
const customRuntime = await createRuntime({ env: { CHAIN_ID: "42161" } });
const quote = await getSwapQuote(
{ fromToken: "...", toToken: "...", fromAmount: "...", chainId: 42161 },
{ runtime: customRuntime },
);
This is useful when different parts of your app need different chain contexts or private keys. See the Runtime Usage guide for the full runtime API.