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

# Monad Integration with Dynamic

> Sign users in with email, create an embedded wallet, and send transactions on Monad with the Dynamic JavaScript SDK.

[Monad](https://monad.xyz) is a high-throughput, EVM-compatible Layer 1. Dynamic supports it like any other EVM chain: no custom adapter or signer required.

This guide shows how to sign a user in with email, create their embedded wallet, switch it to Monad, and send a transaction using the Dynamic JavaScript SDK.

## 1. Dashboard setup

In the [Dynamic dashboard](https://app.dynamic.xyz):

* Under **Chains & Networks**, enable **Monad** (Chain ID: 143)
* Under **Sign-in Methods**, enable **Email**
* Under **Wallets**, enable **Embedded wallets**
* Under **Security** → **Allowed Origins**, add the origin where the app runs (for example `http://localhost:5173`)

Then follow the [Quickstart](/docs/javascript/reference/quickstart) (or [React Quickstart](/docs/javascript/reference/react-quickstart)) to install and initialize the SDK.

## 2. Sign users in and create a wallet

The wallet isn't created automatically. After `verifyOTP` succeeds, call `createWaasWalletAccounts` and wait for it before reading the wallet's address.

<Tabs>
  <Tab title="JavaScript">
    ```typescript theme={"system"}
    import { sendEmailOTP, verifyOTP } from '@dynamic-labs-sdk/client';
    import {
      createWaasWalletAccounts,
      getChainsMissingWaasWalletAccounts,
    } from '@dynamic-labs-sdk/client/waas';

    let otpVerification: Awaited<ReturnType<typeof sendEmailOTP>>;

    async function signInWithEmail(email: string) {
      // Sends the code to the user's email; store the result to verify against later.
      otpVerification = await sendEmailOTP({ email });
    }

    async function verifyEmailCode(verificationToken: string) {
      await verifyOTP({ otpVerification, verificationToken });

      // The embedded wallet does not exist yet: create it and wait for it to finish.
      const missingChains = getChainsMissingWaasWalletAccounts();
      await createWaasWalletAccounts({ chains: missingChains });
    }
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { useState } from 'react';
    import { useSendEmailOTP, useVerifyOTP } from '@dynamic-labs-sdk/react-hooks';
    import {
      createWaasWalletAccounts,
      getChainsMissingWaasWalletAccounts,
    } from '@dynamic-labs-sdk/client/waas';

    function EmailSignIn() {
      const [email, setEmail] = useState('');
      const [code, setCode] = useState('');

      const { mutate: sendEmailOTP, data: otpVerification } = useSendEmailOTP();
      const { mutate: verifyOTP, isPending: isVerifying } = useVerifyOTP();

      const handleVerify = () => {
        verifyOTP(
          { otpVerification, verificationToken: code },
          {
            // The embedded wallet does not exist yet: create it and wait for it to finish.
            onSuccess: async () => {
              const missingChains = getChainsMissingWaasWalletAccounts();
              await createWaasWalletAccounts({ chains: missingChains });
            },
          },
        );
      };

      if (otpVerification) {
        return (
          <div>
            <input value={code} onChange={(e) => setCode(e.target.value)} placeholder="Enter code" />
            <button onClick={handleVerify} disabled={isVerifying}>Verify</button>
          </div>
        );
      }

      return (
        <div>
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="Email address"
          />
          <button onClick={() => sendEmailOTP({ email })}>Send code</button>
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

The wallet then shows up from `getWalletAccounts()` (or `useGetWalletAccounts()` in React), used in the next step.

## 3. Switch to Monad and send a transaction

Switch the wallet's active network to Monad (`networkId: '143'`), then use [`createWalletClientForWalletAccount`](/docs/javascript/reference/evm/getting-viem-wallet-client) to get a viem `WalletClient` for signing.

<Tip>
  If `switchActiveNetwork` throws `NetworkNotAddedError`, call [`addNetwork`](/docs/javascript/reference/wallets/add-network) first, then switch again. See [Switch Active Network](/docs/javascript/reference/wallets/switch-active-network).
</Tip>

<Tabs>
  <Tab title="JavaScript">
    ```typescript theme={"system"}
    import {
      getWalletAccounts,
      switchActiveNetwork,
      addNetwork,
      NetworkNotAddedError,
    } from '@dynamic-labs-sdk/client';
    import { isEvmWalletAccount } from '@dynamic-labs-sdk/evm';
    import { createWalletClientForWalletAccount } from '@dynamic-labs-sdk/evm/viem';

    async function sendOnMonad(transaction: { to: `0x${string}`; value: bigint }) {
      const walletAccount = getWalletAccounts().find(isEvmWalletAccount);
      if (!walletAccount) throw new Error('No EVM wallet connected');

      try {
        await switchActiveNetwork({ walletAccount, networkId: '143' });
      } catch (error) {
        if (error instanceof NetworkNotAddedError) {
          await addNetwork({ walletAccount, networkData: error.networkData });
          await switchActiveNetwork({ walletAccount, networkId: '143' });
        } else {
          throw error;
        }
      }

      const walletClient = await createWalletClientForWalletAccount({ walletAccount });
      const hash = await walletClient.sendTransaction(transaction);

      console.log('Transaction sent:', hash);
      return hash;
    }
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={"system"}
    import { useCallback } from 'react';
    import {
      switchActiveNetwork,
      addNetwork,
      NetworkNotAddedError,
    } from '@dynamic-labs-sdk/client';
    import { isEvmWalletAccount } from '@dynamic-labs-sdk/evm';
    import { createWalletClientForWalletAccount } from '@dynamic-labs-sdk/evm/viem';
    import { useGetWalletAccounts } from '@dynamic-labs-sdk/react-hooks';

    function useSendOnMonad() {
      const { data: walletAccounts = [] } = useGetWalletAccounts();
      const walletAccount = walletAccounts.find(isEvmWalletAccount);

      return useCallback(
        async (transaction: { to: `0x${string}`; value: bigint }) => {
          if (!walletAccount) throw new Error('No EVM wallet connected');

          try {
            await switchActiveNetwork({ walletAccount, networkId: '143' });
          } catch (error) {
            if (error instanceof NetworkNotAddedError) {
              await addNetwork({ walletAccount, networkData: error.networkData });
              await switchActiveNetwork({ walletAccount, networkId: '143' });
            } else {
              throw error;
            }
          }

          const walletClient = await createWalletClientForWalletAccount({ walletAccount });
          const hash = await walletClient.sendTransaction(transaction);

          console.log('Transaction sent:', hash);
          return hash;
        },
        [walletAccount],
      );
    }
    ```
  </Tab>
</Tabs>

## What you can do next

A Monad wallet works like any other EVM wallet: read balances, sign typed data, sponsor gas.

Monad also supports [Earn](/docs/overview/yield), so users can deposit into yield vaults (for example the Hyperithm USDC vault) without leaving your app.

## Related Documentation

* [Earn Overview](/docs/overview/yield)
* [Quickstart (JS SDK)](/docs/javascript/reference/quickstart)
* [Authenticate with Email](/docs/javascript/authentication-methods/email)
* [Creating WaaS Wallet Accounts](/docs/javascript/reference/waas/creating-waas-wallet-accounts)
* [Getting a Viem WalletClient](/docs/javascript/reference/evm/getting-viem-wallet-client)
* [Switch Active Network](/docs/javascript/reference/wallets/switch-active-network)
* [Adding a Network](/docs/javascript/reference/wallets/add-network)
* [Monad Documentation](https://docs.monad.xyz)
