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

# Privy integration

> Authenticate users with Privy and create Startale smart accounts from their embedded wallet.

[Privy](https://www.privy.io/) provides embedded wallets with email, OAuth, and external wallet login. Privy exposes an EIP-1193 provider via `wallet.getEthereumProvider()`, which you wrap with viem's `createWalletClient` and feed to `toStartaleSmartAccount` as a signer.

<Note>
  Source: [`StartaleGroup/scs-aa-sdk`](https://github.com/StartaleGroup/scs-aa-sdk).
</Note>

## Install

```bash theme={null}
npm install @startale-scs/aa-sdk viem @privy-io/react-auth
```

| Package                | Why                                         |
| ---------------------- | ------------------------------------------- |
| `@startale-scs/aa-sdk` | The AA SDK itself.                          |
| `viem`                 | Chain, transport, and `createWalletClient`. |
| `@privy-io/react-auth` | Privy React provider and hooks.             |

## 1. Wrap the app in `PrivyProvider`

```tsx providers.tsx theme={null}
import { PrivyProvider } from "@privy-io/react-auth"
import { soneiumMinato } from "viem/chains"

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <PrivyProvider
      appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID!}
      config={{
        loginMethods: ["email", "google", "wallet"],
        embeddedWallets: {
          createOnLogin: "all-users",
          showWalletUIs: false,
        },
        supportedChains: [soneiumMinato],
        defaultChain: soneiumMinato,
      }}
    >
      {children}
    </PrivyProvider>
  )
}
```

| Setting                            | Effect                                                                                    |
| ---------------------------------- | ----------------------------------------------------------------------------------------- |
| `loginMethods`                     | Which login flows are available to the user.                                              |
| `embeddedWallets.createOnLogin`    | When set to `"all-users"`, Privy creates an embedded wallet for every user automatically. |
| `embeddedWallets.showWalletUIs`    | Disable Privy's own send/sign UIs so the smart account drives the UX.                     |
| `supportedChains` / `defaultChain` | Restrict Privy to Soneium Minato (or `soneium` for mainnet).                              |

## 2. Build the smart account from the embedded wallet

`useWallets()` returns the connected wallets. Take the first one (typically the embedded wallet), pull its EIP-1193 provider, and wrap it with viem.

```tsx useStartaleFromPrivy.ts theme={null}
import { useEffect, useState } from "react"
import { usePrivy, useWallets } from "@privy-io/react-auth"
import { createPublicClient, createWalletClient, custom, http } from "viem"
import { soneiumMinato } from "viem/chains"
import {
  createSCSPaymasterClient,
  createSmartAccountClient,
  toStartaleSmartAccount,
  type StartaleAccountClient,
} from "@startale-scs/aa-sdk"

export function useStartaleFromPrivy() {
  const { authenticated } = usePrivy()
  const { wallets } = useWallets()
  const [client, setClient] = useState<StartaleAccountClient>()

  useEffect(() => {
    if (!authenticated || wallets.length === 0) return

    let cancelled = false
    ;(async () => {
      const wallet = wallets[0]
      const provider = await wallet.getEthereumProvider()

      const walletClient = createWalletClient({
        account: wallet.address as `0x${string}`,
        chain: soneiumMinato,
        transport: custom(provider),
      })

      const publicClient = createPublicClient({ chain: soneiumMinato, transport: http() })

      const account = await toStartaleSmartAccount({
        signer: walletClient,
        chain: soneiumMinato,
        transport: http(),
        index: 0n,
      })

      const paymasterClient = createSCSPaymasterClient({
        transport: http(process.env.NEXT_PUBLIC_PAYMASTER_URL!),
      })

      const smartAccountClient = createSmartAccountClient({
        account,
        transport: http(process.env.NEXT_PUBLIC_BUNDLER_URL!),
        client: publicClient,
        paymaster: paymasterClient,
        paymasterContext: {
          paymasterId: process.env.NEXT_PUBLIC_PAYMASTER_ID!,
        },
      })

      if (!cancelled) setClient(smartAccountClient)
    })()

    return () => {
      cancelled = true
    }
  }, [authenticated, wallets])

  return client
}
```

| Symbol                          | Source                 | Role                                                                     |
| ------------------------------- | ---------------------- | ------------------------------------------------------------------------ |
| `usePrivy`                      | `@privy-io/react-auth` | Hook exposing `authenticated`, `user`, and login helpers.                |
| `useWallets`                    | `@privy-io/react-auth` | Hook returning the user's connected wallets.                             |
| `wallet.getEthereumProvider()`  | Privy                  | Returns an EIP-1193 provider for the embedded wallet.                    |
| `createWalletClient` / `custom` | `viem`                 | Wraps the EIP-1193 provider as a viem `WalletClient`.                    |
| `toStartaleSmartAccount`        | `@startale-scs/aa-sdk` | Builds the smart account from the wallet client.                         |
| `createSmartAccountClient`      | `@startale-scs/aa-sdk` | Wraps the account with bundler and paymaster for sending UserOperations. |

## 3. Send a sponsored UserOperation

```ts theme={null}
const hash = await client!.sendUserOperation({
  calls: [{ to: counterAddress, data: callData, value: 0n }],
})
const receipt = await client!.waitForUserOperationReceipt({ hash })
```

## Common adjustments

<AccordionGroup>
  <Accordion title="Use the EIP-1193 provider directly without a WalletClient">
    `toStartaleSmartAccount` accepts an EIP-1193 provider as a signer too. You can skip `createWalletClient` if you do not need viem's wallet methods elsewhere:

    ```ts theme={null}
    const provider = await wallets[0].getEthereumProvider()
    const account = await toStartaleSmartAccount({
      signer: provider,
      chain: soneiumMinato,
      transport: http(),
      index: 0n,
    })
    ```
  </Accordion>

  <Accordion title="External wallets via Privy">
    `wallets` may contain external wallets (MetaMask, Rabby) alongside the embedded wallet. Pick the one whose `walletClientType` matches your needs before building the signer.
  </Accordion>

  <Accordion title="Pay gas in tokens">
    Replace `paymasterId` with `token` in `paymasterContext`. See [ERC-20 paymaster](/aa-sdk/tutorials/erc20-payment).
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Dynamic integration" icon="user-check" href="/aa-sdk/auth-providers/dynamic">
    The same flow with Dynamic as the auth provider.
  </Card>

  <Card title="Smart account setup" icon="wallet" href="/aa-sdk/tutorials/smart-account-setup">
    Lift the smart account into a context provider.
  </Card>

  <Card title="Smart sessions" icon="key-skeleton" href="/aa-sdk/tutorials/smart-sessions">
    Reduce signature friction with scoped session keys.
  </Card>

  <Card title="Social recovery" icon="user-shield" href="/aa-sdk/tutorials/social-recovery">
    Add guardian-based key rotation.
  </Card>
</CardGroup>
