Skip to main content

Collections — Sales

Dashboard

When your collection has any of the "Sales" features you will be able to manage the parameters or read the status via Dashboard, or React hooks below.

Dashboard Public Sale Widget

Tutorials

Here is step-by-step tutorial on how to launch an NFT sales:

SDK Examples

Here are few ready-made examples on Github for you to get straight into the code:

Pre-built Pages

Minting page

Use link below to provide a sales minting page to your collectors.

https://app.flair.finance/public/mint/PUT_CHAIN_ID_HERE/PUT_CONTRACT_ADDRESS_HERE

Example minting page: https://app.flair.finance/public/mint/137/0xecb1788fa81221cd69b2ad2757981ddbb8786043





Import as iframe widget

Use iframe snippet below to render this sales minting page as a widget.

<iframe
src="https://app.flair.finance/public/mint/PUT_CHAIN_ID_HERE/PUT_CONTRACT_ADDRESS_HERE"
frameborder="0"
width="800px"
height="800px"
allowtransparency="true"
/>

Customization

If you like to customize each component you can try React components and hooks below.

React Components

Here is a list of un-styled React components you can use to customize:

NameDescriptionUsage
<CollectionProvider chainId={number} contractAddress={string} />Provides a context for an NFT collection components. This required.Example
<CollectionSalesMintingProvider/>Provides a context when minting NFTs for sales.Example
<CollectionTitle/>Prints collection title.Example
<CollectionSalesPrice/>Prints pre-sale or public-sale price depending on which one is active.Example
<CollectionSupplyCounter/>Prints current supply and max total supply like 14 / 8000.Example
<CollectionSalesActiveStatus/>Prints status of NFT sales, which is either active or not active yet, or sold out.Example
<CollectionSalesAllowlistStatus/>Shows if the current wallet is allow-listed or not.Example
<CollectionImage/>Renders collection image configured on the contractExample
<CollectionSalesMintInput mintCount={number} setMintCount={function) />An equipped number input that accepts number of tokens to mint, it applies min/max based on configured per-wallet and per-transaction limits.Example
<CollectionSalesMintButton mintCount={number} />A mint button that accepts a number and mints the NFTs accordingly. This component is best used together with ConnectButton and SwitchChainButtonExample
<CollectionSalesMintingSection/>A full blown opinionated pre-built minting widget, you can import without any config.Example

All components are easy to import and use:

import {
CollectionProvider,
CollectionSalesMintingSection,
CollectionTitle,
CollectionSalesPrice,
CollectionSupplyCounter,
CollectionSalesActiveStatus,
CollectionSalesAllowlistStatus,
CollectionSalesMintInput,
ConnectButton,
SwitchChainButton,
CollectionSalesMintButton,
DisconnectButton,
} from "flair-sdk";
import { useState } from "react";
import { BigNumberish } from 'ethers';

const COLLECTION_CHAIN_ID = "137";
const COLLECTION_CONTRACT_ADDRESS =
"0xecb1788fa81221cd69b2ad2757981ddbb8786043";

function App() {
const [mintCount, setMintCount] = useState<BigNumberish>("1");

return (
<div className="flex min-h-screen items-center justify-center">
<CollectionProvider
chainId={Number(COLLECTION_CHAIN_ID)}
contractAddress={COLLECTION_CONTRACT_ADDRESS}
>
// Render a full styled minting widget
<CollectionSalesMintingSection />

//
// OR, use custom components:
//
<CollectionTitle />
<CollectionSalesPrice />
<CollectionSupplyCounter />
<CollectionSalesActiveStatus />
<CollectionSalesAllowlistStatus />
<CollectionSalesMintInput
mintCount={mintCount}
setMintCount={setMintCount}
/>

<ConnectButton>
<SwitchChainButton requiredChainId={Number(COLLECTION_CHAIN_ID)}>
{/* Mint button */}
<CollectionSalesMintButton mintCount={mintCount} />
</SwitchChainButton>
</ConnectButton>

<DisconnectButton className="mt-4 text-sm text-indigo-700" />

// for list of all components, see:
// https://github.com/0xflair/examples/blob/main/react/custom-nft-minting-sales/src/App.tsx
</CollectionProvider>
</div>
);
}

export default App;

React Hooks

