A comprehensive collection of NFT minting contracts for the Hedera network
Version: 2.0 (v1.0 for ForeverMinter, SoulboundBadgeMinter)
Solidity: 0.8.18
Branch:refactor-base-minter
This repository provides four specialized NFT minting contracts, each optimized for different use cases on the Hedera network. All contracts support $LAZY token integration, whitelist systems, and are production-ready with comprehensive testing.
Need transferable NFTs?
- Standard sales β MinterContract
- Pool-based distribution with royalties β ForeverMinter
Need soulbound (non-transferable) NFTs?
- Single badge/certificate type β SoulboundMinter
- Multiple badge types in one contract β SoulboundBadgeMinter
| Feature | MinterContract | SoulboundMinter | ForeverMinter | SoulboundBadgeMinter |
|---|---|---|---|---|
| Token Type | Transferable NFT | Soulbound NFT | Transferable NFT | Soulbound NFT |
| Distribution | Create & mint | Create & mint | Pool-based | Create & mint |
| Primary Use Case | Standard NFT sales | Badges/Certificates | Complex distribution | Multi-badge system |
| Transferability | β Yes | β No (Frozen) | β Yes | β No (Frozen) |
| Royalty Compliance | β Bypassed | N/A | β Respected | N/A |
| Whitelist System | β Address + Token-gated | β Address + Token-gated | β Address + Holder | β Per-badge whitelist |
| Payment Types | HBAR + $LAZY | HBAR + $LAZY | HBAR + $LAZY | HBAR only |
| Discount Types | WL only | WL only | WL + Holder + Sacrifice | Per-badge config |
| Discount Stacking | β No | β No | β WL+Holder | β No |
| Refund System | β Time-based | β Time-based | β Pool return | β No |
| Batch Minting | β Unlimited | β Unlimited | β 50 max | β Unlimited |
| On-Behalf Minting | β No | β Yes | β No | β Yes |
| Revocation | β No | β Optional | β No | β Optional |
| Sacrifice System | β No | β No | β Burn NFTs for discount | β No |
| Admin System | Owner only | Owner only | Multi-admin | Multi-admin |
| Supply Management | Fixed/Unlimited | Fixed/Unlimited | Pool-based | Fixed per badge |
| Contract Size | 19.402 KiB | 20.436 KiB | 18.874 KiB | 14.824 KiB |
| Architecture | v2.0 (Refactored) | v2.0 (Refactored) | v1.0 | v1.0 |
| Documentation | β Complete | β Complete | β Extensive (6 docs) | β Complete |
π Documentation: MinterContract-README.md
π§ Contract: contracts/MinterContract.sol
π§ͺ Tests: test/MinterContract.test.js
π¦ Size: 19.402 KiB | Headroom: 5.174 KiB
Standard transferable NFT minting with flexible pricing, whitelist access, and refund mechanics.
β
Traditional NFT collection launches
β
Transferable collectibles with standard economics
β
Projects needing refund/burn mechanics
β
Token-gated NFT access
β
Simple whitelist discount systems
- Create and mint NFTs on-demand
- HBAR + $LAZY dual payment system
- Time-based refund window with burn mechanism
- Whitelist + token-gated access
- Fixed or unlimited supply options
- Sequential or random metadata selection
- Comprehensive refund tracking
MinterContract
ββ ExpiryHelperV2 (NFT expiry management)
ββ FeeHelperV2 (custom fee handling)
ββ KeyHelperV2 (key management with Bits library)
ββ HederaTokenServiceV2 (HTS integration)
ββ ReentrancyGuard (security)
ββ Ownable (ownership)
- β Custom errors (~90% gas savings on errors)
- β MinterLibrary eliminated (DRY with KeyHelper)
- β KeyHelper Bits library integration
- β 86-byte contract size reduction
- β ~40% cheaper deployment
- β Enhanced maintainability
π Documentation: SoulboundMinter-README.md
π§ Contract: contracts/SoulboundMinter.sol
π§ͺ Tests: test/SoulboundMinter.test.js
π¦ Size: 20.436 KiB | Headroom: 4.140 KiB
Non-transferable (soulbound) NFT minting for badges, certificates, and identity tokens.
β
Educational certificates & credentials
β
Achievement/completion badges
β
Non-transferable membership tokens
β
Attendance/participation proofs
β
Identity verification NFTs
β
Single-type soulbound token systems
β
Gas abstraction (on-behalf minting)
- Frozen tokens - Non-transferable by design
- Optional revocation system
- On-behalf minting (gas abstraction for users)
- HBAR + $LAZY dual payment
- Time-based refunds
- Whitelist + token-gated access
- Optional FREEZE + WIPE keys
// Tokens are frozen at mint
IHederaTokenService.TokenKey[] memory keys = new IHederaTokenService.TokenKey[](2);
keys[0] = getSingleKey(KeyType.FREEZE, ...); // Required
keys[1] = getSingleKey(KeyType.WIPE, ...); // Optional (for revocation)SoulboundMinter
ββ ExpiryHelperV2 (NFT expiry management)
ββ FeeHelperV2 (custom fee handling)
ββ KeyHelperV2 (unified key management)
ββ HederaTokenServiceV2 (HTS integration)
ββ ReentrancyGuard (security)
ββ Ownable (ownership)
- β Custom errors (gas efficient)
- β Unified KeyType enum with KeyHelper
- β MinterLibrary dependency removed
- β 78-byte contract size reduction
- β Improved code quality via DRY
π Documentation: ForeverMinter-README.md
π Extended Docs: docs/ForeverMinter-*.md (6 comprehensive documents)
π§ Contract: contracts/ForeverMinter.sol
π§ͺ Tests: test/ForeverMinter.test.js
π¦ Size: 18.874 KiB | Headroom: 5.702 KiB
Pool-based distribution of existing NFT collections with advanced discount mechanics and royalty compliance.
β
Distributing existing NFT collections
β
Respecting creator royalties is critical
β
Complex discount mechanics (holder incentives, sacrifice)
β
Staking/recycling systems for NFTs
β
Multiple discount tiers with stacking
β
Large collections requiring efficient distribution
β
Multi-admin team management
- Pool-based distribution (not minting new tokens)
- Royalty compliance via TokenStakerV2
- Triple discount system:
- Whitelist discount (stackable)
- Holder discount (global per-serial tracking, stackable)
- Sacrifice discount (exclusive, highest %)
- Burn existing NFTs for discounts
- Time-based refund with pool return
- PRNG serial selection
- Multi-admin system
// Sacrifice existing NFTs for discount
await foreverMinter.mintNFT(
quantity,
lazyAmount,
true, // Use holder discount
true, // Use sacrifice discount
[serial1, serial2] // NFTs to burn
);
// Refund returns NFT to pool
await foreverMinter.refundNFT(serial);
// Serial back in availableSerials, 95% payment returnedForeverMinter
ββ TokenStakerV2 (royalty-compliant transfers)
ββ Ownable (ownership)
ββ ReentrancyGuard (security)
- ForeverMinter-SUMMARY.md: Documentation overview & roadmap
- ForeverMinter-DESIGN.md: Complete technical specification (1700+ lines)
- ForeverMinter-BUSINESS-LOGIC.md: User guide with 40+ FAQs
- ForeverMinter-TODO.md: 23-phase implementation checklist
- ForeverMinter-TESTING.md: 200+ test cases
- ForeverMinter-IMPLEMENTATION-SUMMARY.md: Progress tracking
π Documentation: SoulboundBadgeMinter-README.md
π§ Contract: contracts/SoulboundBadgeMinter.sol
π§ͺ Tests: test/SoulboundBadgeMinter.test.js
π¦ Size: 14.824 KiB | Headroom: 9.752 KiB
Multi-badge soulbound NFT system with per-badge configuration and team management.
β
Multiple badge types in one contract
β
Organization/company badge programs
β
Per-badge supply limits and whitelists
β
Flexible multi-tier badge systems
β
Team-based admin management
β
Badge-specific pricing and configuration
- Multiple badge types in single contract
- Per-badge configuration:
- Individual supply limits
- Separate whitelists
- Badge-specific pricing
- Custom metadata per badge
- Multi-admin team system
- On-behalf minting (gas abstraction)
- Optional revocation per badge
- HBAR-only payments (simpler)
// Each badge is independent
struct BadgeConfig {
string name;
string symbol;
uint256 maxSupply;
uint256 price;
bool revocable;
address[] whitelist;
string metadataURI;
}SoulboundBadgeMinter
ββ KeyHelper (key management)
ββ HederaTokenService (HTS integration)
ββ ReentrancyGuard (security)
ββ Ownable (ownership)
hedera-SC-minter/
βββ contracts/
β βββ MinterContract.sol # v2.0 - Standard NFT minting
β βββ SoulboundMinter.sol # v2.0 - Single soulbound type
β βββ ForeverMinter.sol # v1.0 - Pool distribution
β βββ SoulboundBadgeMinter.sol # v1.0 - Multi-badge system
β βββ ExpiryHelperV2.sol # NFT expiry management
β βββ FeeHelperV2.sol # Custom fee handling
β βββ KeyHelperV2.sol # Key management (Bits library)
β βββ HederaTokenServiceV2.sol # HTS integration
β βββ TokenStakerV2.sol # Staking mechanics
β βββ FungibleTokenCreator.sol # v2.0 - Fungible token support
β βββ interfaces/ # Contract interfaces
β
βββ test/
β βββ MinterContract.test.js
β βββ SoulboundMinter.test.js
β βββ ForeverMinter.test.js
β βββ SoulboundBadgeMinter.test.js
β βββ FungibleTokenCreator.test.js
β
βββ docs/
β βββ ForeverMinter-SUMMARY.md
β βββ ForeverMinter-DESIGN.md
β βββ ForeverMinter-BUSINESS-LOGIC.md
β βββ ForeverMinter-TODO.md
β βββ ForeverMinter-TESTING.md
β βββ ForeverMinter-IMPLEMENTATION-SUMMARY.md
β
βββ abi/ # Contract ABIs
βββ scripts/ # Deployment & interaction scripts
βββ utils/ # Helper utilities
βββ MinterContract-README.md # Complete documentation
βββ SoulboundMinter-README.md # Complete documentation
βββ ForeverMinter-README.md # Quick reference (NEW)
βββ SoulboundBadgeMinter-README.md # Complete documentation
βββ DEV-README.md # Development setup
βββ README.md # This file
- Blockchain: Hedera Hashgraph
- Solidity: 0.8.18
- Framework: Hardhat
- Testing: Mocha, Chai, Hedera SDK
- Libraries:
- OpenZeppelin (ReentrancyGuard, Ownable, SafeCast, Math, EnumerableMap/Set, Address, Strings)
- Hedera Token Service (HTS)
- Custom: KeyHelper with Bits library
- ReentrancyGuard on all payment functions
- Custom errors for gas-efficient error handling
- Comprehensive testing with edge case coverage
- Access control via Ownable or multi-admin systems
- Dual payment: HBAR + $LAZY token integration
- Burn mechanism: Configurable $LAZY burn percentage
- Whitelist discounts: Incentivize early supporters
- Flexible pricing: Per-contract or per-badge configuration
- PRNG integration for fair metadata/serial selection
- Hedera VRF support via IPrngGenerator
- Configurable: Sequential or random distribution
- Time-based windows (configurable)
- Partial refunds (e.g., 95% return)
- Burn tracking for accountability
- Gas optimization via efficient data structures
- IPFS integration for decentralized storage
- Flexible URIs per-token or per-badge
- Sequential or random metadata assignment
# Clone repository
git clone https://github.com/Burstall/hedera-SC-minter.git
cd hedera-SC-minter
git checkout refactor-base-minter
# Install dependencies
npm install# Copy environment template
cp .env.example .env
# Configure Hedera credentials
OPERATOR_ID=0.0.xxxxx
OPERATOR_KEY=your-private-key
NETWORK=testnet# Compile all contracts
npx hardhat compile
# Check contract sizes
npx hardhat compile --force# Run all tests
npm test
# Test specific contracts
npm run test-minter # MinterContract
npm run test-soulbound # SoulboundMinter
npm run test-forever # ForeverMinter
npm run test-badges # SoulboundBadgeMinter
npm run test-ft # FungibleTokenCreator
# Run with gas reporting
REPORT_GAS=true npm test# Deploy to testnet
npx hardhat run scripts/deployment/deploy-minter.js --network testnet
# Deploy specific contract
npx hardhat run scripts/deployment/deploy-soulbound.js --network testnet- Deploy: ~6.5M gas (~40% cheaper with v2.0 custom errors)
- Single Mint: ~800k gas (with PRNG)
- Batch Mint (10): ~6.0M gas base + 325k per NFT
- Refund: ~300k gas
- Deploy: ~6.8M gas
- Single Mint: ~850k gas (FREEZE key adds overhead)
- On-Behalf Mint: +50k gas (gas abstraction)
- Revoke: ~250k gas (if enabled)
- Deploy: ~7.2M gas
- Single Mint: ~700k gas (no token creation)
- Sacrifice Mint: ~900k gas (includes burns)
- Refund with Pool Return: ~350k gas
- Deploy: ~5.5M gas (smallest contract)
- Single Badge Mint: ~800k gas
- Multi-Badge Setup: ~200k per badge configuration
Note: Hedera suggests 20% gas buffer over estimates. Hedera refunds up to 20% of unused gas.
Major Changes:
- β MinterLibrary Eliminated: Single-use helpers inlined
- β Custom Errors: Replaced all string-based reverts (~90% gas savings)
- β KeyHelper Integration: Uses Bits library and unified KeyType enum
- β DRY Principles: Removed code duplication with helper contracts
- β Size Optimization: 78-86 byte reduction per contract
Performance Improvements:
- Deployment: ~40% cheaper
- Error handling: ~90% gas savings
- Runtime: Eliminated JUMP operations for inlined functions
- Maintainability: Better code organization via DRY
Breaking Changes:
- β None - All public interfaces unchanged
- β Frontend error handling should parse custom errors (recommended, not required)
- Original implementations (no refactoring yet)
- May receive v2.0 updates in future
// Modern approach (v2.0) - parse custom errors
try {
await contract.mintNFT(amount, { value: cost });
} catch (error) {
if (error.data) {
const parsedError = contract.interface.parseError(error.data);
if (parsedError.name === 'InsufficientPayment') {
const [required, provided] = parsedError.args;
console.log(`Need ${required}, got ${provided}`);
}
}
}
// Legacy approach (still works)
catch (error) {
if (error.message.includes("InsufficientPayment")) {
// Handle error
}
}// MinterContract & SoulboundMinter
const cost = await contract.calculateCost(quantity, useWhitelist);
// ForeverMinter (v1.0.5+)
const result = await foreverMinter.calculateMintCost(
userAddress,
quantity,
useHolderDiscount,
useSacrifice
);
// Returns: {hbarCost, lazyCost, totalDiscount, holderSlotsUsed, wlSlotsUsed}- MinterContract-README.md - Standard transferable NFT minting
- SoulboundMinter-README.md - Single-type soulbound badges
- ForeverMinter-README.md - Pool-based distribution (NEW!)
- SoulboundBadgeMinter-README.md - Multi-badge system
- docs/ForeverMinter-SUMMARY.md - Documentation overview
- docs/ForeverMinter-DESIGN.md - Technical specification (1700+ lines)
- docs/ForeverMinter-BUSINESS-LOGIC.md - User guide & FAQ
- docs/ForeverMinter-TODO.md - Implementation checklist
- docs/ForeverMinter-TESTING.md - Test plan (200+ cases)
- DEV-README.md - Development environment setup
- Test Files:
test/*.test.js- Comprehensive test suites
| Requirement | Recommended Contract |
|---|---|
| Standard NFT sale | MinterContract |
| Educational certificates | SoulboundMinter |
| Achievement badges (single type) | SoulboundMinter |
| Achievement badges (multiple types) | SoulboundBadgeMinter |
| Pool-based distribution | ForeverMinter |
| Holder incentive discounts | ForeverMinter |
| NFT sacrifice mechanics | ForeverMinter |
| Royalty compliance required | ForeverMinter |
| Multi-admin team | ForeverMinter or SoulboundBadgeMinter |
| On-behalf minting (gas abstraction) | SoulboundMinter or SoulboundBadgeMinter |
| Revocable credentials | SoulboundMinter or SoulboundBadgeMinter |
| Organization badge programs | SoulboundBadgeMinter |
- GitHub: Burstall/hedera-SC-minter
- Branch:
refactor-base-minter(latest) - Issues: GitHub Issues
See LICENSE file for details.
Last Updated: October 2025
Repository Status: β
Production Ready
Latest Version: v2.0 (MinterContract, SoulboundMinter), v1.0 (ForeverMinter, SoulboundBadgeMinter)