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.

This guide integrates the Startale App SDK into a React project. By the end you will have an application that:
  • Connects to a user’s Startale smart account through wagmi.
  • Produces an ERC-1271 signature and verifies it offchain with viem.
  • Sends a transaction packaged as an ERC-4337 UserOperation on Soneium Mainnet.
The reference stack is Vite + React 18 with wagmi 2, viem 2, and TanStack Query. The same code paths apply in Next.js. See SDK installation for framework variants.

Prerequisites

RequirementVersion
Node.js20 or later
Package managerpnpm 9, npm, yarn, or bun
React projectScaffold one below if you do not already have one
If you do not have a React project, scaffold one with Vite:
pnpm create vite@latest startale-quickstart --template react-ts
cd startale-quickstart
pnpm install
1

Install the SDK

Install @startale/app-sdk with its peer dependencies.
pnpm add @startale/app-sdk wagmi viem @tanstack/react-query
Each package has a specific role in the integration:
  • @startale/app-sdk exposes the Startale connector and the underlying EIP-1193 provider.
  • wagmi provides the React hooks, useAccount, useConnect, useSendTransaction, that drive the integration.
  • viem is the typed RPC client wagmi uses for read and write operations.
  • @tanstack/react-query caches asynchronous state, including the connector’s readiness and the smart-account address resolution.
The SDK ships with a wagmi connector by default. To use the SDK without wagmi, see Initialization.
2

Configure the wagmi client

Create src/wagmi.ts. This file declares the supported chain, registers the Startale connector, and configures an HTTP transport.
src/wagmi.ts
import { startaleConnector } from '@startale/app-sdk'
import { http, createConfig } from 'wagmi'
import { soneium } from 'wagmi/chains'

export const config = createConfig({
  chains: [soneium],
  connectors: [
    startaleConnector({
      appName: 'Startale Quickstart',
      appLogoUrl: 'https://your-app.com/logo.png',
    }),
  ],
  transports: {
    [soneium.id]: http(),
  },
})

declare module 'wagmi' {
  interface Register {
    config: typeof config
  }
}
createConfig returns a typed wagmi configuration. The chains field declares which chains the application supports, and the connector derives its appChainIds from this list automatically.startaleConnector accepts a preference object. appName and appLogoUrl appear inside the Startale App popup so the user can identify the requesting application. Use a short name and a square HTTPS image URL.http() with no argument routes to the default public RPC for the chain. Production traffic should use a dedicated endpoint. See Networks for the current options.The declare module 'wagmi' block registers this configuration as the active one for type inference. Without it, hooks like useAccount cannot infer chain-aware return types in your application code.
Add soneiumMinato to the chains array when you need a testing flow. See Networks for the testnet endpoints.
3

Wrap the application

Wrap the application in WagmiProvider and QueryClientProvider in src/main.tsx. Both providers are required. WagmiProvider exposes the config and connection state to wagmi hooks. QueryClientProvider backs the React Query cache that wagmi uses internally for asynchronous state.
src/main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './wagmi'
import { App } from './App'

const queryClient = new QueryClient()

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <App />
      </QueryClientProvider>
    </WagmiProvider>
  </StrictMode>,
)
4

Connect a wallet

Add a button that triggers the Startale connector. The example uses three wagmi hooks: useAccount reads the current connection state, useConnect exposes the registered connectors and a connect action, and useDisconnect clears the local connection.
src/App.tsx
import { useAccount, useConnect, useDisconnect } from 'wagmi'

export function App() {
  const { address, status } = useAccount()
  const { connect, connectors } = useConnect()
  const { disconnect } = useDisconnect()
  const startale = connectors[0]

  if (status === 'connected') {
    return (
      <div>
        <p>Connected as {address}</p>
        <button onClick={() => disconnect()}>Disconnect</button>
      </div>
    )
  }

  return (
    <button onClick={() => connect({ connector: startale })}>
      Connect Startale
    </button>
  )
}
connectors[0] returns the Startale connector because it is the only one registered in wagmi.ts. When multiple connectors are configured, identify Startale by connector.id === 'startaleApp' rather than relying on array position.Run the dev server:
pnpm dev
Click the button. A popup opens to app.startale.com. The user signs in with Google, LINE, Apple, or MetaMask, approves the connection, and the popup closes. The application receives the user’s smart-account address in address.
The address returned is a smart account, not an externally owned account. The same address resolves on every application that integrates the Startale App SDK.
5

Sign a message

Produce an ERC-1271 signature with useSignMessage. Smart accounts do not sign with a private key in the standard ECDSA path. Signatures are produced through the account contract and verified by calling isValidSignature on the same contract.
import { useAccount, useSignMessage } from 'wagmi'

export function SignButton() {
  const { address } = useAccount()
  const { signMessageAsync } = useSignMessage()

  if (!address) return null

  const onClick = async () => {
    const signature = await signMessageAsync({
      message: 'I am verifying ownership of my Startale wallet.',
    })
    console.log({ address, signature })
  }

  return <button onClick={onClick}>Sign message</button>
}
Verify the signature offchain with viem’s verifyMessage:
import { createPublicClient, http } from 'viem'
import { soneium } from 'viem/chains'

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

const isValid = await publicClient.verifyMessage({
  address,
  message: 'I am verifying ownership of my Startale wallet.',
  signature,
})
verifyMessage calls isValidSignature on the smart-account contract. The same code path verifies signatures whether the account is deployed or counterfactual. See Smart accounts for the ERC-6492 wrapping behavior.
ERC-1271 verification is a contract call and requires a publicClient configured against the same chain as the signing account. When the verifier runs on different infrastructure, use the same chain identifier on both sides.
6

Send a transaction

The application calls useSendTransaction exactly as it would with any wagmi-compatible wallet. The SDK transforms the request into an ERC-4337 UserOperation, attaches a paymaster signature if one is configured, and submits the operation through the bundler. The user signs in the popup.
import { useSendTransaction } from 'wagmi'

export function SendButton() {
  const { sendTransactionAsync, isPending } = useSendTransaction()

  const onClick = async () => {
    const hash = await sendTransactionAsync({
      to: '0x000000000000000000000000000000000000dEaD',
      value: 0n,
    })
    console.log({ hash })
  }

  return (
    <button onClick={onClick} disabled={isPending}>
      {isPending ? 'Sending...' : 'Send transaction'}
    </button>
  )
}
A popup opens with the transaction details. The user reviews and approves; the application receives a transaction hash that resolves to a confirmed UserOperation onchain.
Who pays the gas? Inside the Startale App (Mini Apps), the host paymaster sponsors gas automatically. Standalone dapps configure a paymaster through paymasterOptions; without one, the user pays gas from their smart account’s ETH balance. See Gas sponsorship for the full model.
The integration is complete: connect, sign, send. Every signature verifies through ERC-1271, and the same code runs on Soneium Minato.

Next steps

Configure a paymaster

Wire an SCS paymaster or your own ERC-7677 service into the SDK.

Charge in USDSC

Standard ERC-20 transfers in the Startale stablecoin.

Sign typed data

EIP-712 for orders, permits, and consent flows.

Build a Mini App

Run the project inside the Startale App with access to host context.

Handle errors

User rejections, chain mismatches, wrong calls and popup blockers.