Require Sales Extensions

All hooks defined below require the corresponding Solidity extension (e.g. ERC721PublicSaleExtension.sol, ERC721PreSaleExtension.sol), which is already included in ready-made presets.

useSaleMinter

This hooks consolidates simple sale and tiered sales features, so you have a simple interface to interact with your collection. This hook provides you with status of sale, price, allowlist status for the connected wallet, and a single "mint" method to call that will call currently active tier (pre-sale, public sale, or your customer tiers).

Recommended

It is recommended to use this hook as it consolidates majority of the information in 1 interface. Other hooks described on this page are more specific, which would be unnecessary for majority of the cases.

import { useAccount } from "wagmi";
import { useSaleMinter, CryptoValue, TransactionLink } from "flair-sdk";

const App = () => {
const { data: account } = useAccount();

const {
data: {
txReceipt,
txResponse,
start,
end,
price,
hasAllowlist,
isActive,
isAllowlisted,
isEligible,
eligibleAmount,
},
error: mintError,
isLoading: mintLoading,
mint,
} = useSaleMinter({
chainId: 1,
contractAddress: "0x12341234123412341234123412341234",
minterAddress: account?.address,
mintCount: 4,
tierId: 0, // For pre-sale use 0, for public-sale use 1, for customer tiers use their id #
});

return (
<>
<div>
Sale status: {isActive ? "Is active" : "Not yet active"}
</div>
<div>
Price:{" "}
<CryptoValue
symbol={"ETH"}
value={price}
unit={CryptoUnits.WEI}
/>
</div>
<div>
Allowlisted?:{" "}
{isAllowlisted ? "Allowlisted" : "Not allowlisted"}
</div>
<div>
Transaction:
{txReceipt || txResponse ? (
<TransactionLink txReceipt={txReceipt} txResponse={txResponse} />
) : null}
</div>
<div>
Mint now:
<button onClick={() => mint()}>Mint 4x</button>
<button onClick={() => mint({ mintCount: 7 })}>Mint 7x</button>
</div>
</>
);
};

Additional hooks

You can also use the low-level sales-related React hooks exported from Flair SDK (Typescript):

  • usePreSaleAllowlistChecker
  • usePreSaleAllowlistMerkleRoot
  • usePreSaleMaxMintPerWallet
  • usePreSaleMinter
  • usePreSalePrice
  • usePreSaleStatus
  • usePublicSaleMaxMintPerTx
  • usePublicSaleMinter
  • usePublicSalePrice
  • usePublicSaleStatus
  • useSaleTiers
  • useSimpleSaleMinter
  • useTierSaleAllowlistChecker
  • useTierSaleEligibleAmount
  • useTierSaleInformation
  • useTierSaleMinter
  • useTierSaleTotalMints

You can view the source code of these hooks, and ask us any questions in Discord, our developers are happy to support.

Solidity extensions

ERC721PreSaleExtension.sol

This extensions provides pre-sale (closed sale) capability with a fixed price, so that only allowlisted wallets can mint NFTs.

Features:

  • Set a fixed price, and update it anytime, before the pre-sale finishes.
  • Define the maximum number of mints per allowlisted wallet.
  • Configure the allowlist (via generating and setting a merkle root).
  • Checking if a certain wallet is allowlisted or not.
  • Activate or deactivate pre sale anytime.

View the source code.

ERC721PublicSaleExtension.sol

This extensions provides public sale capability with a fixed price, allowing anyone to mint NFTs.

Features:

  • Set a fixed price, and update it anytime, before the public sale finishes.
  • Define the maximum number of mints per transaction.
  • Activate or deactivate public sale anytime.

View the source code.

ERC721TieringExtension.sol

This extensions allows you to define multiple tiers, each with different price, different max per wallet, different allowlist, and different dates.

Features:

  • Set a fixed price, and update it anytime even during sales.
  • Define the maximum number of mints per wallet.
  • Set a start and an end for the sales.
  • Optionally set an allowlist that can have custom allowance for every single wallet, besides the maximum per-wallet defined for the tier.
  • Reserve a minimum for a specific tier, so you ensure that at least that amount is minted for that tier.
  • Set a total maximum a certain tier can mint.

View the source code.

Need help? Ask us any questions in Discord, our developers are happy to support.