npm package: @premintnft/connect
Description: PremintConnect smart contracts
Author: PREMINT
Latest version: 0.0.1

# PremintConnect.sol

This repository contains the contracts that developers should extend for premint to be able to connect to it.

It will be published under the npm package: `@premintnft/contracts`

## Usage for implementers

`PremintConnect.sol` is the contract that developers should extend.

It's an bastract contract containing 2 methods that must be implemented by developers trying to connect their contracts to the premint.xyz website.

There is a third method that implementers can implement, and which allows to set a maximum of mint per wallets (all list included).

### `premintSigner() public view returns (address)`

_**This is a function that must be overrode & implemented by you**_

this function is used in the verification process to validate an allowance and on premint.xyz to show the administration panel to the right wallet.

It should return the address of the wallet that will be tasked to configure the different lists on Premint.

For security reasons, it is recommended to have a specific wallet used to configure the lists.

### `_premint(to, amount) internal virtual;`

_**This is a function that must be overrode & implemented by you**_

This function is the one called internally once the contract successfully verified the user `allowance`

It's where developers need to call their internal mint function.

### `premintMax() external view returns (uint256);`

_This function can be overrode in order to set a max number of mint per wallet, even if they are in several lists_

It is supposed to return an integer that would be the max number of mint per wallet.
0 means no limit.

Be careful: PremintConnect will only track the number of mint of a wallet if `premintMax()` returns a number that is not 0. This in order to not incure higher gas fees on contracts who are already managing the maximum of mint on their own.

## Premint Function

The function that premint.xyz will call is the function `premint(PremintConfig calldata config, uint256 amount)`

This function takes for argument the configuration that proves that the user is in the allowlist, and the amount of tokens they want to mint.

It will automatically check the current config data for the current caller, and if everything is valid, it will internally call the method `_premint(to, amount)`, that you need to implement to actually do the mint.

## Notes

#### What PremintConnect provides?

PremintConnect only provide the minimal interface & methods helping premint.xyz front-end to communicate with your contract during the minting phase(s).

Any method to withdraw/transfer payments, or do any other administration stuff have to be implemented by the contract's developer(s).

#### ReEntrancy

`PremintConnect.sol` will always update the used allowance before calling `_premint(to, amount)`, so we do not include any re-entracy guard.

If you are using things like `_safeMint()` and can have side effects on your mint, you might want to add a re-entracy guard on the internal `_premint` method.

## Local Chain for Tests

After installing the dependencies, you can easily launch an hardhat node and deploy a contract PremintConnect locally in 2 commands:

```
npx hardhat node
npx hardhat run scripts/local.ts --network localhost
```

This will echo the current contract address.

Locally, the default `premintSigner()` is the default hardhat deployer account, private key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

With this, you can use the tool (https://premint-config.dievardump.com/)[https://premint-config.dievardump.com/] to configure some lists that can then be used to interact with the contract.

You will need to be connected with the deployer account mentioned before in order to sign the list.

## Examples

The directory `/src/Mocks/` contains a few examples of contracts that use `PremintConnect.sol`

An ERC721 contract and an ERC721A example are available.

```solidity
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

import {PremintConnect} from "../PremintConnect.sol";

contract ERC721PremintConnect is Ownable, PremintConnect, ERC721("ERC721PremintConnect", "MOCK") {
    uint256 private _lastTokenId;

    function _premint(address to, uint256 amount) internal override {
        // when arriving here, it means the premint verification has been successful
        // and we can just mint `amount` tokens to `to`
        uint256 lastTokenId = _lastTokenId;
        do {
            unchecked {
                amount--;
                lastTokenId++;
            }

            _mint(to, lastTokenId);
        } while (amount > 0);

        _lastTokenId = lastTokenId;
    }


    /// @notice return the address of the person allowed to configure things on Premint
    ///         here for the example, the contract owner
    /// @return the address
    function premintSigner() public view virtual override returns (address) {
      return owner();
    }
}
```

## Tests

### Testing your implementation

@TODO: add description of how to test

### Testing with Forge

For people doing tests in Solidity, you can import and use the `PremintSigUtils.sol` library in order to generate allowlists directly in your tests using Forge built-in signing tools

### Testing this repository

`npx hardhat test` will test all the mocks with example lists created on the go.