Gated sales
Gated sales restrict minting to wallets that satisfy a gate. A gate is a reusable bundle of conditions; attach it to a sale by setting accessMode: "GATED" and gateId.
Unlike public sales, gated sales have no on-chain vector. The backend signs each claim with the platform executor key; collectors submit the signed claim to the chain. This is why gated sales can be added to Live collections — they don’t need an on-chain vector registration.
When to use gated
Section titled “When to use gated”| Goal | Use |
|---|---|
| Allowlist of specific addresses | ALLOWLIST condition |
| Holder-only early access | TOKEN_OWNERSHIP condition |
| Attribute-based (e.g. holders of “Gold” traits) | TOKEN_ATTRIBUTE condition |
| Requires minimum ETH/ERC20 balance | CURRENCY_BALANCE condition |
| Farcaster-based access | FARCASTER_FOLLOW condition |
Combine conditions with matchMode: "ALL" (all must pass) or "ANY" (one must pass).
Ranked auctions cannot be gated. The platform rejects that combination at validation time.
1. Create a gate
Section titled “1. Create a gate”Gates are owned by an account and reusable across many sales.
const gate = (await client.gate.create({ name: "Allowlist + Holders", matchMode: "ANY", conditions: [ { type: "ALLOWLIST", config: { addresses: [ "0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222", ], }, }, { type: "TOKEN_OWNERSHIP", config: { contractAddress: "0xYourPreviousCollection", chainId: 8453, minAmount: 1, }, }, ],})).data!;
const gateId = gate.id;All on-chain conditions (TOKEN_OWNERSHIP, SPECIFIC_TOKEN, TOKEN_ATTRIBUTE, CURRENCY_BALANCE) require a chainId. The gate evaluator reads state on that chain at claim time.
2. Attach the gate to a sale
Section titled “2. Attach the gate to a sale”await client.collection.addSale({ highlightId, type: "FIXED_PRICE", accessMode: "GATED", gateId, startAt: new Date().toISOString(), price: "0.005", currency: "ETH", maxPerTransaction: 1, maxPerWallet: 2, maxTotal: 500, paymentRecipient: creatorAddress, // gasSponsored: true — REJECTED for gated sales});Gated sales can be added to draft or live collections. Either way, the sale is immediately usable — there’s no on-chain registration step.
3. Collector claim (gated)
Section titled “3. Collector claim (gated)”The claim shape is identical to a public sale. The backend decides whether to return a public-vector claim or an executor-signed claim based on the sale’s access mode — the collector doesn’t care.
const claim = (await client.collection.claimSale({ highlightId, saleId: gatedSale.id, amount: 1,})).data!;If the caller’s wallet doesn’t satisfy the gate, the call returns SaleGateCheckFailedError (403) and the payload lists which condition failed.
Submit the returned transaction. The claim shape is flat — { chainId, to, data, value }:
const hash = 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,});On-chain, the mint is authorized by the executor signature embedded in claim.data. The platform contracts verify the signature and the single-use nonce.
4. Gated + choose-token (Series)
Section titled “4. Gated + choose-token (Series)”For Series collections, collectors can pick specific token IDs. Pass tokenIds alongside amount:
const claim = (await client.collection.claimSale({ highlightId, saleId: chooseTokenSale.id, amount: 3, tokenIds: [7, 42, 101],})).data!;The support matrix dictates which mint method backs the call — see support matrix: series.
5. Listing & updating a gate
Section titled “5. Listing & updating a gate”const gates = (await client.gate.list()).data!;const detail = (await client.gate.get({ gateId })).data!;
// Replace conditions wholesale — partial updates are not supportedawait client.gate.update({ gateId, name: "Updated gate", matchMode: "ALL", conditions: [ { type: "ALLOWLIST", config: { addresses: ["0x..."] } }, ],});
await client.gate.remove({ gateId });A gate currently attached to any live sale cannot be deleted — detach first (delete the sale or replace the gate by re-adding the sale).
Constraints
Section titled “Constraints”- A gated sale requires
gateId. - A public sale must not have a
gateId. RANKED_AUCTION+GATEDis rejected.gasSponsored: trueis rejected on gated sales (gas sponsorship requires a public on-chain vector).- Gate condition evaluation happens at claim time, not sale creation. If a collector’s balance drops after you add them via an allowlist, a token-ownership condition they relied on could fail.
Related
Section titled “Related”- Gates concepts — higher-level overview
- Sales reference — all sale configuration options
- Errors: gates and sales — typed failures
- Support matrix — what combinations are valid