Testing with BuildBear Sandboxes | Pimlico Docs
Skip to content

Testing with BuildBear Sandboxes

This guide introduces how to setup a BuildBear Sandbox with for testing the Alto bundler and a mock paymaster. We will be using viem and permissionless to interact with the sandbox enviornment.

Overview

BuildBear provides on-demand, isolated test environments that clone existing blockchain networks. These environments are perfect for testing account abstraction implementations as they:

  • Provide a persistent, dedicated testnet environment
  • Support EIP-4337 and all necessary AA infrastructure
  • Allow you to fork from existing networks (Ethereum, Arbitrum, Optimism, etc.)
  • Unlocked faucets for testing
  • Offer an explorer interface for easy debugging

Steps

Creating and setting up a BuildBear Sandbox

  1. Go to buildbear.io and sign up for an account if you don't have one already.

  2. Create a new Sandbox by clicking "Create a Sandbox" and selecting the network you want to fork (e.g., Ethereum Mainnet, Sepolia, etc.).

  3. Navigate to the Plugin tab on your sandbox dashboard and install the Pimlico Plugin. Ensure the plugin appears as installed in the marketplace or Installed tab.

  4. Go to your Buildbear sandbox dashboard and locate the RPC URL. Copy the RPC URL, which also serves as the Pimlico Client API endpoint. It should look something like the below.

    • BuildBear Sandbox RPC URL: https://rpc.buildbear.io/<YOUR-SANDBOX-ID>
    • Pimlico Client API: https://rpc.buildbear.io/<YOUR-SANDBOX-ID>
  5. Once your Sandbox is created, you'll get access to:

    • RPC URL
    • Chain ID
    • Explorer URL
    • Faucet to fund your test accounts

Setup the clients

Setup Clients
import { createPimlicoClient } from "permissionless/clients/pimlico";
import { defineChain, createPublicClient, http } from "viem";
import { entryPoint07Address } from "viem/account-abstraction";
 
const buildbearSandboxUrl = "https://rpc.buildbear.io/<YOUR-SANDBOX-ID>";
 
const BBSandboxNetwork = defineChain({
  id: 23177, // IMPORTANT : replace this with your sandbox's chain id
  name: "BuildBear x Base Sandbox", // name your network
  nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, // native currency of forked network
  rpcUrls: {
    default: {
      http: [buildbearSandboxUrl],
    },
  },
  blockExplorers: {
    default: {
      name: "BuildBear x Base Scan", // block explorer for network
      url: "https://explorer.buildbear.io/<YOUR-SANDBOX-ID>",
      apiUrl: "https://api.buildbear.io/<YOUR-SANDBOX-ID>/api",
    },
  },
});
 
// Create a new Public Client with Sandbox URL
export const publicClient = createPublicClient({
  chain: BBSandboxNetwork,
  transport: http(buildbearSandboxUrl), //@>>> Put in BuildBear rpc
});
 
// Create a pimlico client in the context of Sandbox
const pimlicoClient = createPimlicoClient({
  transport: http(buildbearSandboxUrl),
  entryPoint: {
    address: entryPoint07Address,
    version: "0.7",
  },
});

Setup the Smart Account Client

Setup Clients
import { createSmartAccountClient } from "permissionless";
import { privateKeyToAccount } from "viem/accounts";
import { toSafeSmartAccount } from "permissionless/accounts";
 
// Get signer for private key
const signer = privateKeyToAccount(privateKey);
 
// Create a Safe Smart Account from our signer
const account = await toSafeSmartAccount({
  client: publicClient,
  owners: [signer],
  entryPoint: {
    address: entryPoint07Address,
    version: "0.7",
  }, // global entrypoint
  version: "1.4.1",
});
 
// Create a client for smart account
const smartAccountClient = createSmartAccountClient({
  account,
  chain: BBSandboxNetwork,
  paymaster: pimlicoClient, // optional, can be removed if paymaster isn't used
  bundlerTransport: http(buildbearSandboxUrl), //sending the tx to BuildBear Sandbox
  userOperation: {
    estimateFeesPerGas: async () => {
      return (await pimlicoClient.getUserOperationGasPrice()).fast;
    },
  },
});

Funding your smart account (Optional)

If you want to fund your smart account with native currency or ERC-20 tokens, you can use the following curl commands:

Funding native currency:

curl -X POST https://rpc.buildbear.io/<YOUR-SANDBOX-ID>  \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "buildbear_nativeFaucet",
    "params": [{
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "balance": "100"
    }]
  }'

Funding ERC-20 tokens:

curl -X POST https://rpc.buildbear.io/<YOUR-SANDBOX-ID> \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "buildbear_ERC20Faucet",
    "params": [{
      "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
      "balance": "100",
      "token": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
    }]
  }'

Sending a userOperation

Verifying Paymaster
import { parseAbi, parseEther, getAddress } from "viem";
 
let txHash = await smartAccountClient.sendUserOperation({
    account,
    calls: [
      {
        to: getAddress("0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063"), //Payment token for gas
        abi: parseAbi(["function approve(address,uint)"]),
        functionName: "approve",
        args: ["0x0000000000000039cd5e8ae05257ce51c473ddd1", parseEther("1")], // approve spend of 1 DAI to Paymaster's address
      },
      {
        to: "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
        value: parseEther("1"),
      },
    ],
  });
 
let result = await smartAccountClient.waitForUserOperationReceipt({
  hash: txHash,
});
 
console.log(
  `User operation included: https://explorer.buildbear.io/uzair/tx/${result.receipt.transactionHash}`
);

More detailed examples and instructions can be found on BuildBear's docs