> For the complete documentation index, see [llms.txt](https://docs.seismic.systems/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.seismic.systems/clients/typescript/react/examples/basic-dapp.md).

# Basic dApp

This example builds a complete minimal dApp that connects a wallet, sends a shielded write transaction, and performs a signed read -- all using seismic-react hooks.

## What You'll Build

1. **Provider setup** with RainbowKit + Seismic
2. **Wallet connection** via RainbowKit's `ConnectButton`
3. **Shielded write** to a contract (encrypted calldata)
4. **Signed read** from a contract (authenticated query)

## Prerequisites

* Node.js 18+
* A [WalletConnect](https://cloud.walletconnect.com/) project ID

Install dependencies:

```bash
npm install seismic-react seismic-viem wagmi viem @rainbow-me/rainbowkit @tanstack/react-query
```

## Step 1: wagmi Config

Create the wagmi configuration with the Seismic testnet chain:

```typescript
// config.ts
import { getDefaultConfig } from "@rainbow-me/rainbowkit";
import { seismicTestnet } from "seismic-react/rainbowkit";

export const config = getDefaultConfig({
  appName: "Seismic Basic dApp",
  projectId: "YOUR_WALLETCONNECT_PROJECT_ID",
  chains: [seismicTestnet],
});
```

{% hint style="warning" %}
Replace `YOUR_WALLETCONNECT_PROJECT_ID` with your actual project ID from [WalletConnect Cloud](https://cloud.walletconnect.com/).
{% endhint %}

## Step 2: Provider Wrapper

Wrap your app with the required providers. `ShieldedWalletProvider` must be nested inside the wagmi and React Query providers:

```typescript
// providers.tsx
'use client'

import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ShieldedWalletProvider } from 'seismic-react'
import { config } from './config'
import '@rainbow-me/rainbowkit/styles.css'

const queryClient = new QueryClient()

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider>
          <ShieldedWalletProvider config={config}>
            {children}
          </ShieldedWalletProvider>
        </RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  )
}
```

## Step 3: Contract Interaction Component

Create a component that uses `useShieldedWriteContract` and `useSignedReadContract` to interact with a shielded counter contract:

```typescript
// ShieldedCounter.tsx
'use client'

import { useShieldedWriteContract, useSignedReadContract } from 'seismic-react'
import { useState } from 'react'

const CONTRACT_ADDRESS = '0x...' as const
const ABI = [
  {
    name: 'increment',
    type: 'function',
    stateMutability: 'nonpayable',
    inputs: [],
    outputs: [],
  },
  {
    name: 'getCount',
    type: 'function',
    stateMutability: 'view',
    inputs: [],
    outputs: [{ name: '', type: 'uint256' }],
  },
] as const

export function ShieldedCounter() {
  const [count, setCount] = useState<string | null>(null)

  const { writeContract, isLoading: isWriting, hash, error: writeError } = useShieldedWriteContract({
    address: CONTRACT_ADDRESS,
    abi: ABI,
    functionName: 'increment',
  })

  const { signedRead, isLoading: isReading, error: readError } = useSignedReadContract({
    address: CONTRACT_ADDRESS,
    abi: ABI,
    functionName: 'getCount',
  })

  const handleIncrement = async () => {
    try {
      await writeContract()
    } catch (err) {
      console.error('Shielded write failed:', err)
    }
  }

  const handleRead = async () => {
    try {
      const result = await signedRead()
      setCount(result?.toString() ?? 'unknown')
    } catch (err) {
      console.error('Signed read failed:', err)
    }
  }

  return (
    <div>
      <h2>Shielded Counter</h2>

      <button onClick={handleIncrement} disabled={isWriting}>
        {isWriting ? 'Sending...' : 'Increment (Shielded Write)'}
      </button>
      {hash && <p>Tx hash: {hash}</p>}
      {writeError && <p>Write error: {writeError.message}</p>}

      <button onClick={handleRead} disabled={isReading}>
        {isReading ? 'Reading...' : 'Get Count (Signed Read)'}
      </button>
      {count !== null && <p>Count: {count}</p>}
      {readError && <p>Read error: {readError.message}</p>}
    </div>
  )
}
```

{% hint style="info" %}
Replace `CONTRACT_ADDRESS` with the address of a deployed shielded contract on Seismic testnet. The ABI above is for a simple counter -- adapt it to match your contract.
{% endhint %}

## Step 4: App Component

Combine the wallet connection button with the counter component. The counter only renders once the shielded wallet is ready:

```typescript
// App.tsx
import { ConnectButton } from '@rainbow-me/rainbowkit'
import { useShieldedWallet } from 'seismic-react'
import { ShieldedCounter } from './ShieldedCounter'

export function App() {
  const { loaded, error } = useShieldedWallet()

  return (
    <div>
      <h1>Seismic Basic dApp</h1>
      <ConnectButton />

      {error && <p>Wallet error: {error}</p>}
      {loaded ? (
        <ShieldedCounter />
      ) : (
        <p>Connect your wallet to interact with shielded contracts.</p>
      )}
    </div>
  )
}
```

## What's Happening

1. **RainbowKit** handles wallet connection and chain switching
2. **ShieldedWalletProvider** automatically creates shielded clients when a wallet connects, performing the ECDH key exchange with the TEE
3. **useShieldedWriteContract** encrypts calldata before sending the transaction, ensuring on-chain privacy
4. **useSignedReadContract** attaches a signature proving caller identity, allowing the contract to return private data only to authorized readers

```
User connects wallet
        |
        v
ShieldedWalletProvider creates shielded clients (ECDH with TEE)
        |
        v
useShieldedWriteContract    useSignedReadContract
  - encrypts calldata         - signs the read request
  - sends TxSeismic           - node verifies identity
  - returns tx hash           - returns decrypted result
```

## Next Steps

* [Hooks Reference](/clients/typescript/react/hooks.md) - Full API for all hooks
* [Wallet Guides](/clients/typescript/react/wallet-guides.md) - Use AppKit or Privy instead of RainbowKit
* [Chains](/clients/typescript/react/chains.md) - Configure Seismic testnet or local Sanvil

## See Also

* [ShieldedWalletProvider](/clients/typescript/react/shielded-wallet-provider.md) - Provider configuration options
* [useShieldedWriteContract](/clients/typescript/react/hooks/useshieldedwrite.md) - Shielded write hook API
* [useSignedReadContract](/clients/typescript/react/hooks/useshieldedread.md) - Signed read hook API
* [Installation](/clients/typescript/react/installation.md) - Full dependency setup


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.seismic.systems/clients/typescript/react/examples/basic-dapp.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
