Blockchain RPC error handling, gas estimation, multi-chain config, and transaction management. Use when interacting with smart contracts, estimating gas, or managing transactions. Triggers on: RPC, contract call, gas, multicall, nonce, transaction, revert.
Common pitfalls and correct patterns for blockchain interactions.
Check all contract calls are wrapped in try/catch.
Ensure gas is estimated with buffer before sending.
Confirm multicall uses allowFailure: true.
// ✅ Wrap ALL contract calls
async function getQuote(tokenIn: Address, tokenOut: Address) {
try {
const quote = await quoter.quoteExactInput(...);
return quote;
} catch (error) {
// Low-liquidity tokens WILL fail - this is expected
console.warn(`Quote failed for ${tokenIn}->${tokenOut}:`, error.message);
return null; // Continue processing other tokens
}
}
// ✅ Validate before calling contracts
if (!isAddress(tokenAddress)) {
throw new Error('Invalid token address');
}
// ✅ Handle "execution reverted" gracefully
if (error.message.includes('execution reverted')) {
// Pool doesn't exist or insufficient liquidity
return null;
}
// ✅ Multicall with individual error handling
const results = await multicall({
contracts: tokens.map(t => ({ ... })),
allowFailure: true, // CRITICAL
});
results.forEach((result, i) => {
if (result.status === 'success') {
// Use result.result
} else {
// Log and skip this token
}
});
// ✅ Always estimate gas before sending
const gasEstimate = await contract.estimateGas.swap(...args);
// ✅ Add 10-20% buffer to gas estimates
const gasLimit = gasEstimate.mul(120).div(100); // 20% buffer
// ✅ EIP-1559 gas pricing
const feeData = await provider.getFeeData();
const tx = {
maxFeePerGas: feeData.maxFeePerGas,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
gasLimit,
};
// ✅ Simulate before execution
try {
await contract.callStatic.swap(...args); // Dry run
const tx = await contract.swap(...args); // Real execution
} catch (e) {
// Would revert - don't send
}
// ✅ Handle gas price spikes
if (feeData.maxFeePerGas > MAX_ACCEPTABLE_GAS) {
throw new Error('Gas too high, waiting...');
}
// ✅ Chain-specific configuration
const CHAIN_CONFIG: Record<ChainId, ChainConfig> = {
ethereum: {
chainId: 1,
rpcUrl: process.env.ETHEREUM_RPC_URL,
blockTime: 12,
confirmations: 2,
nativeToken: 'ETH',
},
polygon: {
chainId: 137,
rpcUrl: process.env.POLYGON_RPC_URL,
blockTime: 2,
confirmations: 5, // More confirmations for faster chains
nativeToken: 'MATIC',
},
};
// ✅ Wait for confirmations
const receipt = await tx.wait(2); // 2 confirmations
// ✅ Nonce management
class NonceManager {
private pending = new Map<Address, number>();
async getNextNonce(address: Address, provider: Provider): Promise<number> {
const onChain = await provider.getTransactionCount(address, 'pending');
const local = this.pending.get(address) ?? onChain;
const next = Math.max(onChain, local);
this.pending.set(address, next + 1);
return next;
}
}
// ✅ Exponential backoff
async function fetchWithRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
if (error.status === 429) { // Rate limited
const delay = Math.pow(2, attempt) * 1000;
await sleep(delay);
continue;
}
throw error;
}
}
throw new Error('Max retries exceeded');
}
// ✅ Fallback RPC endpoints
const RPC_ENDPOINTS = [
'https://eth-mainnet.alchemyapi.io/v2/KEY',
'https://mainnet.infura.io/v3/KEY',
'https://rpc.ankr.com/eth',
];
allowFailure: truenpx skills add aiskillstore/pitfalls-blockchain下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer