tomevault-io

web3-privy

Privy auth SDK. Wallet login, embedded wallets, social login, server verification, wagmi integration. Use when this capability is needed.

tomevault-io 1 Updated 4mo ago
GitHub

Install

npx skillscat add tomevault-io/tomes/web3-privy

Install via the SkillsCat registry.

SKILL.md

Privy SDK Patterns

Setup (React)

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

function App() {
  return (
    <PrivyProvider
      appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID!}
      config={{
        loginMethods: ["email", "wallet", "google", "twitter"],
        appearance: {
          theme: "dark",
          accentColor: "#6366f1",
        },
        embeddedWallets: {
          createOnLogin: "users-without-wallets",
        },
        defaultChain: base,
        supportedChains: [mainnet, base, arbitrum],
      }}
    >
      {children}
    </PrivyProvider>
  )
}

Authentication

Login/Logout

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

function AuthButton() {
  const { login, logout, authenticated, user, ready } = usePrivy()

  if (!ready) return <Spinner />

  if (!authenticated) {
    return <button onClick={login}>Sign In</button>
  }

  return (
    <div>
      <p>{user?.email?.address || user?.wallet?.address}</p>
      <button onClick={logout}>Sign Out</button>
    </div>
  )
}

Auth Methods

Method Config Key User Property
Email "email" user.email.address
Wallet "wallet" user.wallet.address
Google "google" user.google.email
Twitter "twitter" user.twitter.username
Discord "discord" user.discord.username
Farcaster "farcaster" user.farcaster.fid
Passkey "passkey" user.passkey

User Object

const { user } = usePrivy()

// Linked accounts
const email = user?.email?.address
const walletAddress = user?.wallet?.address
const linkedAccounts = user?.linkedAccounts // all linked methods

Embedded Wallets

import { usePrivy, useWallets } from "@privy-io/react-auth"

function WalletActions() {
  const { wallets } = useWallets()

  // Find embedded wallet
  const embeddedWallet = wallets.find((w) => w.walletClientType === "privy")

  // Get provider for transactions
  const provider = await embeddedWallet?.getEthereumProvider()

  // Send transaction
  const txHash = await provider?.request({
    method: "eth_sendTransaction",
    params: [{
      to: recipientAddress,
      value: "0x" + parseEther("0.01").toString(16),
    }],
  })
}

wagmi Integration

import { PrivyProvider } from "@privy-io/react-auth"
import { WagmiProvider, createConfig } from "@privy-io/wagmi"

// Privy provides its own wagmi config wrapper
import { createConfig as createPrivyWagmiConfig } from "@privy-io/wagmi"

const config = createPrivyWagmiConfig({
  chains: [mainnet, base],
  transports: {
    [mainnet.id]: http(),
    [base.id]: http(),
  },
})

function App() {
  return (
    <PrivyProvider appId={appId}>
      <WagmiProvider config={config}>
        <QueryClientProvider client={queryClient}>
          {children}
        </QueryClientProvider>
      </WagmiProvider>
    </PrivyProvider>
  )
}

// Then use standard wagmi hooks
import { useAccount, useBalance, useSendTransaction } from "wagmi"

Server-Side Verification

import { PrivyClient } from "@privy-io/server-auth"

const privy = new PrivyClient(
  process.env.PRIVY_APP_ID!,
  process.env.PRIVY_APP_SECRET!,
)

// Verify auth token (API route / middleware)
async function verifyAuth(req: Request) {
  const token = req.headers.get("authorization")?.replace("Bearer ", "")
  if (!token) throw new Error("No token")

  const { userId } = await privy.verifyAuthToken(token)
  return userId
}

// Get user by ID
const user = await privy.getUser(userId)

Multi-Chain Wallet Support

// Privy supports both EVM and Solana wallets
const config = {
  embeddedWallets: {
    createOnLogin: "users-without-wallets",
    // Solana embedded wallets
    solana: { createOnLogin: "users-without-wallets" },
  },
  supportedChains: [mainnet, base, arbitrum, polygon],
}

// Access Solana wallet
import { useSolanaWallets } from "@privy-io/react-auth/solana"
const { wallets: solanaWallets } = useSolanaWallets()

Common Patterns

Protected Routes

function ProtectedPage() {
  const { ready, authenticated } = usePrivy()

  if (!ready) return <Loading />
  if (!authenticated) return <Redirect to="/login" />

  return <Dashboard />
}

Link Additional Accounts

const { linkEmail, linkWallet, linkGoogle } = usePrivy()

// User can link multiple auth methods to one account
await linkEmail() // Opens email verification flow
await linkWallet() // Opens wallet connection

Converted and distributed by TomeVault — claim your Tome and manage your conversions.