# Privy

> Use Privy with Wallet APIs for EIP-7702, sponsorship, and batching

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

<Info>`@alchemy/wallet-apis` (v5.x.x) is currently in beta but is the recommended replacement for `@account-kit/wallet-client` (v4.x.x). If you run into any issues, please [reach out](mailto:support@alchemy.com).</Info>

Upgrade existing Privy wallets to Wallet APIs to enable gasless transactions, batching, and more in under 10 minutes. Keep Privy for authentication, no wallet migration needed. Add battle-tested transaction infrastructure using EIP-7702 to upgrade your wallets to Wallet APIs:

* [#1 gas abstraction infrastructure](https://www.bundlebear.com/erc4337-bundlers/all) on the market
* [370M+](https://www.bundlebear.com/erc4337-paymasters/all) sponsored transactions
* 99.9% SLAs
* Trusted by Worldcoin, JP Morgan, Gensyn, and more

<Tabs>
  <Tab title="React" language="react">
    ## Setup

    Follow these steps to use Privy signers with the Wallet Client SDK.

    ### Installation

    <CodeGroup>
    ```shell npm
    npm install @alchemy/wallet-apis @privy-io/react-auth viem
    ```

    ```shell bun
    bun add @alchemy/wallet-apis @privy-io/react-auth viem
    ```

    ```shell yarn
    yarn add @alchemy/wallet-apis @privy-io/react-auth viem
    ```

    ```shell pnpm
    pnpm add @alchemy/wallet-apis @privy-io/react-auth viem
    ```
    </CodeGroup>

    ### Prerequisites: Get your keys (API key, Policy ID, Privy App ID)

    * Alchemy API key:
      * Go to the [Alchemy Dashboard](https://dashboard.alchemy.com/)
      * Create or select an app and copy the API key
    * Gas sponsorship Policy ID (Gas Manager):
      * Create a gas sponsorship policy in the [dashboard](https://dashboard.alchemy.com/services/gas-manager/configuration) and copy its Policy ID
    * Privy App ID:
      * Go to the [Privy Dashboard](https://dashboard.privy.io/)
      * Create or select an app and copy the App ID

    <Warning>
      The gas sponsorship policy must be linked to the application behind your Alchemy API key for sponsorship to work.
    </Warning>

    ### 1. Configure PrivyProvider

    Wrap your app with `PrivyProvider` from `@privy-io/react-auth`:

    ```tsx
    import { PrivyProvider } from "@privy-io/react-auth";

    export function App() {
      return (
        <PrivyProvider
          appId="your-privy-app-id"
          config={{
            embeddedWallets: {
              ethereum: {
                createOnLogin: "all-users",
              },
              showWalletUIs: false,
            },
          }}
        >
          <YourApp />
        </PrivyProvider>
      );
    }
    ```

    ### 2. Get a signer from Privy

    Use `toViemAccount` and `useWallets` from `@privy-io/react-auth` to convert a Privy embedded wallet into a viem `LocalAccount`:

    ```tsx
    import { toViemAccount, useWallets } from "@privy-io/react-auth";
    import { useEffect, useState } from "react";
    import type { LocalAccount } from "viem";

    const usePrivySigner = () => {
      const {
        wallets: [wallet],
      } = useWallets();

      const [signer, setSigner] = useState<LocalAccount>();

      useEffect(() => {
        if (!wallet || signer) return;
        toViemAccount({ wallet }).then(setSigner);
      }, [wallet, signer]);

      return signer;
    };
    ```

    ### 3. Handle login

    Use `usePrivy` to manage authentication state and conditionally render your wallet UI once the user is logged in:

    ```tsx
    import { usePrivy } from "@privy-io/react-auth";

    function PrivyWallet() {
      const { ready, authenticated, login, logout } = usePrivy();
      const signer = usePrivySigner();

      if (!ready) return <p>Loading...</p>;

      if (!authenticated) {
        return <button onClick={() => login()}>Login with Privy</button>;
      }

      return (
        <div>
          <button onClick={() => logout()}>Logout</button>
          {signer ? <SendTransaction signer={signer} /> : <p>Loading signer...</p>}
        </div>
      );
    }
    ```

    ### 4. Create the client and send a transaction

    Pass the Privy signer to `createSmartWalletClient` and use it to send transactions:

    ```tsx
    import { useMemo, useCallback } from "react";
    import { zeroAddress } from "viem";
    import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis";
    import { arbitrumSepolia } from "viem/chains";

    function SendTransaction({ signer }: { signer: LocalAccount }) {
      const client = useMemo(
        () =>
          createSmartWalletClient({
            signer,
            transport: alchemyWalletTransport({
              apiKey: "YOUR_ALCHEMY_API_KEY",
            }),
            chain: arbitrumSepolia,
            paymaster: {
              policyId: "YOUR_GAS_MANAGER_POLICY_ID",
            },
          }),
        [signer],
      );

      const handleSend = useCallback(async () => {
        // Send the transaction
        const { id } = await client.sendCalls({
          calls: [{ to: zeroAddress, value: BigInt(0), data: "0x" }],
        });

        // Wait for the transaction to be confirmed
        const result = await client.waitForCallsStatus({ id });
        console.log(`Transaction hash: ${result.receipts?.[0]?.transactionHash}`);
      }, [client]);

      return <button onClick={handleSend}>Send transaction</button>;
    }
    ```

    ### Notes

    * The client defaults to [EIP-7702](/docs/wallets/transactions/using-eip-7702), which delegates the Privy wallet to a smart wallet at send time. No deployment or wallet migration needed. See the [EIP-7702 guide](/docs/wallets/transactions/using-eip-7702) for non-7702 mode.
    * See the [Sponsor gas](/docs/wallets/transactions/sponsor-gas) guide for more on gas sponsorship configuration.
  </Tab>

  <Tab title="JavaScript" language="typescript">
    ## Setup

    Use the `@privy-io/node` package with the Wallet Client SDK in a server environment.

    ### Installation

    <CodeGroup>
    ```shell npm
    npm install @privy-io/node @alchemy/wallet-apis viem
    ```

    ```shell bun
    bun add @privy-io/node @alchemy/wallet-apis viem
    ```

    ```shell yarn
    yarn add @privy-io/node @alchemy/wallet-apis viem
    ```

    ```shell pnpm
    pnpm add @privy-io/node @alchemy/wallet-apis viem
    ```
    </CodeGroup>

    ### Prerequisites: Get your keys

    * Alchemy API key:
      * Go to the [Alchemy Dashboard](https://dashboard.alchemy.com/)
      * Create or select an app and copy the API key
    * Gas sponsorship Policy ID (Gas Manager):
      * Create a gas sponsorship policy in the [dashboard](https://dashboard.alchemy.com/services/gas-manager/configuration) and copy its Policy ID
    * Privy App ID & Secret:
      * Go to the [Privy Dashboard](https://dashboard.privy.io/)
      * Create or select an app and copy the App ID and App Secret

    <Warning>
      Both the Wallet APIs configuration and the gas sponsorship policy must be
      linked to the application behind your Alchemy API key for sponsorship to work.
    </Warning>

    ### Send a transaction

    ```ts
    import { PrivyClient } from "@privy-io/node";
    import { createViemAccount } from "@privy-io/node/viem";
    import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis";
    import { arbitrumSepolia } from "viem/chains";
    import type { Hex } from "viem";

    const privyClient = new PrivyClient({
      appId: process.env.PRIVY_APP_ID!,
      appSecret: process.env.PRIVY_APP_SECRET!,
    });

    // Create or get a Privy wallet
    const wallet = await privyClient.wallets().create({
      chain_type: "ethereum",
    });

    // Get a viem-compatible signer from Privy
    const signer = createViemAccount(privyClient, {
      walletId: wallet.id,
      address: wallet.address as Hex,
    });

    // Create the Smart Wallet client
    const client = createSmartWalletClient({
      signer,
      transport: alchemyWalletTransport({ apiKey: process.env.ALCHEMY_API_KEY! }),
      chain: arbitrumSepolia,
      paymaster: { policyId: process.env.ALCHEMY_POLICY_ID! },
    });

    // Send the transaction
    const { id } = await client.sendCalls({
      calls: [
        {
          to: "0x0000000000000000000000000000000000000000",
          value: BigInt(0),
          data: "0x",
        },
      ],
    });

    // Wait for the transaction to be confirmed
    const result = await client.waitForCallsStatus({ id });
    console.log(`Transaction hash: ${result.receipts?.[0]?.transactionHash}`);
    ```

    ### Notes

    * The client defaults to [EIP-7702](/docs/wallets/transactions/using-eip-7702), which upgrades the wallet to a smart wallet at transaction time without migration or separate deployment. See the [EIP-7702 guide](/docs/wallets/transactions/using-eip-7702) for non-7702 mode.
    * See the [Sponsor gas](/docs/wallets/transactions/sponsor-gas) guide for more on gas sponsorship configuration.
    * This example uses Privy's `@privy-io/node` package which is designed for server environments. `@alchemy/wallet-apis` can be used in any JavaScript environment.
  </Tab>
</Tabs>