An ERC-721 contract that supports gasless minting via EIP-712 typed-data
signatures. The holder signs an off-chain Mint message; an authorized minter
submits the signature on-chain to mint the NFT to the holder.
The contract targets Remix IDE.
- Open Remix
- Paste
contracts/NFToken.sol - Compile with Solidity ^0.8.27
- Deploy with constructor
(minter, name, symbol)
pip install -r requirements.txt
cp .env.example .env # fill in PRIVATE_KEY, CHAIN_ID, VERIFYING_CONTRACT, URI
python test_signature.pyOutput is a hex signature you can pass to sigMint() from the minter account.
User (off-chain) Minter (on-chain)
│ │
│ 1. signTypedData(Mint{to, uri, │
│ nonce, deadline}) │
│ ─────────────────────────────────▶ │
│ │
│ 2. sigMint(...) verifies:
│ - msg.sender == minter
│ - block.timestamp ≤ deadline
│ - nonce == nonces[to]
│ - ECDSA.recover(digest, sig) == to
│ - mint NFT to `to` with `uri`
- Replay protection via per-
tononces[] - Deadline guards against stale signatures
- Minter role is single-address and transferable
(
transferMintership/renounceMinter)
contracts/NFToken.sol ERC-721 + EIP-712 contract
scripts/deploy_with_ethers.ts Remix deployment entry point
scripts/ethers-lib.ts Deployment helper using ethers.js
test_signature.py EIP-712 signature generator (Python)
.env.example Template for the signature script
prettierrc.json Solidity formatting rules
remix.config.json Remix workspace settings
- OpenZeppelin Contracts ^5.4.0 (
ERC721,EIP712,ECDSA) - Python (test script):
eth-abi,eth-keys,eth-utils
MIT