Sol.College

Full lesson

CreatorPass

This is a decentralized web3 project that features content creation, management and content gatekeeping with NFT's and smart contracts ::: LEARN MORE IN README

What it does

From the project README:

I'll like to take account for my numerous commits to this project in a short timeline. Due to hardware limitations, my laptop struggled to build the project's Next.js server locally because of it's size. To ensure smooth development, I relied on Vercel’s CI/CD pipeline for builds and debugging. After every push, Vercel automatically compiles the project, and I review the build logs to fix any errors. This approach ensured continuous progress despite local limitations.
Original
Alivexem/CreatorPass
SuperStack fork
Blockchains/CreatorPass @ c5c8774
Stars
1
Last push (original)
2025-05-16
Languages
TypeScript, JavaScript, CSS
Detected stack
MetaplexNext.jsweb3.js
Categories
NFTs & Digital AssetsConsumer & Social
Licence
MIT
Homepage
https://creator-pass.vercel.app

Architecture

89 source files. By extension: .tsx ×41, .ts ×31, .js ×17.

Top-level directorySource files
app43
components21
models9
utils7
types4
(root)3
libs1
commentSchema1

Dapp: devnet deploy pending

⏳ Devnet deploy pending — goes live when the devnet wallet is topped up. This fork's own dapp is not deployed yet, so there is no program address or transaction to show. It is queued in dapp-queue.txt; once devnet SOL is available it is deployed, exercised with real devnet transactions, and this section switches to the live dapp at /dapps/creatorpass/. Until then, the lesson and step-by-step guide below are complete, and you can run it locally with the commands below.

Key code, explained

Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.

Alivexem/CreatorPass · app/passes/page.tsx L397–420 @ c5c8774 · MIT · original
            ASSOCIATED_TOKEN_PROGRAM_ID        );         const [metadataAddress] = PublicKey.findProgramAddressSync(            [                Buffer.from('metadata'),                TOKEN_METADATA_PROGRAM_ID.toBuffer(),                mintKeypair.publicKey.toBuffer(),            ],            TOKEN_METADATA_PROGRAM_ID        );         console.log('Creating transaction...');        const transaction = new Transaction();        const blockHash = await connection.getLatestBlockhash();        transaction.recentBlockhash = blockHash.blockhash;        transaction.feePayer = walletPubkey;         // Calculate payment splits        const totalPayment = Math.floor(pass.price * LAMPORTS_PER_SOL);        const platformPayment = Math.floor(totalPayment * 0.2); // 20%        const creatorPayment = totalPayment - platformPayment; // 80%         if (!platformAddress) {
  1. Line 400 const [metadataAddress] = PublicKey.findProgramAddressSync(: Derives a PDA from seeds and the program ID and returns the address with its canonical bump.
  2. Line 411 const blockHash = await connection.getLatestBlockhash();: Fetches a recent blockhash. Transactions expire if it gets too old.
Alivexem/CreatorPass · app/creator/[id]/page.tsx L97–120 @ c5c8774 · MIT · original
     const handleSendTx = async (amount: number, receiver: string) => {        try {            const lamports = amount;            const latestBlockhash = connection ? await connection.getLatestBlockhash() : null;            const walletAddress = localStorage.getItem('address') || '';             const transaction = new Transaction({                feePayer: new PublicKey(walletAddress),                recentBlockhash: latestBlockhash?.blockhash,            }).add(                SystemProgram.transfer({                    fromPubkey: new PublicKey(walletAddress),                    toPubkey: new PublicKey(receiver),                    lamports: lamports,                })            );             const signature = connection ? await walletProvider.sendTransaction(transaction, connection) : null;            console.log(signature);                        setToast({                show: true,                message: 'Gift sent successfully!',
  1. Line 101 const latestBlockhash = connection ? await connection.getLatestBlockhash() : null;: Fetches a recent blockhash. Transactions expire if it gets too old.
  2. Line 115 const signature = connection ? await walletProvider.sendTransaction(transaction, connectio: Submits the signed transaction to the cluster.
Alivexem/CreatorPass · components/CreatorChat.tsx L493–516 @ c5c8774 · MIT · original
        throw new Error('Wallet not connected');      }       const lamports = Math.floor(parseFloat(giftAmount) * LAMPORTS_PER_SOL);      const latestBlockhash = await connection.getLatestBlockhash();       const transaction = new Transaction({        feePayer: new PublicKey(userAddress),        recentBlockhash: latestBlockhash.blockhash,      }).add(        SystemProgram.transfer({          fromPubkey: new PublicKey(userAddress),          toPubkey: new PublicKey(creatorAddress),          lamports,        })      );       const signature = await walletProvider.sendTransaction(transaction, connection);            // Generate gift card image      if (giftCardRef.current) {        const giftImage = await toPng(giftCardRef.current);                // Send gift message with updated text format
  1. Line 497 const latestBlockhash = await connection.getLatestBlockhash();: Fetches a recent blockhash. Transactions expire if it gets too old.
  2. Line 510 const signature = await walletProvider.sendTransaction(transaction, connection);: Submits the signed transaction to the cluster.

How to run, build and test

These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.

DirectoryCommandRuns
.npm run devnext dev
.npm run startnext start
.npm run buildnext build
.npm run lintnext lint

What you could build from it

Used in lessons