> For the complete documentation index, see [llms.txt](/llms.txt).

# Smart accounts

Create and manage smart accounts for your users with just a few lines of code, using our smart account feature. Additionally, smart accounts offer enhanced control and programmability, enabling features like those listed below.

- 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 $4,000.
- Set Spending Limits: Allow users to set tailored spending limits.

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

Embedded Wallet's smart account feature gives you the flexibility to configure your bundler client, and integrate with your paymaster. For more insights into how ERC-4337 works 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).

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[​](#enabling-smart-accounts "Direct link to Enabling smart accounts")

prerequisite

Enable smart accounts in the [Embedded Wallets dashboard](https://developer.metamask.io/) under your project's smart accounts settings before configuring the SDK.

## SDK configuration[​](#sdk-configuration "Direct link to SDK configuration")

In v9, account abstraction is enabled by adding `accountAbstractionConfig` to `web3AuthOptions` in your `web3authConfig.ts` file. No separate `AccountAbstractionProvider` or `privateKeyProvider` construction is needed.

- Bare React Native
- Expo

web3authConfig.ts

```
import {
  CHAIN_NAMESPACES,
  WEB3AUTH_NETWORK,
  type AccountAbstractionConfig,
  type Web3AuthContextConfig,
} from '@web3auth/react-native-sdk'

const aaConfig: AccountAbstractionConfig = {
  smartAccountType: 'safe',
}

const web3AuthConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'YOUR_CLIENT_ID',
    redirectUrl: 'yourapp://auth',
    network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
    chains: [
      {
        chainNamespace: CHAIN_NAMESPACES.EIP155,
        chainId: '0xaa36a7',
        rpcTarget: 'https://rpc.ankr.com/eth_sepolia',
        displayName: 'Ethereum Sepolia Testnet',
        blockExplorerUrl: 'https://sepolia.etherscan.io',
        ticker: 'ETH',
        tickerName: 'Ethereum',
      },
    ],
    defaultChainId: '0xaa36a7',
    accountAbstractionConfig: aaConfig,
  },
}

export default web3AuthConfig

```

The configuration is identical for Expo. Only the `Web3AuthProvider` props change (use `expo-web-browser` and `expo-secure-store` instead of the bare equivalents):

web3authConfig.ts

```
import {
  CHAIN_NAMESPACES,
  WEB3AUTH_NETWORK,
  type AccountAbstractionConfig,
  type Web3AuthContextConfig,
} from '@web3auth/react-native-sdk'

const aaConfig: AccountAbstractionConfig = {
  smartAccountType: 'safe',
}

const web3AuthConfig: Web3AuthContextConfig = {
  web3AuthOptions: {
    clientId: 'YOUR_CLIENT_ID',
    redirectUrl: 'yourapp://auth',
    network: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
    chains: [
      {
        chainNamespace: CHAIN_NAMESPACES.EIP155,
        chainId: '0xaa36a7',
        rpcTarget: 'https://rpc.ankr.com/eth_sepolia',
        displayName: 'Ethereum Sepolia Testnet',
        blockExplorerUrl: 'https://sepolia.etherscan.io',
        ticker: 'ETH',
        tickerName: 'Ethereum',
      },
    ],
    defaultChainId: '0xaa36a7',
    accountAbstractionConfig: aaConfig,
  },
}

export default web3AuthConfig

```

Dynamic AA toggle

To let users toggle account abstraction on or off at runtime, maintain the config as state and pass a new `key` to `Web3AuthProvider` when it changes. This forces the provider to remount with the updated configuration:

```
const [useAA, setUseAA] = useState(false)
const config = useMemo(() => getWeb3AuthConfig(useAA), [useAA])

return (
  <Web3AuthProvider key={useAA ? 'aa' : 'eoa'} ... config={config}>
    ...
  </Web3AuthProvider>
)

```

## Configure signers[​](#configure-signers "Direct link to Configure signers")

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.

- Wagmi (recommended)
- Viem
- Ethers

Use Wagmi with `@web3auth/modal/react/wagmi` or `@web3auth/modal/vue/wagmi`. After sign-in, Wagmi hooks (`useConnection`, `useSendTransaction`, and similar) use the smart account signer automatically. No manual `connection.ethereumProvider` wiring is required.

```
import { useConnection, useSendTransaction } from 'wagmi'

const { address } = useConnection()
// useSendTransaction, useWriteContract, etc. work with the smart account

```

For vanilla JavaScript or apps without Wagmi, read the EIP-1193 provider from `connection`:

```
import { createWalletClient, custom } from 'viem'

const connection = web3auth.connection
const provider = connection?.ethereumProvider ?? null

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

```

```
import { ethers } from 'ethers'

const connection = web3auth.connection
const provider = connection?.ethereumProvider ?? null

const ethersProvider = new ethers.BrowserProvider(provider)
const signer = await ethersProvider.getSigner()

```

## Smart account address[​](#smart-account-address "Direct link to Smart account address")

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

- Viem
- Ethers
- Wagmi

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

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

```

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

```

```
import { useConnection } from 'wagmi'

const { address } = useConnection()
const smartAccountAddress = address


```

```

```

## Send transaction[​](#send-transaction "Direct link to 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.

- Viem
- Ethers
- Wagmi

```
import { useSendTransaction } from 'wagmi'

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,
})

```

```
// 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()

```

```
// 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 })

```
