LiveTheLifeTV
  • The Future of Photography?
  • LTL Art Collective
    • Auction House
      • Photogrammetry
      • GVO Premint
      • MetaVerse
    • Culture Code
      • Vision / Mission
      • The Bear Market
    • Dream Team
      • Dimitri Daniloff
      • Official Links
  • LTL Workstreams
    • The Summary ⌐◨-◨
    • Creative Design ⌐◧-◧
      • Brand Guide
      • Experimental
        • The Blind Mint
        • Oncyber 1/1
    • Engineering ⌐◫-◫
      • GVO Free Mint
      • Auction House
      • Experimental
        • Play Grounds
          • AllianceDAO
          • DAOhaus
        • Archived (TBD)
          • NFT Component
          • Dynamic Rarity
          • Bankless Loans
          • ERC 1271
          • Optimism
          • Tokenomics
          • Charged Particles
          • Fair Launch
          • Gitflow
          • Audit
          • ENS polygon
        • Web3 Travel
        • Lens Protocol
        • NFT LootBox
        • NFT Staking
    • Operations ⌐◪-◪
      • Governance
      • SnapShot
      • Discord TBD
    • Treasury & Legal ⌐Ξ-Ξ
      • Onchain LLCs
      • Web3 Grants
      • Fundraising
      • JuiceBox
      • Pre-Seed
      • Fairmint
      • Web3 VC
      • License
    • Partnerships ⌐◩-◩
      • TDM Drops
      • Spatial
      • Token Proof
      • MF + HaLo
      • Whitewall
      • Art Link
      • Anima Supply AR
      • One Tree Planted
      • Klima
    • Marketing & PR ⌐◮-◮
      • MPR Strategy
      • FAQ by Dyno
    • Community Vibes ⌐◭-◭
      • Degen Vibes
        • Degen Vibes Proposal
        • Snapshot Delegate
        • The NounsDAO
      • CC Monthly #01
      • Collectors Club
      • IRL Wine Tasting
      • IRL Experiences
  • LTL Tool Box
    • Creator
      • New To NFTs?
      • Davinci Resolve
      • Capture One
      • Photogrammetry
        • MetaShape
        • ZBrush
        • Capture Reality
        • Blender 3D
      • IRL Workshop
    • Frontend
      • Basics
        • NextJS
        • Tailwind
        • SASS SCSS
        • Bun
        • Vite / Rainbow
        • Postgres
        • ImageKit
        • Vercel
        • Kafka
        • Factoria
      • Web2
        • Ghost
        • Shopify
        • Webflow
    • Backend
      • Fleek
      • Spheron
      • TableLand
      • FileBase
      • Arweave
      • Prisma
      • Sanity GROQ
      • PlanetScale
      • HandShake
    • Contracts
      • Manifold
      • AsyncArt
      • Niftykit
      • Buildship
      • VerisArt
      • Hashlips
      • Bunzz
      • BuildSpace
      • Foundry
    • NFT SDKs
      • Zora V3
      • Rarible
      • Seaport
      • Foundation
      • SudoSwap
    • NFT APIs
      • Reservoir
      • SimpleHash
      • Alchemy
      • Moralis
      • OpenSea
      • NFTport
Powered by GitBook
On this page
  1. LTL Tool Box

Backend

PreviousWebflowNextFleek

Last updated 2 years ago

This solution requires manual schema creation. It also requires the usage of Node.js The Node.js API Starter Kit is probably the most basic approach to getting a GraphQL API up and running. It’s a boilerplate project that comes with all the Node.js libraries needed to connect to a Postgres DB, running an HTTP server and create GraphQL schema and resolvers. It’s a good start for projects that need full control in every part of their API.

db.ts

import { PrismaClient } from '@prisma/client';

export const prisma = new PrismaClient();

constants.ts

export const PORT = process.env.PORT || 3000;

app.ts

