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

# useSellModal

> Hook for managing the sell modal interface for accepting offers on collectibles

## Import

```typescript theme={null}
import { useSellModal } from "@0xsequence/marketplace-sdk/react";
```

<img src="https://mintcdn.com/sequence-0fb8d9e6/D1_ntazyGvTWx9RJ/images/marketplace/sell_modal.png?fit=max&auto=format&n=D1_ntazyGvTWx9RJ&q=85&s=9458d269e8827b672369c453e8384800" alt="Sell Modal" width="4081" height="2024" data-path="images/marketplace/sell_modal.png" />

## Usage

The `useSellModal` hook provides a convenient way to manage the sell modal interface for accepting offers on collectibles. This modal is specifically used when a user wants to sell their collectible to an existing offer (bid) on the marketplace.

<Note>
  Make sure you have followed the [Getting
  Started](https://docs.sequence.xyz/sdk/web/marketplace-sdk/getting-started) guide
  to get the collection address and chainId.
</Note>

### Basic Example

<Note>
  This example uses the
  [`useBalanceOfCollectible`](/sdk/web/marketplace-sdk/hooks/marketplace-data/useBalanceOfCollectible)
  hook from marketplace-sdk to verify ownership before showing the sell modal.
</Note>

```typescript theme={null}
import {
  useSellModal,
  useBalanceOfCollectible,
  useListOffersForCollectible,
} from "@0xsequence/marketplace-sdk/react";
import { useAccount } from "wagmi";
import type { Address } from "viem";
import type { Order } from "@0xsequence/marketplace-sdk";

export default function SellToOfferExample() {
  const { address: accountAddress } = useAccount();
  const { data: marketplaceConfig, isLoading: isMarketplaceConfigLoading } =
    useMarketplaceConfig();

  const collection = marketplaceConfig?.market.collections[0];
  const chainId = collection?.chainId as number;
  const collectionAddress = collection?.itemsAddress as Address;
  // Replace with your collectible ID that has at least one offer
  const collectibleId = "0";

  // Check if user owns the collectible
  const {
    data: balance,
    isLoading: isLoadingBalance,
    isError: isErrorBalance,
  } = useBalanceOfCollectible({
    collectionAddress,
    collectableId: collectibleId,
    userAddress: accountAddress,
    chainId,
  });

  // Get available offers for this collectible
  const {
    data: offersData,
    isLoading: isLoadingOffers,
    error: offersError,
  } = useListOffersForCollectible({
    chainId,
    collectionAddress,
    collectibleId,
  });

  const { show: showSellModal } = useSellModal({
    onSuccess: ({ hash, orderId }) => {
      console.log("Sale completed successfully", { hash, orderId });
    },
    onError: (error) => {
      console.error("Sale failed:", error.message);
    },
  });

  const handleSellToOffer = (offer: Order) => {
    if (!balance || Number(balance) === 0) return;

    showSellModal({
      chainId,
      collectionAddress,
      tokenId: collectibleId,
      order: offer,
    });
  };

  const isOwner = balance && Number(balance) > 0;
  const isLoading = isLoadingBalance || isLoadingOffers;
  const hasError = isErrorBalance || offersError;
  const hasOffers = offersData?.orders && offersData.orders.length > 0;

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (hasError) {
    return <div>Error loading data</div>;
  }

  if (!isOwner) {
    return <div>You don't own this collectible</div>;
  }

  if (!hasOffers) {
    return <div>No offers available for this collectible</div>;
  }

  return (
    <div style={{ padding: "20px" }}>
      <h3>Available Offers</h3>
      <p>Collectible ID: {collectibleId}</p>
      <p>Your Balance: {balance}</p>

      <div style={{ marginTop: "16px" }}>
        {offersData.orders.map((offer) => (
          <div
            key={offer.orderId}
            style={{
              border: "1px solid #e0e0e0",
              borderRadius: "8px",
              padding: "16px",
              marginBottom: "12px",
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
            }}
          >
            <div>
              <p>
                Price: {offer.priceAmount} {offer.priceCurrency?.symbol}
              </p>
              <p>From: {offer.createdBy}</p>
              <p>
                Expires:{" "}
                {new Date(offer.validUntil * 1000).toLocaleDateString()}
              </p>
            </div>

            <button
              onClick={() => handleSellToOffer(offer)}
              style={{
                backgroundColor: "#28a745",
                color: "white",
                border: "none",
                padding: "8px 16px",
                borderRadius: "4px",
                cursor: "pointer",
              }}
            >
              Accept Offer
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}
```

## Parameters

The hook accepts an optional `callbacks` object with the following properties:

```typescript theme={null}
interface ModalCallbacks {
  onSuccess?: ({ hash, orderId }: { hash?: Hash; orderId?: string }) => void;
  onError?: (error: Error) => void;
  successActionButtons?: Array<{ label: string; action: () => void }>;
}
```

| Parameter                        | Type                                                             | Description                                                               |
| -------------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------- |
| `callbacks.onSuccess`            | `({ hash, orderId }: { hash?: Hash; orderId?: string }) => void` | Optional callback function called when the sale is completed successfully |
| `callbacks.onError`              | `(error: Error) => void`                                         | Optional callback function called when an error occurs during the sale    |
| `callbacks.successActionButtons` | `Array<{ label: string; action: () => void }>`                   | Optional array of action buttons to show on success                       |

## Return Type

The hook returns an object with the following methods:

```tsx theme={null}
{
  show: (args: ShowSellModalArgs) => void
  close: () => void
}
```

### Methods

#### show

`(args: ShowSellModalArgs) => void`

Opens the sell modal with the specified parameters to accept an offer.

```typescript theme={null}
interface ShowSellModalArgs {
  collectionAddress: Address;
  chainId: number;
  tokenId: string;
  order: Order;
}
```

| Parameter           | Type      | Required | Description                                                       |
| ------------------- | --------- | -------- | ----------------------------------------------------------------- |
| `collectionAddress` | `Address` | Yes      | The contract address of the collection                            |
| `chainId`           | `number`  | Yes      | The blockchain network ID (e.g., 1 for Ethereum, 137 for Polygon) |
| `tokenId`           | `string`  | Yes      | The collectible ID of the collectible being sold                  |
| `order`             | `Order`   | Yes      | The offer order object containing price, buyer, and other details |

#### close

`() => void`

Closes the sell modal.

## Notes

The `useSellModal` hook provides a convenient way to manage the sell modal interface for accepting offers on collectibles. It handles:

* Opening and closing the modal
* Managing the sale transaction flow state
* Token approval steps (if required)
* Transaction execution and signature steps
* Error handling and success callbacks
* Support for different marketplace types
* Integration with WaaS (Wallet as a Service) fee options

### Prerequisites

Before using this hook, ensure:

1. **User Authentication**: The user must be connected with a wallet
2. **Ownership Verification**: Use hooks like [`useBalanceOfCollectible`](/sdk/web/marketplace-sdk/hooks/marketplace-data/useBalanceOfCollectible) to verify the user owns the collectible
3. **Valid Offer**: Ensure there's a valid offer (Order object) to accept

### Related Hooks

* [`useBalanceOfCollectible`](/sdk/web/marketplace-sdk/hooks/marketplace-data/useBalanceOfCollectible) - Check ownership
* [`useListOffersForCollectible`](/sdk/web/marketplace-sdk/hooks/marketplace-data/useListOffersForCollectible) - Get available offers
