Agent skill

pitfalls-blockchain

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.

Stars 232
Forks 15

Install this agent skill to your Project

npx add-skill https://github.com/aiskillstore/marketplace/tree/main/skills/barissozen/pitfalls-blockchain

SKILL.md

Blockchain Pitfalls

Common pitfalls and correct patterns for blockchain interactions.

When to Use

  • Making contract calls via RPC
  • Estimating gas for transactions
  • Handling reverts and errors
  • Managing nonces for concurrent txs
  • Configuring multi-chain support
  • Reviewing blockchain code

Workflow

Step 1: Verify Error Handling

Check all contract calls are wrapped in try/catch.

Step 2: Check Gas Estimation

Ensure gas is estimated with buffer before sending.

Step 3: Verify Multicall Safety

Confirm multicall uses allowFailure: true.


RPC Error Handling

typescript
// ✅ 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
  }
});

Gas Estimation

typescript
// ✅ 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...');
}

Multi-Chain Configuration

typescript
// ✅ 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',
  },
};

Transaction Management

typescript
// ✅ 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;
  }
}

Rate Limiting & Retry

typescript
// ✅ 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',
];

Quick Checklist

  • All contract calls wrapped in try/catch
  • Multicall uses allowFailure: true
  • Gas estimation with 20% buffer
  • EIP-1559 gas pricing used
  • Transaction simulation before send
  • Nonce management for concurrent txs
  • Confirmations appropriate per chain

Expand your agent's capabilities with these related and highly-rated skills.

aiskillstore/marketplace

perigon-backend

Perigon ASP.NET Core + EF Core + Aspire conventions

232 15
Explore
aiskillstore/marketplace

perigon-agent

Pointers for Copilot/agents to apply Perigon conventions

232 15
Explore
aiskillstore/marketplace

perigon-angular

Angular 21+ standalone/Material/signal conventions for Perigon WebApp

232 15
Explore
aiskillstore/marketplace

fastapi-mastery

Comprehensive FastAPI development skill covering REST API creation, routing, request/response handling, validation, authentication, database integration, middleware, and deployment. Use when working with FastAPI projects, building APIs, implementing CRUD operations, setting up authentication/authorization, integrating databases (SQL/NoSQL), adding middleware, handling WebSockets, or deploying FastAPI applications. Triggered by requests involving .py files with FastAPI code, API endpoint creation, Pydantic models, or FastAPI-specific features.

232 15
Explore
aiskillstore/marketplace

context7-efficient

Token-efficient library documentation fetcher using Context7 MCP with 86.8% token savings through intelligent shell pipeline filtering. Fetches code examples, API references, and best practices for JavaScript, Python, Go, Rust, and other libraries. Use when users ask about library documentation, need code examples, want API usage patterns, are learning a new framework, need syntax reference, or troubleshooting with library-specific information. Triggers include questions like "Show me React hooks", "How do I use Prisma", "What's the Next.js routing syntax", or any request for library/framework documentation.

232 15
Explore
aiskillstore/marketplace

browser-use

Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use when tasks require web browsing, form submission, web scraping, UI testing, or any browser interaction.

232 15
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results