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

# canSponsorUserOperation

# canSponsorUserOperation

Checks if a user operation can be sponsored by the configured paymaster. Works for both single transactions and batch transactions. This is useful to determine if the user will need to pay gas fees or if the operation qualifies for gas sponsorship.

## Usage

```javascript theme={"system"}
import { canSponsorUserOperation } from "@dynamic-labs-sdk/zerodev";
import { isEvmWalletAccount } from "@dynamic-labs-sdk/evm";
import { getPrimaryWalletAccount } from "@dynamic-labs-sdk/client";
import { parseEther } from "viem";

const walletAccount = getPrimaryWalletAccount();

if (walletAccount && isEvmWalletAccount(walletAccount)) {
  const canSponsor = await canSponsorUserOperation({
    walletAccount,
    calls: [
      {
        to: recipientAddress,
        value: parseEther("0.01"),
        data: "0x",
      },
    ],
  });

  if (canSponsor) {
    console.log("Operation will be sponsored - no gas fees required!");
  } else {
    console.log("Operation cannot be sponsored - user pays gas fees");
  }
}
```

## Parameters

You must provide either a `walletAccount` or a `kernelClient`, but not both.

| Parameter       | Type                          | Description                                                           |
| --------------- | ----------------------------- | --------------------------------------------------------------------- |
| `calls`         | `BatchCall[]`                 | Array of calls to execute (single or multiple)                        |
| `calls[].to`    | `Hex`                         | The recipient address for this call                                   |
| `calls[].value` | `bigint`                      | The value to send in wei for this call                                |
| `calls[].data`  | `Hex` (optional)              | The transaction data for this call                                    |
| `walletAccount` | `EvmWalletAccount` (optional) | The wallet account. Required if no `kernelClient` is provided         |
| `kernelClient`  | `KernelClient` (optional)     | An existing kernel client. Required if no `walletAccount` is provided |

## Returns

`Promise<boolean>` - Returns `true` if the user operation can be sponsored, `false` otherwise.

## Examples

### Single transaction with wallet account

```javascript theme={"system"}
const canSponsor = await canSponsorUserOperation({
  walletAccount,
  calls: [
    {
      to: "0x...",
      value: parseEther("0.1"),
    },
  ],
});
```

### Batch transaction

```javascript theme={"system"}
const canSponsor = await canSponsorUserOperation({
  walletAccount,
  calls: [
    { to: "0xRecipient1...", value: parseEther("0.1") },
    { to: "0xRecipient2...", value: parseEther("0.2") },
    { to: "0xRecipient3...", value: parseEther("0.3") },
  ],
});
```

### Using existing kernel client

```javascript theme={"system"}
const kernelClient = await createKernelClientForWalletAccount({
  smartWalletAccount: walletAccount,
});

const canSponsor = await canSponsorUserOperation({
  kernelClient,
  calls: [
    {
      to: "0x...",
      value: parseEther("0.1"),
    },
  ],
});
```

## Error handling

```javascript theme={"system"}
import { isGasSponsorshipError } from '@dynamic-labs-sdk/zerodev';

try {
  const canSponsor = await canSponsorUserOperation({ walletAccount, calls });
  console.log('Can sponsor:', canSponsor);
} catch (error) {
  if (isGasSponsorshipError(error)) {
    console.log('Sponsorship check failed - user will need to pay gas');
  }
}
```

## React

Use `canSponsorUserOperation` inside a button handler to conditionally show a "gasless" badge or adjust UI before sending:

```tsx theme={"system"}
import { canSponsorUserOperation, sendUserOperation } from '@dynamic-labs-sdk/zerodev';
import { isEvmWalletAccount } from '@dynamic-labs-sdk/evm';
import { useGetWalletAccounts } from '@dynamic-labs-sdk/react-hooks';
import { useState } from 'react';
import { parseEther } from 'viem';

function SponsoredSendButton({ recipientAddress }) {
  const { data: walletAccounts = [] } = useGetWalletAccounts();
  const walletAccount = walletAccounts.find(isEvmWalletAccount);
  const [sponsored, setSponsored] = useState(null);

  const calls = [{ to: recipientAddress, value: parseEther('0.01'), data: '0x' as const }];

  const handleSend = async () => {
    if (!walletAccount) return;
    const canSponsor = await canSponsorUserOperation({ walletAccount, calls });
    setSponsored(canSponsor);
    await sendUserOperation({ walletAccount, calls, withSponsorship: canSponsor });
  };

  return (
    <div>
      <button onClick={handleSend} disabled={!walletAccount}>
        Send {sponsored === true ? '(Gasless)' : ''}
      </button>
    </div>
  );
}
```

## Related functions

* [sendUserOperation](/javascript/reference/zerodev/send-user-operation) - Send a user operation (single or batch)
* [estimateUserOperationGas](/javascript/reference/zerodev/estimate-user-operation-gas) - Estimate gas for a user operation
* [createKernelClientForWalletAccount](/javascript/reference/zerodev/create-kernel-client-for-wallet-account) - Create a ZeroDev Kernel client
* [isGasSponsorshipError](/javascript/reference/zerodev/is-gas-sponsorship-error) - Check if an error is a gas sponsorship error
* [Migration guide (v0.9)](/javascript/reference/zerodev/migration-v0.9) - Upgrading from the previous transaction API
