NFT Infrastructure - Current State
Quick Navigation
- Arbitrum Integration - Current development focus
- Quick Start Guide - Get started developing
- Technical Reference - Smart contract details
Status: Production on Tezos, Development on Arbitrum/EVM Last Updated: 2025-12-14
Executive Summary
EmProps has a production-ready NFT minting infrastructure with multi-chain support:
- Tezos - Production, fully integrated (current live system)
- Arbitrum - Active development (grant-funded, primary EVM target)
- Ethereum/Base - Development/Testing
This document provides a comprehensive inventory of what exists today across the codebase, covering:
- What's in emerge-turbo (this monorepo)
- What's in external repos (emprops-hardhat, emprops-ponder, emprops-react-web3)
- The integration points between systems
- Gaps that need to be addressed
Table of Contents
- High-Level Architecture
- Current Implementation - emerge-turbo
- External Repositories (Not Yet Integrated)
- Blockchain Support Matrix
- Data Flow
- Key Integration Points
- What's Missing
- Technology Stack
High-Level Architecture
┌──────────────────────────────────────────────────────────────────────────────┐
│ EmProps NFT Infrastructure │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ emerge-turbo (This Monorepo) │ │
│ │ │ │
│ │ ┌─────────────────────┐ ┌──────────────────────────────────────┐ │ │
│ │ │ emprops-studio │ │ External APIs │ │ │
│ │ │ (Next.js) │───▶│ - Tezos RPC (Taquito) │ │ │
│ │ │ │ │ - EVM RPC (Viem) │ │ │
│ │ │ NFT UI Components: │ │ - emprops-api (backend) │ │ │
│ │ │ - ManageCollection │ └──────────────────────────────────────┘ │ │
│ │ │ - MintButton │ │ │
│ │ │ - PublishModal │ ┌──────────────────────────────────────┐ │ │
│ │ │ - BlockchainSelect │ │ Smart Contracts │ │ │
│ │ │ - NFTPublishForm │───▶│ (Deployed on-chain) │ │ │
│ │ │ - CollectionRecvrs │ │ │ │ │
│ │ └─────────────────────┘ │ Tezos: │ │ │
│ │ │ - FA2 Collections │ │ │
│ │ ┌─────────────────────┐ │ - Member Gated Collections │ │ │
│ │ │ Contract ABIs │ │ │ │ │
│ │ │ (TypeScript) │ │ Ethereum/Base: │ │ │
│ │ │ │ │ - ERC721 Collections │ │ │
│ │ │ - collections │ │ - Member Collections │ │ │
│ │ │ - member-colls │ │ - Patron Pass │ │ │
│ │ │ - patron-pass │ └──────────────────────────────────────┘ │ │
│ │ └─────────────────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────┐ ┌──────────────────────────────────────┐ │ │
│ │ │ Wallet Context │───▶│ Wallet Providers │ │ │
│ │ │ │ │ - Beacon SDK (Tezos) │ │ │
│ │ │ - Tezos (Taquito) │ │ - Dynamic Labs (EVM) │ │ │
│ │ │ - EVM (Viem) │ │ - RainbowKit (planned) │ │ │
│ │ └─────────────────────┘ └──────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ External Repos (Not Yet Integrated) │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ emprops-hardhat │ │ emprops-ponder │ │emprops-react-web3│ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ Smart Contracts │ │ Event Indexer │ │ Reference SDK │ │ │
│ │ │ (Solidity) │ │ (Ponder) │ │ (Demo/Patterns) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ - OwnerToken │ │ - 8 DB tables │ │ - Wagmi adapter │ │ │
│ │ │ - NFTContractFactory │ │ - WebSocket API │ │ - React hooks │ │ │
│ │ │ - SimpleApp │ │ - REST API │ │ - Type defs │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ │ Location: /Users/the_dusky/code/emprops/nft_investigation/ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────┘Current Implementation - emerge-turbo
1. Smart Contract Interfaces (TypeScript ABIs)
Location: apps/emprops-studio/contracts/ethereum/
These are TypeScript-generated interfaces from deployed EVM smart contracts:
| File | Contract Type | Purpose |
|---|---|---|
collections-contract.ts/json | ERC721 | Main NFT collections with minting logic |
member-collections-contract.ts/json | ERC721 | Member-gated NFT collections |
member-collections-token-contract.ts/json | ERC721 | Token contract for member collections |
patron-pass-collections-contract.ts/json | ERC721 | Patron pass NFT implementation |
patron-pass-token-contract.ts/json | ERC721 | Patron pass token contract |
utils.ts | Utility | ABI method detection helpers |
Note: Generated using ethereum-abi-types-generator
2. Blockchain Client Layer
Location: apps/emprops-studio/clients/
contract-client.ts (~1,270 lines)
The main NFT infrastructure client providing:
Type Definitions:
type TezosCollectionKey = "projects" | "collections"
type Blockchain = "TEZOS" | "ETHEREUM" | "BASE"
interface CollectionMetadataRequest { ... }
interface CollectionMetadataResponse { ... }
interface CreateTezosCollectionParams { ... }
interface CollectionData { ... }
interface CollectionContractConfig {
price: number;
editions: number;
status: "ON" | "OFF";
}Key Functions:
| Function | Purpose |
|---|---|
getTezCollection() | Fetch Tezos collection data from on-chain |
getEthCollection() | Fetch Ethereum/Base collection data |
createTezosCollection() | Deploy new NFT collection on Tezos |
handleContractsMintBatchs() | Batch minting operations |
getRedeemableTezFunds() | Get available royalty funds (Tezos) |
getRedeemableEthFunds() | Get available royalty funds (EVM) |
updateTezCollectionStatus() | Toggle minting on/off |
updateTezCollectionPrice() | Update mint price |
updateTezCollectionEditions() | Update max supply |
tezos-client.ts (42 lines)
Tezos-specific functionality:
- Domain resolution via
@tezos-domains/taquito-client - Tzip16 metadata support
- Domain name lookup
emprops-api-client.ts
REST API client for EmProps backend:
- Projects, contracts, sales, tokens, profiles, events
- SWR-based data fetching
3. React Hooks
Location: apps/emprops-studio/hooks/
Collection Hooks (collections.ts)
| Hook | Purpose |
|---|---|
usePublishedCollections() | Paginated collection listing |
usePublishedCollection() | Single collection lookup |
useCountPublishedCollections() | Count collections by owner |
useCollections() / useCollection() | Collection CRUD operations |
useCurrentCollection() | Current collection in context |
useCollectionPreview() | Preview data for collection |
useCreateCollection() | Create new collection |
useUpdateCollection() | Update collection metadata |
useMoveCollection() | Reorganize collections |
useUpdateCollectionVisibility() | Publish/unpublish |
Contract Hooks (contract-client.ts)
| Hook | Purpose |
|---|---|
useCollectionContract() | Get contract instance for writing |
useCollectionQuerierContract() | Get contract instance for reading |
useCollectionInfo() | Collection metadata |
useCollectionConfig() | Collection configuration (price, editions, status) |
useMintToken() | Token minting mutations |
usePublishCollection() | Collection publication to blockchain |
useGetCollectionTokensMinted() | User's token inventory |
Other Hooks
| Hook | Purpose |
|---|---|
useCollectionRewards() | Reward distribution tracking |
useCollectionOutputs() | Collection-specific output management |
4. UI Components
Location: apps/emprops-studio/components/
Mint Button Components
| Component | Purpose |
|---|---|
MintButton/index.tsx | Router - selects blockchain-specific button |
MintButton/TezosMintButton.tsx | Tezos minting UI |
MintButton/USDTezosMintButton.tsx | USD price display for Tezos |
MintButton/USDEthereumMintButton.tsx | USD price display for Ethereum |
MintButton/MintButtonLabel.tsx | Common label rendering |
MintButton/BatchMintCounter.tsx | Batch minting quantity selector |
Blockchain/Ethereum/v1/MintButton.tsx | Ethereum/EVM minting |
Blockchain/Base/v1/MintButton.tsx | Base chain minting |
Blockchain/Base/v1/Redeem.tsx | Fund redemption for Base |
Collection Management
| Component | Purpose |
|---|---|
ManageCollection/ | Collection management dashboard |
ManageCollectionPreview/ | Quick preview |
PublishCollectionModal/ | Publication workflow |
CollectionSettings/ | Collection configuration UI |
CollectionDetails/ | Collection metadata display |
CollectionDetailsForm/ | Form for updating collection details |
CollectionDetailsForm/CollectionReceiversForm.tsx | Revenue split configuration |
CollectionDetailsForm/CollectionReceiversList.tsx | Display receivers |
CollectionHistory/ | Historical events tracking |
CollectionItems/ | NFT grid display |
GridItemCollection/ | Gallery item renderer |
UpdateCollectionDetails/ | Inline editing |
CollectionCorruptedModal/ | Error recovery |
NFTPublishingForm/ | NEW - Comprehensive NFT publishing form |
Blockchain UI
| Component | Purpose |
|---|---|
BlockchainSelector/ | UI for choosing blockchain (Tezos/Ethereum/Base) |
Studio V2 Collection View
| Component | Purpose |
|---|---|
studio/v2/CollectionView/index.tsx | Main collection view |
studio/v2/CollectionView/CollectionOutputGrid.tsx | NFT output grid |
studio/v2/CollectionView/CollectionOutputGroup.tsx | Output grouping |
studio/v2/CollectionView/CollectionOutputCard.tsx | Individual NFT card |
studio/v2/CollectionView/CollectionStats.tsx | Collection statistics |
5. Wallet & Context
Location: apps/emprops-studio/context/ and apps/emprops-studio/types/
clients-context.tsx
React Context for wallet clients:
- Dynamic import of
TezosWallet(SSR-safe) ClientsProviderwrapper componentuseClients()hook for wallet access
wallet.ts
Type definitions for blockchain integration:
type Blockchain = "TEZOS" | "ETHEREUM" | "BASE"
enum ChainId {
// Mainnet
TezosMainnet = "NetXdQprcVkpaWU",
EthereumMainnet = "1",
BaseMainnet = "8453",
// Testnet
TezosGhostnet = "NetXnHfVqm9iesp",
EthereumSepolia = "11155111",
BaseSepolia = "84532"
}
interface Wallet {
connect(): Promise<void>;
disconnect(): Promise<void>;
authenticate(): Promise<string>;
// ...
}6. State Management
Location: apps/emprops-studio/atoms/
mint.ts
import { atom } from 'jotai';
export const recentlyMintedAtom = atom(false);utils/mintStatus.ts (~150 lines)
Mint state determination logic:
getTezMintStatus()- Can user mint? (allowlist, freelist, public)getTezProjectsMintStatus()- Project-level restrictionsgetTezCollectionsMintStatus()- Collection-level restrictions- Checks: mint mode, allowance, freelist limits, sold-out status
7. API Endpoints
Location: apps/emprops-studio/pages/api/
| Endpoint | Purpose |
|---|---|
/api/contracts/[network]/[contractAddress]/mints/ | Mint operations |
/api/contracts/[network]/[contractAddress]/mints/signings/ | Signing operations |
/api/blockchains/tezos/[network]/contracts/[contractAddress]/mints/ | Tezos-specific mints |
/api/blockchains/tezos/[network]/contracts/[contractAddress]/mints/signings/ | Tezos signing |
8. Mint Modes & Access Control
Implemented on both Tezos and Ethereum:
| Mode | Description |
|---|---|
PUBLIC | Anyone can mint |
ALLOW_LIST / ALLOWLIST | Whitelisted addresses with per-address limits |
FREE_LIST / FREELIST | Free minting list with per-address redemption limits |
ON / OFF | Contract state for enabling/disabling minting |
9. Dependencies
Tezos Stack
{
"@taquito/taquito": "16.0.1",
"@taquito/beacon-wallet": "16.2.0",
"@taquito/tzip16": "16.1.2",
"@tezos-domains/taquito-client": "1.24.0",
"@airgap/beacon-sdk": "4.6.2"
}EVM Stack
{
"viem": "2.28.4",
"ethereum-abi-types-generator": "1.3.4"
}Wallet Integration
{
"@dynamic-labs/sdk-react-core": "4.25.7",
"@dynamic-labs/ethereum": "4.39.0"
}External Repositories (Not Yet Integrated)
These repos exist at /Users/the_dusky/code/emprops/nft_investigation/ and are documented for future integration.
1. emprops-hardhat (Smart Contracts)
Status: ✅ Complete, needs migration
Location: /Users/the_dusky/code/emprops/nft_investigation/emprops-hardhat
Contracts:
| Contract | Purpose | Pattern |
|---|---|---|
OwnerTokenContract.sol | Master NFT for collection ownership | ERC721A + UUPS |
NFTContractFactoryContract.sol | CREATE2 factory for NFT collections | UUPS Upgradeable |
SimpleAppContract.sol | Individual ERC721A NFT collection | Minimal Proxy |
SimpleAppInitializerContract.sol | Collection configuration | One-time init |
Features:
- Gas-optimized (ERC721A, minimal proxies, CREATE2)
- Upgradeable (UUPS pattern)
- Database integration for deployment tracking
- Cross-chain compatible (deterministic addresses)
See: emprops-hardhat-documentation.md
2. emprops-ponder (Blockchain Indexer)
Status: ✅ Complete, needs migration
Location: /Users/the_dusky/code/emprops/nft_investigation/emprops-ponder
Database Schema (8 tables):
| Table | Purpose |
|---|---|
owner_tokens | Owner NFTs (collection ownership) |
owner_token_transfers | Transfer history |
apps | NFT collections |
app_tokens | Individual NFTs |
app_token_mints | Batch minting events |
app_token_transfers | NFT transfer history |
contract_upgrades | Contract upgrade events |
Features:
- Real-time event indexing via Ponder framework
- HTTP API (Hono) + WebSocket server (Socket.io)
- Dynamic configuration from database
- Sub-second latency
See: emprops-ponder-documentation.md
3. emprops-react-web3 (Reference SDK)
Status: ℹ️ Reference only, do not migrate
Location: /Users/the_dusky/code/emprops/nft_investigation/emprops-react-web3
Valuable Patterns:
- Adapter pattern (WagmiAdapter vs PonderAdapter)
- React Query + WebSocket integration
- Transaction hooks with pre-validation
- Zod environment validation
- Type definitions
See: emprops-react-web3-documentation.md
Blockchain Support Matrix
| Feature | Tezos | Ethereum | Base |
|---|---|---|---|
| Collection Creation | ✅ Production | ⚠️ Dev | ⚠️ Dev |
| Minting | ✅ Production | ⚠️ Dev | ⚠️ Dev |
| Batch Minting | ✅ | ✅ | ✅ |
| Allowlist | ✅ | ✅ | ✅ |
| Freelist | ✅ | ✅ | ✅ |
| Fund Redemption | ✅ | ✅ | ✅ |
| Price Management | ✅ | ✅ | ✅ |
| Status Toggle | ✅ | ✅ | ✅ |
| Wallet Integration | ✅ Beacon | ✅ Dynamic | ✅ Dynamic |
| Contract ABIs | N/A (FA2) | ✅ | ✅ |
| Event Indexing | ❌ | ⚠️ ponder | ⚠️ ponder |
Legend:
- ✅ Production ready
- ⚠️ Development/Testing
- ❌ Not implemented
Data Flow
Current Flow (Tezos - Production)
1. User clicks "Publish to Blockchain" in emprops-studio
│
├─▶ PublishCollectionModal opens
│
├─▶ User selects blockchain (TEZOS), configures price/editions
│
├─▶ ManageCollection calls contract-client.ts
│
├─▶ createTezosCollection() deploys FA2 contract via Taquito
│
├─▶ Beacon wallet prompts for signature
│
├─▶ Transaction submitted to Tezos network
│
├─▶ Collection contract deployed
│
└─▶ Collection data stored in database + contract address savedPlanned Flow (EVM with Ponder Integration)
1. User clicks "Publish to Blockchain" in emprops-studio
│
├─▶ NFTPublishingForm collects settings
│
├─▶ Viem submits transaction to NFTContractFactory
│
├─▶ SimpleApp deployed via CREATE2
│
├─▶ Events emitted on blockchain
│
├─▶ emprops-ponder indexes events
│ └─▶ Stores in PostgreSQL
│ └─▶ Emits WebSocket event
│
└─▶ UI updates in real-timeKey Integration Points
1. emprops-studio → Smart Contracts
Current:
- Direct blockchain interaction via Taquito (Tezos) and Viem (EVM)
- Contract ABIs stored in
contracts/ethereum/
Needed:
- Integration with emprops-hardhat contracts
- Deployment flow using NFTContractFactory
2. emprops-studio → emprops-api
Current:
- REST API for collection CRUD
- Database storage for collection metadata
Needed:
- API endpoints for EVM contract interactions
- Metadata pinning (IPFS)
3. emprops-ponder → emprops-studio
Current:
- Not integrated
Needed:
- Real-time collection/mint data
- WebSocket subscriptions for UI updates
- Historical data queries
4. Smart Contracts → Database
Current:
- Tezos contract addresses stored in database
- EVM contracts not tracked
Needed:
- Contract deployment tracking
- Cross-chain address mapping
What's Missing
Critical Gaps
| Gap | Current State | Needed |
|---|---|---|
| Event Indexing | No blockchain event indexing | Integrate emprops-ponder |
| EVM Contract Management | Basic UI, no deployment | Full NFTContractFactory integration |
| Real-time Updates | Polling | WebSocket from ponder |
| Cross-chain History | Per-chain queries | Unified indexer API |
Nice-to-Have
| Feature | Status |
|---|---|
| Secondary market support | ❌ Not planned |
| Royalty distribution automation | ⚠️ Manual |
| Multi-chain deployment | ⚠️ Per-chain |
| Gas estimation | ⚠️ Basic |
Technology Stack
Current (emerge-turbo)
| Layer | Technology |
|---|---|
| Frontend | Next.js, React, Tailwind |
| State | Jotai, SWR |
| Tezos | Taquito, Beacon SDK |
| EVM | Viem, Dynamic Labs |
| Database | PostgreSQL, Prisma |
| API | Next.js API Routes |
External (Not Integrated)
| Layer | Technology |
|---|---|
| Smart Contracts | Solidity, Hardhat, OpenZeppelin |
| Indexing | Ponder, PostgreSQL |
| Real-time | Socket.io |
| Reference SDK | Wagmi, RainbowKit |
Next Steps
- Validate external repos - Ensure emprops-hardhat and emprops-ponder compile and work
- Plan integration - Follow ADR-019 for migration strategy
- Migrate contracts - Move to
packages/nft-contracts - Deploy indexer - Set up
apps/nft-indexer - Connect UI - Wire emprops-studio to indexer API
Related Documentation
Current Development Focus
- Arbitrum Integration - Primary development target
- Technical Architecture - System design details
- Development Plan - Phase breakdown
Technical Reference
- Smart Contracts (Hardhat) - Contract documentation
- Blockchain Indexer (Ponder) - Indexer API and schema
- React Web3 Patterns - Frontend patterns
Planning & Architecture
- Integration Evaluation - Feasibility analysis
- Implementation Plan - Migration roadmap
- ADR: NFT Minting Infrastructure - Architecture decision
