Skip to content

monad-developers/next-serwist-privy-camera-nft

Repository files navigation

Next.js 14 + Privy + Serwist + Camera NFT

A modern, full-stack Progressive Web Application built with Next.js 14, featuring Web3 authentication with Privy, camera photo NFT minting, and offline capabilities powered by Serwist.

πŸš€ Features

  • πŸ“Έ Camera NFT Minting: Capture photos with your camera and mint them as NFTs on Monad testnet
  • πŸ” Web3 Authentication: Seamless wallet connection and user authentication using Privy
  • 🌐 IPFS Storage: Decentralized storage for images and metadata via Pinata
  • πŸ“± Progressive Web App: Full PWA capabilities with offline support via Serwist
  • πŸ”” Push Notifications: Web push notifications for user engagement
  • πŸŒ™ Dark/Light Mode: Responsive design with theme support
  • πŸ“± Mobile-First: Optimized for mobile devices with install prompts
  • ⚑ Modern Stack: Built with Next.js 14, TypeScript, and Tailwind CSS

πŸ›  Tech Stack

  • Frontend: Next.js 14, React 18, TypeScript
  • Styling: Tailwind CSS
  • Web3: Privy, Wagmi, Viem, Monad Testnet
  • NFT Storage: IPFS via Pinata
  • Camera: MediaDevices API, Canvas API
  • PWA: Serwist (Service Worker)
  • State Management: TanStack Query
  • Notifications: Web Push API

πŸ“‹ Prerequisites

Before you begin, ensure you have the following:

  • Node.js (v18 or higher)
  • npm or yarn
  • A Privy account and App ID from privy.io
  • A Pinata account and JWT token from pinata.cloud
  • MON tokens for gas fees on Monad testnet
  • A device with camera access (for NFT minting)

πŸš€ Quick Start

1. Clone the Repository

git clone https://github.com/monad-developers/next-serwist-privy-camera-nft
cd next-serwist-privy-camera-nft

2. Install Dependencies

npm install

3. Environment Configuration

Create a .env.local file in the root directory:

# Option 1: Copy from example (if .env.example exists)
cp .env.example .env.local

# Option 2: Create manually
touch .env.local

Add the following environment variables to your .env.local file:

#Β Privy 
NEXT_PUBLIC_PRIVY_APP_ID=your_privy_app_id_here
NEXT_PUBLIC_PRIVY_CLIENT_ID= # optional, you can leave this empty

# Web Push
WEB_PUSH_EMAIL=user@example.com
WEB_PUSH_PRIVATE_KEY=your_vapid_private_key
NEXT_PUBLIC_WEB_PUSH_PUBLIC_KEY=your_vapid_public_key

# Pinata Configuration (Required for IPFS - get from Pinata Dashboard)
PINATA_JWT=your_pinata_jwt_token_here

# NFT Contract Configuration (Required after deployment)
NEXT_PUBLIC_NFT_CONTRACT_ADDRESS=your_deployed_contract_address_her

Important: Replace all placeholder values with your actual credentials. Follow the steps below to obtain these values before running the application.

4. Generate VAPID Keys

Generate VAPID keys for web push notifications:

npx web-push generate-vapid-keys --json

Copy the generated keys to your .env.local file.

5. Get Privy App ID

  1. Visit privy.io and create an account
  2. Create a new app, choose Web as the Platform and create the app
  3. Right after creating the app, copy the App ID
  4. Add the App ID to your .env.local file

πŸ“Έ Camera NFT Setup

Configure Pinata for IPFS

  1. Sign up at Pinata
  2. Go to API Keys section
  3. Generate a new JWT token with permissions:
    • βœ… pinFileToIPFS (required for uploading files)
    • βœ… pinJSONToIPFS (required for uploading metadata)
  4. Add it to your .env.local file as PINATA_JWT

Deploy NFT Contract

Deploy the provided contracts/PhotoNFT.sol contract to Monad testnet using Remix IDE or Hardhat/Foundry:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract PhotoNFT is ERC721 {
    uint256 private _nextTokenId;
    mapping(uint256 => string) private _tokenURIs;
    
    constructor() ERC721("Camera Photo NFT", "PHOTO") {
        _nextTokenId = 1;
    }
    
    function mint(address to, string memory uri) public {
        uint256 tokenId = _nextTokenId++;
        _safeMint(to, tokenId);
        _tokenURIs[tokenId] = uri;
    }
    
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_ownerOf(tokenId) != address(0), "Token does not exist");
        return _tokenURIs[tokenId];
    }
}

