> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cow.bleu.builders/llms.txt
> Use this file to discover all available pages before exploring further.

# Wagmi Integration

> Integrate the CoW Protocol SDK with Wagmi and Viem in React applications

# Wagmi Integration

This guide demonstrates how to integrate the CoW Protocol SDK with [Wagmi](https://wagmi.sh/) and [Viem](https://viem.sh/) for a production-ready React application with proper wallet management.

## Why Wagmi?

Wagmi provides:

* Easy wallet connection with multiple providers
* Automatic account and network management
* React hooks for blockchain interactions
* TypeScript support
* Better developer experience

## Installation

```bash theme={null}
npm install @cowprotocol/cow-sdk @cowprotocol/sdk-viem-adapter wagmi viem @tanstack/react-query
```

## Setup Wagmi

Configure Wagmi with your app settings:

```typescript theme={null}
import { http, createConfig } from 'wagmi'
import { mainnet, sepolia } from 'wagmi/chains'
import { injected, metaMask, safe, walletConnect } from 'wagmi/connectors'

const projectId = 'YOUR_WALLETCONNECT_PROJECT_ID'

export const config = createConfig({
  chains: [mainnet, sepolia],
  connectors: [
    injected(),
    walletConnect({ projectId }),
    metaMask(),
    safe(),
  ],
  transports: {
    [mainnet.id]: http(),
    [sepolia.id]: http(),
  },
})

declare module 'wagmi' {
  interface Register {
    config: typeof config
  }
}
```

## Setup CoW SDK

Create a Trading SDK instance:

```typescript theme={null}
import { SupportedChainId, TradingSdk } from '@cowprotocol/cow-sdk'

export const tradingSdk = new TradingSdk({
  chainId: SupportedChainId.MAINNET,
  appCode: 'MyWagmiApp',
})
```

## Bind SDK to Wagmi Hook

Create a custom hook to sync the SDK with Wagmi's wallet state:

```typescript theme={null}
import { useAccount, usePublicClient, useWalletClient } from 'wagmi'
import { useEffect, useState } from 'react'
import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
import { tradingSdk } from './cowSdk'
import { setGlobalAdapter } from '@cowprotocol/cow-sdk'

export function useBindCoWSdkToWagmi(): boolean {
  const account = useAccount()
  const { chainId } = account
  const { data: walletClient } = useWalletClient()
  const publicClient = usePublicClient()

  const [isSdkReady, setIsSdkReady] = useState(false)

  useEffect(() => {
    if (!walletClient || !chainId) {
      setIsSdkReady(false)
      return
    }

    setGlobalAdapter(
      new ViemAdapter({
        provider: publicClient,
        walletClient,
      })
    )

    tradingSdk.setTraderParams({ chainId })

    setIsSdkReady(true)

    return () => {
      setIsSdkReady(false)
    }
  }, [publicClient, walletClient, chainId])

  return isSdkReady
}
```

## Swap Component

Create a swap form that uses Wagmi hooks:

```tsx theme={null}
import {
  isSupportedChain,
  EVM_NATIVE_CURRENCY_ADDRESS,
  OrderKind,
  type QuoteAndPost,
  WRAPPED_NATIVE_CURRENCIES,
} from '@cowprotocol/cow-sdk'
import { useEffect, useState } from 'react'
import { tradingSdk } from './cowSdk'
import { useAccount } from 'wagmi'
import { formatUnits, parseUnits } from 'viem'

export function SwapForm({ isSdkReady }: { isSdkReady: boolean }) {
  const { address: account, chainId, status } = useAccount()

  const [sellAmount, setSellAmount] = useState('0.1')
  const [quoteAndPost, setQuoteAndPost] = useState<QuoteAndPost | null>(null)
  const [swapError, setSwapError] = useState<Error | null>(null)
  const [postedOrderHash, setPostedOrderHash] = useState<string | null>(null)
  const [isOrderPostingInProgress, setIsOrderPostingInProgress] = useState(false)
  const [slippagePercent, setSlippagePercent] = useState(0.5)

  const slippageBps = slippagePercent * 100
  const isLoading =
    isOrderPostingInProgress ||
    Boolean(account && sellAmount && !quoteAndPost)

  const WETH = chainId && isSupportedChain(chainId)
    ? WRAPPED_NATIVE_CURRENCIES[chainId]
    : null
  const USDC =
    chainId === 1
      ? {
          address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
          decimals: 6,
          symbol: 'USDC',
        }
      : chainId === 11155111
      ? {
          address: '0xbe72E441BF55620febc26715db68d3494213D8Cb',
          decimals: 18,
          symbol: 'USDC',
        }
      : null

  const postOrder = () => {
    if (!quoteAndPost) return

    setIsOrderPostingInProgress(true)

    quoteAndPost
      .postSwapOrderFromQuote({
        appData: {
          metadata: {
            quote: {
              slippageBips: slippageBps,
            },
          },
        },
      })
      .then((response) => {
        if (!response) {
          setSwapError(new Error('No response from order posting'))
          return
        }
        setPostedOrderHash(response.orderId)
      })
      .catch(setSwapError)
      .finally(() => {
        setIsOrderPostingInProgress(false)
      })
  }

  useEffect(() => {
    const sellAmountNum = Number(sellAmount)

    if (!isSdkReady) return
    if (!chainId || !account || Number.isNaN(sellAmountNum) || sellAmountNum <= 0) return
    if (!WETH || !USDC) return

    setQuoteAndPost(null)

    tradingSdk
      .getQuote({
        chainId,
        kind: OrderKind.SELL,
        owner: account,
        amount: parseUnits(sellAmount, WETH.decimals).toString(),
        sellToken: WETH.address,
        sellTokenDecimals: WETH.decimals,
        buyToken: USDC.address,
        buyTokenDecimals: USDC.decimals,
        slippageBps,
      })
      .then((quote) => {
        setQuoteAndPost(quote)
        setSwapError(null)
      })
      .catch(setSwapError)
  }, [slippageBps, sellAmount, chainId, account, isSdkReady])

  const buyAmountRaw = quoteAndPost?.quoteResults.amountsAndCosts.afterNetworkCosts.buyAmount
  const buyAmountView =
    buyAmountRaw && USDC
      ? Number(formatUnits(buyAmountRaw, USDC.decimals)).toFixed(6)
      : undefined

  if (status !== 'connected') {
    return (
      <div>
        <h3>Please connect your wallet</h3>
        <p>Wallet status: {status}</p>
      </div>
    )
  }

  return (
    <div>
      {postedOrderHash && (
        <div className="box success">
          <h4>Order has been posted!</h4>
          <p>
            <strong>Order UID:</strong>
            <br />
            <code>{postedOrderHash}</code>
          </p>
          <p>
            <a
              href={`https://explorer.cow.fi/orders/${postedOrderHash}`}
              target="_blank"
              rel="noopener noreferrer"
            >
              View in CoW Explorer
            </a>
          </p>
        </div>
      )}

      <div className="box">
        <strong>Sell</strong>
        <input
          type="number"
          value={sellAmount}
          onChange={(e) => setSellAmount(e.target.value)}
        />
        <span>{WETH?.symbol}</span>
      </div>

      <div className="box">
        <strong>Buy</strong>
        <input type="number" value={buyAmountView ?? 'Loading...'} disabled />
        <span>{USDC?.symbol}</span>
      </div>

      <div className="box">
        <label>Slippage:</label>
        <input
          type="number"
          value={slippagePercent}
          min={0}
          max={10}
          step={0.5}
          onChange={(e) => setSlippagePercent(+e.target.value)}
        />
        <span>%</span>
      </div>

      {swapError && (
        <div className="box error">
          {swapError.message || JSON.stringify(swapError)}
        </div>
      )}

      <button disabled={isLoading} onClick={postOrder}>
        {isOrderPostingInProgress ? 'Posting...' : 'Post order'}
      </button>
    </div>
  )
}
```

## Main App Component

```tsx theme={null}
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { WagmiProvider, useAccount } from 'wagmi'
import { config } from './wagmi'
import { SwapForm } from './components/SwapForm'
import { useBindCoWSdkToWagmi } from './hooks/useBindCoWSdkToWagmi'

