Skip to main content

Create orders - bulk listings

This page shows how to enable a user to list multiple NFTs for sale on the orderbook witha single signature.


Creating bulk listings

The orderbook SDK allows you to create multiple listings with a single EIP712 message signature. This is useful for improving the user experience for marketplace users by increasing liquidity, and allowing sellers to list their assets faster and more efficiently. The fee and token details associated with creating bulk listings is the same as creating individual listings, so the details are not repeated here. Please also note that the following approach can be used for both individual and multiple listings. The maximum number of listings that can be created at once is 20.

The call to prepareBulkListings returns actions, and a scoped completeListings method that is used to submit the users signature to the orderbook API. Actions for preparing bulk listings include both transaction and signable action types. The details of these actions are as follows:

  • APPROVAL transactions - An approval transaction is required per collection when the user has not yet approved the seaport contract for each collection they are creating a listing for.
  • CREATE_LISTING signable message - This signable message is used to create the orders on the Immutable order book.
import { orderbook } from '@imtbl/sdk';
import { Wallet } from 'ethers'; // ethers v5

const createBulkListings = async (
client: orderbook.Orderbook,
signer: Wallet,
): Promise<orderbook.BulkListingsResult> => {
const offerer = await signer.getAddress();

const { actions, completeListings } = await client.prepareBulkListings({
makerAddress: offerer,
listingParams: [
// Listing #1
{
// native payment token
buy: {
amount: '1000000',
type: 'NATIVE',
},
// ERC721 sell token
sell: {
contractAddress: '0x300516606a8100342f6d45b24b8af8c4191cb195',
tokenId: '1',
type: 'ERC721',
},
makerFees: [
{
amount: '1000',
recipientAddress: '0xMarketplaceFeeCollectionAddress',
}
],
},
// Listing #2
{
// ERC20 payment token
buy: {
amount: '2000000',
type: 'ERC20',
contractAddress: '0x5b0516606a8100342f6d45b24b8af8c4191cb172',
},
// ERC721 sell token
sell: {
contractAddress: '0x300516606a8100342f6d45b24b8af8c4191cb195',
tokenId: '2',
type: 'ERC721',
},
makerFees: [
{
amount: '2000',
recipientAddress: '0xMarketplaceFeeCollectionAddress',
}
],
},
// Listing #3
{
// native payment token
buy: {
amount: '1000000',
type: 'NATIVE',
},
// ERC1155 sell token
sell: {
contractAddress: '0x300516606a8100342f6d45b24b8af8c4191cb195',
tokenId: '1',
type: 'ERC1155',
amount: '10'
},
makerFees: [
{
amount: '1000',
recipientAddress: '0xMarketplaceFeeCollectionAddress',
}
],
},
]
});

let bulkListingsSignature = ''
for (const action of actions) {
// If the user hasn't yet approved the Immutable Seaport contract to transfer assets from this
// collection on their behalf they'll need to do so before they create the listings
if (action.type === orderbook.ActionType.TRANSACTION) {
const builtTx = await action.buildTransaction()
console.log(`Submitting ${action.purpose} transaction`)
await signer.sendTransaction(builtTx);
}

// For listings to be created (and subsequently filled), Immutable needs a valid signature for the bulk order data.
if (action.type === orderbook.ActionType.SIGNABLE) {
bulkListingsSignature = await signer._signTypedData(
action.message.domain,
action.message.types,
action.message.value,
)
}
}

// Now pass the bulk listing signature to the scoped completeListings method,
// which is responsible for submitting the bulk listings information and signature to the orderbook
return completeListings(bulkListingsSignature);
};