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

# Ethereum / EVM

## Creating a Wallet

When a new user logs in, they do not yet have a Web3 wallet by default. You can create a wallet for them by calling the `createWallet` function on the user object.

<Info>
  Currently, we don't support connecting users' existing self-custodial wallets. This is coming soon.

  Right now, we only support embedded wallets, which are generated on behalf of the user by our non-custodial wallet partner.

  You could use Civic's `embeddedWallet()` wagmi connector alongside other connectors like Metamask, so your code can switch between Civic embedded wallets and the user's other installed wallets. Currently those wallets cannot be linked to the Civic account, they are separate.

  Neither Civic nor your app ever has access to the wallets' private keys.
</Info>

Here's a basic example:

<Check>
  Complete examples can be found on github:

  * [Vite + Wagmi](https://github.com/civicteam/civic-auth-examples/tree/main/packages/civic-auth-web3/wagmi)

  * [NextJS + Wagmi](https://github.com/civicteam/civic-auth-examples/tree/main/packages/civic-auth-web3/wagmi-nextjs)
</Check>

```tsx theme={null}
import { userHasWallet } from "@civic/auth-web3";
import { useUser } from "@civic/auth-web3/react";

export const afterLogin = async () => {
  const userContext = await useUser();

  if (userContext.user && !userHasWallet(userContext)) {
    await userContext.createWallet();
  }
};
```

## The useUser hook and UserContext Object

The useUser hook returns a user context object that provides access to the base library's [user object](/integration/react#user) in the 'user' field, and adds some Web3 specific fields. The returned object has different types depending on these cases:

If the user has a wallet,

```tsx theme={null}
type ExistingWeb3UserContext = UserContext & {
  ethereum: {
      address: string // the address of the embedded wallet
      wallet: WalletClient // a Viem WalletClient
  }
}
```

If the user does not yet have a wallet:

```tsx theme={null}
type NewWeb3UserContext = UserContext & {
  createWallet: () => Promise<void>;
  walletCreationInProgress: boolean;
}
```

An easy way to distinguish between the two is to use the `userHasWallet` type guard.

```tsx theme={null}
if (userHasWallet(userContext)) {
  user.ethereum.wallet; // user has a wallet
} else {
  user.createWallet();// user does not have a wallet
}
```

## Using the Wallet

The Civic Auth Web3 SDK uses [Wagmi](https://wagmi.sh/) and [Viem](https://viem.sh/) to expose the embedded wallet to your app, simplifying wallet interactions on both the front end and back end.

* **React Apps**: Civic Auth is optimized for React, with easy access to **Wagmi hooks** for a seamless experience.

* **Non-React Apps**: For non-React frameworks, use **Viem** directly to interact with the wallet.

### Using the Wallet with Wagmi

To use the embedded wallet with Wagmi, follow these steps:

<Info>
  **Prerequisites**

  Follow the [Wagmi documentation](https://wagmi.sh/) to learn how to set up your app with Wagmi.

  Ensure you have created the user's wallet first as described [above](/web3/ethereum-evm#creating-a-wallet).
</Info>

#### 1. Add the Embedded Wallet to Wagmi Config

Include `embeddedWallet()` in your Wagmi configuration as shown below:

```tsx theme={null}
import { embeddedWallet } from "@civic/auth-web3/wagmi";

import { mainnet } from "viem/chains";
import { Chain, http } from "viem";
import { createConfig, WagmiProvider } from "wagmi";

const wagmiConfig = createConfig({
  chains: [mainnet],
  transports: {
      [mainnet.id]: http()
  },
  connectors: [
    embeddedWallet(),
  ],
});
```

#### 2. Connect the wallet

#### Autoconnect

If you want to automatically connect the civic wallet as soon as the user has logged in, you can use the `useAutoConnect()` hook:

```tsx theme={null}
import { useAutoConnect } from "@civic/auth-web3/wagmi";

useAutoConnect();
```

This hook also creates the wallet, if it is a new user.

#### Manual

If you want a little more control, first create the wallet,

```tsx theme={null}
import { userHasWallet } from "@civic/auth-web3";
import { embeddedWallet } from "@civic/auth-web3/wagmi";
import { CivicAuthProvider, UserButton, useUser } from "@civic/auth-web3/react";

// A function that creates the wallet if the user doesn't have one already
const createWallet = () => {
  if (userContext.user && !userHasWallet(userContext)) {
    // Once the wallet is created, we can connect to it
    return userContext.createWallet().then(connectWallet)
  }
}
```

then initiate the connection to the embedded wallet using Wagmi's `connect` method.

```
const { connectors, connect } = useConnect();

const connectWallet = () => connect({
// connect to the "civic" connector
  connector: connectors[0],
});
```

#### 3. Use Wagmi Hooks

Once connected, you can use Wagmi hooks to interact with the embedded wallet. Common hooks include:

* `useBalance`: Retrieve the wallet balance.

* `useAccount`: Access account details.

* `useSendTransaction`: Send transactions from the wallet.

* `useSignMessage`: Sign messages with the wallet.

For more detailed documentation on how to use these hooks, see the [Wagmi docs](https://wagmi.sh/react/api/hooks).

### A Full Example

See below for a full minimal example of a Wagmi app using Civic Auth for an embedded wallet. This is based on [this GitHub repository](https://github.com/civicteam/civic-auth-examples/tree/main/packages/civic-auth-web3/wagmi) that contains a sample implementation.

```tsx theme={null}
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { WagmiProvider, createConfig, useAccount, useConnect, useBalance, http } from "wagmi";
import { userHasWallet } from "@civic/auth-web3";
import { embeddedWallet } from "@civic/auth-web3/wagmi";
import { CivicAuthProvider, UserButton, useUser } from "@civic/auth-web3/react";
import { mainnet, sepolia } from "wagmi/chains";

const wagmiConfig = createConfig({
  chains: [ mainnet, sepolia ],
  transports: {
    [mainnet.id]: http(),
    [sepolia.id]: http(),
  },
  connectors: [
    embeddedWallet(),
  ],
});

// Wagmi requires react-query
const queryClient = new QueryClient();

// Wrap the content with the necessary providers to give access to hooks: react-query, wagmi & civic auth provider
// initialChain is passed into <CivicAuthProvider /> to indicate the first chain you want to use.
// The chain can be switched later using wagmi's useSwitchChain() hook.
const App = () => {
  return (
    <QueryClientProvider client={queryClient}>
      <WagmiProvider config={wagmiConfig}>
        <CivicAuthProvider clientId="< YOUR CLIENT ID >" initialChain={mainnet}>
          <AppContent />
        </CivicAuthProvider>
      </WagmiProvider>
    </QueryClientProvider>
  );
};

// Separate component for the app content that needs access to hooks
const AppContent = () => {
  // Add the civic hooks
  const userContext = useUser();
  useAutoConnect();

  // Add the wagmi hooks
  const { isConnected, address } = useAccount();
  const balance = useBalance({ address });

  return (
    <>
      <UserButton />
      {userContext.user &&
        <div>
          {!userHasWallet(userContext) &&
            <p><button onClick={createWallet}>Create Wallet</button></p>
          }
          {userHasWallet(userContext) &&
            <>
              <p>Wallet address: {userContext.eth.address}</p>
              <p>Balance: {
                balance?.data
                  ? `${(BigInt(balance.data.value) / BigInt(1e18)).toString()} ${balance.data.symbol}`
                  : "Loading..."
              }</p>
              {isConnected ? <p>Wallet is connected</p> : (
                <button onClick={connectExistingWallet}>Connect Wallet</button>
              )}
            </>
          }
        </div>
      }
    </>
  );
};

export default App;
```

### Using the Wallet with Viem

If you are not using Wagmi, you may also use [Viem](https://viem.sh) directly to access the same wallet capabilities:

```tsx theme={null}
const userContext  = useUser();

if (userContext.user && userHasWallet(userContext)) {
  const { wallet } = userContext.ethereum;
  const hash = await wallet.sendTransaction({
    to: "0x...",
    value: 1000n
  })
}
```

Full documentation for Viem can be found [here](https://viem.sh/docs/getting-started).

#### Using Viem without React

Our SDK is currently being adapted to support other frontend frameworks beyond React.

Contact Civic in [our developer community](https://join.slack.com/t/civic-developers/shared_invite/zt-37tv9fyo7-aDT43mUjOFQwdQFmfZLTRw) if you have questions about integrating Civic Auth Web3 with a different framework.

## Configuration

The library works out of the box without additional configuration.

If you need to customize the library's behavior, you can pass additional configuration options to the `CivicAuthProvider` component. Here is an example:

## Supported EVM Chains

Civic Auth embedded wallets support the following EVM-compatible blockchain networks:

<CardGroup cols={3}>
  <Card title="Ethereum" icon="ethereum">
    Mainnet and testnets
  </Card>

  <Card title="Base" icon="circle">
    Coinbase Layer 2
  </Card>

  <Card title="Polygon" icon="hexagon">
    MATIC ecosystem
  </Card>

  <Card title="BSC (BNB)" icon="coins">
    Binance Smart Chain
  </Card>

  <Card title="Arbitrum One" icon="arrow-up-right">
    Ethereum Layer 2
  </Card>

  <Card title="Avalanche" icon="mountain">
    AVAX C-Chain
  </Card>

  <Card title="Unichain" icon="link">
    Uniswap Layer 2
  </Card>

  <Card title="Sonic" icon="bolt">
    High-speed blockchain
  </Card>

  <Card title="Cronos" icon="clock">
    Crypto.com Chain
  </Card>

  <Card title="OP Mainnet" icon="circle-dot">
    Optimism Layer 2
  </Card>

  <Card title="Linea" icon="lines-leaning">
    ConsenSys zkEVM
  </Card>

  <Card title="ZKSync Era" icon="shield-check">
    Matter Labs zkEVM
  </Card>

  <Card title="Filecoin" icon="folder">
    Decentralized storage
  </Card>

  <Card title="Gnosis" icon="users">
    Community-driven chain
  </Card>

  <Card title="Rootstock" icon="bitcoin">
    Bitcoin sidechain
  </Card>

  <Card title="Mantle" icon="layer-group">
    Modular Layer 2
  </Card>

  <Card title="Ronin" icon="gamepad-2">
    Gaming-focused sidechain
  </Card>

  <Card title="Celo" icon="smartphone">
    Mobile-first blockchain
  </Card>
</CardGroup>

<Note>
  All supported chains are EVM-compatible, meaning you can use the same wallet address across all of them.
</Note>

### Limiting to specific chains

By default, Civic Auth supports all chains supported by viem. If you want to restrict wallet usage to specific chains, you can pass an array of chains to the CivicAuthProvider. Pass the `initialChain` property to define the chain you want to start using.

#### Example 1. Using viem chain objects

```tsx theme={null}
import { mainnet, polygon } from "viem/chains";
<CivicAuthProvider chains={[mainnet, polygon]} initialChain={mainnet}>
```

#### The chain can be switched using wagmi's useSwitchChain hook:

```tsx theme={null}
import { useSwitchChain } from "wagmi";

// Switch chain to polygon
switchChain({
   chainId: polygon.id,
});
```

#### Example 2. Specifying custom RPCs

```tsx theme={null}
import { mainnet, polygon } from "viem/chains";
<CivicAuthProvider endpoints={{
    rpcs: {
        [mainnet.id]: {
            http: [<your mainnet HTTP RPC URL>],
            webSocket: [<your mainnet WS RPC URL>], // or omit if not available
        },
        [polygon.id]: {
            http: [<your polygon HTTP RPC URL>],
            webSocket: [<your polygon WS RPC URL>], // or omit if not available
        }
    }
}}>
```

<Note>
  If you are having trouble connecting to the default RPC endpoints (e.g. timeouts, failed transactions), you can specify a custom RPC provider here. Find an alternative RPC endpoint for your chain and add it using the configuration above.
</Note>
