Edit a Listing

Prerequisites ⚙️

Install and configure ReservoirKit.

EditListingModal

ReservoirKit provides a simple to configure modal for editing oracle listings in your react app. Below is an example of a simple EditListingModal setup.

It is important to note that you can only edit oracle powered listings

import { EditListingModal } from '@reservoir0x/reservoir-kit-ui'

<EditListingModal
	trigger={
  	<button>
      Edit Listing
    </button>
  }
  listingId="0x99e3ad649dbd9ae2f1a3c9f1331d69021a61ff9a15e1a50550b548c2d502ff05"
	collectionId="0x21227ea09f9e7ec425f59cea621debb52de8bee9"  
  tokenId="1"
  onEditListingComplete={(data: any) => {
		console.log('Listing updated', data)
  }}
  onEditListingError={(error: any, data: any) => {
  	console.log('Edit Listing Error', error, data)
  }}
  onClose={() => {
  	console.log('EditListingModal Closed')
  }}
/>

Let's dive into the parameters. You'll need to provide an element to trigger the modal, this can be any valid html element. Next you'll want to provide a listingId,collectionId and a tokenId. These can be set to undefined until the data is ready.

You can also set some optional parameters:

PropDescription
normalizeRoyaltiesUse this to ensure that royalties are added to the stats and market pricing information. If unspecified then the global setting will be used if provided.
openStateThis is a state tuple from react's useState, you can use this to programmatically open or close the modal. The modal will use this state when determining if the modal is open or closed.

Finally you can set some optional callbacks:

onEditListingComplete: Triggered when editing the listing was completed successfully, returns some useful data about the listing and the cancel step.

onEditListingError: Triggered when editing the listing resulted in an error, returns the error and the listing data.

onClose: Triggered when the modal was closed. Returns some useful data about the listing as well as the step data and the current step.

Conditional Rendering

ReservoirKit's EditListingModal doesn't take care of conditionally showing the button/modal based on if the listing is editable by the user, we leave that logic up to the developer. Below are the requirements for editing a listing and how to go about getting that data:

  • The user needs to have a connected wallet. You can check this by looking for a signer from the useSigner wagmi hook.
  • The user must be the maker of the listing, you can check this by comparing maker in the listing object to the connected wallet address. You can get a full list of a wallet's listings by using the useListings hook or the underlying api.
  • The listing must be an oracle powered listing. You can check this by verifying that the listing kind returned from the useListings hook is of type seaport-v1.4. You also need to verify that the listing's order zone is included in this list of zone addresses. You can get this info by adding the includeRawData flag to the the useListings hook or the underlying api.

Custom EditListingModal

The EditListingModal also comes with a custom renderer which can be used to just get the data layer that the EditListingModal uses internally to handle the underlying business logic. With the renderer you can rebuild the UI completely to your liking. Below is an example of how it works in practice.

import { EditListingModal, EditListingStep } from '@reservoir0x/reservoir-kit-ui'

<EditListingModal.Custom
  listingId="0x99e3ad649dbd9ae2f1a3c9f1331d69021a61ff9a15e1a50550b548c2d502ff05"
	collectionId="0x21227ea09f9e7ec425f59cea621debb52de8bee9"  
  tokenId="1"
>
    {({
        loading,
        listing,
        token,
        price,
        currency,
        isOracleOrder,
        quantityAvailable,
        collection,
        quantity,
        expirationOption,
        expirationOptions,
        editListingStep,
        transactionError,
        usdPrice,
        totalUsd,
        royaltyBps,
        stepData,
        setPrice,
        setQuantity,
        setExpirationOption,
        editListing,
      }) => {
        { Your Custom React Elements }
    })}
</EditListingModal.Custom>

The custom EditListingModal takes a few parameters like before with one additional one being the open parameter. This is because there is no trigger, you have control over what sort of modal you want this to eventually live in and how to trigger that modal. You'll have the ability to add a custom button with a custom handler, etc. The custom EditListingModal then passes some key data into the children which we parse above and use in our custom UI. It's also important to note the EditListingStep here which is used to manage the internal state of the EditListingModal's logic. You can decide to use all or some of the data passed into your custom implementation.