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
// 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' },
},
});// 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
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
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
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
// 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
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
| Setting | Recommendation | Why |
|---|---|---|
| Client retry count | 0–1 | Prism already retries reads across providers |
| Request timeout | 10–15s | Long enough to survive a failover, short enough to fail fast |
| Batching | On | Fewer round trips, more deduplication |
| Polling interval | 2s or slower | Robinhood Chain block times make faster polling wasted quota |
| Network detection | Static | Saves 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.
