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

# SwapWidget Integration

> Integrate Pods SwapWidget for same-chain and cross-chain swaps

Use `SwapWidget` to ship same-chain and cross-chain swap UX quickly while your host app still owns signing and transaction submission.

## Install

Use the same package set and the same `DeframeProvider` wrapper as `EarnWidget`:

```bash theme={null}
pnpm add pods-sdk@0.2.87 @deframe-sdk/components@0.1.91 @reduxjs/toolkit@^2 react-redux@^9 redux@^5
```

<Note>
  Use the Pods Wallet-style swap view by overriding `SwapFormView` with `PodsSwapFormView`. Import `DeframeProvider`, `EarnWidget`, and `SwapWidget` from `pods-sdk` so the widgets share the same React context.
</Note>

## Styles and Theme

`SwapWidget` follows the same styling model as `EarnWidget`:

* Import `@deframe-sdk/components/styles.css` once in the host app entrypoint.
* Keep host CSS scoped and avoid global resets leaking into `.deframe-widget`.
* Configure branding through `DeframeProvider.config.theme`.
* Use `.deframe-widget` CSS variables only from a wrapper you own.

See [EarnWidget Styles and Theme](/widgets/earn-widget#styles-and-theme) for the full CSS example.

## Render SwapWidget

Mount `SwapWidget` inside the shared `DeframeProvider` wrapper from the Earn guide.

```tsx theme={null}
'use client'

import { SwapWidget } from 'pods-sdk'
import { DeframeWidgetProvider } from './DeframeWidgetProvider'

export function SwapPage({
  walletAddress,
  userId,
}: {
  walletAddress: string
  userId?: string
}) {
  return (
    <DeframeWidgetProvider walletAddress={walletAddress} userId={userId}>
      <div className="deframe-widget-slot" data-testid="swap-widget-container">
        <SwapWidget autoHeight />
      </div>
    </DeframeWidgetProvider>
  )
}
```

## Use the Pods Wallet Swap View

Register `PodsSwapFormView` at the provider level so every `SwapWidget` renders the Pods Wallet-style view: title and subtitle, history action, two token amount cards, the centered direction button, and the primary action button state.

```tsx theme={null}
'use client'

import { useMemo, type ReactNode } from 'react'
import { PodsSwapFormView } from '@deframe-sdk/components'
import { DeframeProvider } from 'pods-sdk'
import { processBytecode } from './processBytecode'

type DeframeWidgetProviderProps = {
  children: ReactNode
  walletAddress?: string
  userId?: string
}

export function DeframeWidgetProvider({
  children,
  walletAddress,
  userId,
}: DeframeWidgetProviderProps) {
  const podsApiUrl = process.env.NEXT_PUBLIC_PODS_API_URL
  const podsApiKey = process.env.NEXT_PUBLIC_PODS_API_KEY
  const podsWebSocketUrl = process.env.NEXT_PUBLIC_PODS_WEBSOCKET_URL

  const config = useMemo(() => ({
    // pods-sdk@0.2.87 still expects these provider field names.
    DEFRAME_API_URL: podsApiUrl,
    DEFRAME_API_KEY: podsApiKey,
    DEFRAME_WEBSOCKET_URL: podsWebSocketUrl,
    walletAddress,
    userId,
    enableCrossChainInvestments: true,
    components: {
      SwapFormView: PodsSwapFormView,
    },
  }), [podsApiKey, podsApiUrl, podsWebSocketUrl, walletAddress, userId])

  return (
    <DeframeProvider config={config} processBytecode={processBytecode}>
      {children}
    </DeframeProvider>
  )
}
```

Keep this override in the wrapper that owns `DeframeProvider`, not on each swap page. The page still renders the SDK widget normally with `<SwapWidget />`; the provider decides which swap form view is used.

## Prefill Token/Chain Params

You can initialize swap inputs from host route or query params. This is the pattern to use when another widget or dashboard card sends the user into swap with a target token already selected.

```tsx theme={null}
'use client'

import { Suspense, useMemo } from 'react'
import { useSearchParams } from 'next/navigation'
import { SwapWidget } from 'pods-sdk'
import { DeframeWidgetProvider } from './DeframeWidgetProvider'

function readNumberParam(params: URLSearchParams, key: string): number | undefined {
  const value = params.get(key)
  if (!value) return undefined

  const parsed = Number(value)
  return Number.isFinite(parsed) ? parsed : undefined
}

function SwapContent({
  walletAddress,
  userId,
}: {
  walletAddress: string
  userId?: string
}) {
  const params = useSearchParams()

  const fromTokenAddress = params.get('fromTokenAddress') ?? undefined
  const fromChainId = readNumberParam(params, 'fromChainId')
  const toTokenAddress = params.get('toTokenAddress') ?? undefined
  const toChainId = readNumberParam(params, 'toChainId')

  const widgetProps = useMemo(() => ({
    autoHeight: true,
    fromTokenAddress,
    fromChainId,
    toTokenAddress,
    toChainId,
  }), [fromTokenAddress, fromChainId, toTokenAddress, toChainId])

  const widgetKey = [
    fromTokenAddress,
    fromChainId,
    toTokenAddress,
    toChainId,
  ].join('-')

  return (
    <DeframeWidgetProvider walletAddress={walletAddress} userId={userId}>
      <div className="deframe-widget-slot" data-testid="swap-page">
        <SwapWidget key={widgetKey} {...widgetProps} />
      </div>
    </DeframeWidgetProvider>
  )
}

export function SwapPageWithPrefill({
  walletAddress,
  userId,
}: {
  walletAddress: string
  userId?: string
}) {
  return (
    <Suspense fallback={<div className="deframe-widget-slot">Loading swap...</div>}>
      <SwapContent walletAddress={walletAddress} userId={userId} />
    </Suspense>
  )
}
```

## `SwapWidget` Props

```ts theme={null}
type SwapWidgetProps = {
  className?: string
  style?: React.CSSProperties
  height?: string | number
  enableScroll?: boolean
  autoHeight?: boolean
  fromTokenAddress?: string
  fromChainId?: number
  toTokenAddress?: string
  toChainId?: number
}
```

## API Endpoints Used in Swap Flows

* `GET /v2/swap/quote` to request same-chain/cross-chain quotes
* `POST /v2/swap/bytecode` to build executable transaction payloads
* `GET /v2/swap/status/{id}` to track cross-chain swap lifecycle

Guides:

* [Get Quote](/guides/swaps/get-quote)
* [Execute Swap](/guides/swaps/execute-swap)

## Cross-chain Lifecycle Recommendations

1. Generate quote and bytecode.
2. Execute all returned bytecodes in order through `processBytecode`.
3. Persist `quoteId` and `clientTxId` in your backend.
4. Poll the swap status endpoint until the flow reaches a terminal state.
5. Display status history in customer support/admin surfaces.

## Transaction Bridge

`SwapWidget` uses the same `processBytecode` contract as `EarnWidget`.

See [processBytecode Contract](/widgets/process-bytecode) for required status emissions and error mapping.
