Skip to main content

Listings

A listing is an order (standard or cosigned) to sell an NFT once filled by a taker. Listings are gaslessly signed off-chain by the owner/seller of the NFT.

Notional Exchange Listing Flow​

  1. Maker browses their items and selects an item to list for sale.
  2. Maker inputs: Listing Currency/Payment Method, Price, Validity Time.
  3. Maker prompted to acknowledge/accept maker marketplace fee percentage and on-chain royalty fee (display sale price, fees, and net seller proceeds)
  4. Maker prompted to decide on standard order (on-chain cancellations) or co-signed order (gasless cancellation).
  5. Signature Prompt for SaleApproval signature.
  6. Order and signature submitted to order book.

Basic Sale Approval Signatures​

When listing an individual NFT for sale the seller/maker MUST be prompted by the exchange to sign an EIP-712 sale approval in the following format. If the order is a standard order cosigner MUST be set to address(0), for cosigned orders cosigner is set to the address that will cosign the order at time of fulfillment. The exchange MUST submit the signature and order data to an integrated order book via its API(s).

SaleApproval(
uint8 protocol,
address cosigner,
address seller,
address marketplace,
address fallbackRoyaltyRecipient,
address paymentMethod,
address tokenAddress,
uint256 tokenId,
uint256 amount,
uint256 itemPrice,
uint256 expiration,
uint256 marketplaceFeeNumerator,
uint256 maxRoyaltyFeeNumerator,
uint256 nonce,
uint256 masterNonce,
uint256 protocolFeeVersion
)

Typed data hash: 0x36e5aab0dde52c07206863cf8fe7b4b1a25be63a3ae5286f8fe80d159c154c4f

Advanced Sale Approval Signatures​

There are two types of advanced sale approvals: permits and bulk orders.

Permitted Sale Approval Signatures​

Instead of approving Payment Processor to transfer tokens, users can instead authorize Permit-C to transfer tokens and issue gasless permits allowing Payment Processor to transfer their NFTs instead. A permitted sale approval is a Permit-C transfer permit with the sale approval embedded and signed as a signle signature. The structure of the EIP-712 message for permitted sale approvals is shown below.

PermitTransferFromWithAdditionalData(
uint256 tokenType,
address token,
uint256 id,
uint256 amount,
uint256 nonce,
address operator,
uint256 expiration,
uint256 masterNonce,
SaleApproval approval
)
SaleApproval(
uint8 protocol,
address cosigner,
address seller,
address marketplace,
address fallbackRoyaltyRecipient,
address paymentMethod,
address tokenAddress,
uint256 tokenId,
uint256 amount,
uint256 itemPrice,
uint256 expiration,
uint256 marketplaceFeeNumerator,
uint256 maxRoyaltyFeeNumerator,
uint256 nonce,
uint256 masterNonce,
uint256 protocolFeeVersion
)

Typed data hash: 0xb1cb65a3e643070d9d33047fdfd384badc7cd70b2415e548b37db5a10c708716

Bulk Sale Approval Signatures​

For users seeking to list many items at once, users can sign a bulk sale approval order. Listings signed in bulk can be filled independently of the others. Up to 1024 items may be listed with one signature. Due to how EIP-712 struct hashing works, a nested array of [2] * treeHeight will produce the same hash as the root hash, provided it contains the same data and is padded with empty structs. Trees of depths 1 (2^1 = 2) to 10 (2^10 = 1024) are supported on Payment Processor.

Bulk Order Typehashes​

The Bulk Order Typehash Lookup tables are generated by concatenating the hashes from each height into one bytes array. This is decoded by taking the bytes32 output of the offset of height - 1 * 32.

// keccack256("BulkSaleApproval(SaleApproval[2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_1_HASH = 0x8659f55d4c88f84030fe09241169834754ebf2e61099b616e530c6b65712c644;

// keccack256("BulkSaleApproval(SaleApproval[2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_2_HASH = 0x5106f4043cda72e04ca2c760016628ea8d5667309323ba590682ea5254b4e82e;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_3_HASH = 0x71267a8f42e7ccde4ac75848a93b741df7a2f7a58e40274055f2fa51dbaa69ce;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_4_HASH = 0x6e90557aed2a349f8b6efb2b652c4025c56cfa82424c5cd0c6801cc234ebf519;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_5_HASH = 0xcaf42fc49ad57705ea6be2ca9e1835c9ccddf7bc6fdea8f851917329b1d53a7f;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_6_HASH = 0x09b32b6b5ffee898d5fe18398652042cc8c46449329c5a1a79e425f4ede9bc2b;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_7_HASH = 0xc2362dea3338b88607906397acfdcc5651f19b40a038ee7c89dc4ab54c736cac;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2][2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_8_HASH = 0xf2bbc4f6d7ccfa2b8aab6505f0c8f2868c5a190c6c4cfce8c0de447804904df9;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2][2][2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_9_HASH = 0x81f99e15003039550d3597e34e6426b1e230992a5a3727cb5e230754f18f3566;

// keccack256("BulkSaleApproval(SaleApproval[2][2][2][2][2][2][2][2][2][2] tree)SaleApproval(uint8 protocol,address cosigner,address seller,address marketplace,address fallbackRoyaltyRecipient,address paymentMethod,address tokenAddress,uint256 tokenId,uint256 amount,uint256 itemPrice,uint256 expiration,uint256 marketplaceFeeNumerator,uint256 maxRoyaltyFeeNumerator,uint256 nonce,uint256 masterNonce,uint256 protocolFeeVersion)")
bytes32 constant BULK_SALE_APPROVAL_HEIGHT_10_HASH = 0x012178d0a6b8f8748e48411572bdc391435539737aafc91fcba6f2c24ae156cf;

For more details on bulk order signing, see the Bulk Orders section of the docs.

Limit Break

TwitterLimitBreak.comMedium

© 2026 Limit Break International, Inc. All rights reserved.

Privacy PolicyTerms of ServiceCookie PolicyDo Not Sell My Info