Fill orders
This page demonstrates how an order can be filled. For fulfillment to occur, the user must have sufficient funds to cover the asking price of the order.
Immutable provides two distinct types of orders:
- Listings: These are orders initiated by an NFT owner who intends to sell their asset on a marketplace. Listings are considered sell orders.
- Bids: Representing a prospective buyer's intention to acquire an asset, bids allow users to express their interest in purchasing a specific asset. Users can place a bid on the order book, anticipating a match with a seller. Bids are considered buy orders.
Get, sign and send transactions for fulfillment
This call returns actions that are required to fulfill an order. For fulfillment all actions are transaction actions and include a type and builder method that can be used to generate the raw transaction for submission. The purpose of these transactions are as follows:
APPROVAL
- An approval transaction is required to be submitted before the fulfillment transaction if spending an ERC20 token and the seaport contract does not yet have the required allowance.FULFILL_ORDER
- The fulfillment transaction to be submitted to fulfill the order.
The taker
below is any ethers
compatible Signer
or Wallet
instance for the user creating the listing.
When a marketplace submits a fulfill order request, they could include a takerFees
field as demonstrated in the code block below. This fee should be represented as the net amount that the marketplace wishes to receive for the services provided, and it should be quoted in the same ERC20 (or native) token in which the order is listed.
The fulfillOrder
call also returns the expiry for the transactions (if an user submits a transaction after the expiration it will fail on chain) and the order
entity with confirmed fee information.
Please be advised that all fees and quantities within our system are denoted in the smallest unit of the respective currency, and decimal representations are not supported.
For instance, IMX, which has 18 decimal places, will have a fee of 0.000000000000000001 IMX represented as "1".
Similarly, 1 IMX is represented as "1000000000000000000" in our system.
Select the tabs below to learn about filling ERC721 and ERC1155 listings:
- ERC721 fulfillment
- ERC1155 fulfillment
// Fulfill ERC721 listing
const fulfillERC721Listing = async (listingID: string) => {
const { actions } = await orderbookSDK.fulfillOrder(
listingID,
accountsState[0],
takerEcosystemFeeRecipient != "" ? [{
recipientAddress: takerEcosystemFeeRecipient, // Replace address with your own marketplace address
amount: takerEcosystemFeeAmount, // Insert taker ecosystem/marketplace fee here
}] : [],
);
for (const action of actions) {
if (action.type === orderbook.ActionType.TRANSACTION) {
const builtTx = await action.buildTransaction();
await (await signer.sendTransaction(builtTx)).wait(1);
}
}
};
The fulfillment transaction is now processed. You can poll Get orders for the off-chain representation of the order.
The order will asynchronously transition to FILLED
once on-chain events have been registered by Immutable services.
As shown below, the fill_status
field in the response of the Get orders endpoint will have the numerator
and denominator
values equal to 1
to indicate that the order has been fully filled.
{
"fill_status":{
"numerator": "1",
"denominator": "1"
}
For further details on order fill status, see the following product guide
It is possible to partially fill ERC1155 orders and if only a portion of the order is to be filled (partial fill scenario), an optional amountToFill
parameter is used to specific the quantity of tokens to be filled.
If the amountToFill
parameter is not specified for ERC1155 orders, the entire order will be filled.
If an order is attempted to be filled beyond the available quantity a best effort
fulfillment is attempted where the order is filled up to the available quantity.
If fulfilling an ERC1155 order, the taker fee amount
should be a multiple of the sell token amount. For example, if the original listing is selling 5
tokens, the taker fee amount should be a multiple of 5
so 5, 10, 15, etc.
The taker fee amount should reflect the complete view of the order and should not be scaled down in the case of a partial fill.
For example, if the original listing is selling 5
tokens at 100
IMX each and the taker fee is 1%
(i.e., 1
IMX per token), the taker fee amount on all fills (partial or full) should be 5
IMX. The orderbook will pro-rate the fee for the marketplace based on the quantity executed.
// Fulfill ERC1155 listing
const fulfillERC1155Listing = async (
listingID: string,
unitsToFill?: string, // Number of units to fill
) => {
const { actions } = await orderbookSDK.fulfillOrder(
listingID,
accountsState[0],
takerEcosystemFeeRecipient != "" ? [{
recipientAddress: takerEcosystemFeeRecipient, // Replace address with your own marketplace address
amount: takerEcosystemFeeAmount, // Insert taker ecosystem/marketplace fee here
}] : [],
unitsToFill,
);
for (const action of actions) {
if (action.type === orderbook.ActionType.TRANSACTION) {
const builtTx = await action.buildTransaction();
await (await signer.sendTransaction(builtTx)).wait(1);
}
}
};
The fulfillment transaction is now processed. You can poll Get orders for the off-chain representation of the order.
The order will asynchronously transition to FILLED
if the order was fully filled and once on-chain events have been registered by Immutable services. If however, the order was only partially filled the order will stay in the ACTIVE
state.
The fill_status
field in the response of the Get orders endpoint will indicate the ratio of the order that is currently filled. If the order has been fully filled, the numerator
and denominator
values will be equal.
For instance, the below snipped would indicate that 50% of the order has been filled.
{
"fill_status":{
"numerator": "1",
"denominator": "2"
}
For further details on order fill status, see the following product guide