Skip to content

Files

Latest commit

029d50d · Mar 15, 2023

History

History
114 lines (88 loc) · 2.49 KB

token-gated-chat.mdx

File metadata and controls

114 lines (88 loc) · 2.49 KB
title
Video: Token Gated Chat

Watch Calum build an NFT-gated chat app with Polybase from scratch.

<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/YzPfCLQBGTI" title="Build an NFT Gated Chat App using Polybase | Tutorial by Calum" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

Deployed app

View a deployed version of the app: Token gated chat app

Code

View the code on Github: Token gated chat app

Schema

collection User {
  id: string;

  @delegate
  @read
  publicKey: PublicKey;

  // Called when a new record is created db.collection('User').create([])
  constructor () {
    // ctx.publicKey is populated if the user signs the call
    if (!ctx.publicKey) {
      error('You must sign the txn');
    }

    // .toHex() converts the public key to a hex string
    this.id = ctx.publicKey.toHex(); // 0x...

    // Store the public key so we can use it for permissions
    this.publicKey = ctx.publicKey;
  }
}

// Anyone can read NFT collection
@read
collection NFT {
  id: string;

  // The NFT delegates all responsibility it is given to the owner
  @delegate
  owner: User;

  // Called when new NFT created db.collection('User')
  //   .create(["nft-name", db.collection("User").record(userId)])
  constructor (id: string, owner: User) {
    this.id = id;
    this.owner = owner;
  }
}

collection Chat {
  id: string;
  name: string;
  
  @delegate
  @read
  members: NFT[];

  constructor (id: string, name: string) {
    this.id = id;
    this.name = name;
    this.members = [];
  }

  // Anyone who with an NFT in members can call this fn
  @call(members)
  addMember (nft: NFT) {
    // Maximum of 5 members
    if (this.members.length > 5) {
      error('Too many people in the room');
    }

    this.members.push(nft);
  }

  // Anyone who with an NFT in members can call this fn
  @call(members)
  setName (name: string) {
    this.name = name;
  }
}

collection Message {
  id: string;
  message: string;

  // Currently timestamp must be passed in from the client
  // so is untrusted
  timestamp: number;

  // You can read this record, only if you are 
  // part of the chat 
  @read
  chat: Chat;

  constructor (id: string, message: string, timestamp: number, chat: Chat) {
    this.id = id;
    this.message = message;
    this.timestamp = timestamp;
    this.chat = chat;
  }
}