prismRPCDocs

viem, ethers & wagmi

Prism is a URL. Every EVM client accepts one, so integration is configuration rather than code.

Define the chain once and import it everywhere.

viem

ts
// lib/chain.ts
import { defineChain } from 'viem';

export const robinhoodChain = defineChain({
  id: 42088,
  name: 'Robinhood Chain',
  nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
  rpcUrls: {
    default: {
      http: ['https://mainnet.prismrpc.co/v1/YOUR_API_KEY'],
      webSocket: ['wss://mainnet.prismrpc.co/v1/YOUR_API_KEY'],
    },
  },
  blockExplorers: {
    default: { name: 'Explorer', url: 'https://explorer.robinhoodchain.com' },
  },
});
ts
// lib/client.ts
import { createPublicClient, http } from 'viem';
import { robinhoodChain } from './chain';

export const publicClient = createPublicClient({
  chain: robinhoodChain,
  transport: http(undefined, {
    // Prism already retries reads across providers. Keep the client's own
    // retry count low so a failure surfaces instead of being multiplied.
    retryCount: 1,
    batch: true,
  }),
});

batch: true collects calls made in the same tick into one JSON-RPC batch. Combined with Prism's deduplication this cuts request volume sharply on component-heavy pages.

Wallet client

ts
import { createWalletClient, custom } from 'viem';
import { robinhoodChain } from './chain';

export const walletClient = createWalletClient({
  chain: robinhoodChain,
  transport: custom(window.ethereum),
});

Signing stays in the wallet. Only the signed transaction reaches Prism.

ethers v6

ts
import { JsonRpcProvider, Network } from 'ethers';

const network = Network.from({ chainId: 42088, name: 'robinhood-chain' });

export const provider = new JsonRpcProvider(
  'https://mainnet.prismrpc.co/v1/YOUR_API_KEY',
  network,
  {
    // The network is known and static, so skip the detection round trip.
    staticNetwork: network,
    batchMaxCount: 20,
  }
);

Set staticNetwork - without it ethers issues an eth_chainId probe before your first real call.

WebSocket provider

ts
import { WebSocketProvider } from 'ethers';

const wsProvider = new WebSocketProvider('wss://mainnet.prismrpc.co/v1/YOUR_API_KEY', network);

wsProvider.on('block', (blockNumber) => {
  console.log('new block', blockNumber);
});

wagmi

ts
// wagmi.config.ts
import { createConfig, http } from 'wagmi';
import { robinhoodChain } from './lib/chain';

export const config = createConfig({
  chains: [robinhoodChain],
  transports: {
    [robinhoodChain.id]: http('https://mainnet.prismrpc.co/v1/YOUR_PUBLIC_KEY', {
      batch: true,
    }),
  },
});

Use an origin-locked, read-scoped key here - a wagmi transport URL ships in your client bundle.

web3.js

ts
import { Web3 } from 'web3';

const web3 = new Web3('https://mainnet.prismrpc.co/v1/YOUR_API_KEY');
const block = await web3.eth.getBlockNumber();

Foundry & Hardhat

Both are covered in networks & chain IDs.

Recommended settings

SettingRecommendationWhy
Client retry count0–1Prism already retries reads across providers
Request timeout10–15sLong enough to survive a failover, short enough to fail fast
BatchingOnFewer round trips, more deduplication
Polling interval2s or slowerRobinhood Chain block times make faster polling wasted quota
Network detectionStaticSaves a probe request per client

What not to do

Do not wrap Prism in your own provider-fallback list. Two balancers stacked on each other multiply requests during an incident - exactly when upstream capacity is scarcest.

Do not retry aggressively on 429. Back off. The header tells you when to come back; see rate limits.

Do not create poll filters in long-lived services. eth_newFilter pins you to one upstream and forfeits failover. Use WebSockets or bounded eth_getLogs scans.