import express, { Request, Response } from 'express';
import helmet from 'helmet';
import * as bodyParser from 'body-parser';
import cors from 'cors';
import { PORT } from './constants';
import morgan from 'morgan';
import { upsertUser, getUserByWalletAddress } from './controllers/user';
import { getNfts, listNft } from './controllers/nft';

const app = express();

app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.use(helmet());
app.disable('x-powered-by');
app.set('json spaces', 2);
app.use(morgan('tiny'));

app.get('/', (req: Request, res: Response) => {
  res.send({
    ok: true,
    message: 'App is running'
  });
});

app.get('/api/user/:walletAddress', async (req: Request, res: Response) => {
  try {
    const { walletAddress } = req.params;
    const user = await getUserByWalletAddress(walletAddress);

    res.send({
      ok: true,
      user
    });
  } catch (e) {
    res.status(500).send({
      ok: false,
      error: 'User was not found'
    });
  }
});

app.post('/api/user', async (req: Request, res: Response) => {
  try {
    const { body } = req;
    const user = await upsertUser(body);

    res.send({
      ok: true,
      user
    });
  } catch (e) {
    console.log(e);
    res.status(500).send({
      ok: false,
      error: 'Could not create user'
    });
  }
});

app.post('/api/nft', async (req: Request, res: Response) => {
  try {
    const { body } = req;
    const nft = await listNft(body);

    res.send({
      ok: true,
      nft
    });
  } catch (e) {
    console.log(e);
    res.status(500).send({
      ok: false,
      error: 'Could not list nft'
    });
  }
});

app.get('/api/nfts', async (req: Request, res: Response) => {
  try {
    const nft = await getNfts();

    res.send({
      ok: true,
      nft
    });
  } catch (e) {
    console.log(e);
    res.status(500).send({
      ok: false,
      error: 'Could not get nfts'
    });
  }
});

app.listen(PORT, () => {
  console.log(`App running on port ${PORT}`);
});

controllers/nft.ts

import { prisma } from '../db';

export const listNft = async (nft: {
  contractAddress: string;
  type: string;
  tokenId: number;
  royaltyReceiver: string;
  royaltyPercent: number;
  paymentAmount: number;
  paymentCurrencyAddress: string;
}) => {
  return await prisma.nft.create({ data: nft });
};

export const getNfts = async () => {
  return await prisma.nft.findMany();
};

controllers/users.ts

import { prisma } from '../db';

export const getUserByWalletAddress = async (walletAddress: string) => {
  return await prisma.user.findFirst({
    select: {
      walletAddress: true,
      id: true
    },
    where: {
      walletAddress
    }
  });
};

// TODO: Replace any type
export const upsertUser = async (userInfo: { walletAddress: string }) => {
  return await prisma.user.upsert({
    where: {
      walletAddress: userInfo.walletAddress
    },
    update: {
      walletAddress: userInfo.walletAddress
    },
    create: {
      walletAddress: userInfo.walletAddress
    }
  });
};

prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
    id        Int      @id @default(autoincrement())
    createdAt DateTime @default(now())
    walletAddress     String   @unique
}

model Nft {
    contractAddress         String
    type                    String // 1155 or 721
    tokenId                 Int
    royaltyReceiver         String
    royaltyPercent          Int
    paymentAmount           Int
    paymentCurrencyAddress  String
  @@unique([contractAddress, tokenId])
}

env.example

DATABASE_URL=postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public

LogoHeroku
LogoInstalling PostgreSQL on Local and Cloud | PostgreSQL Tutorial
LogoGitHub - kriasoft/relay-starter-kit: 💥 Monorepo template (seed project) pre-configured with GraphQL API, PostgreSQL, React, Relay, Material UI.GitHub
PostgreSQL database connector (Reference)Prisma
LogoBigchainDB • • The blockchain database.BigchainDB
are there solid decentralized alternatives to Hasura + Heroku + PostgresQL ?
Instant Real-time GraphQL on Postgres.
LFG