Skip to main content

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.

If your project already has a user base (players with progress, collectors with NFTs, customers with purchase history), those users have everything tied to their personal wallets. Inside a Mini App, the connected wallet is a brand-new smart account. This walkthrough uses sdk.context.startale.eoaWallets to bridge the gap.

What you’ll build

Inside your Mini App:
  1. Read the user’s verified linked EOAs from the host context.
  2. Check whether any of them holds a specific NFT.
  3. Unlock content (or prompt the user to take an action) based on that check.

Prerequisites

The Mini App sandbox does not simulate eoaWallets. Test this flow against staging or the production Startale App.

Steps

1. Read linked EOAs

import { useEffect, useState } from 'react'
import { sdk } from '@farcaster/miniapp-sdk'

const [eoas, setEoas] = useState<string[]>([])

useEffect(() => {
  void sdk.context.then((ctx) => {
    setEoas(ctx.startale?.eoaWallets ?? [])
  })
}, [])

2. Check NFT ownership across all linked EOAs

import { createPublicClient, erc721Abi, http } from 'viem'
import { soneium } from 'viem/chains'

const NFT_CONTRACT = '0xLegacyNftContract...' as const

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

async function holdsLegacyNft(addresses: string[]) {
  for (const address of addresses) {
    const balance = await publicClient.readContract({
      address: NFT_CONTRACT,
      abi: erc721Abi,
      functionName: 'balanceOf',
      args: [address as `0x${string}`],
    })
    if (balance > 0n) return true
  }
  return false
}

3. Render gated content

const [hasNft, setHasNft] = useState<boolean | null>(null)

useEffect(() => {
  if (eoas.length === 0) {
    setHasNft(false)
    return
  }
  void holdsLegacyNft(eoas).then(setHasNft)
}, [eoas])

if (hasNft === null) return <Spinner />

return hasNft
  ? <PremiumContent />
  : <PromptToLinkEoa />

4. Handle the “no linked EOA” case

If eoaWallets is empty, the user has not linked an EOA to their Startale account. Prompt them to do so, but the actual linking happens outside the Mini App, in the Startale App’s settings.
function PromptToLinkEoa() {
  return (
    <div>
      <p>Want to access your existing collection? Link your wallet in the Startale App settings.</p>
      <a href="https://app.startale.com/settings/wallets">Open settings</a>
    </div>
  )
}

Important constraints

  • You can only read from a linked EOA inside a Mini App. You cannot sign or send transactions from it. See Wallet integration.
  • Each address in eoaWallets is verified server-side via SIWE. Treat them as cryptographically owned: they are safe to use for eligibility checks, identity matching, and analytics.

What you’ve learned

  • That eoaWallets is the canonical bridge between a user’s legacy identity and their new Startale smart account.
  • How to do read-only contract calls against linked EOAs inside a Mini App.
  • That EOA linking itself happens outside the Mini App, your job is to detect and react.