# Smart accounts

> @web3auth/react-native-sdk Native Smart accounts | Embedded Wallets

Effortlessly create and manage smart accounts for your users with just a few lines of code, using our Smart Account feature. Smart accounts offer enhanced control and programmability, enabling powerful features that traditional wallets can't provide.

**Key features of smart accounts include:**

- **Gas abstraction:** Cover transaction fees for users, or allow users to pay for their own transactions using ERC-20 tokens.
- **Batch transactions:** Perform multiple transactions in a single call.
- **Automated transactions:** Allow users to automate actions, like swapping ETH to USDT when ETH hits a specific price.
- **Custom spending limits:** Allow users to set tailored spending limits.

:::tip

For more about ERC-4337 and its components, [check out our detailed blog post](https://blog.web3auth.io/an-ultimate-guide-to-web3-wallets-externally-owned-account-and-smart-contract-wallet/#introduction-to-eip-4337).

:::

Our smart account integration streamlines your setup, allowing you to create and manage smart accounts using your favorite libraries like Viem, Ethers, and Wagmi. You don't need to rely on third-party packages to effortlessly create ERC-4337 compatible Smart Contract Wallets (SCWs), giving users the ability to perform batch transactions and efficiently manage gas sponsorship.

:::note

This is a paid feature and the minimum [pricing plan](https://web3auth.io/pricing.html) to use this
SDK in a production environment is the **Growth Plan**. You can use this feature in Web3Auth
Sapphire Devnet network for free.

:::

## Enabling smart accounts

:::info prerequisite

To enable this feature, you need to configure smart accounts from your project in the [Embedded Wallets dashboard](https://developer.metamask.io/).

:::

### Dashboard configuration

To enable smart accounts, navigate to the smart accounts section in the MetaMask Developer Dashboard, and enable the "Set up Smart accounts" toggle. Web3Auth currently supports [MetaMaskSmartAccount](https://docs.gator.metamask.io/how-to/create-delegator-account#create-a-metamasksmartaccount) as a Smart Account provider.

## Installation

To use native account abstraction, you'll need to install the
[@web3auth/account-abstraction-provider](https://www.npmjs.com/package/@web3auth/account-abstraction-provider),
which allows you to create and interact with Smart Contract Wallets (SCWs). This provider simplifies
the entire process by managing the complex logic behind configuring the account abstraction
provider, bundler, and preparing user operations.

```bash npm2yarn
npm install --save @web3auth/account-abstraction-provider
```

## Configure

When instantiating the Account Abstraction provider, you can pass configuration objects to the
constructor. These configuration options allow you to select the desired Account Abstraction (AA)
provider, as well as configure the bundler and paymaster, giving you flexibility and control over
the provider.

```tsx
// focus-start

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'
// focus-end

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

// focus-start
const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    smartAccountInit: new SafeSmartAccount(),
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
  },
})
// focus-end
```

Please note this is the important step for setting the Web3Auth account abstraction provider.

- [Configure Smart Account provider](#configure-smart-account-provider)
- [Configure Bundler](#configure-bundler)
- [Configure Sponsored Paymaster](#sponsored-paymaster)
- [Configure ERC-20 Paymaster](#erc-20-paymaster)

## Configure smart account provider

Web3Auth offers the flexibility to choose your preferred Account Abstraction (AA) provider.
Currently, we support Safe, Kernel, Biconomy, and Trust.

<Tabs
defaultValue="safe"
values={[
  { label: "Safe", value: "safe" },
  { label: "Kernel", value: "kernel" },
  { label: "Biconomy", value: "biconomy" },
  { label: "Trust", value: "trust" },
]}
>

<TabItem value="safe">

```ts
// focus-start

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'
// focus-end

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    // focus-next-line
    smartAccountInit: new SafeSmartAccount(),
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
  },
})
```

</TabItem>

<TabItem value="kernel">

```ts
// focus-start

  AccountAbstractionProvider,
  KernelSmartAccount,
} from '@web3auth/account-abstraction-provider'
// focus-end
const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    // focus-next-line
    smartAccountInit: new KernelSmartAccount(),
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
  },
})
```

</TabItem>

<TabItem value="biconomy">

```ts
// focus-start

  AccountAbstractionProvider,
  BiconomySmartAccount,
} from '@web3auth/account-abstraction-provider'
// focus-end

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    // focus-next-line
    smartAccountInit: new BiconomySmartAccount(),
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
  },
})
```

</TabItem>

<TabItem value="trust">

```ts
// focus-start

  AccountAbstractionProvider,
  TrustSmartAccount,
} from '@web3auth/account-abstraction-provider'
// focus-end
const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    // focus-next-line
    smartAccountInit: new TrustSmartAccount(),
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
  },
})
```

</TabItem>
</Tabs>

## Configure bundler

Web3Auth enables you to configure your bundler and define the paymaster context. The bundler
aggregates the UserOperations and submits them onchain via a global entry point contract.

Bundler support is not limited to the examples below; you can use any bundler of your choice.

<Tabs
defaultValue="pimlico"
values={[
  { label: "Pimlico", value: "pimlico" },
  { label: "ZeroDev", value: "zerodev" },
]}
>

<TabItem value="pimlico">

```ts

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    smartAccountInit: new SafeSmartAccount(),
    // focus-start
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
    },
    // focus-end
  },
})
```

</TabItem>

<TabItem value="zerodev">

```ts

  AccountAbstractionProvider,
  KernelSmartAccount,
} from '@web3auth/account-abstraction-provider'

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    smartAccountInit: new KernelSmartAccount(),
    // focus-start
    bundlerConfig: {
      // Get the ZeroDev API from https://dashboard.zerodev.app/
      url: `https://rpc.zerodev.app/api/v2/bundler/${projectId}`,
    },
    // focus-end
  },
})
```

</TabItem>
</Tabs>

## Configure paymaster

You can configure the paymaster of your choice to sponsor gas fees for your users, along with the paymaster context. The paymaster context lets you set additional parameters, such as choosing the token for ERC-20 paymasters, defining gas policies, and more.

### Sponsored paymaster

<Tabs
defaultValue="pimlico"
values={[
  { label: "Pimlico", value: "pimlico" },
  { label: "ZeroDev", value: "zerodev" },
]}
>

<TabItem value="pimlico">

```ts

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    smartAccountInit: new SafeSmartAccount(),
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
    },
    // focus-start
    paymasterConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
    },
    // focus-end
  },
})
```

</TabItem>

<TabItem value="zerodev">

```ts

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    smartAccountInit: new SafeSmartAccount(),
    bundlerConfig: {
      // Get the ZeroDev API from https://dashboard.zerodev.app/
      url: `https://rpc.zerodev.app/api/v2/bundler/${projectId}`,
    },
    // focus-start
    paymasterConfig: {
      // Get the ZeroDev API from https://dashboard.zerodev.app/
      url: `https://rpc.zerodev.app/api/v2/paymaster/${projectId}`,
    },
    // focus-end
  },
})
```

</TabItem>
</Tabs>

### ERC-20 paymaster

When using an ERC-20 paymaster, ensure you include the approval transaction, as Web3Auth does not
handle the approval internally.

For Pimlico, you can specify the token you want to use in the paymasterContext. If you want to set
up sponsorship policies, you can define those in the paymasterContext as well.
[Checkout the supported tokens for ERC-20 paymaster on Pimlico](https://docs.pimlico.io/infra/paymaster/erc20-paymaster/supported-tokens).

```ts

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
      // focus-start
      paymasterContext: {
        token: 'SUPPORTED_TOKEN_CONTRACT_ADDRESS',
      },
      // focus-end
    },
    smartAccountInit: new SafeSmartAccount(),
    // focus-start
    paymasterConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoAPIKey}`,
    },
    // focus-end
  },
})
```

