Ranked auctions
A ranked auction is a sealed-bid auction that runs fully on-chain. Bidders submit over the sale window; when the sale ends, the top maxTotal bids win. Optional: rebates, so all winners pay the same clearing price.
Ranked auctions are on-chain only — there’s no gated variant. They’re supported for LimitedEdition, standard Series, and Limited GenerativeSeries. See the support matrix for exact combinations.
Configuration
Section titled “Configuration”const sale = (await client.collection.addSale({ highlightId, type: "RANKED_AUCTION", accessMode: "PUBLIC", startAt: new Date().toISOString(), endAt: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(), price: "0.01", // reserve price, used for on-chain min currency: "ETH", maxPerTransaction: 1, maxPerWallet: 5, maxTotal: 100, // winners count paymentRecipient: creatorAddress, typeConfig: { reserveBidAmount: "0.01", rebateWinningBids: true, },})).data!;typeConfig fields:
reserveBidAmount— minimum bid, as a decimal string of the currency’s major unit (e.g."0.01"ETH).rebateWinningBids— whentrue, all winners pay the clearing price (lowest winning bid); higher bids are rebated.
Bidding (three steps)
Section titled “Bidding (three steps)”Each bid is a three-step flow: build, submit on-chain, confirm with the backend.
// 1. Build the bid transactionconst bid = (await client.collection.bidSale({ highlightId, saleId: sale.id, bidAmount: "0.05",})).data!;// bid is { chainId, to, data, value } — a flat contract-execution shape.
// 2. Submit it on-chainconst bidHash = await walletClient.sendTransaction({ to: (bid.to ?? undefined) as `0x${string}` | undefined, data: bid.data as `0x${string}`, value: BigInt(bid.value ?? "0"),});await publicClient.waitForTransactionReceipt({ hash: bidHash });
// 3. Tell the backend about the confirmed bid so it appears in auction stateawait client.collection.confirmBid({ highlightId, saleId: sale.id, txHash: bidHash,});confirmBid is called after every bid (not at auction-end). It records the on-chain bid in the backend’s ranked-auction ledger so it shows up in collection/sale reads and is eligible to win.
To update an existing bid, include the bidId emitted by the on-chain bid event. The bidId isn’t in the bidSale SDK response — it’s in the EditionEdgeRankedAuctionBid log on the receipt of the first bid transaction. Read it from the receipt, persist it client-side, then pass it back:
await client.collection.bidSale({ highlightId, saleId: sale.id, bidAmount: "0.06", bidId: existingBidIdFromReceipt,});Claiming after the auction ends
Section titled “Claiming after the auction ends”Once endAt passes, winning bidders claim their tokens via claimSale — the same call used for fixed-price and Dutch auctions:
const claim = (await client.collection.claimSale({ highlightId, saleId: sale.id, amount: 1,})).data!;
const claimHash = await walletClient.sendTransaction({ to: (claim.to ?? undefined) as `0x${string}` | undefined, data: claim.data as `0x${string}`, value: BigInt(claim.value ?? "0"), gas: 500_000n,});The backend verifies the caller is on the winning ledger, builds a claim against the mechanic contract, and (if rebateWinningBids) issues the rebate in the same transaction.
Calling claimSale before endAt on a ranked auction returns AuctionNotEndedError (400).
Ranked auction state
Section titled “Ranked auction state”The indexer tracks bids in real time. You can observe state via the collection get call — the sale object includes the current high bid and validity hash for the auction’s bid tree.
For server-side code that needs to react to bids, the packages/highlight backend maintains per-chain indexer DOs that watch RankedAuction events. You don’t call the indexer directly; you just poll client.collection.get at whatever cadence your UI needs.
Failure modes
Section titled “Failure modes”| Error | When |
|---|---|
SaleTypeNotSupportedError (400) | Ranked auction on an unsupported collection (open editions, 1-of-1, collectors-choice series, open generative) |
InvalidTypeConfigError (400) | Missing reserveBidAmount or rebateWinningBids |
AuctionNotEndedError (400) | claimSale called before endAt on a ranked-auction sale |
NoValidBidsError (400) | Caller has no valid winning bids when trying to claim |
| Ranked + Gated | Rejected at validation — 400 with a schema error |
Related
Section titled “Related”- Sale types concepts — ranked auction overview
- Support matrix — exact valid combinations
- Sales reference — full sale API surface
- Errors: sale errors — typed failures