> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rhinestone.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# ERC-4337

> Configure bundlers and paymasters for Rhinestone user operation flows.

Rhinestone intents use the prepare, sign, and submit transaction flow. Use ERC-4337 UserOperations for account workflows that explicitly require a bundler, such as deploying or setting up some existing accounts and executing recovery operations.

## Configure a bundler

The SDK can use Pimlico, Biconomy, or a custom bundler URL. If you omit `bundler`, it uses Pimlico's public endpoint, which is suitable for development but not production volume.

<Tabs>
  <Tab title="Pimlico">
    ```ts theme={null}
    const rhinestone = new RhinestoneSDK({
      auth: {
        mode: 'apiKey',
        apiKey: process.env.RHINESTONE_API_KEY!,
      },
      bundler: {
        type: 'pimlico',
        apiKey: process.env.PIMLICO_API_KEY!,
      },
    })
    ```
  </Tab>

  <Tab title="Biconomy">
    ```ts theme={null}
    const rhinestone = new RhinestoneSDK({
      auth: {
        mode: 'apiKey',
        apiKey: process.env.RHINESTONE_API_KEY!,
      },
      bundler: {
        type: 'biconomy',
        apiKey: process.env.BICONOMY_API_KEY!,
      },
    })
    ```
  </Tab>

  <Tab title="Custom">
    Use one URL for every chain, or map chain IDs to different URLs.

    ```ts theme={null}
    const rhinestone = new RhinestoneSDK({
      auth: {
        mode: 'apiKey',
        apiKey: process.env.RHINESTONE_API_KEY!,
      },
      bundler: {
        type: 'custom',
        url: {
          [base.id]: process.env.BASE_BUNDLER_URL!,
          [optimism.id]: process.env.OPTIMISM_BUNDLER_URL!,
        },
      },
    })
    ```
  </Tab>
</Tabs>

These examples are server-side. Do not bundle Rhinestone, bundler, or paymaster secrets into browser code.

## Configure a paymaster

A paymaster is optional. Add it when you want the paymaster to sponsor ERC-4337 UserOperation gas:

```ts theme={null}
const rhinestone = new RhinestoneSDK({
  auth: {
    mode: 'apiKey',
    apiKey: process.env.RHINESTONE_API_KEY!,
  },
  bundler: {
    type: 'pimlico',
    apiKey: process.env.PIMLICO_API_KEY!,
  },
  paymaster: {
    type: 'pimlico',
    apiKey: process.env.PIMLICO_API_KEY!,
  },
})
```

The paymaster and bundler are separate configuration fields even when they use the same provider credential. Custom paymasters accept the same `url: string | Record<number, string>` shape as custom bundlers.

## Send a UserOperation

UserOperations use a separate API from intents:

```ts theme={null}
const prepared = await account.prepareUserOperation({
  chain: base,
  calls,
})
const signed = await account.signUserOperation(prepared)
const result = await account.submitUserOperation(signed)
const receipt = await account.waitForExecution(result)
```

Use `sendUserOperation({ chain, calls })` only when you do not need to inspect or transport the prepared payload between steps.

<Note>
  A paymaster sponsors ERC-4337 gas only. To configure sponsorship for Rhinestone intents, follow [sponsorship setup](/transactions/sponsorship/set-up).
</Note>
