guide · smart wallets

Privy + ZeroDev smart wallets on Robinhood Chain

Robinhood Chain Testnet (chainId 46630) isn't in Privy's preset chain list yet, so you register it as a custom chain in the Privy dashboard and point the ZeroDev Kernel bundler + paymaster at it. Once wired, every logged-in user gets an ERC-4337 smart wallet with sponsored gas — no MetaMask, no faucet, no signature popup for gas fees.

Live in this app

The Choreo Ledger demo is wired to this exact setup. Sign in with Google → Privy provisions a Kernel smart wallet → ZeroDev sponsors the tx.

What you'll set up

  • · A ZeroDev project scoped to Robinhood Testnet with "Sponsor all transactions" enabled.
  • · A Privy app with the Kernel (ZeroDev) smart-wallet provider active.
  • · Robinhood Testnet registered as a Privy custom chain (id 46630), with your Alchemy RPC + the ZeroDev bundler and paymaster URLs.

1 · ZeroDev dashboard

  1. Open dashboard.zerodev.app and Create Project.
  2. Enable Show Testnets and tick Robinhood Testnet (46630). Save.
  3. Open the project → Gas Policies → select chain Robinhood Testnet → toggle Sponsor all transactions → confirm Enable.
  4. Copy the Bundler URL and Paymaster URL from the project's RPC tab — you'll paste them into Privy.

2 · Privy dashboard — enable smart wallets

  1. Open dashboard.privy.io → your app → Wallet infrastructure → Smart wallets.
  2. Click Enable smart wallets for your app and pick Kernel (ZeroDev) as the provider.

3 · Configure chains → Add new chain → Custom chain

Robinhood Testnet isn't in Privy's preset list, so add it as a Custom chain and fill in exactly:

Name
Robinhood Testnet
ID number (chainId)
46630
RPC URL
Your Alchemy URL (https://robinhood-testnet.g.alchemy.com/v2/<ALCHEMY_KEY>)
Bundler URL
From ZeroDev dashboard → project → RPC tab
Paymaster URL
From ZeroDev dashboard → project → RPC tab
Explorer
https://explorer.testnet.chain.robinhood.com
Currency
ETH (18 decimals)

Save. Privy will show Robinhood Testnet alongside Sepolia / Tempo / Base Sepolia in Configure chains. That entry — not a preset — is what activates Kernel on chainId 46630.

4 · Client wiring

Wrap the app in SmartWalletsProvider so useSmartWallets() is available. Privy reads the provider + custom chain from the dashboard, so no bundler/paymaster URL belongs in code.

src/components/privy-client-entry.tsx
// src/components/privy-client-entry.tsx
import { PrivyProvider } from "@privy-io/react-auth";
import { SmartWalletsProvider } from "@privy-io/react-auth/smart-wallets";
import { defineChain } from "viem";

export const robinhoodTestnet = defineChain({
  id: 46630,
  name: "Robinhood Testnet",
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
  rpcUrls: {
    default: {
      http: [
        import.meta.env.VITE_ROBINHOOD_TESTNET_RPC_URL ||
          "https://rpc.testnet.chain.robinhood.com",
      ],
    },
  },
  blockExplorers: { default: { name: "Blockscout", url: "https://explorer.testnet.chain.robinhood.com" } },
  testnet: true,
});

<PrivyProvider
  appId={import.meta.env.VITE_PRIVY_APP_ID}
  config={{
    loginMethods: ["google", "email"],
    embeddedWallets: { ethereum: { createOnLogin: "users-without-wallets" } },
    defaultChain: robinhoodTestnet,
    supportedChains: [robinhoodTestnet],
  }}
>
  <SmartWalletsProvider>
    <App />
  </SmartWalletsProvider>
</PrivyProvider>

5 · Send a sponsored transaction

any component
// Sponsored tx via the ZeroDev-backed smart wallet
import { useSmartWallets } from "@privy-io/react-auth/smart-wallets";
import { encodeFunctionData } from "viem";
import abi from "@/data/abi/ChoreoLedger.json";
import contract from "@/data/contract.json";

const { client } = useSmartWallets();

const hash = await client!.sendTransaction({
  to: contract.address as `0x${string}`,
  data: encodeFunctionData({ abi, functionName: "log", args: [cid] }),
});
// Gas is sponsored by ZeroDev paymaster — user pays $0.

The user signs a UserOp with their embedded EOA; ZeroDev's bundler submits it and the paymaster covers gas. Estimated fee in the Privy popup reads US$0.00.

Troubleshooting

  • · "Add funds on Robinhood Chain Testnet to complete transaction" in the Privy popup means the wallet is sending as an EOA, not a smart wallet. Confirm Kernel is the provider and the custom chain is saved with the ZeroDev bundler + paymaster URLs.
  • · Sponsorship policy denied → open ZeroDev → Gas Policies → make sure the toggle Sponsor all transactions is on for chain 46630, or add a chain-level policy that whitelists your contract.
  • · Chain not shown in Privy → the custom chain is saved per-app; switch to the same app whose appId is in VITE_PRIVY_APP_ID.