Skip to main content

Scaffold

npx create-inco-app@latest my-app --wallet privy --framework hardhat --chain evm --yes

Environment Setup

Get your Privy app ID from dashboard.privy.io and add it to frontend/.env.local:
NEXT_PUBLIC_PRIVY_APP_ID=your_app_id_here
NEXT_PUBLIC_CONFLOTTERY_ADDRESS=<deployed_contract_address>

Provider Setup

Privy wraps your app with PrivyProvider for authentication and uses its own WagmiProvider from @privy-io/wagmi (not the standard wagmi package) to bridge wallet state.
Providers.tsx
"use client";

import { ReactNode } from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { PrivyProvider } from "@privy-io/react-auth";
import { WagmiProvider, createConfig } from "@privy-io/wagmi";
import { http } from "wagmi";
import { ThemeProvider } from "next-themes";
import { baseSepolia } from "wagmi/chains";

const queryClient = new QueryClient();

const appId = process.env.NEXT_PUBLIC_PRIVY_APP_ID || "";

const config = createConfig({
  chains: [baseSepolia],
  transports: {
    [baseSepolia.id]: http(),
  },
  ssr: true,
});

const Providers = ({ children }: { children: ReactNode }) => {
  return (
    <ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
      <PrivyProvider
        appId={appId}
        config={{
          appearance: {
            theme: "dark",
          },
          embeddedWallets: {
            createOnLogin: "users-without-wallets",
          },
          defaultChain: baseSepolia,
          supportedChains: [baseSepolia],
        }}
      >
        <QueryClientProvider client={queryClient}>
          <WagmiProvider config={config}>{children}</WagmiProvider>
        </QueryClientProvider>
      </PrivyProvider>
    </ThemeProvider>
  );
};

export { Providers };
Provider hierarchy: ThemeProviderPrivyProviderQueryClientProviderWagmiProvider
The WagmiProvider import comes from @privy-io/wagmi, not the standard wagmi package. This is required for Privy’s embedded wallet to work correctly with wagmi hooks.
Key config options:
  • embeddedWallets.createOnLogin: "users-without-wallets" — automatically creates an embedded wallet for users who sign in via email/social but don’t have an external wallet.
  • defaultChain / supportedChains — locks the app to Base Sepolia.

Inco SDK Integration

The Inco SDK works with the walletClient provided by wagmi (which Privy bridges through @privy-io/wagmi). Here’s the core pattern:
useConfLottery.ts
import { Lightning } from "@inco/js/lite";
import { handleTypes } from "@inco/js";
import { useAccount, useWalletClient, useWriteContract } from "wagmi";
import { parseEther } from "viem";

// Initialize Inco once
const zap = await Lightning.latest("testnet", 84532);

// Encrypt a value before sending on-chain
const { address } = useAccount();
const { data: walletClient } = useWalletClient();

async function deposit(amount: string) {
  const ciphertext = await zap.encrypt(parseEther(amount), {
    accountAddress: address,
    dappAddress: LOTTERY_ADDRESS,
    handleType: handleTypes.euint256,
  });

  const fee = await publicClient.readContract({
    address: zap.executorAddress,
    abi: getFeeAbi,
    functionName: "getFee",
  });

  writeContract({
    address: LOTTERY_ADDRESS,
    abi: confLotteryAbi,
    functionName: "deposit",
    args: [ciphertext],
    value: fee,
  });
}

// Decrypt with attestation
async function checkWinner() {
  const encryptedHandle = await publicClient.readContract({
    address: LOTTERY_ADDRESS,
    abi: confLotteryAbi,
    functionName: "getMyWinnerCheck",
    args: [currentRound],
    account: address,
  });

  const result = await zap.attestedDecrypt(walletClient, [encryptedHandle]);
  const isWinner = result[0].plaintext.value; // true or false
}
Whether the user connects with an external wallet or Privy’s embedded wallet, wagmi’s useWalletClient() provides the signer that Inco’s attestedDecrypt uses for signing attestation requests.

Dependencies

PackagePurpose
@privy-io/react-authPrivy authentication & wallet management
@privy-io/wagmiPrivy-wagmi bridge (custom WagmiProvider)
@inco/jsInco encryption/decryption
wagmiEVM wallet hooks
viemEthereum utilities