Tutorials
Video: Token Gated Chat

Video: Token Gated Chat

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

Deployed app

View a deployed version of the app: Token gated chat app (opens in a new tab)

Code

View the code on Github: Token gated chat app (opens in a new tab)

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;
  }
}

Polybase DB Docs