Skip to main content

Recommended: JavaScript SDK for React Native

While this SDK is still supported, we recommend using newer JavaScript SDK, which is optimized for React Native, but also comes with a host of other benefits.
When using account abstraction in your project to sponsor gas, batch transactions, or any other account abstraction features, you will likely want to get a ZeroDev kernel client to perform these operations. You can use the @dynamic-labs/zerodev-extension package to create a ZeroDev kernel client for a wallet. Here is how you can set up and create a kernel client.
The @dynamic-labs/zerodev-extension depends on the Viem Extension, so before going through this setup, make sure to have the Viem Extension set up and working. Viem Extension Setup

Setup

Install ZeroDevExtension

Install the @dynamic-labs/zerodev-extension package:
Shell

Resolve File Resolution Error (Optional)

When running the ZeroDevExtension in your React Native application, you might encounter an error where Metro cannot resolve the paymasterClient.js file. This issue occurs because Metro tries to load paymasterClient.js, but the actual file is named paymasterClient.ts. To fix this, you need to customize Metro’s resolver in your metro.config.js file to handle TypeScript file extensions properly.

Generate metro.config.js for Expo Projects

If you don’t have a metro.config.js file in your project, you can generate one using the following command:
Shell

Customize Metro Resolver

Add the following code to your metro.config.js file to instruct Metro to resolve .ts files when it cannot find the corresponding .js files:
metro.config.js
This modification allows Metro to attempt to resolve .ts files when it fails to find .js files, which fixes the resolution error for the paymasterClient file.

Events Polyfill

ZeroDevExtension requires a polyfill for the Node.js events module. You can install the events polyfill using one of the following commands:
Shell

Integrate with your Dynamic client

To include the ZeroDev module in your Dynamic client, you need to extend the client with the ZeroDev extension:
dynamicClient.ts
The fast-text-encoding import is only required when using Expo SDK 53 and below. Expo SDK 54 and above have built-in text encoding support.
Now your setup is complete, and you have the ZeroDev module available in your Dynamic client.

Usage

Now that you have the ZeroDev module in your Dynamic client, you can get the ZeroDev kernel client by using the client.zeroDev.createKernelClient method. Here is an example:
dynamicClient.ts
Then, you can specify the paymaster and bundler URL in your dynamic environment configuration: Dynamic Environment Configuration
You can also use the ZerodevBundlerProvider.Alchemy or ZerodevBundlerProvider.Gelato provider to use the Alchemy or Gelato bundler services.You can either use PaymasterTypeEnum.SPONSOR to sponsor all transactions or PaymasterTypeEnum.NONE to send a non-sponsored transaction.
Two React Native-specific gotchas compared to the Web/React SDK:
  • Use paymaster, not withSponsorship. Pass paymaster: PaymasterTypeEnum.SPONSOR when creating the kernel client. The withSponsorship: true option used by the Web/React SDK does not apply here — sponsorship is configured at kernel-client creation time, not per user operation.
  • Set bundlerProvider explicitly. React Native does not automatically pick up the bundler/paymaster provider from your Dynamic dashboard configuration the way the Web SDK does. Pass bundlerProvider: ZerodevBundlerProvider.Pimlico (or Alchemy / Gelato) to createKernelClient — otherwise the default may not match your dashboard and sponsorship will fail.

Examples

Sponsored transactions allow users to interact with your dApp without paying gas fees. The gas costs are covered by your application through a paymaster service.

Simple Sponsored Transaction with sendTransaction

The kernel client exposes a viem-style sendTransaction method that accepts a calls array. Because paymaster: PaymasterTypeEnum.SPONSOR was set when creating the client, every call sent through it is sponsored — you do not pass any per-transaction sponsorship flag.

Basic Sponsored Transaction

Here’s how to send a sponsored transaction:
You can customize the paymaster and bundler settings for different use cases:

Troubleshooting: AA20 account not deployed

If a sponsored user operation fails with an error like:
the bundler handling the request doesn’t support EIP-7702, which is the default mechanism Dynamic uses to enable smart-account features on existing EOAs. React Native does not automatically select a 7702-compatible bundler based on your Dynamic dashboard configuration, so the fix is to set it explicitly when creating the kernel client:
Pimlico is the recommended default for EIP-7702 sponsorship on React Native.

Conditionally Sponsored Transactions

If your app decides at runtime whether to sponsor a transaction — for example, your backend evaluates each transaction and returns a sponsorship decision — pass that decision as the paymaster value when creating the kernel client. PaymasterTypeEnum.SPONSOR sends the transaction through your paymaster; PaymasterTypeEnum.NONE creates a kernel client without a paymaster, so the user pays the gas.
With PaymasterTypeEnum.NONE, gas is paid in the network’s native token from the smart wallet’s balance. For kernel smart accounts this is the smart wallet’s contract address (a different address from the signing wallet); for EIP-7702 wallets the smart wallet is the user’s own wallet address. Either way, that address must hold enough native token to cover the transaction.

Batch Transactions

Batch transactions allow you to execute multiple operations in a single transaction, reducing gas costs and improving user experience.

Batch Transaction Example

This example demonstrates how you can use a ZeroDev kernel client to perform a batched transaction:
Last modified on July 24, 2026