Build a Stock Prediction App with NextJS & Solana!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we are going to be making stock prediction dap with an xjs I'll be showing you guys how to utilize something called the pith network if you don't know what the pith network is it delivers real-time on-chain Market data to the Solana blockchain you'll learn how to utilize this Oracle in your Solana smart contract to get real-time data on stocks like AMC Amazon Google and even crypto if you like as a bonus I'll show you guys how to make price predictions on these stocks so that you can bet money and win big and get some soul of course I'll also teach you how to connect your wallet to this app using Phantom wallet and also how to get your funding connected to your Solana program so without further Ado let's get started alright so here's the app in its full entirety with all the functionality working I have it open up twice because this needs two players so that means when you deploy this app you can have any of your friends or somebody else play against you to bet on the stocks of this app so as you can see 3w is player two 4A is going to be player one so and you have a couple options there's Bitcoin Amazon Google right so let's work with AMC for now and what we want to do is put a prediction out there so the current stock price is four so let's do something simple I want to make player one the winner so we're going to do four it's gonna be four dollars and two minutes essentially and I'll even bet two Solana for this so I hit submit and you can see when you approve the transaction it says send to Seoul so when I hit approve it's going to send it to a third-party account it's an escrow so when the BET's finished it's going to distribute it to the winner whether that's player one or player two let's hit approve and after a second you should see approved bet or failed to approve it and there you go created the BET and it should load we can go to player two and you can see the BET once it loads and there it is so let's enter this and I'll say eight dollars in two minutes it should be wrong and it's going to send two Soul as well because that is the uh pot amount to enter right so the player one always sets the pot amount so as you can see the total pot amount is four to the winner and now we can hit claim so if I go here this should update to claim and in just a second so now it's claim and after the two minutes is up we can go ahead and claim the BET and the cool thing is that no matter who is the winner you can still claim it so let's say player two lost you can still hit claim but the money will still go to the right person player a okay and let's set up in the logic which I'll show you later in the video so I'm gonna wait till the time is up and we can hit Clinton alrighty so I think enough time has passed so let's go to player a and claim the bet hey see that we received four Soul because that means Solana determined that we won and our prediction was closer to the actual price so let's hit proof claim bet and now you should see the state update so player A1 as well player a is on a win streak he's killing it he knows all the right answers so if you look now we have five cylinder when I just had three earlier and if he goes to player B if you look at his uh right here he should have two Soul right he had four now he has two there you go that is the demo so if you want to learn how to build this let's just Dive Right In All right so you're probably wondering how do I get started Lance well you could copy what I do as I get started but we have front end for you guys and all you have to do is use our CLI tool to get it so let's do command J and make sure you see the into a folder where you put your projects I put mine here so that's fine so all you guys have to write is npx cleverprogrammer at latest you'll get all the modules all the front end that you need and have access to every single build in our YouTube channel within the last year and from there you could copy and change these projects and add it to your own portfolio or follow along on YouTube so let's do npx clever programmer latest be sure to build this project with me and try to do it on your own as well so that you have a deep understanding of it so all you have to do to get access to everything is just type in your email address like so type in your name and ba or bam I said bot but there you go we have tons of projects here a lot of solidity a lot of Solana but the one that we care about is the Solana prediction app so hit enter and this will make sure that you have all the modules and files you need so there's no more of those node module dependency errors and all you have to do is just wait for this to finish and I'll open a new vs code for you so once that's done I'll cut back and we'll get started alrighty so if you made it this far you've successfully downloaded the files that you need to get started so all you have to do now is just say yarn Dev and start the server right it's going to be on localhost 3000 so you can do like a control click and if you do that your browser should open and you can see this is what we're working on it's different than the demo because if you look at the top right there's no Phantom wallet connection and none of the other features work just yet right our goal together is to make this static site work right so we can learn a lot about salonout by making this work together so right now it says creating BET right here which means it's just a function that just counts allows creating bit but nothing actually happens so what do we need to do first the first thing that we should probably do is let's get Phantom right so if you don't know what Phantom is it is a wallet that we can use to connect to our dapps right there's multiple different kinds of wallets but today we're going to be using Phantom so if you've never had Phantom before all you have to do is type in Phantom wallet and it's going to work with chrome because there's an extension for it so it's Phantom one extension is actually what you need now I hit Chrome and there it is I already have it so we're good to go and if you know how to set Phantom feel free to skip a little bit ahead in the video to the next part but go ahead and add this extension open up the Phantom here and it's going to ask you to set your password and remember your phrase so don't share that phrase anybody or I'll still be able to get into your wallet so I'm just going to write my password as you can see once you make an account you should see something like this so it says wallet number one I have nine Solana and you can go ahead and go to your settings just click this button right here developer settings and make sure your network is devnet I repeat make sure your net network is devnet otherwise a lot of your stuff isn't going to work there is also the mainnet which is your is going to use real Salt test net and devnet and localhost so again devnet and you should be good once that's done if you want to add some Salon to your wallets there's a couple different resources but you can use what I call Soul faucet just take your wallet right here and you can copy the address with this paste it on here you can add up to two and click devnet look at that successfully airdrops to Seoul and now let's see how much I have and we have 11 Solana so you stock up on Solana because we're going to be testing with it a lot so with that said you should have Phantom extension installed what we can do next is set it up on our app so we can we don't have to worry about the browser right now let's go ahead go to your vs code and we're going to be working on the index page or actually the underscore app page and now when you're in your app.js this is where we're going to set up the pro connection provider for our wallet and so that we can connect to the Solana chain so one thing that we can do to make our lives easier is if you go into the utils folder you'll see a couple files that I set up for you what you want to do is go to con constants.js and let's set up a couple different things the first thing I'm going to write is expert const RPC underscore endpoint all right if you don't know what our PC endpoint is this is essentially a node that we use to connect to the Solana blockchain and there's a lot of different uh endpoint providers out there like infuria um quick node Alchemy but today we're going to be using quick note all right so do something like this and all you have to do is go to quick note and let's get an endpoint together so we're going to go back to the browser right right here let's head over to quick note okay so go to quickenow.com or click in the link in the description so that you can get in right away all you have to do is Click sign in and create your or create your account so go ahead and do that verify your email and your endpoint should be good to go I already have an account so I'll just quickly log in and Bam once you confirm your email you should see uh something that says create your endpoint so right now I have this endpoint called bold stylish voice right but I'm going to go ahead and archive it so that we can create one together if it's your first time all right so feel free to use whatever endpoint you like meantime we'll do with this so archive that endpoint and this is the exact screen that you guys should see I'm gonna go click create an endpoint and again it supports multiple different chains eth Bitcoin polygon Avalanche right but we're using Solana of course and quick question which net are we going to be using main test net or devnet exactly good job George that's gonna be definite we're gonna go ahead continue there's a couple other extra features like an nft fetch tool but we don't need that let's just make the endpoint down in the bottom right all right give it a second there you go right guess what that's it that's all you have to do is set up an endpoint if you were to do this yourself it would take a lot longer so let's go ahead and click this copy and this HTTP provider and that's all we need so you can go back into your code now and in the quotes after you made this variable in your constant.js you should have one just paste that bad boy in there and guess what you have an end point ready all right so now that you have your endpoint and you're exporting we can now go back to our app and we're going to be using that endpoint soon to use it though all you have to do is if I make this bigger for you guys go into here if you export it you're allowed to do something like this restructure here and say RPC uh end point oh I think it's underscore endpoint and then you can see the Auto Import go ahead and click that or write it out like this and now now that uh endpoint is successfully imported into our underscore app right so that's not all that we need to do we need to import a lot of other things such as the Solano wallet um modules so I'm gonna go ahead and do that let's import the connection provider so I'll say connection provider and you can see this is coming from our module Solano wallet adapter react right so all these modules are already installed if you did it with our CLI tool if you didn't use our CLI tool go ahead and do yarn add this right here go and there's actually another thing that we need to get from Solana wallet adapter rack which is going to be a wallet provider okay so we need to provide the connection and then we need to provide the wallet this is how you can look at these Imports and it's cool because again Solana modules are helping us make it a lot easier for us so we can do is another import ant okay if you remember in any other videos when I click on the connect wallet button you should see a nice modal that comes up that shows the different wallets right I didn't make that myself you actually can get that provided for you from Solana as well as you can say wallet modal provider right here and you can see this is the module that it comes with so Solano wallet adapter react UI the next thing we're going to say import and I'm going to hit enter here because there could be a bunch of imports that you'd want but you can do a phantom wallet adapter and if you want to add more wallets put more options for the users you can add all the wallets here there's a couple different other adapters that Salon provides and you can get this from at Solana wallet adapter Dash wallets right here okay so once you do that that should be it for wallets we can do import this last thing which is the CSS so you can say uh Solana wallet adapter react UI and then the slash styles dot CSS right because if you don't have this we're going to have a really blank Phantom or connect wallet button rather okay so all of our actors are set now let's put it together [Music] so one thing I'm going to do is we've imported use state from react all right that was given to you what we need to do is make the state for something called mounted okay so to set up a state you're just going to say const uh mounted and then set I'm just going to SQL that to use State and the default for this is actually going to be false okay cool hit save and the next thing you want to do is let's set up all the wallets that we're going to use and like I said it's going to be one so make a variable called wallets and equal set it equal to use memo right and then to use use memo it's going to take an arrow function and then put this array here and then you're going to say new and let's use all our Imports so the first thing that we're going to use is this Phantom wallet adapter so we're gonna make a new instance of this adapter hit comma for this variable and hit save uh after this array it does need a dependency module so just do this cool and let's set up a used effect right because there is this SSR arrow with next so I just want to set up a use effect right here [Music] boom boom and then here we can set mounted to true okay and again let's add another dependency module right there cool all right so if you didn't know it in line 28 this component with dot dot dot page props this is what represents our index.js right so what we need to do is wrap all of our providers around our app right or our index so the first thing we can do is at the top say connection provider like so right if you're wondering where did my where am I getting this well we imported it right here now it's not grayed out and we could do is essentially just put it and wrap it like this so now our connection provider oops sorry about that but as I was saying what we did there was all we wrapped our app with this provider and we're gonna do the same thing with the wallet provider right so how it should go it should be the connection provider on the top and inside that is the wall provider and inside that is the modal provider okay makes sense so I'm going to enter right here and just say wallet provider okay and I'm gonna close it and then take this and put it right here right make sure that this closing wallet provider isn't under connection right because this is nested okay and then from there one more we're going to hit enter hit this curly bracket right so we can use some jsx and what we want to do here is essentially say mounted and and all right so where's my and button right so this means if this is true right then we can load our app right because then we know that it's mounted and put the component inside of that okay cool and actually above that is the model provider so we can say wallet model provider amazing so this is how it should look connection wallet wallet model and then this mounted check right here it wants to make sure this is true and then we'll load the index okay cool and this will automatically become true because the use effect is going to run this right when the app or this app.js component loads okay and the next thing we should do is let's put in a couple different properties right so in this connection provider the opening tag if you hit enter it has a uh prop or attribute called endpoint and it's going to take in an endpoint that we use so um we're going to use our RPC endpoint right so now it's coming into play essentially it's going to be what it looks like underneath the hood is quotes and then your long link that you have so we have that stored in the variable so we can just write this okay and next it should take in this Con fig and it's going to be equal to object object commitment and you're going to say confirmed awesome one more thing it's going to be the wallet provider we need to provide this with the wallets that we set up which we did with this variable right so kind of like the end point you're just going to go into the opening tag of this hit enter okay enter and then do wallets is equal to well well because that's what we call okay awesome and then there's another cool thing that we have uh built in which is the auto connect right so when you're already logged into your Phantom it'll automatically connect that wallet to your app if it's been connected before so this is a cool feature to have if you don't want this you don't have to have it alrighty that said we got our wallet set up right so how do we start using it well we have to figure out where we want to add this connection so if I go quickly back to my app and I asked you guys what component is going to be holding this connect wallet button right well if you ask me I think it's going to be what we have as the header component so go into your components it's nice and organized for you guys click on header.js and let's scroll to line 35 right there it is the connect wallet button so what can we do to start using the wallet that Salon provides for us we can just import it right so we can say import and it's called wallet a multi button like so see this all right hit save we can do now is remove this whole div and just use that very component wallet multi button okay all right so with that said let's take a look so I'm gonna go look into here and look at that there's my wallet and I've connected this before but this is what it would look like initially right so I can hit refresh if you want to see the full process you can hit select wallet and Bam all right if you want to give it more styling because it does look a little small right what we could do is I have styling ready and I think it's called menu item right I gave it that same styling so all you need to do is just put class name is equal to [Music] styles dot menu item so hit save there and Bam right it's not so it's small and Tiny anymore and it has that nice hover effect so don't be afraid if you don't want to use the default uh CSS styling of the button you can give it a custom one to match your theme so there you go we're connected guys this is it that's how you set up your Phantom connection let's move on to the next step alrighty so with that out of the way let's get to the main part of the video I xed out the quick note tab so if you don't need it go ahead and get rid of it what we need to do is head over to seoul.pg or rather beta.soul.pg or if you don't know what this is this is a browser where you can write your very own Salama smart contract usually we can use vs code and create our anchor project here but this is a nice tool that lets us test functions create functions and everything we need without downloading all the files that we usually do so if you've seen our other tutorials this is what we've been using so I can see this is our lib.rs our anchor file and each of these is part of the program this is called the account struct right with and every single function like this one right here initialize is going to have a struct that goes with it so let's get started the first thing we're going to do is let's create a new project actually and as you can see there's three different types of Frameworks native rust anchor which is a framework of rust and then now it supports seahorse python so if you want to see us use seahorse follow the Instagram tutorial where I use Python for that build so what we're going to do is write prediction right tap and hit create open select the framework bam cool so nothing should change right this is pretty much the app but let's go ahead and erase everything and start from scratched and before we move any further let's figure out what are we trying to do with this Solana smart contract well what do we know and this is called pseudocode so what I'm going to do is say prediction dap right and the goal of this smart contract is what right we need to get the price of the stock using the pith Network right or pyth and then the functionality of it because we can easily just get the price of the stock using this with the key but the fun part about this is that we're making it uh so that users can bet on if the stock is going to go high or low and during a certain amount of time so what we need is player a to choose an asset that's available in pith all right so that makes sense and and inputs the length of the bed right because that user should select something like AMC stock and say like hey within the next two minutes let's see if the price is going to go up or down okay that's player a and this is important because if we don't know how the logic works we might get into some trouble so this is for us to understand if you feel like you understand this and you just want to see me code skip a little bit ahead in the video and let's keep on going but player B though well other players can see all existing beds so after the bed is created all right so this is basically creating a bit create bet you can see all existing bets right so how does that have work well we're going to be able to fetch the bets right and then after that player B can match Penny bets so what does match mean to you guys so matching a bet let's say I create a bet over here and I bet two soul that AMC is going to go up in two minutes right player B will also a bit too so that could go down or go even higher right so that's why it's going to match any bet that's and inputs his own prediction okay does that make sense good awesome so another thing is uh if the timing is over whoever whoever is closest to the price can claim the whole amount right so if player one player one or player a bets two Soul player B matches that with another two Soul What's the total price that they get after winning it's gonna be four right so again logic is very similar to the lottery bet except now we're actually inputting our predictions here instead of just a random or semi-random uh algorithm cool alrighty cool so that should be enough pseudocode for now let's get to coding and one of the first things we need to do is import anchor Lang into our project right so usually in JavaScript you've seen like import anchor from whatever right but we are on Rust right now or rather anchor so to import it in Rust you just say use right you can see this little suggestion is helpful input right you're going to literally say use anchor underscore Lang and then colon colon right you can think of colon colon like us going into a folder right we're gonna CD into anchor Lang and if we do this we can destructure what we want inside of anchor link so what do I want inside of anchor Lang well there's going to be something called Prelude right and if I do a colon colon here what does that mean we're going inside Prelude exactly so you guys are getting it all right so what I want inside Prelude is going to be a star or an Asterix this means I want everything inside the Prelude right and then if you put a comma here we're gonna get something else that's inside is it going to be Prelude or anchor length you've got it it's gonna be inside of anchor Lang we can get something called system underscore program right and another key thing about anchor is make sure you put semicolons right semicolons Mark The End Of The Line in code in JavaScript it's not like that and you don't need to put it but here we do so if you see any errors it's probably because you missed a semicolon so now the important thing that we need to import is we need to be able to get the price of the stock using the network right so what we could do is say pith underscore SDK underscore salon right the pith network has an SDK that we can use in our Solana program to load the price feed into our smart contract right so we can get that by going into it right and we don't need to destructure it you can say load price oops price underscore feed from underscore account underscore info and then semicolon right don't worry about memorizing a lot of this for me I had to read a lot of documentation um test some code and I was like okay this is what we need right cool so we are using that library and the next thing we should do is we should have the declare ID all right so oops declare ID and I enter and looks like this right this is going to be where our uh the pub program key of our app is going to be right which essentially is the key to access this program on the Solana blockchain so for now you can just put empty quotes because when we press this build button it's going to generate that public key for us all right think of it as the address of this program on the salon chain okay cool and the next thing you need to do is use this program macro so you do a hashtag and the right program because everything underneath this is going to represent the program right so then right underneath it if you hit enter say mod prediction underscore dab right this is the name of the program right which we also have right here okay so if you want to change the name of your Solano Pro Smart contract like on chain change this all right next thing you can do is put these curly brackets and everything within these curly brackets represents the program right that's the code blue okay cool and now that you guys made the program what you write in between these query brackets is all the functionality right so this should be familiar to you right how do we make a function an anchor right so to make it I would just say Pub all right public FN and then the function name so if you open up the default version of beta soul.pg you would see something like initialize right we need to initialize our app in here so it's a function called initialize what do we need for this prediction dap well we need to do something called creating the master so let's call that create underscore Master right because before we can create bets right and have player a player B we need to set up what's called a master account that's gonna hold the information of our program and you know all the functionality okay so how do we make the rest of the skeleton of the function we're just going to say uh Arrow here and then you're going to say result right boom and then open and close it and then parentheses inside of there and put these curly brackets in there and that's it this is the skeleton of a function in Anchor right see this so function name right this is basically the result and then curly brackets to put the scope got it okay cool so what's next now usually when you're making a function in Anchor you have to create what's called a struct that goes along with it so we need to make well the master struct so usually you can do it right here but what we could do is just make another file right so go to right here under source and we should be able to make another file let's create let's go here new file there we go and this new file we can call it state DOT RS right make sure it's RS and in this file we'll hold all of our structs that go along with our function right I've done it before where you put it all inside of the program right but the idea is to organize it and split it to files and then import the states into our program okay so I'm just going to make a state.rs alright so go ahead and do that and once you do that we can use anchor laying colon colon Prelude colon colon star and then semicolon nice cool so make sure you're using anchor link and we're getting preload and how do we set up um the struct for creating the master [Music] so the first thing you have to do is use this macro called account right because these structs they're essentially opening up what we call accounts on Solana the closest thing I could think of to help you understand it is that think of it as a object that you're creating on the Solana blockchain and anytime you put stuff on this line of blockchain it's gonna cost some soul right you're going to pay for the space that you're using depending on the size so what we're doing here is we're creating the uh the struct of the master account like what is that Master object look like what kind of properties does it have right so to start doing that you do the hashtag account then you can say Pub struct Master right okay and after that we can Define what is the master right uh this is going to make more sense to you if we make the bet but think about the reason we need the master is because we want to keep track of the last bet ID right so that every time we make a new bet we can just increment the master so we know how many bets exist so we could say Pub last underscore bet underscore ID and then colon right another thing that you need to know about Russ is that it needs to know the type of this like that it's expecting right so you say unsigned integer and then 64 is how many bits or bytes is this gonna be the limit right of the ID so it's going to be 64. and with that said that's it that's it for the master right but at this moment right now this master does not exist in the lip so how do we make it exist in the lib.rs right you guessed it we need to import it right so the way we import stuff you can go top here and you can say mod and then say the name of the file state all right oops and then afterwards we're not done yet we have to use crate right so what is use crate uh crates and anchor is kind of like package.json right it's the equivalent so you can say create use crate clone colon and inside of the crate we want to get a couple things and right now we just want to get a state right and remember what this means get me everything inside of this state all right so essentially we are bringing everything inside of the state into the top level of our lib.rs right so um in order to use it in here we have to do something like state DOT or whatever but if you just want to just use it straight up we can do something called use super right so at the top uh right here line 20 for me you can say use super colon colon star and then semicolon and don't forget to put the semicolon after the use crate as well boom cool so what does U super do it's going to bring everything in the top level of your lib into the program so you don't have to do state DOT or state whatever right you can just straight up use this master struct that we created okay awesome and I will just put this comma here because it's nice all right looks pretty good to me so next thing we gotta do is inside of this program here we have to create the struct for create master like I said for every function you need to have a struct with the same name all right you like that's the case like most of the time so I'm gonna go into line 25 for me make some space and let's get started on that all right so what can we do to get started well what I would probably do is go into here start up a macro and this one is going to be called derive oops to arrive accounts right so we're gonna use accounts right when we're defining the struct of create master so we can say Pub struct right anything under here is going to be using this so we're going to do Pub struct create master right and then give it a lifetime variable of info which just has one apostrophe in front of it basically a lifetime variable lets you know how long does this struct live in the smart contract right with the anchor uh and rust essentially it needs to know how big everything is how long everything will last so that you can manage your space really well look in JavaScript uh we're kind of uh we're they hold our hand in JavaScript because they have a garbage collector that collects it the unused variables that we don't use anchor you gotta do it all yourself anyways after you create the name of the struct you add this lifetime variable info right you just want to go ahead have this account macro here and put parentheses right and it's going to we have to initialize uh the account so it's going to say an account here right so let me just do it manually first and what you want to do is inside this parentheses say init and you're going to say pair uh payer who's going to pay for the space of this account and it's you the payer should equal the pair right and then comma the space is going to be uh eight which is how big this is going to be it's just going to be eight and then after that you're going to say Plus 8 so this second eight is what we call the account discriminator right how much space uh this account takes there's always going to be an account discriminator which you can think of it as the spacing between all the accounts in your program okay cool and then we have something called the seeds right so what are the seeds right essentially seeds are what the you know shuck takes in which is going to help generate a unique public key for this account right because after a while when we build this app we're gonna get a string of numbers and letters that's going to showcase the address of where our program lives every account is also going to have a public key Associated and it's going to be dependent on the seeds right so let's say it's inside the seeds it's going to take in the string Master right so we don't have that yet so let's just leave that blank for now let's finish writing this rest of it we're going to say bump and I'll explain that in a second as well but after in line 35 after the end of the macro enter and you're gonna say Pub Master right and what is what does this master mean this is the account itself right so this is the account macro this is the account that we're talking about right I'm talking about the master account what is the master account guys come on you made it right here the master object itself with this ID all right so that means we want create the create master struck to be aware of the master account so that's why we're doing this right here so how do we get this state all right we can just say count all right get the account give it info comma and then say the name of the um account which is going to be Master okay cool and what other information do we want in this struct Ure well it's going to be the account mute this is how we're going to get the payer right so we're gonna say Pub pair right because when we said pair equals payer at the moment you don't know what who that is right well payer is going to be the signer right whoever signs a transaction and you might be thinking Lance when did you write sign or we didn't make that in our state well guess what sign there comes from Prelude yeah so again this is stuff that you can do by reading a lot of the documentation I'm just simplifying it in my explanations if this is your first time okay amazing so the pair now exists right we're good to go in that and the last thing is we always have to put the system underscore program and this is going to be the type of program right so this is just defining what type uh to expect from this so Master is an account payer is the signer System Program is coming from program and then again info system okay which is coming from another library that we're importing at the top okay well believe it or not this is it this is the create master struct we just need to put in the seeds right so what I'll do is create another file and this one I'm going to be calling constants const the install RS and this is where we're going to hold all of our variables our constant variables right and again another way to do this is putting it all at the top here but we could just make a constants.rs all right so what I'll do first is say use anchor Prelude right there you go uh and we don't necessarily want everything but Let's see we can leave this for now all right we're gonna add more to it later but let's say our first variable is gonna be Pub const and remember this is for the seeds we'll say master underscore seed colon and what type is the master seed well it's going to be and brackets u8 is equal to B don't make sure you do B quotes master all right this is essentially a binary string right cool and we want to take this binary string and put it into our seeds all right so bear with me for a second so that should be it put make sure you put on the comma put a semicolon and we're going to be adding to this every single time as we go through the app and let's get imported our constant so you know if you want to test yourself try pausing the video and see if you can get the constants.rs into your lib.rs awesome if you tried it the answer is you need to put mod right here and it doesn't really matter what order you do it but you can just say constant constants and then you can put a semicolon okay and then in your crates you can do a comma and say constants constant colon colon and get everything from constants even though there's one thing we're going to get more later so constant state boom so now we can just use it directly onto here and instead of getting you know the fair like saying it's constant and then getting Master seed right we can just say master seed right all right so like I said just write Master C all right me doing this is almost the same thing as writing uh binary string Master inside of the seats okay but we want this one because that's going to hold the variable all right so now for my explanation what the hell is the seeds lens well you could think of it like this I'm going to use something called a dice bear right which generates an avatar based on your seed right season um what's called Solana is a little bit different right oh I'm not going to go over like how it works exactly but the way that I understand it you can go into here right depending on what you write as your seed we'll get a unique Avatar that's how dice Spirit works so if I write Master here this is my avatar when I put in master as a string and a seat right so it's the same idea with Solana if I put uh the Master Seat here it's gonna instead of generating an avatar it's going to generate a public key for my master account right so let's add let's do a little diagram right let's say this is our app and this is the Solana blockchain Solana right my app is going to create an account or a master account and what it does is it's going to create some space in here this is going to be the master account right and this master account is going to have a unique public key so it's going to be something like this right well there's not those special characters but it's going to be a random set of letters numbers or whatever and this is going to be the essentially the address of this account so when I go to fetch it right I just type this in my app and I'll be able to fetch that Master based on the public key so that's why we need to generate a unique uh public key we have to put in the seed right and this bump right here let's say there's already there's already something that exists with this public key bump is going to essentially go to the next available public key right so you can imagine this like oh there's already something that exists with Master let's Sprite that's right um Master one and this is our unique Avatar or our unique public key hopefully that made sense right essentially let's generate a new public key and if it's not available bump it cool and then from there we can test it by building right there might be an error but let's just see if it works if we cannot compile you can use Imports constants oh okay okay I see all right so we got the error um I think oh yeah we need to add commas here right I can't forget that and the last thing we should probably do is finish up our function so the only thing we need to do with create master right the struct handles it already right in this truck we're initializing the account so we don't have to write any new functionality for that anchor is handling that for us so what let's do is just say okay right it's an enum basically saying like we're done we're oh it's successful right okay all right so now let's try to build there is a error custom attribute panicked oh and how could I forget I think I know the reason why the reason is because if you look in here the function it needs to take in what we call context right and usually to do that you just write CTX for context and if it's unused in the function you have to put underscore and now what is the type of the context what is context well usually like I said when you create a function you have to create a struct with a similar name right because what you want to do is bring in all of this into the function so you could just say the type of this is context inside of it it's going to have the create master struct okay and boom this is like a return the result and then we'll do a building come on let's go build successful guys so that's it that's how you create a master their very first function on the Solana smart contract all right so the next thing you want to do is go ahead and deploy the app and you might need some Solana to do so right so if you need more Solana on your app you're just going to say Solana airdrop 2. right cool uh it says success internal error that's fine sometimes it does that you just have to wait a bit and you should get some soul but I think I have enough because there's not much in our program I'm gonna go ahead and hit deploy and once it's deployed right we're essentially taking our smart contract and the pl this is our smart contract it's kind of the big deployed onto the Solana blockchain right so that's why we have to pay some soul and luckily it's not real right so we can deploy as much as we want and then later on we need to fetch that program into our app okay so that's the idea [Music] all right so I'll just check back in when it's done hey let's go deployment successful right and as you can see we lost uh three soul for that the point uh deployment so now that's deployed we can go ahead and test our functions and see if they work right so let me show you guys how to test your function so anything that says instruction that's your function and now this is also the accounts as you can see here that we created so if I asked you guys do we have any Master accounts that we created no we have none and it comes in an array so keep that in mind so how do we create a master well we can test that function right here without even connecting our app which is awesome so first thing we need is the master uh public key and we can generate this from seed so what did we put in here right remember in our constants we have a binary string called Master it doesn't have to write a binary anything here you could just say master for this and it interprets it and the program ID is going to be there by default hit generate and the payer right who did we say the payer is guys the payer is payer or in other words the signer right so we can say my address because I'm the payer so now uh if you don't have any Solana you should probably get some now but it doesn't usually cost much much to create this and I know that because it's only 64 bytes so let's go ahead and hit test let's go test pass creating the master so now if I fetch all we can see that this master has this address right so to visually show you guys this master has this public key as the address right and it has the traits of the account that we gave so it has the last last bet ID okay so what do we want to do with this every time we make a bet we have to go into our master account here and update it with plus one right so once we do that uh our last bet ID will be one so keep that in mind this is the master I'm glad the test passed what's next all right so if you understood everything that just happened you essentially finished the tutorial let's move on to the beta count itself okay so what we need to look at right we don't need to see this that much anymore we need to look at is creating a function guys so how do we create a function inside of this app all right we can say Pub FN oops FN create underscore BET right and how does the skeleton look like it's going to be parentheses Arrow result like this and then so the curly brackets like so another thing I'll do is I'll move uh this struct outside of the program because it doesn't need to be there all right and see if it builds still I might not build because we didn't we actually didn't finish uh right in the function so I'm going to just take it out temporarily or comment it out it's still acceptable yes okay so this is acceptable still and we updated our build now let's continue writing our function so we made the function what else do we need to do we need to create a struct that also has this function so the struct that has this function is called create BET right and what should create bet do right what should create but do it should create a bet account right so we want to create a better account first we have to Define what a better account is so I'm going to stop doing that and go to state.rs and let's create a bit account so to start creating or defining an account right we can say attribute account and then you can say Pub struct bet okay that's all you have to do and then after that you have to identify what goes into a bit so what are the attributes of a bet if you guys made classes before in JavaScript it's essentially this is essentially making a class so every bet should have what should have in ID all right and what should be the type of an ID an unsigned intrader 64. kind of like this all right and we can use the master to Define what the idea is all right what's the last one plus one of that there you go it's the new ID okay uh next is we need the pub amount right how much is the BET Worth right how much does it cost and another thing is usually we talk about it in Seoul when you're in the Solana smart contract it's going to be in what we call Lamp ports right which is a smaller unit of Soul so if you think about a dollar uh a sense is what land boards are essentially okay the next thing we need is Pub prediction underscore a right this is the essentially the prediction of player a and the type of this is going to be pretty interesting right it's gonna be something else that we call a bet prediction all right and I'll explain that later but prediction [Music] like so cool and then next we need Pub prediction B right and it's not going to be the same thing right because there's going to be an option right because by default uh when you create a bet you're always going to be prediction a that's always going to exist but when you're creating a bet player B doesn't exist yet so it should be null at first so that's why we're going to say option and then inside of that we'll put but prediction okay and then after that uh we should have the state right and by state I just mean what is the current state of this bet is it it was just created did the BET start did somebody win right that's going to be controlled by something called a bad State and we're going to be defining what this is and this is just a bit uh last but not least we need the pyth price key right the pub both or piss price key and that's gonna be a public key and you can simplify by writing Pub Key so what is pith price key well we're going to be using we're going to be using the uh what's it called the pith Network so what we can do is make a new tab and say pith Network right and essentially they're getting real-time data from Real World Markets as it says here and if you look there's many different stocks and crypto that's keeping track of and if you let's go ahead and click AMC you can see that it's fluctuating between its price and you can see from the graph here it's that three point eight nine right now right and you can see that all the transactions where it's updating that price and it's pretty fast it's going to be from two seconds to you know two minutes and to get the price or to know what the price is you need this public key right here this is called the price key and the cool thing is that you should understand what this is now because this public key is going to go to the account in the Solana chain that holds the price which is like 3.8 right and this account constantly gets updated over and over again right over and over within that time frame so it's always going to know right it's real time of the stock of AMC okay and to utilize that right that's why we're using the SDK all right we also need the public key stored into that bet itself right so we know which one to look for all right uh the last thing we need is something called the timestamp right we need to know how long is this bet going to last for it's going to last for one minute two minutes five months right so we need to say uh expiry expiry underscore TS colon and then you can say uh I 64. this is different than u64. to sign an integer and comma okay so I'm just gonna add comments really quickly so that you understand what and remember what each of these are [Music] there we go so I just paused it take a moment and write some comments for you guys so you can understand so pause the video if you want to take a look and add these yourself but essentially it's what I explained as I was typing so we need to define a bet prediction so I'm going to come down below here and we need to write something like this derived and then we need anchor serialize and to deserialize and it should be coming from Prelude as well and then there's last thing called clone because we need to add some more attributes or I guess properties inside of this prediction a right because prediction a is going to have a struct called bet prediction all right and this is also going to be inside prediction B the goal with this is to store the player right so you say Pub play and that's going to have a public key right every this is going to be the wallet essentially that's playing so your wallet if you remember has a public key all right and my public key is this 8tkz round okay so that's done um another thing is it needs to know the price right the price prediction right what did I predict that it would be all right and I want to use this right inside b as well so I'm going to reuse bit prediction right and give it an option because the option can be none or it can be these okay and this is the Safari comments this is the price prediction in USD and of course this is just the address that bets all right it could be player a or player B and then after that we need to make another one this is for the BET state right because it's going to be different things and we need to serialize it and deserialize it again so anchor serialize comma oops anchor oops deserialize clone and then there's a partial EQ that we need okay because this is going to be an enum right so Pub enum uh bet State and again it's going to be created started uh what's another one uh player a one and it's also player B one and then there could be a draw where they both somehow guessed the same exact price not likely but it could happen Okay so there's created started player a player B and draw right there's actually a lot of logic that goes into this uh I did simplify it so that you can get just a better understanding so keep that in mind and that should be it so believe it or not all the states should be done unless we need any more later but I feel pretty good about this so that state is done now that's next is let's finish the create bet struct so I'm here at the create bet uh struct right at the lib.rs and what we need to do is just derive accounts again so we're gonna say derive oops the rice derive accounts like that and then just say Pub instruct create BET right as you can see it's similar to create master and even the info part is going to be the same okay put the color brackets to identify the scope and next let's initialize the account so again uh anchor has a way to initialize the account already oops you can initialize it by literally writing a name now we're done it's initialized right next to Define who's paying for this you guys should know it's going to be the payer which we'll Define later next is how much space it needs right so we need to essentially figure out how much space does a bet need and depending on the type right we need to tell him all right it's this plus this plus this plus this right you can find this out by looking in the anchor documentation how much is each thing uh but I can tell you already it's going to be eight plus eight plus thirty two plus 8 plus 8 plus 32 plus 8 plus 1 plus 32. plus eight plus one and let me just double check this is it yep that looks good to me let's put a little space here yep this takes a lot of space because the BET has a lot of information right even has uh some more properties within that okay so that is the account initialization we just have to put the account right underneath that so we can say the pub bet colon is account right and what is the account well first you got to put the lifetime variable of info and then you can say the account is BET cool next we need this struct should also have in the in the context when we bring it in it should know about the master account so we need to get the master account so we don't need to initialize it keep that in mind we just need to get it so yeah I might have a comma here there you go now it's the correct color we say account and instead of saying init we want to say mute because it can change it says seeds is equal to master seed so what do we do here we're getting an account with this seed right and again if it's what exists was Bump there cool Pub master is gonna be the account info comma master all right so there we go we got we're able to pull the master account by doing this next is gonna be the player account right we need the player so actually this I named this player now same thing it's going to be the exact same thing uh account is mute because it can be there can be different players here and you're just gonna write Pub player so now this is defined but what the type is this it's just like before it just has a different name guys it's gonna be signer with info okay I should keep forgetting to add these commas there you go and last but not least the pub system program and we can pull program from there a lot of anchor code is uh just repeating it's like boilerplate so once you get the pattern it's going to be easier for you to create whatever smart contracts you want so that is the create bet struct okay now for the functionality of create bet so what does that need to do well create bet uh you can do a couple of things the first thing is needs to take in the context so get the context and this is actually gonna take a couple of things you can say CTX right comma you can say amount uh when you create a bet what else do you need you need the price prediction right duration um and the pith price key or pyth Price key I don't know how to say price key okay cool and then close it off next you have to put the type of it right so the context is going to be context and the context is going to be the create bed struct the amount right how much are we betting is u64 what is the price prediction uh remember it's going to be in USD so it's going to be f64 and then duration is going to be u32 and I'll just make a little comment here that this should be in seconds rights seconds and then we have this which is a pub key right this is the price key that we will get from here and I've already hardcoded that into the code so you don't need to pull it okay next is the result right so what is the actual logic of this function well the first thing you need to do is uh increase the last ID on each back creation on the master right it's the master ID should be increased and to get the master ID right we first have to make a variable called let Master right this is normal is equal to and mute so this is new right so we want to say that the whatever after this can change it's not one static thing Russ needs to know that right so if it does change or if we do update it it's going to be CTX dot accounts all right so what CTX it's our context okay what's in our context all of these two accounts so that means if I do T accounts I now have access to the BET account and the master account so how do I get the master account from here right think about what an object is you have to say dot Master cool and let's get the BET while we're here too is equal to and mute ctx.accounts.bet make sense right this is essentially the object and we're getting the master from the accounts and we also have the bet there it all exists because we ourselves created obstruct okay so now we can do whatever we want so like I said how do we increase the last ID on the master well this variable holds the account so I can say master right and then in if this is an object what properties does it have so we can even look at it here if it makes sense for you it has last bet ID so all we have to do guys right is dot last bet underscore ID and do plus equals one right just not scary code Solana isn't scary all right you just need to get used to the wording the documentation and why we do things right and again I'm no expert right I just do this a couple times until I get it I've had help right ask questions on the anchor Discord or the Solana Discord and it'll help you get better at this so keep doing this over and over watch this tutorial several times and it'll make more sense so then the BET ID is going to be the master last remember I told you right the bed ID is going to be whatever the master was plus one we already initialize it here or update it rather and we can just use that same variable here cool and this will happen every time I want to create a threat so it's pretty good logic here the next thing is the bet dot pith underscore price key our pipe key is going to be equal to this right the one that we passed into the argument right because we're going to do that in the front end oops sorry pyth or pith price key and then don't forget the semicolon here uh and then it's it's pretty straightforward you just plug and play everything you wrote down so it's going to be better amount is equal to the amount I passed in the BET dot expiryts right this is the timestamp and you need to do something something like this function called the get Unix timestamp right we're able to just get the current timestamp using this and we're going to add a duration as I 64. and then semicolon right because what's happening is I'm saying um the bet is going to take uh 150 seconds which is like two minutes it's going to take what's the timestamp now and then add the two minutes and that is when the BET expires and you can't enter anymore right or else it's unfair all right next is the bet.prediction underscore a right we're actually going to Define that the bet prediction right it's the object here and the player because we Define bet projection has player is going to be CTX we need the public key of the player we can get that by viewing dot accounts dot player dot key okay and then come then from there you can say price okay and then semicolon here after the bad prediction and the last thing to do is uh we need to actually get the Solana from our Phantom wallet and put it into a third-party account or an escrow to hold that bet right so the idea is both players put money into the third party account and then when it's done that third party account will send the winner the total pot okay so we can use an escrow for this so we can do this and I'll just write a comment here transfer the amount to the BET PDA so we can say system underscore program transfer and say CPI context new there you go and that's exactly what we'll write so we say c p i context I'll go into that and say new I just how you oops oh well okay uh don't need that boom all right this is the how we go and transfer it CTX dot accounts dot system underscore program dot okay oh sorry dot two account I think two underscore account underscore info and boom okay so essentially we're putting that's the player's Solana into the BET PDA or the account okay and here we can do the transfer System Program let's get the transfer [Music] and we're gonna get this from the player so we do is ctx.accounts.player.2 underscore account info and then we can do two bet so we're taking the money the soul putting it into the bed account and once the BET's over we'll give it to the winner uh and we can comma here but the BET dot amount okay and there's some things you need to add like this of course when the function is done we're going to hit OK so I know it's done um so that should be it for this and now I'm just gonna run build there might be some type of errors or I might have spelled something wrong so let's just see do a check yep there it is oh there's a little M here all right it's insane with uh rust because one error is going to mess up the whole code let's do this one more time believe there's still more yep forgot some semicolons so let's go to where I wrote bet semicolon semicolon [Music] and then it says beta expiry TS is unknown okay let me just check this state oh underscore TS whoops where is that it should be better expiry underscore TS okay and I think there was one more issue it was [Music] CPI context oh is it because I forgot the add 30 let's see build [Music] okay cool uh now we need to fix the get you next time stamp [Music] get your next time stamp doesn't exist oh right okay I need to make one more file it's gonna be the utils right there's some functions that we need to create uh to make a lot of the code doable again this is a pretty big program that I have to scale down so if you do use anchor Lang in here get a couple things oops and we want to get Prelude of course Prelude colon colon star comma means Solana program clock Unix time stamp okay uh the main thing we want to do with this is create that uh get your next timestamp function right because it doesn't exist so let's make it exist and we can bring in our variables here because we're going to use them later so let's do a use crate let's get constants star and also State Hong Kong star so we can use them here and what we want to do with this is create that function so we need to make a function Pub FN get Unix timestamp so now it's going to exist uh boom and we can do an arrow here yep so now let's define a type of time step boom and this is literally just going to pull the clock from the anchor program and unwrap it and then we could store it Unix time step so this is what it returns get the timestamp at this current moment when it's run and then we can just go to the lib this should exist now because we need to import it so to get this into our program you say utils say comma utils colon colon star you super brings it into this and crossing my fingers let's go ah still doesn't work oh unexpected token okay that that's that error is usable expected a semicolon here can't forget those [Music] and try again foreign missing something new next time stamp not found in scope that's weird should be in scope oh anchor land that's probably why yeah so spelling is really important guys I messed that up a lot but we should be better now warnings are okay use clay just create constants let's go all right cool so again none of it was the logic it was just me putting semicolons and then the spelling so build successful right we can go ahead and deploy this now right yep let's hit build and boom right uh one thing is that we can't really test this just yet be because uh if you want to test it on Solana playground it uses the local local host and we can't it doesn't this python pith network doesn't work with localhost so I'm gonna have to transfer it into our app and then test it there but that is essentially the create bet all right so with that out of the way let's get to the next function so the next function is going to be entering the BET right so what does entering the bet mean it just means we should be able to uh participate in the bets that are already created right so we're not creating a brand new one we are becoming this is essentially player B's ticket to participate all right so it's gonna be called enter bet okay and the arrow and then the result at this point you guys should be picking up on the pattern to make the function okay and we know that this is going to have CTX and we know that it's going to take in the price right this is player B's price prediction okay so what do we need to do when we enter the BET guys well we need to create the context right or the struct that goes with uh entering the bit okay so let's go down here great bet and underneath this enter the bin so again we first need to derive accounts all right so oops I'd ask you guys do we need to crew initialize a bit account nope we don't need to do that we can just get the bed account so we'll just say Pub struct enter but and then put the info inside [Music] okay and then from there we can have the count and again we're not initializing it we just need to get that account so it can be the bets that we enter can be different so you want to make sure it's mutable the C oh did I put a seed for the BET I did not all right so that's one thing we need to remember I put the space here but so go back to your creep bet struct and we need to put the seeds in there all right otherwise it's not going to be able to create a new BET with the right public key all right so the seeds this takes in is going to be into state or sorry constants we're going to say Pub uh which we call this it should be I can just be bed seed so there's a pub const bet seed and it's gonna be similar it's gonna be and you ate oops [Music] is equal to Binary string and say a bit and semicolon cool oh and this should be Capital bad seat nice so now we have that it's already being imported so now for the create bet we're still back in Korea but we just want to say uh bet here bet seed seed not not seed but okay there is one more thing that we need we need to have the Masters last ID right so this is different than last time right we have the binary string bet and the master's last ID so if it was zero this would be the publicly if the last video is one two right so it's Unique every time depending on the last ID okay so it's going to be and master that last bit ID you can't just write Master last bit ID because you need to format it like so plus one and then you say dot two lip bites you have to convert this into bytes because that's what the seeds need to read it okay and then this should be come right here boom all right so we'll check on the facts give us any errors later on but we also need to add bump right because if it exists go to the next available public key cool so now you know good thing we did that because now remember to get the when we enter the bet to get to the bet that we want we need to get it by seats all right so that's the purpose of seeds you can also get the public key you want by putting in the matching seeds all right so to do that we'll say Bad Seed all right let's put in the bed ID because the BET ID is the same as that last Master uh bet ID all right the last one so let's do end that's that ID and we gotta convert this to bytes again so that to l e bytes [Music] and then to uh method there you go all right don't forget to add bump here then there is some constraints some seed constraints so we gotta say constraint is equal to validate enter underscore bet and you say and uh asterisk bet you can say at bet error can't enter right so basically if there is already some the bet is already entered you cannot enter that bed so this is an error better that we need to grab and create and this is another thing in our utils function okay so we'll come back to that in a second but let's just write out the rest of this it says Pub BET right all of this information is in this bet and what is the type of it it's an account that already exists it's info and then cool next thing we need is going to be the player right so there's no account for player it's just going to be stored as the signer right Pub player is the signer [Music] the assistant program right we always need this one system program is the program and look at the system nice cool cool so that is the enter bet struck where we didn't have to make a new account uh we do need to work on this part though so remember we got to check if uh player B is allowed to enter this BET right so we can go back to our utils we're gonna make a new function again say Pub FN uh validate enter underscore bet and it's going to take in the bet and bet and it's gonna be a Boolean here okay and essentially this is what we were going to return a Boolean and we're gonna get that Boolean by saying bit prediction right underscore B dot is none okay and then you can enter here and I'll just say end and we gotta check for the expiration so basically what I want to say is let's say player a makes a bet for AMC and he says it's going to go up within two minutes right you can kind of cheat that bet right if you think about it you can look at you can stare at this and if there's like two seconds left I want to say oh the price actually is 3.9 right you'll have a more accurate guess if you bet later so we shouldn't make an expiration time right so to make that expiration time we can just head over to Constance and make it right so uh let me just write that comment the closer we are to the expiry the more chances a player has to win right so we want to make an expiration time to make it more fair right we can add even more logic to like check for that but again this tutorial will be way too long but if you do want to see that comment down below and see like a full-on uh like full scale build of a betting system so let's go adjust this to make it more fair right so what I mean by that is we can say Pub const it's a really long variable minimum remaining time until expiry right and to get this you can use um printing another Library honestly don't even need Prelude here and it's going to be unused so let's actually get Solana program yeah we need this Library instead program inside program there should be a clock inside the clock it should be you next time stamp that's what we need yep okay so then now we can say Unix timestamp here okay oh sorry and set this equal to uh 120 seconds right so the last 120 seconds they can't enter the BET right uh we can adjust this to make it more fair you can say like oh after one hour before the bet you can't enter the bet anymore all right so this is essentially like a minute okay so I think it's a pub const maximum claimable period right since we're here this one is for let's say somebody wins they should be able to claim the money all right after a certain amount of time uh the money will actually just go to the user or be given back to the user right cool so maximum claimable period 300. [Music] okay so we have that we would really care about though right now is this one right here so let's go back to the lib and go back to our validate interpet and now that we made that variable and we're importing it here still we can use it so Twitter was I again now they bet we need the expiry expiry I can't forget the underscore and minus all right so the the time that the bed expires minus the minimum remaining time until expiring right there could be a better name but it's what we got is greater than the get Unix timestamp there you go right so this is how we can validate if player B can enter the bet or not all right it's going to be true or false right that's what is running right here so we're gonna have a constraint we're gonna check okay can player B enter the BET yes all right if he can't if it's false then we need to run this error this bet error right but right now bet error doesn't exist so we can make the error so to make an error we can have a file to have all of our errors so we can say error.rs and inside this this is the one that's going to use anchor Prelude so I'll hit oops let's see if I can use their import here nice and to set up your error codes which you can do in Solana is error underscore code and then say Pub enum bet ever like that okay so next we can do hashtag array oops and then just do message right so we're going to send a message and it's going to be can not enter right and the the name of this error is going to be cannot enter right so what's happening now uh is in here we're gonna the constraint of entering the bet is we check if this is true or false if they could enter the bet if it's false and there's going to be an error and the name of that specific error is the cannot enter one right and one thing we should do is import error as well so let's get mod error.rs oh sorry error and we need to put this in here as well so comma error colon star okay I think we are good uh we do need to finish up the rest of the what's it called the rest of the functionality of interbet so let's go ahead and do that so we finished the struct we're on the functionality now uh the context is the enter bet struct so we can add that right now enter bet the price is something that we're going to input through the front end and we say f 64. like it's going to be in USD right [Music] or like at least a decimal so it's float64 and let's get the BET into a variable and we need something here guys do you remember yes exactly good job Jeffrey it's and mute ctx.accounts.bet okay but that prediction underscore B is equal to right because this is for the the whole purpose of this function is for prediction B and remember prediction B um what is it again it has or state it has bet prediction and it starts off as an option right so we got to keep that in mind and so it's going to equal to sum bet prediction and kind of like how we set up the prediction a when and creating a bet you're gonna do the same thing so the player is going to be the player that's entering so that's the CTX that accounts that player and then we need their key so that's how you get their key again and then we need the price right so we're taking our argument and placing it here okay and then we should update the BET state to equal the bet state of started right where is this pet State started coming from guys all right if you remember our state we made that right here it's an enum which which means it could either be created started or any of these cool so the BET state is equal to started right we're not done yet though because when you enter a bet you gotta give us some soul to enter right we're gonna match the price so if it's two Soul give me two Soul so transfer the amount to the bad PDA once again uh-huh and then we do the system underscore program let's get the transfer in here and let's run that and we can say CPI context so it won't forget the T this time the new [Music] and pass it oops pass in these arguments which is going to be the System Program so to get that is ctx.com System Program dot two account underscore info okay and then in there we're going to say System Program transfer all right and so here we'll do the transfer we need the from and two so who is this from this is from player B which is the person signing so we can say card accounts.player.2 count underscore info and it's going to go to the betpda right so the better count so it's gonna go to that bed account okay comma here comma here right bet dot amount I go with the amount that goes in and we do need this question mark and there we go uh last thing we do need though is the okay and boom all right this okay if you don't know uh you can think of it as a return so if this function is all done and it's good you can return like the number five right I don't know how you do that but you don't need to we're gonna put nothing in here because all the functionality is happening right here [Music] okay looks pretty good to me um that should be interbet let's just build this and check for any errors which is normal right if there is a time that I never had errors I get so happy so prediction B uh some bet okay something wrong I might be the spelling yeah predict cyton prediction B and let's go build successful again don't worry about all these warnings right you can build even though the warnings are here it's just letting anchor letting you know like hey uh you wrote this but you didn't use it but we're all gonna use it eventually right so I'm just setting some stuff up so build is done that is entered in all right so we have enter bet let's get started on claiming BET right because what we have so far logic wise is we can you know create a bet put duration on the price player B can now enter it but now once the bet is over we need a function that's going to let us claim that said bet so once again how do we make a function it's just Pub FN and then the function name right from here you need to put the parentheses for the argument the arrow and then result boom okay and then after that Charlie brackets to put the scope and the only thing that we're going to need for the argument is going to be CTX right and we're going to Define what the context type is in just a moment all right so the first thing we're going to do is scroll down to the bottom right here and let's find and create claim bet all right so we have enter BET right here and then we need to claim bit all right so claiming bet how do we start this all right the first thing we need to do is get the accounts that are relevant for the function right so to derive accounts we need to say derive accounts right and what accounts do you think we'll need for this BET right after I write the name so as I'm writing this think about that Pub struct claim okay and then we need this info here info and color brackets all right from there we can do the account that we need and you guessed it it's going to be the BET account right so we don't want to initialize an account so we don't need to write init here we should write though mute right and then how do we get the specific bet that we need we need to put in the seeds all right so to put in the seeds we're gonna do a seed equals oops C equals and then we have to say I believe bet underscore seed comma and then we have to say the and bet dot ID Dot and turn this into bytes so do two underscore Le bytes and that is a method so parentheses boom and that should give us the bet that we enter uh and then boom right and then the constraint so there is also a constraint here oh compataro right constraint so what's the constraint here well we need to validate the enter the not the intimate the claimed like can we claim this bet that's what we need to validate so we need to go back into our utils and let's create that function real quick so I'm going to go under here and say Pub FN validate right this time the claim but can we claim this BET right so there's two things you need to think about one is uh is the is this over right is it expired is the BET expired can we still claim it is time not up yet if it is up we shouldn't be able to claim it right if the bet is two minutes long and it's only been 30 seconds I can't claim this BET right you should get an error for that which is like six thousand and two I believe Okay cool so what we can do to check this is a match statement and say bet.state all right if the bet that state bet State colon colon started and if you're wondering what uh BET's date is if you go back to our state.rs we made bet prediction and we made bet state so what are the couple different states we can have created started right so which one do we need right so let's go back to our utils so if the bet is started right what does that mean okay then say equals Arrow and then curly brackets all right so if the bed is started let current timestamp or TS equal to get Unix timestamp all right get the current timestamp with this method okay and set that to current TS and don't forget the semicolons here and what we need to check for is this variable let's say let time past since expiry right is equal to the current time so the current underscore TS minus the when the BET expires because the bet that's another condition you think about the bet is expired uh we shouldn't be able to claim it anymore expiry dot oh underscore TS okay and then uh if zero is less than the timed past [Music] expiry and oops and the time passed since expiry that would mean it is less than or equal to less than or equal to I wonder if I do this yeah there you go that's the symbol we need maximum claimable period right we're checking if this total statement is less than the claimable period because if it is we should still be able to claim it if it's not then this will return false which means we cannot claim it right so that's what's Happening Here we can do a comma and then we have to do a dash I believe what underscore then do equals Arrow false and then come cool so that's how we can get it to be false and then if that's false then we get the Boolean false as well [Music] let's go that's going to be the validate claim bet which means we can come back to our lib.rs and actually use that function we just created which is going to be validate oops valid date claim underscore bet okay and then it should be like a and star but just like before up here and the BET error that we want is cannot claim so at bet error cannot oops cannot claim it means let's make just sure we have that error so check error.s we do not have cannot claim so we need to create it right so put a comma here oops I need to put a message that says [Music] I cannot clean all right so now it exists after we Define it [Music] okay and there's a couple different errors that we're going to need since we're here and you get the idea I'm going to do the rest of them now so let's do another message this one's going to be cannot close right [Applause] [Music] okay not close okay uh there's a couple other error messages where it's gonna be like if you have an invalid pith key so we can say given key for the pyth count I'm always saying the different way to say it does not match right so let's say you're right you put in the Amazon stocks key and then later you're trying to use Google it's gonna know it's gonna be like that's not the same one so then you say invalid this will help us troubleshoot okay there's another one message uh there's also another invalid pith account right so we can say invalid fifth account my hands doesn't need to be capital invalid count this one has to be capital one last one I believe it's gonna be the price is too big to parse right because if you remember when you create a bet you parsed it with u64 right so if I go to state yeah u32 so this is the limit of the space so we don't want to do anything bigger than that and just to be safe we need to put it to 32. so we can say uh this error happens when price is too big to parse to you 32 right even that's the limit is u64. we don't want to hit that limit right so we can just say a price too big [Music] all right cool so we might not use all these errors but we're definitely going to use these three for sure but this if you want to add more unique errors for other situations because there's a lot of Logics in a fully functioning lottery app make sure to add them here so this is all the errors and now back to the lib.rs this bet cannot claim error is gonna run now because it exists and all I have to do is put a comma here and the whole point of this oops the whole point of this was underneath this whole account information we're gonna set up the bed so we're gonna say Pub BET right and the type is an account info and a bit and now I'll put the apostrophe in a second there we go all right we're good and then a comma here to set up the pyth Oracle account right the pith price Oracle account so we can say say like this all right because remember each of these is an account as well so there's an account for AMC and it's going to contain a price and in in the back end this is constantly updating to the latest price so for here to get that account we have to put parentheses and don't press init because that's making a new one we're going to say the address of this account that we want is gonna be the BET right because now we have access to the bed account if in this truck the BET dot uh sorry bet that dot pith underscore price underscore key and then there we go all right so how did we know that this is where the pith price key is well if you go back to your state there is a attribute or property where we store that and it should be there after you create your bet right so you can say is equal to that and then you can say at bet error right because what does this do it means that if there's an error here it's probably because uh it's an invalid right so that's why I made those errors and then from there uh we can say Pub pyth or pith account info boo so essentially get me the address of the bet.pets price key and if it's not the same then we'll get the invalid or it's not correct it's going to be the invalid error next thing we need to initialize is both players so let's get their accounts as well or their the part of their accounts which is going to be account mute and their address is equal to the BET oops bet dot prediction underscore B dot as underscore ref dot unwrap right because whenever you do this you have to unwrap it and then you get the player from that bet all right so we're going to the bed account and if you remember in the bed account there is a uh prediction bet prediction here there's two actually one for a and one for B so we need the one for a right so this is for B so let's do one for a actually I'll come back to that because that's for B and I'm thinking about it so we need to count address is equal to oh sorry mute this could be different address is equal to but that prediction and how do we get a a DOT player yes and then from here we could say Pub player underscore a is equal to account info all right because we just want the info of this account apostrophe not quotes info keep pressing that okay in oh there we go then the comma after here cool so that's player a and this is player B and the reason why I did this for player B is because they they are in an option so we're gonna unwrap it first get the then get the player [Music] oh man this one's gonna be Pub player underscore B is equal to count info what's going on Pub player foreign oh it's not equal sorry colon colon account info info .com hey there you go cool and uh the next thing we need is the things that we always do every time we create a struct which is identify the signer who's signing this transaction and the system program so honestly we could just copy this [Music] and paste it right here and hit save oops we don't have to save it like that and then the player right this is gonna be confusing because there's two players we can just change the name of this to a signer signer and System Program can stay the same and with that said that is the clan bedroom struct right so we have all the account information we're accessing player a player B within the struct let's bring that struct into our function right as context and say context Arrow claim bet and let's start working on the function itself so this function has a lot of logic that goes into it because not only does it need to run a couple checks it needs to take the money right from that third-party escrow account the BET account to the winner and that winner could be player a or player B and we can also need to check for can they even claim it so let's go ahead and work on that function now all right so now we're working on claimbet and what I want to do is write a couple comments so that we can identify each section so the first uh thing that we should think about is check the winner and send the prize to the winner or return them back if it's a draw right because that's also a possibility right so how can we do that well first what we've done before was set a variable and set the account in that variable so let's do the same thing again so let's set the bed right it's a variable equal to and mute right and mute CTX right our context argument and from that object you can get the accounts and the account that we want is the BET awesome Okay cool so we have the better count and what is the prize Well the prize is let prize is equal to oops to bet.amount dot checked Mo to uh dot on rap okay and then from there we can do this right here bet dot two account oops account info under uh parentheses Dot fry borrow all right try borrow mute Lan ports equal to the price all right this is important that we do this because we need to figure out how much the prize was so we can do that by getting the BET amount right and then we can go into the bed accounts info and get the all the Lan ports that we put in there we're going into the third party account and subtracting it by the prize which should be the whole thing that's in there or that we put into there and then from there let's get the pith price because we need to determine the winner right so we do that by saying let pith or pyth account info is equal to and CTX Dot accounts.pit okay cool so then let's say the feed right so we gotta load the price feed now right because if you remember this this right here is updating constantly so we need to know as you can see it's like moving slightly we need to know what the the current price is at the moment so we said load price underscore feed from underscore account underscore info pith underscore account underscore info and then you can add a DOT map here right after.map uh map error sorry error and then this bar oops okay I learned a lot of this from looking at the documentation and testing so oops let me do this and then you can say space error exclamation point and then if there's anything that goes wrong we say bet error you got the invalid python remember that error we made earlier so we're going to use it here if that error exists all right so if it's good it doesn't there's no error we can keep continuing so we say price data is equal to feed dot get price on checked all right so now we can get the price in price data and I'm gonna hit enter again and let's do a require here and we need the price dot data dot price right so yeah and then a less than equal to again for f64 that float 64. and the max that it can accept as signed into juror 64. comma bet error right so remember the price too big error that we made so we're gonna do that here so here's another check price is too big too big cool so first we're checking if it's a valid pith account then we're checking if the price is too big and then we can after all that's good we know that the pith price now fifth price is valid and it's equal to this variable which is going to be the price data dot price and make sure it's as a f64. okay and then now we can put in the message here for ourselves so we say pith price is colon and then if you put this curly bracket here it's Gonna Fill this is kind of like a placeholder right where if I put a pith dot price here it's gonna take whatever the price is so let's say the price is like two dollars it's gonna put this in the code bracket and the message will need that the price is to Solana or to sold or two dollars whatever it is cool now we need to adjust prices to compare them with pits price right so we need to compare the guesses essentially that player a and player B wrote and compare it to the current price and see who's the closest right so this is another place with a lot of checks okay and then we also want to just make a note here real price is equal to pith price times 10. this is something that took me a while to figure out but there's something called pith exponent and that's just the conversion that we need to compare all right so the real price is this the real price of the stock is this price time step you guys keep that in mind so we can say the mult we can store that multiplier in a variable I'll call multiplier is equal to uh 10 F 64 dot p o w i and then you can say Dash price underscore data dot Expo right yeah there's going to be a lot of troubleshooting after this because this is where their apple can go wrong most of the time so you're gonna might be here a while cool that multiplier is equal to that and then we could say we need to get the player a and player B's adjusted uh bet prediction so we can say let adjusted player a is what I'll call it equal to bet Dot prediction underscore a DOT price times the multiplier okay and then we could do it let adjusted player B is equal to bet that prediction underscore B Dot and this is the one that's in the option right so we have to do the B dot as ref dot unwrap it first and then we could do a DOT price yep and then times it by the multiplier to get it to compare to the pith price and multiply nice okay now we can say the message here just for sanity's sake and say the adjusted player a prediction is now this right and then what we're going to put in the color brackets is this variable player a cool okay same thing here I might just copy and paste it to save some time [Music] and just make sure you change this from player A to B and this should be player b as well okay awesome now we have to uh compare the price who's the closest so we need to do this by saying another variable let ABS player all right a is equal to parentheses here fifth price or what the pith price is minus the adjusted oops adjusted underscore player underscore a and then dot absolute abs and then same thing player B ABS player B is equal to pith underscore price minus adjusted player B dot abs and then whoever is closest should win so how do we check for that well we're going to need an if statement here if ABS player a is less than ABS player B who should win guys all right think about that for a second if the difference of the pith price and the adjusted player is less than the difference of this and player B who should win all right well if the the price adjusted price is lower that means there's less of a difference which means it's the closest right so then you can say if uh this is true [Music] the winner is drum roll winner is player a and then you can say sending uh this much lamp ports right because all everything that's happening here is done through Lan ports and then later we gotta convert that to Seoul when we uh give it to the player and then comma uh the thing we'll put in the curly brackets is the prize okay cool so now we can do a bit dot state is equal to but state right we gotta change the state because it was it was started but now if the player a wins we have to say the state is player a one if you've got an error here it's because you probably spelled it wrong okay and then now we have to update the CTX account so we can say CTX oops CTX and I'm gonna hit enter here and then tab so that I can format it like so that accounts nope dot player a right so I'm just going to my contacts I'm getting the accounts I'm going to the player a and I'm going to get the account info in there so uh oops so to get the account info I'm gonna say dot to account info then let's get the Lan ports try borrow mute Lan ports question mark If there is landports plus equals prize let's go cool all right you with me so far guys if that's the case it's gonna add uh get Lan Port from this equal to the and add it to the prize variable and then we can close it off so where is the closing one for this it's right here because now we need an else if what's going to be the else if condition I'm gonna give you guys three seconds three two one right the lsif is the opposite right so which is ABS player B is less than uh ABS player underscore a all right and then this is going to be the same thing uh we can copy this message and the BET State actually [Music] accept change this to player B make sure you change it and the BET state is not player A1 it's gonna be player B1 okay cool and then from there uh same thing I need to go into the context again so CTX and then I'll do this format oops dot accounts or in the accounts [Music] now we can go into player B but remember player B should be option but then we can just get the account info because we got it before to account info of player B and then let's try to borrow try borrow mute and then get the lamp Port then plus equals prize as well Okay cool so we have the situation for a you have the situation for B oh yeah there is an else statement right because the last possibility is what it's the draw right so then we can say and what should happen in the drop right let's think about this in a draw everyone just gets their money back right let's for say whatever reason you have the same exact guest and you're the same distance from the uh real price then we can set up a variable called Draw amount is equal to the BET dot amount right and then you can say message here and let them know it's a draw draw sending both players lamp ports oops you don't need to put this in color brackets lamp ports okay and then what is in that color bracket you can put the draw amount so sending both players like two Souls the the price to match is to sold and then uh the winner would usually get four but in a draw they just get two they both get two [Music] so the draw amount is here and then semicolon we say the BET dot state but that state is equal to bet State colon draw cool yeah like I said there's a lot of checks in this lot in this uh bet prediction app um again there was a way it can get even more insane right depending on uh the complexity right so this is a simplified version actually so let's return both players all right okay so let's return it so we have to do this twice so CTX [Music] dot accounts let's do player a player a oh underscore a dot two underscore account info and then try borrow mute Lan ports there is available Plus equals draw amount so we're both sending them the two okay and then same thing here but we're just gonna do this for player B and since it's the exact same thing which is going to change one thing player a to player B uh we should be good to go so after that closing else statement I'm gonna hit enter and from here we can just say okay okay that was a hefty function um I'm gonna do is hit build and let's just troubleshoot this because I'm not sure if it's perfect or there could be some spelling errors or some semicolons I forgot so let's go ahead and do some troubleshooting all right let's see what we need to work on so let's do build and yep as expected so let's go over all these errors there's a lot right so the first thing is going to be missed match closing limiters that should be an easy fix going to line 222 222 and it might seem like a lot but maybe some of these are caused because of the first air right because that's how strict rust is so let's take a look and taking a look at this I can see that usually this has a closing parenthesis opening parenthesis and it doesn't close right here so let's close that off and let's just wonder One More Time okay so building here expected semicolon bound bit so again means we forgot semicolon line 114 to do and the lib oh yes in our message we need to copy that and I'm pretty sure we did copy paste this so we need to make sure you copy paste the semicolon as well so did we do that yep here's a message and one hack is that you can actually clear the terminal by saying clear so we can start fresh all right easy on the eyes hit build okay expected a comma or a closing credit bracket but found an exclamation point again in our lib so 122 oh see notice how this message here right isn't the same color as this message here right so that means there is something weird with this hmm trying to sit here think about what this is something to do with what's before there is a curly bracket for it oh I see there is a space here hey okay there you go awesome all right I forgot to put underscore B let's just clear this again hit build all right what's next so cannot find context in the scope that's interesting so let's go to 87 and can't find a claim bet so let's just check down below did we have clean bet yeah we do oh did I write context wrong con oh context without the T so we need the T in there don't forget your little tea so let's go ahead clear hit build all right so we need 99 yeah this is why it's good we're doing this now but require uh needs and exclamation point all right so let's add that exclamation point did we use require anywhere else here nope [Music] let's do it clear and build [Music] price 99 yeah there's no such thing as price.data it should be underscored data okay I think build again good price not fine let's go cool so it's a lot less errors than before pith price is not found in scope and I should it's probably one of those things where it's like underscore price again okay 107 cannot find multiplier spelling right yeah at least the the errors are not like code breaking so far it's just smelling uh 99 and needs Max all right so I just took a moment to clear a lot of these spelling errors and semicolons the next thing that's not either of those things is this Arrow right here all right if you look closely it says uh could not de-reference that's what this star star is and it's in line 2124 so let's take a look we should be able to de-reference it because it didn't give us any problems in 116 right but it's giving us problems in 124. so let's take a look hmm okay so this looks like it's fine we are going into accounts player B to account info same try borrow Lan ports oh oh okay I see let's see if we add this semicolon here because we have to make sure that we're able to do that first awesome okay cool I think that fixed it yep needs a question mark here and now we just have the one error which is uh 219 and I feel like it's a spelling error which you guys know that we could fix so 219 per dick saiton right this switching of the two letters can break your whole code but if you put it back to normal it should be good to go fingers crossed building come on one let's go build successful guys so that means no errors not even any warnings anymore notice that it's nice and clean all right we're using all the Imports that we have and now for one last function which is the close bet and then we can move into the front end and put this into an app all right everybody so we're on to the last function if you made it this far you guys are crushing it so really proud of you if you're here comment down below let's go so I know that you made it this far right we have one function left on the smart contract and that's gonna be the ability to close the BET account right because let's say uh you wanna you claim the BET already right you got the money you need to close the account right when you close the account these the the money that you spent to get Space there which is not a lot of soul in the devnet you get that money back right so you can do that by saying Pub FN close underscore bet and then we can say the arrow like so result and then curly bracket and then from here you can say the CTX and one rule is if you don't use the CTX in the function the context you have to put an underscore and we're not all right so let's quickly make the close bet struct so I'm going to come down below to the bottom and you guys know the deal by now you guys are Pros right spent almost an hour right at this point so we can say derive counts right derive accounts and then from there we can say enter name your struct which should be just close bet info curly bracket boom so this curly bracket represents the information of this struct so let's get what account do we need the better count so we say account right do we want to initialize nope we want to get the mute right because this could be different bets that we're closing so we need to make sure it's mutable the seeds how do we get the bet the exact bet that we want well you need to put in the string the binary string and then you got to pass in the ID and they should have different IDs right since we're incrementing it each time we are making a bet cool to convert it into bytes because that's what the seeds need to read and then we can say bump then we can say close is equal to play it right you haven't seen this one before close just like you knit when you're writing it initialize it this struct actually handles the closing of the account for you so you don't need to write anything so you can say close right it's equal to player meaning the player who created the bet or assigning is allowed to close so you can say and then we can make that functionality by adding this constraint here which is validate uh close bet and now do we have that in utils we do not so we do have one more utils function to make so let me just write this out uh it's going to be and oops reference this and then star bet comma player dot key parentheses and then you can have outside of this at the bet arrow which we should have which is cannot close right only the one who created the BET should be able to close and then we can make that functionality in our utils so all we have to do is come below here and say Pub FN uh validate close BET right and then you can get the BET like so and then you can do that by saying bet here the type uh reference the bet and we do need the user key right so we can say user key takes in user key and it has to be Pub Key that's the type and this will return a Boolean right and then we need to do a match statement here so we say match bet.state and bet state equals Arrow bet dot prediction right by prediction right yeah underscore a DOT player is equal to user key right because the one who created the bet is always going to be user a or player a so we can set that equal to the user key all right uh we can also do bet State started right the is player oops is player pass in the bet right so you're probably wondering what his player is this is the actual function that checks if the user is a player so we can pause that for a second we can say uh FN here because it doesn't have to be public so we say FN is player because this is the only place we're going to call this function uh it's gonna be bet reference to bet again comma get the user key once again Pub Key turns another Boolean forgot to put bull here and put bull here so is player we can check if there is a player by doing bet dot prediction underscore a DOT player is equal equal to the user key all right just like before and then you can also do or right and I press tab here to format it or parentheses the bet.prediction B that is underscore sum all right checking the option and bet dot prediction underscore B dot as ref dot unwrap right because remember B is an option we need to unwrap it then we can go into the player and then check that is and check if that is a player okay cool so now this should make a little more sense we check if uh his player is in here passing the user key of player a yeah and then we can do an and get your next time stamp bet dot expiry underscore TS plus the maximum claimable period okay cool and now we can just check the other states right because the BET state the BET state is player A1 then the BET prediction underscore a DOT player is equal equal to the user key comma then the same thing for B player B one all right so these are basically all the times that you can close the BET right if the BET state is a then you know player a can close it started player a we have to check if the player is a player and then uh the maximum claimable period it's greater than that with the timestamp the current timestamp we can we can close the BET and then at player AO player B1 you can still close the button so bet dot prediction B dot as ref because this is an option like I said before so we gotta unwrap it dot player is equal to the user equal equal to the user key yep bets date draw and then we can use this player here again [Music] bet and the user underscore key cool and we just need a comma here and that should be it for the utils so let's go back to our lib right so we then we have to validate the closed bet pass in the player key as the user key and then it'll run through the logic depending on the state thanks to our match statement and if it returns a Boolean that is false error cannot close right so that's how our error handling works right now so we can make this the BET account count uh info and I'm back comma and then let's get the player [Music] so we can say mute and the player is basically the signer so player colon signer we don't need to get an account for that one then you can do Pub system underscore program info system okay cool and that's it guys closed bet is pretty simple because all you have to do since the struct is handling the close all you need to do and here is just write okay and that's the logic of the closed bet guys and that isn't that insane oh okay I'm struggling with this let's try one more time not that one this one hey okay that's the close bet that should be all the functions let's just test for any spelling mistakes or errors and then we can move on to adding this to the front end and this time let's just actually look at the closed bet I'm just gonna do a sweep so maybe we can minimize the error just by just proofreading it so back to Here Close bet let's put in the context I just noticed that context is going to be close but okay and a lot of that logic was in here validate close bet player key what about in utils did I spell prediction right print D I see one predict for the action right that's it that's one way to spell it uh create should be created and I think the rest might be some spelling errors I missed that's about prediction right protection okay looks like I spelled it right that's a build ah yes of course so lib 248 [Music] oh yeah commas can't forget that oops let me hit clear oh let's go that is like a world record it's one error and it's just a context spelling again 149 keep forgetting that t don't forget your teas guys so context right and now we have build successful let's go all right now next step let's take this code and move it to our front end and to do that we first need to hit upgrade all right and to upgrade I went ahead and cleared my terminal right and all I have to do is make sure you have some Solana let's hit upgrade and it's going to deploy and if any issues come up it should let us know but that's why we do build first before we do before we deploy so let's go ahead and wait and I'll check back in when it's done a deployment successful so we have our upgraded smart contract the next thing that you should do is look at this IDL and make sure you hit export right here and uh if you're on Chrome or any other browser it should show your ideal here don't mind the number nine that's just how many ideas I have in my downloads right what you could do is go ahead and click it and I'll open it in vs code okay oops what you want to do next is uh alt Ctrl B and you want to get this IDL inside of your utils right and just rename it to just say uh idea if it doesn't already boom okay if I hit save here it should format it [Music] there you go cool I couldn't see it for a second but if you look this essentially is all the information about our Solana program right create master create bet we need this because we're going to be pulling that IDL in here so go to your constants and let's fill out any constant variables that we're going to reuse over and over so what I'll do is at the top here we do need one to import one thing and let's import public key from Solana web3 public key Solano web3.js and this stays the same but we need to do is export cons we also need to get the program ID so what is the program ID guys well it's going to be a variable that holds I'm going to use this import make a new instance of a public key based on this string okay what string do we use well simply just go to your beta soul.pg click copy this whole thing this is the address of where your program lives on the blockchain and we can just hit paste here oops there's already quotes in there so we don't need these extra quotes boom right so this is our program yours is going to look different than mine but it should be similar okay next is we should also keep the export const minimum remaining time until expiry right this is the one that we can change to make it more fair boom minimum remaining time until expired cool and that should be all of our constants awesome so remember when I was explaining how each of the functions work some of the things we can do is put that in our front end and pass it into our Solana smart contracts such as this minimum remaining time until expiry we can use this right another thing we should do is head over to our program.js so it should be in here and inside program.js we can have a lot of our helper functions for our Solana program so let me show you what I mean by that by doing something like this and let's hit import and let's get a couple things I want anchor provider provider and then we want big number which is BN program and this is going to come from project serum anchor okay another thing we need is that public key again because we're going to convert a couple of strings into public keys okay and let's get some of our constants in here and then what we need from the the constants is import the minimum remaining time until expiry and the program ID cool what's up next we need to get uh is well actually we can get that later but we need to get the program right so we can create a function all right create a function that gets the Solana program we created right so how do we do that we need to say export const oops const get program that's what we'll call it is equal to a function all right so what does our function do connection takes in and it takes in a wallet right and then we can say const IDL right what do we have we seen IDL before we seen it not there right here the IDL we just brought in so make sure you have your ideal so RDL is equal to require dot forward slash idl.json right so we can get the ID bring it in here and then we have to set up what's called a provider so the provider is going to be given through anchors so say new anchor provider and it's an object here also an object it's a parentheses here and you can say connection and wallet right so the connection and wallet that we passed in is going to come into here and then you say anchor provider.default options parentheses there you go so that's the provider variable setup next thing we need is the program so let's set the variable cons program is equal to new program right one of our Imports and set the IDL the program ID and the provider and that should give us um the program information and create a new instance of it and then all you do is just return it and there you go that's our program so get program texting connection wallet set up the IDL the provider and may use that to make the new instance of our program all right cool now a couple other things while we're here we also should remember how we have to fetch bets right usually when you fetch a bet you can just do a fetch all right or uh fetch of Master right but you can just get a specific account by putting in the public key so let's look what happens when I take the master and just put that to fetch boom that's This One Singular account object right so we need to do the same thing and write a function that gets the program account right so we can do that by saying can't get uh oops other way around export const get program account yeah and PK stands for public key so this is going to be an asynchronous function because we're going to make a promise all right this is going to take in the seeds right usually when you get an account you need the seeds [Music] okay so then we're going to return and say oh wait a public key and we have public key right yep and it has a built-in method dot find program address right this is how you can find a program using this you pass in the seeds and the program underscore ID and then you have to do bracket parenthesis parentheses zero okay cool I think wait boom okay and then uh this shouldn't be here so let's do a fine program address there you go and this doesn't need to be exported because we're going to be reusing that a lot when we get the other account so that's fine okay and then let's start using a function so we can say export const get master account PK right because we want to be able to fetch the master account that we create and to do that we're going to say async you don't need to pass anything in all we need to do is just say return a weight uh get program I can't PK and then pass in the C's right so if you think back to our app in the soul playground right if you go here how do we create the master we had to put in the seeds and then how do we even fetch the specific Master we have to pass in the master seed and if you know this is the string so we have to format that here and press basically an array and do this buffer Dot from and then you can say uh Master right this is the same thing as us writing that binary straight master in Seoul PG all right works the same way cool so after we did that we should get the bets right so how do we get the bets you can say export cons get oh sorry get bet account PK this is asynchronous and does it need to be passed in anything it does right it needs to get past the ID so get the ID in there and we're going to do something with it we're going to say return oh wait get program account PK okay and we say this and we want to put is that buffer because we do put a string in here and what was that string it was bent right so bet comma and then we need to pass in the ID and we can turn that into bytes right so to do that in the front end in JavaScript you say new BN that import we used ID dot two array like buffer comma and then remember we did the Le so comma and then eight and that's how you do it okay there you go [Music] okay so the next thing that we have to do is let's go ahead and set up our state so if you go open up this folder go to Global you're going to see that it's empty well we got to set this up and then wrap our entire app with our state and you'll see what we'll use it for in just a second all right so essentially our global.js is going to be our context so in order to create the context we need to say import and say create context and you get that from react all right but there is a couple more things that we need to import which is going to be a use callback hook as well as the use effect and I believe you stay yep use state awesome all right and then from there uh we can get this import it's called Lamp ports per Soul all right because we're going to do some conversions from Seoul to Lan ports and vice versa because that's what our contract likes to read it in so let's import another thing which is going to be use anchor wallet and use connection and it's going to come from Solana wall adapter react which we used before all right cool now we remember those functions that we created bring them all in here so we could say get program get uh master account PK and get bet account PK as well all right and another thing I like to do here is use toast so if you saw the demo this is where we got those notifications where you can get react hot post awesome all right and then to create a context to get started you just say export const and you can give the name of your context here I called it Global so it's a global context it's equal to the create context hook so I say create context parentheses and then inside takes in an object with all of the stuff we want to pass all right so I could tell you all the variables that we want to pass on throughout our app and it's going to be is connected is one and that can be set to null or we could have the wallet no all these are going to be set to null and they will be defined later on right has user account no uh all bets right we need to have a variable that holds all the bad accounts and that's no we need something that fetches the bets we also need create user create post now and then create now create sorry update the post no delete post no actually now we need to we don't need these we don't need these okay and go back yeah I think those are fine we can delete those uh fetch pets doing anything else no I think that's it so we have those and then we can get the global speed so export const Global state and set that equal to the children okay and from there we just do an arrow function here and then say const program comma set program right this is a State variable that's going to hold the program on our app and while we're here let's go ahead and set up the other states like is connected set is connected [Music] uh we can also say const master account right because we should save the master account and it should only be one per program so it sets master account is equal to your state and we can say const all bets set all bets right so this is a state variable that holds all the bets that we fetch set that equal to use State as well and there's also an optional one which is going to be user bets so we want to save all the bets that are relevant to the user and say set user that's like so equals use state okay and last one is just essentially just uh yeah we could have one more but I think we'll save that for later it's gonna make more sense and then from there we can just set up the connection so if we see our Imports we have can use connection here let's set that up by destructuring it and saying connection and saying equals use connection [Music] and then there's also anchor wallet so we can set that in a variable it's a constant wallet is equal to use anchor well because this will return for us a wallet and store it in this variable all right cool so now that we have a lot of the things set up let's get to writing out the logic of the global.js okay and then don't forget we need to return here and then put parentheses and then what you want to return is the provider so you say Global context provider or sorry contact stop provider yep and press enter and the key here is that the global context sub provider is going to have a attribute called value value set this equal to object and anything you put in this value is going to be what is going to be in our context right and in between the provider itself you have to pass in the children okay so make sure you have children here make sure you have children here and in the value let's say we make a variable it's going to be pulled out by writing it inside of here awesome uh one thing we do have to do is go to Hooks and if you don't have this make a file called use globalstate.js and then you can uncomment this used context so now it exists right because it's just using it's using the context now and what context are we using the global context right but one thing though is that our app doesn't have it just yet because we have to import it over here so at this point you are in your app.js and what we have to do is around here we have to say import Global state right import ant Global state from state slash Globe right the point of this is so that we can wrap our app with the global state so we can go um should go like right here and say Global state and then put that in between our app and there's only one way to test if this works is let's say uh is connected is a variable here let's make a variable let's call it let it connect it all right let connected is equal to true right and we can pass connected like so okay now it's not grayed out and then we can go to let's go to our index page and let's import the global here yep here's the hook use Global state and we can say something around here const oops const use Global state and we want to connect it is connected and let's see if this works console.log oops connected and hello I'm putting this comment here so I know which console log this is so let's go back to playground it's been a while since I opened this one are we running our app svr let's see it might be blank oh it's true let's go right so that means our Global stays working right so how does the context work so let's picture our app so I'm back in the Whiteboard this is our app right and it has a bunch of components like index and the index has header and portfolio right so this is the header and this is the charts right and this is the index all right so usually all components have a hierarchy apparent child relationship and let's say I wanted to have a connected variable in order to get that to the header I would first have to pass it to the index and then pass it down to header as a prop right if you have a long list of components that's going to be called prop Drilling and it may cause some issues down the line another alternative to instead of passing it like so oops lost the rectangles here boom boom another alternative instead of making it an app is to create what's called a store or a context and put it here because with this context I can just pull it from anywhere I don't have to pass it down from parent to child parent to child right so that's why we did that so that's my really really fast crash course explanation on that context but as you can see we have connected available to us so we can put in a lot of our functionality in here so we can erase that and now global.js is all set up so the first thing that I want to do is let's use use effect and let's set the program right set program so users spec is going to run several times depending on how you structure it so if I do something like comma array this is called a dependency module and it will only run once right we want this to run more than once but the first thing we should do is if a connection right if there's a connection then we can set the program to get program right and we can do that by because we passed in that program from our util so all the setup is coming into play guys don't worry it was all part of the plant so we say connection then we say wallet and then you do question mark question mark uh object here okay so if there's no wallet just use an empty object that's what that is saying and then the else right if there is no connection then set the program to no right and the cool thing about our program it does have a master already so we don't need to create that uh one thing to note is again this makes it run once or it runs once when it first loads or whenever the connection changes right so if the connection ever changes it's going to try to set the program again if the wallet ever changes when I switch wallets it's going to set the program again with that new wallet so that is important okay uh one thing I should have is another check which is gonna just check for the wallet connection right so we can do this with another use effect there's gonna be a lot of use effects guys so get used to it so use effect set is connected right I think I have that yep so you can say this if there is a wallet essentially that public key like so it's a double negative in that sense and we can have a dependency module that only happens when the wallet changes oh not that one this one nice cool and if you don't know what this question mark means is if it exists right so if I don't put this question mark you might get an error that says uh undefined Dot Public key right because it doesn't know what this is right this is only going to run if wallet exists it'll only get the dot part if there is a wallet which happens sometimes when you first load the page all right now for the first uh tangible thing that we can see is is a checking if the master account is there right so we can say const fetch master account right it's going to use callback so we're going to say use callback and say async Arrow and all you have to do is uh if there's no program then we can just return right this won't even run okay there's still more because we can do a try catch here not page transition try and then catch I just set up my catch first it doesn't really matter and then for the console log couldn't Fetch Master count and then we could just put the E Dot message here Dot message okay and then for the try the try we're gonna say we have to get the public key first to get the master count right so we can say cons master account PK is equal to and usually you have to write a lot of code just to get the master account PK but luckily for us we made a reusable way to do that it's this function right here Boop so bring that function down here and to say get master count PK so we did it right this should work and then she get us the variable and then we could say cons the master account itself right we can say our way to program because program is going to have all the accounts without account.master .fetch fetch the master with the with the specific master account PK and then set it to this variable and then once that's done we can set to the master account to that variable right so it all should make sense uh if this fails the semester count should just be no so we know it failed and what we could do is just pass that master account all right I think that's what I called it yep so I passed it in in value which means it's in our context so I can go into here instead of connected Let's Do master account and let's say master okay so it should show the master account that's created if it exists so I'm going to go back to here to refresh to inspect undefined so it doesn't seem to have the master account [Music] and if I double check yeah still undefined if I double check here it should have one right should say it should have an object like this that we fetch so that means there's somewhere where it went wrong let's go double check let's see if it's even getting the program so let's pass in program is there a programming program oh what program I'm going to be here it should be here program yep set program [Music] oh I mean it would be helpful to call the function so let's call this function it's still grayed out so we should call this in a use effect so what I'm going to do is down below here we could say check for master account so then we can say use effect [Music] and just do a check if no master account and program oops and program then Fetch Master account dependency module should just be a master account changes try this again or if the program changes then try this again right so if there's no master account and the ad there's a program we need to get the master account okay so let's see that works now hey all right we got it look at this last bed ID BN right it's BN because that's the format it's in so it should be zero um if you want to read it you have to go into index right the trick with big numbers is that JavaScript can't really read BNS so you can just do a DOT the property which should be last uh last bet ID dot to string and then we should be able to see it right zero so anytime you want the actual number itself do a DOT two string so that's the pattern that's the logic we're using that's the master account [Music] amazing okay so master account is done so we successfully created a way to fetch all the master accounts and then check for them we should do the same thing for all the bets so let's make a function called Fetch bets is equal to use callback and then say async Arrow boom okay uh and then same check we always do this if there's no program then you should just return uh same thing is const all bets results right result right and we can get all the bets if we do await program dot account dot bet.all this is how you get all the better counts in your program if there's none you'll get none but then from there you can say const all bets is equal to all bets result dot map right because the reason we want to map is to get every single post right and then well every single bet not post but and then from here we can say bet.account and that should give us just the BET object itself because otherwise you get the whole thing you don't want the whole thing so we can just do this and then take that and set all bets to all bets okay and then if I were to pass this down here it should give us nothing uh we can also just filter user bets but I don't think we need to filter user bets just yet you can just make it to show all the bets in general [Music] so yeah I'm just going to comment if you want you can use that filter to get just the user's bets right but the way our app works we should see all the available bets even if we didn't create it ourselves okay uh and then there should be a comma here dependency module program okay and then now yeah get and update all bets so it's kind of like we did with the the master account we can set up one more use effect like so and in this use effect we want to fetch our bets if our bets if all bets does not exist all right so if it doesn't exist already let's get them so if uh okay then we can say fetch [Music] okay comma and say oh oh if all bets change then run it again it fetch bets changes then run it again [Music] so now this function is being called and just to test it out it should be nothing because we don't have any bits we'll just pass this down oh bits okay and then index [Music] do all bets then console.log all bets should be empty array yep empty right because we don't have any and we could double check that with playground and you can see empty array so it's still pretty accurate awesome okay now we can go back to global.js and work on the next thing all right keeping it moving we are going to our first function which is going to be creating bits and we can actually test if creating bet uh works on our contract as well if this goes well so good to create a bet I'm gonna go down here const create bit and this is going to be use callbacks just like the other ones and it's going to take in uh an async not a misfunction right make sure it's a narrow function and inside of this async function what do we need to create a bet guys right think about it we need the amount we need the price prediction we need how long is your bet going for and we need the with pyth price T right so we need all those things and then inside this async function we have to do the if there is no master account right we can't do this otherwise the mastercount can't increment each bit all right so make that check in there it's our Edge case and then we have the try catch so I'll set up just now e and boom okay toast dot error [Music] yeah so as our first toaster error that we will see a visual cue I'll say failed failed to create BET right and then we can have a console log of the error.message okay cool because we'll get the toast notification it failed and then a console log of what exactly happened so that sounds good to me and in the try catch we can just say const bet ID is equal to the master account right which we'll have access to dot last bet ID and then to increment it we can just do the add in one add one next is we have to make a variable called response or res as equal to 08 we have to get the BET account PDA or PK and pass in the bed ID right and again if it doesn't exist if that if we if there's no better count that exists yet it will create one so we can say console.log and then we can just visually see it case but okay [Music] and inside we say rest okay so then after that we can make a transaction hash it's going to show us when it finishes program dot methods and we can look at this through Soul scan or Soul Explorer from here every program has a DOT methods and the methods that we can call on is our Solana instructions that we created together so we can do that by saying Dot all right Dot wait dude I can't press tab here is hit back Dot create bit so I'm calling the create bet function from Solana playground a month amount amount price and duration we're gonna pass that in as well [Music] pith price key ounce I gotta pass in accounts this is our like context [Music] the accounts that we need to pass in is the BET account just gonna be a way to get bad account PK bet ID plus we need we need the master right because if it doesn't exist we can't run this anyways a way to get master like this is why I love that we made those helper functions it makes it nice and easy I don't need to pass anything into that one though and then the player right the player is easy to get because we have access to that when we say wallet and then we can just get the public key because that's what it needs you don't need to turn it to a string and then last but not least you should write this dot RPC okay and then we can say await connection dot confirm transaction and then pass in the hash right so we need to confirm that this transaction went through and usually what you could do is console log uh created bet and then show me the hash that's why we made the variable and then I also like to put a toast.success here and say created cool so there is our creates bet function okay and then there is one more thing though uh there's catch here then there is this here we can put a comma and then we have to put in the dependency module is if the master count is different then uh that's the that is going to determine the BET ID so that should be here okay so let's put fetch bets and let's try it out so I'm going to go to the index and let's figure out where to fetch the BET all right so how do we fetch a bit it should be through the submit button right so I'm gonna go to find out where that submit button is it might be in the index it's been a while yeah it is and you can see that I actually commented out what we need to do so erased static bit and then comment out this right here so the first thing that you should understand is this e dot prevent default this is needed here otherwise if you hit submit on a form it's going to refresh your page and we lose all our states that we set up so make sure you have this so that it doesn't refresh next we need to get create BET right because right now it doesn't exist [Music] we should go back to our globals I put fetch bets but it really is create bets yep great bets create bet cool that exists save and back to our index and instead of all bets all we can keep our best then we say create [Music] then we console log create bet [Music] to see if it exists and it should give us a function that's not running we did this right yep function amount nice so it does exist it's really it's the right name and make sure it's in the on click of the submit button right so what's what's happening here it's going to take the amount of soul that we type in right in the input field that's what this soul is and convert it into lamp ports right because when we take something into Solana he doesn't work with Seoul it works with Lan ports and one billion Lan ports are in one Soul so next is the guest right what is the prediction price of the stock and then lastly the time which I'm going to put to like 150 seconds for example and then lastly the price key so how are we getting the price key right remember uh if you look at here you have to come down below get the price key that you want right so that's what you have to do normally but I've hard coded some of that for you here so if you look in data stock data right this is coming from data variable I mean data.js should be somewhere around here yep you can see that I have a price key of each of these stocks so that you don't have to and then the the graph that you're seeing that's not real it's still static right if you want the real stock prices you could just use an API not really through the pith Network the the main functionality that we're teaching here is how to use it in your salon program but again if you want to see that comment down below so back to whatever I was doing we want to set up the create bets so let's just double check one more time and let's just try it okay so creating bet awesome and let's see what happens so I'm going back to our app let's say let's use the AMC stock right you can see Bitcoin you can see Amazon let's go to AMC and then we can X this out and see so my prediction I will predict that the price will go lower to 3.8 right and I'm going to bet two soul and let's make the BET 150 seconds which should be around two minutes oh yeah I need to log in oh okay so my wallet is there uh this might fail them failed to create bet see is there any what's the reason I see it constraint was violated okay that's something we can work with so one Theory I have is when we call the function we might have passed in something that wasn't correct so we can go back to our global go to Korea bet and let's just take a look at all of these accounts so I want to console log them before we create the bed itself so let's do console.log um [Music] get this bad ID [Music] yes let's do this let's say let a bet is equal to this let Master is equal to this oops [Music] and let player is equal to this okay so what I'm doing is I'm just checking to see if these are the right accounts that we need to pass in otherwise the error might be when we're calling the account PKS so let's do this and then we can say a console log [Music] and say the bet is the bet then we can say player I'm sorry Master we should do that to string too by the way so it can be more readable got two string [Music] and then the player that two string player all right this is only going to run when we call create bet so let's try that so hit this one more time okay prediction uh 3.8 Soul it's gonna be two seconds 150. it's mint okay so those are our three console logs yeah so the seed constraints are still violated all right so let's see this is the BET account and let's see if that is accurate so create bet hmm great bet master player is that the master account yep four five eight four five eight the player is a t so a seeds constraint was violated [Music] program log six seven so I didn't like when we did the bet so let's take a look at our utils function that's my next guess all right this is live debugging right here when you're making your app program sorry and get the bet so there's something around here oh this isn't nine why is this a nine it should be an eight okay let me just double check yep late yeah so that's the first that's the C constraint right so this is where we pass in the seats to get the better count PK I put a nine here that's definitely wrong so let's see if that fixes it might not it might might not do anything but it definitely shouldn't be a nine there okay so again the prediction is uh let's just say two or three point eight pass into Seoul 150 seconds is the duration submit different account let's go minus two Soul this works guys oh I can't get too excited but usually when you see that number that's a good sign a create a bet awesome so we have a bet here right and we have to notice something we have to see if the available bets show up right so uh what we could do is go to our index and I think not that index I I think we already have all bets all right we have all bets here so let's console log it and see if that array is still empty if it is when then we're not um we didn't make the bet it doesn't exist array one oh let's go array one so our bet is there right so what do you want to do then what do you want to do after you have all the bets we need to get that component that shows all the BET information which we have made so let's take a look at our app once again and scroll all the way to the bottom see this available bets right here this is what we need to go to so available bets is all of those components so let's click on that boom right as you can see we have a static all bets here we don't want the static all bets we want the real thing so we need to import to Global context again so I'll say oh it's already here it's already imported nice and line 17 so I'll just say const all bets is equal to use Global state and now it should map through the actual bet so let's see if it works [Music] a and it's the right bet we did AMC there's two soul and we should be able to enter the bet but we can't just yet because we need to set up that functionality let's go so we have bets all right so let's work on another simple one as you can see here there's already a x right here where you can close the bet so let's do that it says static closing bet function let's get the real deal in here so if I ask you guys where are we going to write the function to close the bet for our front end that's right if you said global.js you are correct so go down below here 116 for me and say const close but right it's gonna use call back not anchor wallet callback and it's going to take in a asynchronous Anonymous function all right so when you close a bet you do need uh to pass in what the bet is right the specific bet you want to close and if you say if master account then return right shouldn't be able to close the bet if there's no master from here we do a try catch you know the deal guys say e we can console log all right first do a toaster error right and say uh failed Too Close bet all right and then the console log to let me know what exactly happened couldn't close bet and then comma here is why dot pair Dot message nice and then what did we want to try we have to do the same thing as we did last time let's set up a transaction hash variable that we will confirm later so we say away to that program.methods right and then uh we can say dot here or press enter to format it dot close bet all right because that's the name of our instruction in our program and then you can do a DOT account and pass in the accounts that you need for the context which is just two things it's going to be bet and then it's gonna be oh wait get bet count PK which we fixed now thank God bet that ID don't forget to comment here and get the player which should be very easy wallet Dot Public key awesome and then the RPC all right cool and then you can console log uh or sorry maybe not console you're going to say toast that success right because if you made it this far it's successful and you could say closed but now to see if this functionality works we have to pass in close bet here and then think about where do you want to call close bet where do you want to run that function so if you look at our app it should run when I click that x button and and do you know which components that is a living I'd say in this one available bets so if let's scroll down for the close yep you can see static closed bet which means we don't want to use this anymore so let's erase that and let's do close okay I believe that's what it's called yep close bet and it does need one thing it does need to pass in the BET right here and as you can see if I highlight it it does know which bit we're talking about because of this map right here okay so when we map and create a component of that bet information it has the BET stored there so we could close it it knows which bet it is all right that's what I did in the front end for you guys so now we can just do a refresh for just in case and let's see if we can close it and we should get refunded our two soul hey look at that plus two so let's hit approve close the BET let's go all right so that's done we are able to close any bet we create now now we just have to enter the BET and then claim the rewards okay so I think we're ready to set up for entering the bet so you know what to do let's go back to our app and let's go to global.js and let's just say the const enter bet now to enter the bit it's the same as all the other functions this is just us calling enter bet in the front end to call the function in Solana right so we're going to do use callback here and it's going to be async anonymous think about it what two uh arguments do we need when we enter a bet we need the um the price prediction of player B and which bet are you predicting on so price bet okay then you can just console.log uh well you don't need to cancel out actually then you can say uh X if there's no master account once again we we should just return and then from there our favorite try catch e and then console.log if it fails uh couldn't enter a bet and then tell me why with the E Dot message okay and then there's the toaster error so it's the visual cue that hey this didn't work so let's say failed to enter but exclamation point all right so what are we gonna try well you know what to do transaction hash is await program dot methods and then we can hit enter just for formatting purposes and say enter bet and we're going to enter the price uh we also need to say dot accounts all right and then put an object and the accounts that we need is the BET itself which you can say await get bet account to make because we made our lives easier and since we passed in bet here just pass that in to get the ID all right and it does all the fetching for us gets the account that we need then it's the player up next and then you can say wallet Dot Public key uh there's an error here because the comma as you can see I'm more comfortable with the front end than Solana so we can just say dot RPC here foreign [Music] and again I didn't do this for the closed bet but if you want you can confirm the transaction entry console log the TX hash again optional you do something like this connection.confirm transaction but if you just want to make sure or you could just console log the transaction hash that comes of this cool all right so that's entering the bet let's put this here and again if you think back it's been a while but if you think back to our demo the enter bet function should be somewhere here with all the other information next to our closed bed so let's go to available bets and let's try to find it so current amount you might have to create it now and here is where we want to set up that enter button or claim button right so we need to uh have a button that changes depending on the state of the BET right so how do we know what the state of the bed is well we have this console log here and you'll see what it's used for so let's just temporarily make a new one let's say one one one one 100 right and submit and Bam created bet [Music] oh accidentally refreshed there you go AMC right we should see an enter or claim button depending on the state here but if we look in our console what is our state our state is created right so if it's created we should be able to enter the BET right so this is how we get the state object.keys give me the state 0 to uppercase right cool so what can we do with that information well we can just do just get that right right away so say object that keys bet that state um in bracket zero and then dot to uppercase I'm making an uppercase so when I do a check all the letters is going to be the exact same or else I'd have to know how to write it exactly so you'll see what I mean in just a second so make that uppercase uh object Keys best case to uppercase is equal equal to starting right so and this is has to be Capital because of the two operators right yeah so this should be started started is when player B enters the pit so this is what I want to do first first get the started one and I have a question mark here because this is a ternary operator essentially if the set of the bait is started then what I want to happen is we have a div here and don't worry about the area it'll go away in a second we have a div here what is in this div well in this div is going to be the class name styles.com see we're still doing some HTML and CSS here styles that button and it's going to happen on click right you set this equal on click of claim bet so we don't have the claim bet function yet so we'll say static claim bit for now like so and inside that very div is where you can write claim right so if I save this um well we're still going to error because we're not done hit claim and then you're going to say uh or right or else this is the else the colon here after you use the question mark So if this is started load the claim div if it's not started then we want uh enter here we want object dot Keys again essentially this whole first part so let's just we can copy that all right so this is a nested ternary statement right here and this setup started we want to check for uh player A1 so we have to do all the states here to make it one button right you could just have multiple buttons like enter claim uh close right but I want to fancy I want it so that changes depending on the state so player A1 so it kind of goes down the nest so first is the BET started no then load player A1 is it player A1 no then that must mean player B1 all right so first we'll do the player A1 so you can copy this dip [Music] right and say player A1 right so player a one and this isn't on click and this also isn't a button this is the uh available bets title which I set up before for you guys and we're not done yet have another one all right another nest right so this one is going to be for the second option b [Music] right so player B1 okay and then if that's the case then it's going to be similar to this one I'm sorry this one [Music] tab save boom [Music] and then say player B1 okay and then if none of that happens then what we could do is roll in that's when you just see the uh enter button right so the enter button you don't need another object stack Keys here because it's the only other state that's possible so you can just copy the Styles button one okay and instead of this you just say uh enter and we do need to fix this a little bit because it's not claim bet it's actually enter bet enter bet well actually no we don't even enter But Here guys I was wrong when you enter but you get a little modal that comes up and to make the model come up we have to change this on click to a enter that set selected bet this is a front end function that I have that's going to open up our custom model then it will say set show model to true [Music] I also want to do an on click and we don't want this to run so we'll do something like this there we go so that's how you can make two functions happen one after another is make it Anonymous first and then make the two functions run okay uh let's see what happens [Music] oh [Music] foreign [Music] undefined or no oh okay oh okay so it's not my fault it's I just spelled State wrong I put satatate okay [Music] that should definitely exist now [Music] hey we can now enter the BET right so this doesn't actually enter the bet this does right and this is where I can enter our prize prediction if I hit submit that's where the static one comes in a closing bet okay cool so let's go to that which is the custom model which I haven't opened yet and in here we have static enter bet it says closing bet we don't need that anymore we can just get the import which I should have use Global State and then how do we get it guys you just say const enter bet is equal to use Global State like so and I just got to make sure I'm passing it here yep so now I should have access to it here and we have to go to enter yeah instead of static enter bet we need enter bet and it's going to take in the player 2's guest and the bet that we selected all right now moment of truth I will close this one because it's probably expired in the time span of me explaining and coding that so let's get our soul back and let's test it okay cool so now that I closed that bit Let's test the enter bet functionality and see if it works so let's get a player B so what I'll do is I made another window and we can go to localhost again but this is a different account so as you can see instead of 18 my wall address here says 3w so you should be able to see all our bets as well and enter as player B so let's see how much Solana he has he has five Soul all right so five sold for him and player two as well player one actually has how many soul I think this one has a lot should have he has 12. all right so let's make our bet so right now current stock price is 3.9 let's predict it goes to 3.8 and I'm gonna bet three Solana in it and let's say it's about 150 seconds right eventually you can set up a function that converts this from days to months right but right now we still just want seconds and now let's go ahead and submit and again let's test if create but still works let's go minus three that's good hit approve create a bet amazing so we can all tab to here and let's see what it says can we see it yes all right so the mat the pot to match is three let's hit enter and I'll predict it's going to be eight Solana so this one is going to be wrong so let's see minus three Soul approve let's go he entered the BET right so we can X this out and then now if you just look at a t and look at the status of the BET here three Soul it's gonna say claim now right it said enter before but because of our ternary operator it now says clean next thing we have to do is the final function of today guys which is claiming the BET and you remember this is the complicated one but we did the heavy lifting in Solana playground if you look if I did fetch here there's our BET right we can see player a who's eight T and then three W which is player B and you can even see the guesses if you fetch it so cool all right so let's go ahead and work on our last function all right so right now we want to claim the bet but as you can see I'm clicking it there's no functionality so let's give it life and let's go to prediction app and let's go we can go down below here and say const claim BET right and usually guys should know the pattern by now we're going to use callback and and this structure of calling the salon instructions is the same so if you want to make your own dap keep this structure in mind if you don't learn anything from here just learn that this is how I create a function this is how I call the function right those things are going to help you make your app so here we go claiming a bet all it needs is the bet that's selected and then we have our Edge case here what's our Edge case if there's no master account just hit return all right you with me home stretch guys then we do our handy dandy try catch here with e and you know I like to cancel that log couldn't claim and then show me why I couldn't claim with e Dot message and this has to be a comma actually outside the quotes okay and we also do a toast dot error here and then we can say failed failed to claim okay cool now for the try which is going to be simply just const TX hash is equal to program or wait sorry await program [Music] dot methods all right so we're going to call it the last instruction here which is just going to be claim bet okay and claim bets doesn't take anything but what does take stuff is the accounts that we pass in is just going to be the well actually it's going to be a couple of things and I think about it's gonna be the BET right which should be the 08 get bet account PK and pass in the bet.id and then from there we can pass in the pith right the pith is just the bets.pith price key we have to validate if that's the correct key and then we got player a and player B right so player a how do we get their key well we stored it in the BET account itself so we need to get to the prediction prediction a DOT player right how do I know this is what it needs well if I go to salon a playground I go to the account and then inside that go dot prediction a and then go to player to get that same thing with B so let's do that prediction and Dot player comma let's put player B player B here is going to be same thing but dot prediction and then we say B dot player last but not least we need the signer and that is essentially who uh is able who's claiming right so wallets Dot Public key the cool thing is that anybody can claim player a can claim and player B can claim so let's say player A1 and player B lost a player B claims uh the the money still gets transferred to player a right that's how we set it up which is pretty handy so then from here we can just say the RPC and then you can say a toast that's success uh success claimed bet all right hit save and we also I didn't I don't know if I did this for the other one but we need to put the dependency module for master count yeah I don't believe I did that for the last one so let's do dependency module master account [Music] same thing comma this is where they use callback part yep and I did that here alrighty so with that said we can now claim the BET and now we just have to go ahead and test it so I'm going to do this and then where are we going to claim the bet you saw the button so it should be around here so instead of the static claim bit we need the real clan bit and we should also press equals this so it doesn't run right away when the page loads and we should probably get an error because this is here static one and we need to pull it right claim claim Pull It in from here save and we shouldn't have any errors awesome so let's hopefully enough time has passed since I did that so that we can claim the bet so here we go deep breath let's see if the claim works hopefully enough time has passed or it doesn't give me any errors let's go do you see that plus six in our wallet right so this took a lot of work to build if I hit approve it should go through claim the bet uh it might take a while for your soul to update on Phantom should have 15 Soul right we just made a profit from you know predicting whether a stock will go up and down but I hope you guys learned something today comment down below if you liked the video and subscribe I'll see you guys in the next video peace
Info
Channel: Clever Programmer
Views: 22,117
Rating: undefined out of 5
Keywords: cleverprogrammer, programming, developer, javascript, web development, coding, programmer, software developer, software development, react js, tutorial
Id: 0KlXTd-1I-4
Channel Id: undefined
Length: 210min 51sec (12651 seconds)
Published: Sun Jan 22 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.