Create orders - bulk listings
This page shows how to enable a user to list multiple NFTs for sale on the orderbook.
Creating bulk listings
The orderbook SDK allows you to create multiple listings with a single EIP712 message signature when using an externally owned address (EOA) for instance using Metamask. 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(s) 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 listing 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',
}
],
},
]
});
// Multiple signatures are required when using a Smart contract wallet like Passport
let bulkListingsSignatures: string[] = [];
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) {
bulkListingsSignatures.push(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(bulkListingsSignatures);
};