Chopin
GuidesNFT

NFT

This guide is a work in progress. While it is generally accurate, it has not been fully tested.

Before starting this tutorial, be sure to have a Chopin Framework project set up. If you don't have one, follow the Quickstart guide to get started.

Overview

In Chopin Framework, NFTs are simply defined by your database and backend. There is no need to define an NFT contract. In this guide, we will present an idea for how you could create NFTs using Next.js and a PostgreSQL database.

You could use this method to add collectibles to your app—or to use Chopin Framework for traditional NFT usecases. However, keep in mind this is a technical guide and not legal advice.

Collections and NFTs

You can store NFT collections and individual NFTs in tables.

CREATE TABLE collections (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    symbol VARCHAR(255) NOT NULL,
    base_uri VARCHAR(255)
);
 
CREATE TABLE nfts (
    id SERIAL PRIMARY KEY,
    collection_id INTEGER NOT NULL REFERENCES collections(id),
    metadata JSONB,
    owner VARCHAR(42) NOT NULL REFERENCES users(address),
);

Or you can omit the collection_id column and the collection table if there is only one collection.

Collection Creation

export async function createCollection(name: string, symbol: string, base_uri?: string) {
    await sql`INSERT INTO collections (name, symbol, base_uri) 
        VALUES (${name}, ${symbol}, ${base_uri})`;
}

NFT Operations

Minting

export async function mint(
    collection_id: number, 
    owner: string,
    metadata: object
) {
    await sql`INSERT INTO nfts (collection_id, owner, metadata)
        VALUES (${collection_id}, ${owner}, ${metadata})`;
}

Checking Ownership

export async function getOwner(collection_id: number, id: number) {
    const result = await sql`
        SELECT owner 
        FROM nfts 
        WHERE collection_id = ${collection_id} 
        AND id = ${id}`;
    return result[0]?.owner;
}

Transferring

import { getAddress } from '@chopinframework/next';
 
export async function transfer(
    to: string,
    collection_id: number,
    id: number
) {
    const from = getAddress();
    const owner = await getOwner(collection_id, id);
    
    if (owner !== from) {
        throw new Error('Not the owner');
    }
 
    await sql`
        UPDATE nfts 
        SET owner = ${to} 
        WHERE collection_id = ${collection_id} 
        AND id = ${id}
        AND owner = ${from}`;
}

Usage

Now you can control when this is invoked on the frontend by calling these functions in API routes. For example, here is a Next.js route that would allow a user to transfer an NFT.

import { getAddress } from '@chopinframework/next'
import { transfer } from '@/nft';
 
export async function POST(req: Request) {
    const { to, collection_id, id } = await req.json();
    const from = getAddress();
    
    await transfer(from, to, collection_id, id);
    return new Response('NFT transferred successfully');
}

Bridging

Bridging is a work in progress. More information will come soon. It will eventually be possible to transfer NFTs from your database to a third-party blockchain—and vice versa.