## Set up

### Configure Web3Auth instance

<Tabs
  values={[
    { label: "React Native Bare App", value: "rn-bare" },
    { label: "React Native Expo App", value: "rn-expo" },
  ]}
>
<TabItem value="rn-bare" default>

```ts

// focus-start

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'
//focus-end

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

// focus-start
const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
    smartAccountInit: new SafeSmartAccount(),
  },
})
// focus-end

const privateKeyProvider = new EthereumPrivateKeyProvider({
  config: { chainConfig },
})

const web3auth = new Web3Auth(WebBrowser, EncryptedStorage, {
  clientId,
  redirectUrl,
  network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET, // or other networks
  privateKeyProvider,
  // focus-next-line
  accountAbstractionProvider: aaProvider,
})
```

</TabItem>
<TabItem value="rn-expo">

```ts

// focus-start

  AccountAbstractionProvider,
  SafeSmartAccount,
} from '@web3auth/account-abstraction-provider'
//focus-end

const chainConfig = {
  chainNamespace: CHAIN_NAMESPACES.EIP155,
  chainId: '0xaa36a7',
  rpcTarget: 'https://ethereum-sepolia.publicnode.com',
  displayName: 'Ethereum Sepolia Testnet',
  blockExplorerUrl: 'https://sepolia.etherscan.io',
  ticker: 'ETH',
  tickerName: 'Ethereum',
  logo: 'https://cryptologos.cc/logos/ethereum-eth-logo.png',
}

// focus-start
const accountAbstractionProvider = new AccountAbstractionProvider({
  config: {
    chainConfig,
    bundlerConfig: {
      // Get the pimlico API Key from dashboard.pimlico.io
      url: `https://api.pimlico.io/v2/11155111/rpc?apikey=${pimlicoAPIKey}`,
    },
    smartAccountInit: new SafeSmartAccount(),
  },
})
// focus-end

