> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crossmint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# NFT Drops Gated by Accesslists

> Allow purchasing in accesslist-protected NFT drops

## Access Lists

<Note>
  Accesslist support is a premium feature. To get started, [contact sales](https://www.crossmint.com/contact/sales)
</Note>

Crossmint allows you to whitelist both wallet and email addresses. Once the team
has approved your request, you will need to provide the following information:

1. Your Crossmint `clientId` or `collectionId` for the collection.

2. The list of wallet and email addresses to be included in the accesslist.

<Tip>
  If you whitelist users' email addresses, Crossmint will create wallets associated with those email addresses and
  provide them to you for inclusion in the accesslist. Users will then be able to authenticate during the purchase and
  execute the transaction.
</Tip>

<Tabs>
  <Tab title="EVM">
    You can set up accesslists using Merkle Trees or inserting the list of whitelisted addresses directly on the smart contract:

    ### A. Merkle Tree Accesslists

    While using Merkle Trees is more gas-efficient, it involves a slightly more complex setup.
    Here is an example accesslist mint function:

    <Accordion title="See Example">
      ```solidity Solidity theme={null}
      //SPDX-License-Identifier: Unlicense
      pragma solidity ^0.8.0;

      import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
      import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
      import "@openzeppelin/contracts/access/Ownable.sol";

      contract Accesslist is ERC721, Ownable {
          bytes32 public merkleRoot;
          uint256 public nextTokenId;
          mapping(address => bool) public claimed;

          constructor() ERC721("ExampleNFT", "NFT") {
              merkleRoot = 0x0;
          }

          function isWhiteListed(bytes32[] memory proof, bytes32 leaf) public view returns(bool) {
              return MerkleProof.verify(proof, merkleRoot, leaf);
          }

          function setMerkleRoot(bytes32 merkleRoot_) external onlyOwner {
              merkleRoot = merkleRoot_;
          }

          function mint(address to, bytes32[] calldata merkleProof) public payable {
              require(claimed[to] == false, "already claimed");
              claimed[to] = true;
              require(
                  isWhiteListed(
                      merkleProof,
                      keccak256(abi.encodePacked(to))
                  ),
                  "invalid merkle proof"
              );
              nextTokenId++;
              _mint(to, nextTokenId);
          }
      }
      ```
    </Accordion>

    ### B. Mapping-Based Accesslists

    The most straightforward method of whitelisting involves maintaining
    a mapping of the whitelisted addresses within your smart contract.
    This approach is faster but consumes more gas and savvy developers
    may be able to determine the addresses of the accesslist.

    <Accordion title="See Example">
      ```solidity Solidity theme={null}
      mapping(address => uint256) public whitelistMapping;
      ```

      ```solidity Solidity theme={null}
      function presale(address _to, uint256 _count) external payable {
          // ensure _to address has tokens left to mint
          require(whitelistMapping[_to] > 0, "no whitelist tokens for user");

          // decrement mapping for user
          whitelistMapping[_to] -= _count;

          // presale minting logic here
      }
      ```
    </Accordion>
  </Tab>

  <Tab title="Solana">
    You can set up accesslists on your Candy Machine using Merkle Trees or SPL Tokens

    ### A. Merkle Tree Accesslists

    Simply send the user IDs to Crossmint. Once you have the Merkle proof, you can pass it into the Crossmint Hosted Checkout `lineItems.callData` as a string, as in the example below:

    <Accordion title="See Example">
      ```jsx React theme={null}
      <CrossmintProvider apiKey="_YOUR_CLIENT_API_KEY_">
          <CrossmintHostedCheckout
              lineItems={{
                  collectionId: "crossmint:_YOUR_COLLECTION_ID_",
                  callData: {
                      type: "candy-machine",
                      quantity: 1,
                      mintingGroup: "pre",
                      merkleProof: "62, 43, 204, 46, 222, 219, 236, 32, 60, 4, 235, [...]",
                  }
              }}
          />
      </CrossmintProvider>
      ```
    </Accordion>

    ### B. SPL Token-based Accesslists

    You can whitelist wallets by airdropping them SPL tokens.
  </Tab>
</Tabs>

## Geofencing

<Note>
  Geofencing support is a premium feature only available to customers on a paid plan. To get started, [contact
  sales](https://www.crossmint.com/contact/sales)
</Note>

Crossmint supports geofencing capabilities through our Customer Success Engineering (CSE) team. Our CSE team can work with you to block transactions from specific countries or geographic regions via Stripe rules.

To set up geofencing for your project, please contact our sales team to discuss your specific requirements and implementation details.
