0.0.1 • Published 1 year ago

@premintnft/connect v0.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

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.

//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.