const privateKeyProvider = new EthereumPrivateKeyProvider({
  config: { chainConfig },
})

const web3auth = new Web3Auth(WebBrowser, SecureStore, {
  clientId,
  redirectUrl,
  network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET, // or other networks
  privateKeyProvider,
  // focus-next-line
  accountAbstractionProvider: aaProvider,
})
```

</TabItem>
</Tabs>

### Configure signer

The Web3Auth Smart Account feature is compatible with popular signer SDKs, including wagmi, ethers,
and viem. You can choose your preferred package to configure the signer.

You can retreive the provider to configure the signer from Web3Auth instance.

:::info Wagmi

Wagmi does not require any special configuration to use the signer with smart accounts. Once you
have set up your Web3Auth provider and connected your wallet, Wagmi's hooks (such as useSigner or
useAccount) will automatically use the smart account as the signer. You can interact with smart
accounts using Wagmi just like you would with a regular EOA (Externally Owned Account) signer—no
additional setup is needed.

:::

<Tabs
  defaultValue="viem"
  values={[
    { label: "Viem", value: "viem" },
    { label: "Ethers", value: "ethers" },
  ]}
>

<TabItem value="viem">

```tsx

// Use your Web3Auth instance to retreive the provider.
const provider = web3auth.provider

const walletClient = createWalletClient({
  transport: custom(provider),
})
```

</TabItem>

<TabItem value="ethers">

```tsx

// Use your Web3Auth instance to retreive the provider.
const provider = web3auth.provider

const ethersProvider = new ethers.providers.Web3Provider(provider)
const signer = await ethersProvider.getSigner()
```

</TabItem>
</Tabs>

## Smart account address

Once the signers or Wagmi configuration is set up, it can be used to retrieve the user's Smart
Account address.

<Tabs
  defaultValue="viem"
  values={[
    { label: "Viem", value: "viem" },
    { label: "Ethers", value: "ethers" },
    { label: "Wagmi", value: "wagmi" },
  ]}
>

<TabItem value="viem">

```tsx
// Use walletClient instance from previous step
const addresses = await walletClient.getAddresses()

const smartAccountAddress = addresses[0]
const eoaAddress = addresses[1]
```

</TabItem>

<TabItem value="ethers">

```tsx
// User signer from previous step
const smartAccountAddress = signer.getAddress()
```

</TabItem>

<TabItem value="wagmi">

```tsx

const { address } = useAccount()
const smartAccountAddress = address
```

</TabItem>
</Tabs>

## Send transaction

Developers can use their preferred signer or Wagmi hooks to initiate onchain transactions, while
Web3Auth manages the creation and submission of the UserOperation. Only the `to`, `data`, and
`value` fields need to be provided. Any additional parameters will be ignored and automatically
overridden.

To ensure reliable execution, the bundler client sets maxFeePerGas and maxPriorityFeePerGas values.
If custom values are required, developers can use the
[Viem's BundlerClient](https://viem.sh/account-abstraction/clients/bundler#bundler-client) to
manually construct and send the user operation.

Since Smart Accounts are deployed smart contracts, the user's first transaction also triggers the
onchain deployment of their wallet.

<Tabs
  defaultValue="viem"
  values={[
    { label: "Viem", value: "viem" },
    { label: "Ethers", value: "ethers" },
    { label: "Wagmi", value: "wagmi" },
  ]}
>

<TabItem value="wagmi">

```tsx

const { data: hash, sendTransaction } = useSendTransaction()

// Convert 1 ether to WEI format
const value = web3.utils.toWei(1)

sendTransaction({ to: 'DESTINATION_ADDRESS', value, data: '0x' })

const {
  data: receipt,
  isLoading: isConfirming,
  isSuccess: isConfirmed,
} = useWaitForTransactionReceipt({
  hash,
})
```

</TabItem>
<TabItem value="ethers">

```tsx
// Convert 1 ether to WEI format
const amount = ethers.parseEther('1.0')

// Submits a user operation to the blockchain
const transaction = await signer.sendTransaction({
  to: 'DESTINATION_ADDRESS',
  value: amount,
  // This will perform the transfer of ETH
  data: '0x',
})

// Wait for the transaction to be mined
const receipt = await transaction.wait()
```

</TabItem>
<TabItem value="viem">

```tsx
// Convert 1 ether to WEI format
const amount = parseEther('1')

// Submits a user operation to the blockchain
const hash = await walletClient.sendTransaction({
  to: 'DESTINATION_ADDRESS',
  value: amount,
  // This will perform the transfer of ETH
  data: '0x',
})

// Wait for the transaction to be mined
const receipt = await publicClient.waitForTransactionReceipt({ hash })
```

</TabItem>
</Tabs>

## Advanced smart account operations

To learn more about supported transaction methods, and how to perform batch transactions, [checkout our detailed documentation of AccountAbstractionProvider](/embedded-wallets/sdk/react).
