技能 编程开发 QuickNode Web3开发最佳实践

QuickNode Web3开发最佳实践

v20260423
quicknode-sdk-patterns
本指南提供了生产级别的最佳实践模式,用于开发健壮的去中心化应用(dApps)。内容涵盖了提供者单例模式、基于指数退避的重试逻辑(处理RPC暂时性故障)、多链连接管理、批量RPC调用以提高效率,以及使用ethers.js进行合约缓存。适用于需要构建高可靠性、可扩展的Web3基础设施的开发者。
获取技能
309 次下载
概览

QuickNode SDK Patterns

Overview

Production-ready patterns for blockchain development with QuickNode: provider singletons, retry logic, batch RPC calls, and multi-chain support.

Prerequisites

  • Completed quicknode-install-auth
  • ethers.js or @quicknode/sdk installed

Instructions

Step 1: Provider Singleton

import { ethers } from 'ethers';

let _provider: ethers.JsonRpcProvider | null = null;

export function getProvider(): ethers.JsonRpcProvider {
  if (!_provider) {
    _provider = new ethers.JsonRpcProvider(process.env.QUICKNODE_ENDPOINT, undefined, {
      staticNetwork: true,  // Skip chainId lookup on every call
      batchMaxCount: 10,    // Enable batch RPC
    });
  }
  return _provider;
}

Step 2: Retry Wrapper with Backoff

async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err: any) {
      const isRetryable = err.code === 'SERVER_ERROR' || err.code === 'TIMEOUT' || err.status === 429;
      if (!isRetryable || attempt === maxRetries) throw err;
      const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
      await new Promise(r => setTimeout(r, delay));
    }
  }
  throw new Error('Unreachable');
}

// Usage
const balance = await withRetry(() => getProvider().getBalance(address));

Step 3: Multi-Chain Client Factory

const ENDPOINTS: Record<string, string> = {
  ethereum: process.env.QUICKNODE_ETH_ENDPOINT!,
  polygon: process.env.QUICKNODE_POLYGON_ENDPOINT!,
  arbitrum: process.env.QUICKNODE_ARB_ENDPOINT!,
};

const providers = new Map<string, ethers.JsonRpcProvider>();

export function getChainProvider(chain: string): ethers.JsonRpcProvider {
  if (!providers.has(chain)) {
    const url = ENDPOINTS[chain];
    if (!url) throw new Error(`No endpoint for chain: ${chain}`);
    providers.set(chain, new ethers.JsonRpcProvider(url, undefined, { staticNetwork: true }));
  }
  return providers.get(chain)!;
}

Step 4: Batch RPC Calls

async function batchGetBalances(addresses: string[]): Promise<Map<string, bigint>> {
  const provider = getProvider();
  const results = new Map<string, bigint>();

  // ethers.js batches these automatically when batchMaxCount > 1
  const promises = addresses.map(async (addr) => {
    const balance = await provider.getBalance(addr);
    results.set(addr, balance);
  });

  await Promise.all(promises);
  return results;
}

Step 5: Contract Wrapper with Caching

import { LRUCache } from 'lru-cache';

const contractCache = new LRUCache<string, any>({ max: 100, ttl: 60000 });

async function cachedContractCall(contract: ethers.Contract, method: string, ...args: any[]) {
  const key = `${contract.target}:${method}:${JSON.stringify(args)}`;
  const cached = contractCache.get(key);
  if (cached) return cached;

  const result = await contract[method](...args);
  contractCache.set(key, result);
  return result;
}

Output

  • Thread-safe provider singleton with batch support
  • Retry logic for transient RPC failures
  • Multi-chain client factory
  • Cached contract calls reducing RPC usage

Error Handling

Pattern Use Case Benefit
Singleton All RPC calls One connection, reused
Retry wrapper Transient failures Automatic recovery
Multi-chain factory Cross-chain dApps Clean chain switching
Contract cache Repeated reads Fewer RPC calls

Resources

Next Steps

Build transaction workflows: quicknode-core-workflow-a

信息
Category 编程开发
Name quicknode-sdk-patterns
版本 v20260423
大小 4.21KB
更新时间 2026-04-28
语言