Filling Orders
Filling A Single Listing (Buy Now)
- Taker browses listings and chooses a listed item.
- Taker selects "Buy Now".
- Taker selects beneficiary (whether self or other account).
- Taker prompted to review the details, including review and acknowledgement of fee on top when applicable.
- If listing order was co-signed, client requests a co-signature for the listing.
- Marketplace calls the PaymentProcessorEncoder
encodeBuyListingCalldatafunction to generate the calldata to fill the order. Encoding Details - Wallet pops up a transaction confirmation of the
buyListingcall. Usage Details - Taker confirms the transaction through their wallet interface.
Filling A Batch Of Listings (Shopping Cart)
- Taker browses listings and chooses several listed items (they may be from one or more collections).
- Taker selects "Add To Shopping Cart" for each item.
- Taker reviews cart and "Checks Out".
- Taker selects beneficiary (whether self or other account).
- Taker prompted to review the details, including review and acknowledgement of all fees on top when applicable.
- For any co-signed listing orders, client requests co-signatures.
- Marketplace calls the PaymentProcessorEncoder
encodeBulkBuyListingsCalldatafunction to generate the calldata to bulk fill the orders. Encoding Details - Wallet pops up a transaction confirmation of the
bulkBuyListingscall. Usage Details - Taker confirms the transaction through their wallet interface.
Filling A Batch of Listings (Collection Sweep)
- Taker chooses "Sweep Collection" for the desired collection.
- Taker specifies desired quantity and maximum price per item.
- Taker selects beneficiary (whether self or other account).
- Order book supplies listings that are the best matches.
- Taker prompted to review the details, including review and acknowledgement of the fee on top when applicable.
- For any co-signed listing orders, client requests co-signatures.
- Marketplace calls the PaymentProcessorEncoder
encodeSweepCollectionCalldatafunction to generate the calldata to fill the sweep. Encoding Details - Wallet pops up a transaction confirmation of the
sweepCollectioncall. Usage Details - Taker confirms the transaction through their wallet interface.
Filling A Single Offer (Accept Offer)
- Taker browser offers where the offer criteria matches items they own and chooses one.
- Taker selects "Accept Offer".
- Taker prompted to review the details, including review and acknowledgement of the current on-chain royalty fee, maker marketplace fee, and fee on top when applicable.
- If the offer order was co-signed, client requests a co-signature for the offer.
- Marketplace calls the PaymentProcessorEncoder
encodeAcceptOfferCalldatafunction to generate the calldata to fill the order. Encoding Details - Wallet pops up a transaction confirmation of the
acceptOffercall. Usage Details - Taker confirms the transaction through their wallet interface.
Filling A Batch Of Offers (Offer Cart)
- Taker browser offers where the offer criteria matches items they own and chooses several.
- Taker selects "Add To Offer Cart" for each item.
- Taker reviews cart and "Checks Out".
- Taker prompted to review the details, including review and acknowledgement of the current on-chain royalty fees for each item, the maker marketplace fees for each item, and the fees on top when applicable.
- For any co-signed offer orders, client requests co-signatures.
- Marketplace calls the PaymentProcessorEncoder
encodeBulkAcceptOffersCalldatafunction to generate the calldata to bulk fill the orders. Encoding Details - Wallet pops up a transaction confirmation of the
bulkAcceptOfferscall. Usage Details - Taker confirms the transaction through their wallet interface.
Note: There are other steps marketplaces may need to implement to prompt users in the workflow. For instance: approving Payment Processor to transfer NFTs and ERC-20 payments, prompting to wrap native currency or swap currencies when needed, or prompting buyers to perform a one-time signature to prove they are EOAs [for select ERC721-C security levels only].
Taker Operations / Functions
Buy Listing
Exchanges should call buyListing when a taker wants to purchase a single listing using a UX analogous to "Buy Now".
There are four order types that may be filled through the buyListing function:
Standard Sell Order Without Fee On Top - To be used when the taker fills a standard sell order and the maker and taker marketplace is the same, or when the taker marketplace does not include a fee on top. For this type of order execution the cosignature and feeOnTop struct parameters passed to PaymentProcessorEncoder would be filled with zero values.
Standard Sell Order With Fee On Top - To be used when the taker fills a standard sell order via a secondary marketplace. While the maker marketplace can assess a primary fee that is deducted from the seller's proceeds, the taker marketplace may assess an extra fee on top paid by the taker in excess of the item purchase price. For this type of order execution the cosignature struct parameter passed to PaymentProcessorEncoder would be filled with zero values and the feeOnTop struct parameter would contain the recipient and amount for the fee being added by the taker marketplace.
Cosigned Sell Order Without Fee On Top - To be used when the taker fills a co-signed sell order and the maker and taker marketplace is the same, or when the taker marketplace does not include a fee on top. For this type of order execution the feeOnTop struct parameter passed to PaymentProcessorEncoder would be filled with zero values and the cosignature struct parameter would contain the signer, taker, expiration and cosignature v, r and s values for the cosignature.
Cosigned Sell Order With Fee On Top - To be used when the taker fills a co-signed sell order via a secondary marketplace. While the maker marketplace can assess a primary fee that is deducted from the seller's proceeds, the taker marketplace may assess an extra fee on top paid by the taker in excess of the item purchase price. For this type of order execution both the feeOnTop and cosignature struct parameters passed to PaymentProcessorEncoder would contain the values for the additional fee on top and cosignature validation.
Use the PaymentProcessorEncoder to encode the calldata(./calldata-encoding#encodebuylistingcalldata).
Note: The taker/buyer (msg.sender) pays for the item and any fee on top when applicable. Because the buyListing function is payable, both native or ERC-20 payment methods are accepted.
Advanced Buy Listing
Advanced orders include 2 additional features, Permits and executing listings / offers which were generated via the Bulk Order merkle root. These orders can include any combination of the above 4 types, but are separated to prevent extra gas costs for standard orders.
Permit Order - To be used when the maker generated the signature including the Permit Processor field. This will include the Permit Processor required data as well as advanced data which will need to match the order that is being fulfilled.
Bulk Order - To be used when the maker generated the signature via signing a merkle tree. The BulkOrderProof must include the correct merkle proof and the correct index of the listing in order to process correctly.
Accept Offer
Exchanges should call acceptOffer when a taker wants to sell a single item that matches an offer made by a prospective buyer. The kinds of offers are currently supported by Payment Processor:
- Item Offer - An offer made on a specific collection where only one specific token id can be used to fill the order.
- Collection Offer - An offer made on a specific collection where any token id can be used to fill the order.
- Token Set Offer - An offer made on a specific collection where any token id contained in a specified subset of token ids can be used to fill the order.
There are four order types that may be filled through the acceptOffer function:
Standard Offer Without Fee On Top - To be used when the taker fills a standard buy order (offer) and the maker and taker marketplace is the same, or when the taker marketplace does not include a fee on top. For this type of order execution the cosignature and feeOnTop struct parameters passed to PaymentProcessorEncoder would be filled with zero values.
Standard Offer With Fee On Top - To be used when the taker fills a standard buy order (offer) via a secondary marketplace. While the maker marketplace can assess a primary fee that is deducted from the seller's proceeds, the taker marketplace may assess an extra fee on top paid by the taker in excess of the item purchase price. For this type of order execution the cosignature struct parameter passed to PaymentProcessorEncoder would be filled with zero values and the feeOnTop struct parameter would contain the recipient and amount for the fee being added by the taker marketplace.
Cosigned Offer Without Fee On Top - To be used when the taker fills a co-signed buy order (offer) and the maker and taker marketplace is the same, or when the taker marketplace does not include a fee on top. For this type of order execution the feeOnTop struct parameter passed to PaymentProcessorEncoder would be filled with zero values and the cosignature struct parameter would contain the signer, taker, expiration and cosignature v, r and s values for the cosignature.
Cosigned Offer With Fee On Top - To be used when the taker fills a co-signed buy order (offer) via a secondary marketplace. While the maker marketplace can assess a primary fee that is deducted from the seller's proceeds, the taker marketplace may assess an extra fee on top paid by the taker in excess of the item purchase price. For this type of order execution both the feeOnTop and cosignature struct parameters passed to PaymentProcessorEncoder would contain the values for the additional fee on top and cosignature validation.
Note: The taker/seller (msg.sender) pays for the fee on top when applicable. The maker/buyer pays the cost of the filled item. Because the acceptOffer function is not payable, only ERC-20 payment methods are accepted.
Bulk Buy Listings
Exchanges should call bulkBuyListings when a taker wants to purchase more than one listing using a UX analagous to a "Shopping Cart". This allows a taker to select many NFTs across different collections or with varying payment methods and fill all of the listings at once.
Each listing being purchased may be any of the four transaction types supported by the buyListing function (see Buy Listing above). When encoding bulk purchases the Order, SignatureECDSA, Cosignature and FeeOnTop struct values are passed as arrays of values where the item at the same index in each array corresponds to the listing being purchased. All four arrays MUST be of equal length and follow the same structure as a single listing purchase for standard versus cosigned orders and execution with or without a fee on top.
Bulk Accept Offers
Exchanges should call bulkAcceptOffers when a taker wants to accept/fill more than one offer at once. This allows a taker to sell multiple items they own across one or more collections in a single transaction. The kinds of offers are currently supported by Payment Processor:
- Item Offer - An offer made on a specific collection where only one specific token id can be used to fill the order.
- Collection Offer - An offer made on a specific collection where any token id can be used to fill the order.
- Token Set Offer - An offer made on a specific collection where any token id contained in a specified subset of token ids can be used to fill the order.
Each offer being accepted may be any of the four transaction types supported by the acceptOffer function (see Accept Offer above). When encoding bulk accept offers the offerType enumerated value and Order, SignatureECDSA, TokenSetProof, Cosignature and FeeOnTop struct values are passed as arrays of values where the item at the same index in each array corresponds to the offer being accepted. All six arrays MUST be of equal length and follow the same structure as a single offer acceptance for standard versus cosigned orders and execution with or without a fee on top.
Sweep Collection
Exchanges should call sweepCollection (a more gas efficient form of bulkBuyListings) when a taker wants to purchase more than similar listings. A common UX is the "Collection Sweep" UX where the taker specifies a number of items from a collection they want to buy, with some pricing limits.
For a sweep to be filled, all items in the sweep order must share the following commonalities:
- All sell orders fillable in the sweep must be from the same collection.
- All sell orders fillable in the sweep must use the same method of payment.
- All sell orders fillable in the sweep must specify the same beneficiary of the NFT.
When filling sweep orders, the following fields can be different for each filled item:
- Maker
- Marketplace
- Fallback Royalty Recipient
- Token Id
- Amount
- Item Price
- Nonce (for standard orders)
- Expiration
- Marketplace Fee Numerator
- Max Royalty Fee Numerator
Sweep orders may be executed with or without a single fee on top for the sweep. To execute with a fee on top the feeOnTop struct value passed to PaymentProcessorEncoder would contain the recipient and amount for the fee. To execute without a fee on top the feeOnTop struct value passed to PaymentProcessorEncoder would contain zero values for recipient and amount.
When encoding sweep orders with PaymentProcessorEncoder the SweepItem, SignatureECDSA and Cosignature structs are passed as arrays of values where the item at the same index in each array corresponds to the listing being purchased. All three arrays MUST be of equal length and follow the same structure as a single listing purchase for standard versus cosigned orders.
Note: The taker/buyer (msg.sender) pays for the items and any fee on top when applicable. Because the sweepCollection function is payable, both native or ERC-20 payment methods are accepted.
Note: For the most gas-efficient collection sweeps, marketplaces should make a best effort to group orders in the array by marketplace address, seller, and royalty recipient.
Cosignature Format
All cosigned listings and offers require a secondary signature to be provided at fill-time/execution time. The same cosignature format applies to all cosigned maker signatures, and takes a cosigner expiration and the maker's signature v, r, s components as typed data inputs. Note: for security purposes, co-signatures must always be signed by EOA co-signers. Furthermore, cosignature expiration times should be relatively short. A cosignature expiration time between 5 and 10 minutes is suggested. If the expiration time is too short, transactions may fail because the expiration time elapses before a transaction has been confirmed. However, if the expiration time is too long a leak of the co-signature could be executed well into the future.
Cosignature(
uint8 v,
bytes32 r,
bytes32 s,
uint256 expiration,
address taker
)
