Wallet Setup

How we setup our appchain wallet to make it frictionless for end users

Adrift uses embedded wallets powered by Para to make onboarding and gameplay frictionless. Users can sign in instantly, no browser extensions or seed phrases required, and interact with the appchain as their wallet becomes both their identity and signature for all onchain actions.

This guide explains how Adrift implements this flow and how you can build a similar wallet UX for your own appchain projects.

Onboarding Flow

  • Provider Setup:

    • The app is wrapped in a ParaProvider (from @getpara/react-sdk), which manages wallet state and connection.
    • The provider is configured for the Pacifica appchain and customized for Adrift's branding.
  • Connect Button:

    • The ConnectWallet component displays a "Sign In" button if the user is not connected, or their address if they are.
    • Clicking the button opens the Para modal for onboarding (embedded wallet creation or connection).
  • User Experience:

    • Users can onboard with a few clicks—no seed phrase or extension required.
    • The wallet is embedded and managed by Para, but can be exported or connected to external wallets if needed.
// Example: ParaProvider setup
<ParaProviderBase
  config={{ appName: "Adrift" }}
  externalWalletConfig={{ wallets: [], evmConnector: { config: { chains: [pacifica], ssr: true } } }}
  paraClientConfig={{ apiKey: process.env.NEXT_PUBLIC_PARA_API_KEY, env }}
  paraModalConfig={{ /* ...branding and UX options... */ }}
>
  {children}
</ParaProviderBase>

Wallet as Identity

  • Identity:

    • Each user is assigned an EVM-compatible address upon onboarding.
    • This address is used as their unique identity in the game and for all appchain interactions.
    • The app uses hooks like useAccount, useWallet, and useMe to access the current user's wallet and player data.
  • Player Data:

    • The wallet address is used to fetch and store player state (e.g., check-ins, status, winner/disqualified, etc).
// Example: Accessing the current user's wallet
const { embedded } = useAccount()
const { data: wallet } = useWallet()
const me = useMe() // gets player data for wallet address

Transaction Signing & Appchain Actions

  • Transaction Flow:

    • When a user performs an action (e.g., "Check In"), the app uses the Para wallet to sign and send a transaction to the appchain.
    • The app uses the viem library (via Para's integration) to create a wallet client for signing.
  • Signing Example:

    • The app checks the wallet's balance, estimates gas, and sends the transaction using the embedded wallet.
    • After sending, it polls for transaction confirmation and updates the UI.
// Example: Signing and sending a transaction
const { viemClient } = useViemClient({ walletClientConfig: { chain: pacifica, transport: http() } })
const tx = await viemClient.writeContract({
  address: gameData.address,
  abi: [parseAbiItem("function checkIn()")],
  functionName: "checkIn",
  chain: pacifica,
  account: viemClient.account,
  gas: gas * BigInt(2)
})

Key Files & Components in Adrift

By following this pattern, you can build a seamless wallet UX for your own appchain projects, making onboarding and onchain actions as easy as possible for your users.

On this page