> ## 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.

# Biconomy

<Card title="Recommended: JavaScript SDK with React Hooks" icon="react" color="#4779FE">
  For new React apps, we recommend the JavaScript SDK with React Hooks (`@dynamic-labs-sdk/react-hooks`) instead of the legacy React SDK documented here. The JS SDK comes with many benefits such as a much smaller bundle size and other optimizations. Use the [React quickstart (JavaScript SDK)](/javascript/reference/react-quickstart) to get started.
</Card>

<Note>This guide is currently React only.</Note>

This guide will walk you through how to use Biconomy's smart accounts with Dynamic. You can find more info on how Biconomy works here: [https://docs.biconomy.io/account](https://docs.biconomy.io/account). We will use Ethereum Sepolia, so make sure your paymaster etc. is set up for that, and also make sure your user is on this network once logged in.

<Note>
  This guide and example is for V4 of the Biconomy packages and V4 of Dynamic.
</Note>

## Install Dynamic and Biconomy

Install the required packages:

```bash theme={"system"}
yarn add @dynamic-labs/sdk-react-core @dynamic-labs/ethereum @biconomy/account @biconomy/bundler
```

## Initialize & configure Dynamic

### Add the DynamicContextProvider

All you need to get started is the DynamicContextProvider - you will want to wrap your app with this component at the highest possible level, like so:

```jsx theme={"system"}
import { DynamicContextProvider } from '@dynamic-labs/sdk-react-core'
import { EthereumWalletConnectors } from '@dynamic-labs/ethereum'

<DynamicContextProvider
  settings={{
    // Find your environment id at https://app.dynamic.xyz/dashboard/developer/api
    environmentId: 'REPLACE-WITH-YOUR-ENVIRONMENT-ID',
    walletConnectors: [EthereumWalletConnectors]
  }}
>
  {/* Your app's components */}
</DynamicContextProvider>
```

<Tip>
  To enable embedded wallets for your users, [toggle it
  on](https://app.dynamic.xyz/dashboard/embedded-wallets/dynamic) along with
  [email/social auth](https://app.dynamic.xyz/dashboard/log-in-user-profile) in
  the dashboard.
</Tip>

## Configure your Biconomy bundler and paymaster

Go to the Biconomy Dashboard and configure a Paymaster and a Bundler for your app. Make sure these correspond to the desired network for your user's smart accounts.

Make sure to set the paymaster URL as the value for REACT\_APP\_BICONOMY\_PAYMASTER\_URL in your env file, and do the same with your bundler URL for REACT\_APP\_BICONOMY\_BUNDLER\_URL.

### Create our Biconomy constants

Let's introduce a new `biconomy.js` file to house our Biconomy methods. Here we'll initialize the paymaster, the bundler, the validation module, and the method to create a smart account using createSmartAccountClient.

The validation module allows the user to authorize actions from their Biconomy smart account by signing messages with their Dynamic wallet.

```js biconomy.js theme={"system"}
import { Bundler } from "@biconomy/bundler";
import { Paymaster, createSmartAccountClient, DEFAULT_ENTRYPOINT_ADDRESS, ECDSAOwnershipValidationModule, DEFAULT_ECDSA_OWNERSHIP_MODULE } from "@biconomy/account";
import { sepolia } from "viem/chains";

const bundler = new Bundler({
  bundlerUrl: process.env.REACT_APP_BICONOMY_BUNDLER_URL,
  chainId: sepolia.id, // Replace this with your desired network
  entryPointAddress: DEFAULT_ENTRYPOINT_ADDRESS, // This is a Biconomy constant
});

const paymaster = new Paymaster({
  paymasterUrl: process.env.REACT_APP_BICONOMY_PAYMASTER_URL,
});

const createValidationModule = async (signer) => {
  return await ECDSAOwnershipValidationModule.create({
    signer: signer,
    moduleAddress: DEFAULT_ECDSA_OWNERSHIP_MODULE, // This is a Biconomy constant
  });
};

export const createSmartAccount = async (walletClient) => {
  const validationModule = await createValidationModule(walletClient);
  console.log('creating')

  return await createSmartAccountClient({
    signer: walletClient,
    chainId: sepolia.id, // Replace this with your target network
    bundler: bundler, // Use the `bundler` we initialized above
    paymaster: paymaster, // Use the `paymaster` we initialized above
    entryPointAddress: DEFAULT_ENTRYPOINT_ADDRESS, // This is a Biconomy constant
    defaultValidationModule: validationModule, // Use the `validationModule` we initialized above
    activeValidationModule: validationModule, // Use the `validationModule` we initialized above
  });
};
```

### Create our custom hook

We'll create a custom hook to fetch the wallet client from Dynamic, and then initialize the Biconomy smart account using the methods we created above.

```jsx useBiconomyAccount.js theme={"system"}
import { useState, useEffect, useCallback } from 'react';
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import { createSmartAccount } from "./biconomy.js";

export function useBiconomyAccount() {
  const { primaryWallet } = useDynamicContext();
  const [smartAccount, setSmartAccount] = useState(null);

  const createAndSetSmartAccount = useCallback(async () => {
    if (!primaryWallet) {
      setSmartAccount(null);
      return;
    }

    if(!primaryWallet.connector.isEmbeddedWallet) {
      alert('No embedded wallet selected');
      return;
    }

    try {
      const walletClient = await primaryWallet.getWalletClient();
      if (walletClient && !smartAccount) {
        const newSmartAccount = await createSmartAccount(walletClient);
        setSmartAccount(newSmartAccount);
      }
    } catch (error) {
      console.error('Error fetching wallet clients or creating smart account:', error);
    }
  }, [primaryWallet, smartAccount]);

  useEffect(() => {
    createAndSetSmartAccount();
  }, [createAndSetSmartAccount]);

  return { smartAccount };
}
```

## Create Main component

Since we're calling dynamic hooks, we need to do this inside the component tree, above where the DynamicContextProvider wrapper lives. For our purposes, let's create a Main.js component, and this is also where we can place or signup and login UI (DynamicWidget):

```jsx Main.js theme={"system"}

import { useEffect } from "react";
import { useBiconomyAccount } from "./useBiconomyAccount.js";

const Main = () => {
  const { smartAccount } = useBiconomyAccount();

  useEffect(() => {
    console.log('My Biconomy smart account', smartAccount)
  }, [smartAccount])

  return <></>;
};

export default Main;
```

As you can see, we're looking the now initialized smart account in Main, and you can then do whatever you want with it!

## End to end flow