const queryClient = new QueryClient()

function SwapApp() {
  const { address } = useAccount()
  const isSdkReady = useBindCoWSdkToWagmi()

  return (
    <div className="App">
      <h1>CoW Protocol Swap</h1>

      {address && (
        <div className="account">
          Connected: {address}
        </div>
      )}

      <SwapForm isSdkReady={isSdkReady} />
    </div>
  )
}

export default function App() {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <SwapApp />
      </QueryClientProvider>
    </WagmiProvider>
  )
}
```

## Main Entry Point

```tsx theme={null}
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
)
```

## Token Approval with Wagmi

Handle token approvals using the SDK:

```typescript theme={null}
import { tradingSdk } from './cowSdk'
import { parseUnits } from 'viem'

const [approvalTxHash, setApprovalTxHash] = useState<string | null>(null)

const approveToken = async () => {
  if (!sellToken || !chainId) return

  try {
    const amount = parseUnits(sellAmount, sellToken.decimals)
    const txHash = await tradingSdk.approveCowProtocol({
      tokenAddress: sellToken.address,
      amount,
      chainId,
    })

    setApprovalTxHash(txHash)
  } catch (err) {
    console.error('Approval failed:', err)
  }
}
```

## Key Benefits

1. **Automatic Network Switching**: Wagmi handles network changes automatically
2. **Multi-Wallet Support**: Users can connect with various wallets
3. **TypeScript Safety**: Full type safety with Viem
4. **React Query Integration**: Efficient data fetching and caching
5. **Better UX**: Professional wallet connection UI

## Connect Wallet Button

Add a proper wallet connection button:

```tsx theme={null}
import { useConnect, useDisconnect, useAccount } from 'wagmi'

function ConnectButton() {
  const { connect, connectors } = useConnect()
  const { disconnect } = useDisconnect()
  const { address, isConnected } = useAccount()

  if (isConnected) {
    return (
      <div>
        <span>{address}</span>
        <button onClick={() => disconnect()}>Disconnect</button>
      </div>
    )
  }

  return (
    <div>
      {connectors.map((connector) => (
        <button
          key={connector.id}
          onClick={() => connect({ connector })}
        >
          Connect {connector.name}
        </button>
      ))}
    </div>
  )
}
```

## Network Switching

Handle network switching gracefully:

```tsx theme={null}
import { useSwitchChain, useAccount } from 'wagmi'
import { SupportedChainId } from '@cowprotocol/cow-sdk'

function NetworkSwitcher() {
  const { chainId } = useAccount()
  const { switchChain } = useSwitchChain()

  const isSupportedNetwork =
    chainId === SupportedChainId.MAINNET ||
    chainId === SupportedChainId.SEPOLIA

  if (!isSupportedNetwork) {
    return (
      <div className="warning">
        <p>Please switch to a supported network</p>
        <button onClick={() => switchChain({ chainId: SupportedChainId.MAINNET })}>
          Switch to Mainnet
        </button>
      </div>
    )
  }

  return null
}
```

## Next Steps

* Learn about [Node.js usage](/cow-sdk/examples/nodejs-usage)
* Explore [limit orders](/cow-sdk/examples/limit-orders)
* Read the [Trading SDK documentation](/cow-sdk/api/trading-sdk)
