I built a decentralized chat dapp // GUN web3 Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

This is bonkers. I saw this video earlier and I'm still puzzled by how it all works behind the scenes. I've tried reading the docs and the PDF presentation (from TEDTalk) but I still don't understand their explanation of the conflict resolution algorithm (HAM). It's actually wild.

๐Ÿ‘๏ธŽ︎ 4 ๐Ÿ‘ค๏ธŽ︎ u/Der_Jaegar ๐Ÿ“…๏ธŽ︎ Sep 05 2021 ๐Ÿ—ซ︎ replies

Sorry to go off-topic but what software did you use to create this video? (It's really slick)

๐Ÿ‘๏ธŽ︎ 1 ๐Ÿ‘ค๏ธŽ︎ u/cp-sean ๐Ÿ“…๏ธŽ︎ Sep 06 2021 ๐Ÿ—ซ︎ replies
Captions
i recently built a chat app that can handle thousands of messages per second scales around the world and cost me nothing to run but the real weird thing about it is that the data and infrastructure is not controlled by a big tech company instead it's decentralized across the entire user base using web technologies in fact you can chat with me right now on the live demo by going to gunchatdap.web.app again that's gunchatdap.web.app and i'm trusting you not to hack it to pieces this time in today's video we'll build a decentralized chat app or dap if you prefer similar to youtube super chat using a library called gun js in the process you'll learn about the benefits of building a decentralized app along with the weird trade-offs and challenges for the front end ui we'll use svelt a javascript library that's not sponsored by big tech if you're new here like and subscribe and you'll find the full source code on github then i want to give a shout out to mark nadal the creator of gun js who donated a bunch of his time to answer all my questions and help make this video happen before we jump into the code let's first answer the question of how does this thing actually work i made a short video about gun js a few weeks ago and you guys had a ton of questions about it at a high level gun js is a decentralized graph database a normal database would store all of your data in a hard disk somewhere in the cloud it may be sharded across multiple machines but for all intents and purposes you can imagine your entire data set on a single disk gun on the other hand stores a small subset of data on each user based on the actual data that they consume in the application when a user makes a query for some data it will search across the network for other users that have that data and sync it up using technologies like webrtc so you can think of the entire database as the union of all peers on the network the idea is very similar to a blockchain ledger where no one individual has control of the entire network but it's important to point out that this is not blockchain technology which tends to be too slow and just unnecessary to build something like a super chat however it does rely heavily on cryptography to implement things like user authentication when you create a new user account a cryptographically secure key pair is generated the username is associated with a public key so past messages can be found and the password is a proof of work seed to prove and decrypt access to the account's private keys in addition it's possible to implement end-to-end encryption which we'll do in this demo but we'll talk more about that later in the video another good question is how is data persisted and what happens if a user just clears out their browser cache by default data is stored in the browser's local storage which is limited to 5 megabytes and if a user clears out the data in local storage it could potentially be lost if it's not somewhere else on the network that's probably not acceptable if you're building a production grade app but what you can do is deploy a relay server that uses a different storage mechanism called radix that can store a lot more data on the disk of an actual server and that makes the network more robust because a query can fall back to a relay if it's not available from another peer now another really important concept to understand is that when you create a node in the database it'll be available to the entire decentralized network that means another developer can easily access your public data by simply knowing the name of the node where it's stored now it is possible to encrypt data and things like that but it just requires a completely different mental model than you might be used to let's go ahead and jump into the source code i'm not going to cover every single line of code in this project and instead just focus on the important parts related to the database what we have here is a spelt app with two main features email password user authentication and then a massive group chat room that anybody can join the only dependency in this project is gun which can be installed with npm the first thing we'll focus on is user authentication and to do that i'm creating a file called user.js at the top of the file we'll import gun and below that import two supporting libraries the first one c which stands for security encryption and authorization and is the module that enables user authentication next we have ax which stands for advanced exchange equation and is basically an alternative way to connect peers together and tends to be more performant for a chat app like this and there's a whole dock on it if you want to learn more from there we'll create a variable called db to initialize the database then we'll use it to make a reference to the currently authenticated user i'm also chaining the option of recall to session storage here so the user stays logged in between browser sessions now to manage the user in the app we need to know if the user is logged in and we also want their username so we can show it in the ui we can get the username by making a reference to the user then calling git alias which will be the value of whatever username they choose when they sign up now we're going to use this value frequently throughout the application so i'm importing writable from spelt store to make it reactive a store is like an observable value that will re-render the ui whenever it's changed and it can be shared across multiple components so whenever the alias for the current user updates we'll set the value of the store to that value but we also want to listen to changes to the auth state when the user signs in or signs out to handle that we'll listen to the auth event on the database and basically do the same thing here where we fetch the alias and then set that as the value on the store now i'm going to kind of do things in reverse here because i first want to show you how the store works in spelt we have this header component here that will show the title of the app if you're not logged in but if you are logged in it'll show your username as well as your avatar now implementing sign out is really easy all we have to do is import the username store and the gun user object then we'll create a function called sign out that calls leave on the user and sets the username store to an empty string then down in the html we have a button that when clicked we'll call the sign out function but we only want to show that button if the user is signed in and the way we can tell if a user is signed in is if their username is present the cool thing about svelt is that we can easily do that with a store in any component by adding an if statement followed by a dollar sign and then the name of the store the dollar sign will subscribe to the store and react to any changes that happen to it if the username does exist then we'll go ahead and show the username by subscribing to the store once again we can also do the same thing to show an avatar with the user's initials by using the awesome dicepare api i made a short video about this already but dicebear will basically make a unique avatar based on the username as the random seat then after that we have a button that fires the sign out function when clicked and finally we'll add an else block here to show something else if the user is not logged in that takes care of the header component and you'll notice that i'm declaring it here in the app component and now we can move on to the login component that will allow the user to sign in or sign up with their username and password in the component we'll import the user object then set up local state for the username and password in svelt we can implement two-way data binding with a variable by creating a form input and then saying bind value to that variable that means anytime the user types into the form the value of the variable will change we have separate form inputs for username and password and we'll share them for both the login and signup process which itself just consists of two different buttons that will either call the login function or the sign up function to log a user in we use the user auth method it takes the username and password as arguments then the third argument allows you to define a callback in this case the value of the store that we set up earlier will update automatically but we can do other things here as well like error handling now the process to sign up a new user is very similar but instead of calling auth we call that create method on the user and if the user creation is successful then we will log that user in automatically now at this point we have a working user authentication system but one thing to keep in mind here is that we're not enforcing the uniqueness of the username which is just a caveat you'll want to keep in mind i should mention that it is possible to enforce username uniqueness but it's beyond the scope of this video now we can move on to the chat component which is where we will query items from the database and also give the user the ability to send a message the component has two pieces of state a string for a new message that the user will type into a form input and an array of messages which will contain the message text along with the user who sent it and a time stamp to query messages i'm going to set up the on mount lifecycle hook that will run whenever the component is first initialized inside of it we'll use the database to make a reference to the chat node in this demo since we have one giant super chat we can just give it a name of chat but if you have multiple chat rooms you'd likely want to give each one a different name after that we'll call map to basically loop over every single message in the chat and then call once to only read each message once in this case each message is immutable so we don't need to listen to changes in real time but you could do that if you wanted to using the on method we can then define a callback that will be called on each new message that will give us access to the data and the id of that node now if the data is defined we're going to format a message that's more suitable for the ui with the properties of who what and when who is the user that sent the message and we can figure out who sent it by taking that data of the raw message and using it to get the alias next we have what which is the actual text of the user's message but the interesting thing here is that we're actually implementing end-to-end encryption that means the value in the database is encrypted and the only way to decrypt it is to have the corresponding key in this demo our data is encrypted but it's not really secure because i'm just hard coding the encryption key right here in the source code so anybody could find it but if it was an actual secret between two users you could use it to encrypt and decrypt messages and finally we have the win property to get an accurate timestamp across all of our users we're using gun state as the final source of truth with the raw data that'll give us all the data we need for the ui then the final step is to take each message and add it to an array that we can then loop over in the ui with spelled you can loop over an array of items in svelt with each this will render the chat message component for each message in the array and also notice how i'm adding parentheses with message win which provides felt with a unique key to sort all of the messages efficiently that gives us a way to read messages in the chat now we just need a form to submit them in the ui you'll notice that i have a form that on the submit event we'll call the send message function inside the function the first thing we'll want to do is use c to encrypt the actual message text and notice how the key is the same as the one we used earlier to decrypt the messages from there we can associate the message to the current user using the encrypted message as the value then we'll create a date to serve as the index for the message so it can be sorted properly at which point we can reference the chat collection create a new node based on that index and store the message value congratulations you just built a decentralized chat app it'll be interesting to see if this thing actually works when the video is released let me know how things go for you in the comments make sure to like and subscribe thanks for watching and i will see you in the next one
Info
Channel: Fireship
Views: 256,670
Rating: undefined out of 5
Keywords: webdev, app development, lesson, tutorial, web3, js, javascript, blockchain
Id: J5x3OMXjgMc
Channel Id: undefined
Length: 10min 47sec (647 seconds)
Published: Tue Aug 31 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.