Deployment Options:

Option A: Using Remix IDE

  1. Go to Remix IDE
  2. Create a new file and paste the contract code
  3. Compile the contract (Solidity version ^0.8.19)
  4. Connect to Monad testnet via MetaMask
  5. Deploy the contract
  6. Copy the deployed contract address

Option B: Using Hardhat/Foundry

  1. Set up a deployment script
  2. Configure Monad testnet in your config
  3. Deploy using your preferred tool

Update Contract Address

After deploying your contract, update the .env.local file:

NEXT_PUBLIC_NFT_CONTRACT_ADDRESS=0xYourActualContractAddress

πŸƒβ€β™‚οΈ Running the Application

Development Mode

npm run dev

The application will be available at http://localhost:3000.

Production Mode

For full PWA functionality (including install prompts):

npm run build && npm run start

Note: The install app button only works in production mode (npm run build && npm run start)

πŸ“± PWA Features

Installation

  • Desktop: Install button appears in supported browsers
  • Mobile: Add to Home Screen prompts on iOS/Android
  • Offline: Service worker enables offline functionality

Push Notifications

The app includes web push notification capabilities for user engagement and updates.

πŸ”” Notification Setup

Important

Enable notifications for the best experience!

To receive push notifications from this app, you need to enable notifications in your browser and/or system settings:

Browser Settings

Chrome/Edge:

  1. Click the lock icon πŸ”’ in the address bar
  2. Set "Notifications" to "Allow"
  3. Or go to Settings β†’ Privacy and security β†’ Site Settings β†’ Notifications

Firefox:

  1. Click the shield icon πŸ›‘οΈ in the address bar
  2. Turn off "Enhanced Tracking Protection" for this site (if needed)
  3. Allow notifications when prompted
  4. Or go to Settings β†’ Privacy & Security β†’ Permissions β†’ Notifications

Safari:

  1. Go to Safari β†’ Settings β†’ Websites β†’ Notifications
  2. Find your site and set it to "Allow"

System Settings

macOS:

  1. System Preferences β†’ Notifications & Focus
  2. Find your browser and ensure notifications are enabled
  3. Check "Allow notifications from websites" in browser settings

Windows:

  1. Settings β†’ System β†’ Notifications & actions
  2. Ensure your browser can send notifications
  3. Check browser notification settings

iOS:

  1. Settings β†’ Notifications β†’ [Your Browser]
  2. Enable "Allow Notifications"
  3. Also enable in browser settings

Android:

  1. Settings β†’ Apps β†’ [Your Browser] β†’ Notifications
  2. Enable notifications
  3. Check browser notification permissions

πŸ”§ Backend Integration Required

Note

The SendNotification.tsx component is sample code that requires backend implementation:

  • Save subscription data when users subscribe (see TODO comments in code)
  • Delete subscription data when users unsubscribe
  • Implement /notification endpoint to send actual push notifications
  • Use web-push library or similar for server-side notification delivery

🎨 Customizing Notification Content

To customize your push notification content, edit app/notification/route.ts and modify the title, message, icon, and other properties in the sendNotification call.

Changing the app name

  • Edit the manifest.json file
  • Change the name and short_name fields
  • Run npm run build to update the app

πŸ”§ Project Structure

next-serwist-privy-camera-nft/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ components/          # React components
β”‚   β”‚   β”œβ”€β”€ CameraNFT.tsx   # Camera NFT minting component
β”‚   β”‚   β”œβ”€β”€ InstallPWA.tsx  # PWA install prompt
β”‚   β”‚   β”œβ”€β”€ UseLoginPrivy.tsx # Privy authentication
β”‚   β”‚   └── ...
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   └── upload-ipfs/    # IPFS upload API route
β”‚   β”œβ”€β”€ ~offline/           # Offline page
β”‚   └── ...
β”œβ”€β”€ contracts/
β”‚   └── PhotoNFT.sol       # NFT smart contract
β”œβ”€β”€ public/                 # Static assets
└── ...

πŸ”— Key Components

  • CameraNFT: Complete camera capture and NFT minting functionality
  • UseLoginPrivy: Privy authentication integration with Monad testnet
  • InstallPWA: PWA installation prompts
  • upload-ipfs API: Handles file uploads to IPFS via Pinata

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ†˜ Support

If you encounter any issues or have questions:

  1. Join Monad Dev Discord
  2. Review the Privy documentation
  3. Check the Pinata documentation
  4. Visit Monad Explorer to view transactions
  5. Check the Next.js 14 documentation
  6. Check the Serwist documentation

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published