This tutorial demonstrates the complete process of launching a Solana SPL token, covering metadata storage on Arweave for immutable token information (name, symbol, image), creating an Anchor project with proper dependencies (Anchor SPL, Metaplex token metadata), writing Rust smart contract functions for token initialization and minting, deploying the program to Solana Devnet, writing unit tests to verify token operations, and implementing JavaScript functions to transfer tokens between wallets using Associated Token Accounts (ATAs).
Launch a Solana SPL Token: Mint, Transfer, and Metadata - Tutorial
Added:all righty in this video tutorial we are going to learn how to write our SPL token program and launch our token in the salon blockchain but first we need to understand that in order for us to write that contract or write that program we are going to be interacting with the anchor SPL frameware the moment we import anchor SPL onto the program we have access to associate this to the SPL token program which is a very important this is what will allow us to create the token and mint the token and we are also going to have access into instructions to interact with the token but not only that there's one important thing that we are also going to be interacting with in this program the metaplex metadata I am pretty sure that you have seen on tokens the picture the symbol the name and when we obtain tokens from an SPL contract or an SPL program when we open that wallet we should automatically see the token listed in our token list well all that information needs to be provided on the program so the blockchain know knows the token name it knows the symbol and it knows where to find the picture so it can display that picture in the wallet and in the block Explorer so we are going to be learning how to provide metadata to that SPL program but that metadata needs to be stored somewhere we are going to be using art weave which is a decentralized file blockchain that will store that data and make it immutable we will have the data available to provide that to the Token so the contract or the program is going to know where to look look for those details the token name the symbol and the picture and third and finally we are going to be writing a test that will initialize the token program it will mint some tokens and it will provide those tokens to the wallet the owner of that contract or that program so if I launch the token using my personal wallet then that will be the owner of that program right so when we mint tokens those tokens will be delivered into that particular wallet and we know on the first video we discussed that the tokens are not associated to the wallet directly they're Associated to the ATA that is the combination between the system program and the wallet address or the public key we are going to be writing a function in JavaScript that will allow me to transfer tokens from one wallet to another so with this function you should have the capability to do airdrops let's say we are going to be minting the entire supply of tokens when we launch the program then those tokens will be sent to the owner of that program well now I need to know what I'm going to do with those tokens so with this simple code that we're going to write is going to send those tokens to a destination wallet of your choice and with this video we will end our journey in deploying our SPL token okay let's go ahead let's make this [Music] happen okie dokie so the first thing that I have to do is I'm going to create a new file called metadata. Json okay so we are going to be creating a new Json file that will include the structure with all the metadata that I need to provide to the program once we initialize this token once we deploy the program we launch the program onto the Solana blockchain then I will be initiating this program we will provide this metadata here's the thing I have to create a Json file that will include the name it will include the symbol description and the image path this is the file of the image we will be pointing to this file this file must be stored in a decentralized file blockchain and we will be using our we on this demonstration what I'm going to do is I am going to be uploading the image file because I have to provide the path to that image on this metadata.
Json file so then we can upload that into artwe okay so we have to number one upload the file to artwe then obtain the URL then we can go ahead and create this what I'm going to do I'm just going to pre-fill this out with most of the information that I already know so the first I'm going to be providing is going to be the name okay and the name of this token is going to be the net to the SPL rewards token okay this will be the name of the token the next thing that I'm going to be providing is going to be the symbol and the symbol of this token is going to be the end to the r okay awesome next let me provide a description so let me go ahead and do description okay net to Def SPL tutorial demo token finally I have have to provide the image okay those are the properties inside this Json file that will be compatible when we Index this on the blockchain we search for the metadata the Phantom wallet all the interaction in web 3 with the salonic blockchain this will be a valid URI to obtain the information about that token so then it can be shown on the Block Explorer it could be shown on the wallet we can see the picture and all that so make sure that you are following this layout okay now on the image I have to provide the path to the image which means that I have to upload the image to rwe we will obtain the path and I can provide this path right here so let's go ahead and do that so what I'm going to do here this is a service that interacts with artwe and allows me to upload so I don't need to run my own local artwe node I can subscribe to a service that will paint those files into art weave okay in this case we are using Accord so I can upload all these information onto aord and I will be obtaining the artwe link create an account and again you can use any other service as long as you can just upload the files and obtain the URLs you should be fine so what I'm going to do I'm going to create an account in accord for example and once I create the account I can go ahead and create the first Vault this will be the only Vault and I am going to say that it's going to be an nft asset it's not an nft but we have to treat it as an nft because this will be publicly available remember this should be accessible from anywhere in the internet like any site that will query information regarding that metadata the block explorers will be a great example another great example example will be the wallets Etc we need to make sure that this file is publicly available it's not private okay so we're going to say set of Vault and we're going to say the SPL token metadata an example and we will just create a vault okay beautiful we have created The Vault now I can go ahead and upload that image file okay so what I'm going to do I'm going to look for my token image in this case I have this image right here so this will be the token image I am going to upload that and now it's asking me hey this make sure that you're allowing this to be says publicly this will be publicly available I'm going to say upload yes that's that's fine okay now we are officially uploading this to Art weave now what will happen is the following we should be obtaining that arweave URL right here so we have the art weave. net URL this will be the path to that picture don't use this art d.net because this is a private service this will be a service that is pinning that file on your behalf you want to use the public URL so that is available anywhere and let's say you Clos this account you still have access to the file right because it's not dependent upon the service okay so we want to make sure that we use this but also you keep in mind that when we upload data into artwave we should have a delay of 5 to 15 minutes to get that data online and accessible but we already have the URL this is what we need so we're going to copy this and we will go back to the metad data here we go and now we can go ahead and paste here okay awesome so we have the picture uploaded we have the metadata now I can go ahead and upload this metadata also to ourwe now now that I have the file ready to go I'm going to save it and let's go ahead and upload this metadata file also to our we okay and I am going to add an asset upload a file metadata here we go and we will upload the metadata file and boom now we have both the picture and the details this will be the token name symbol description everything okay when we use this file this metadata Json that we just created right what will happen is the Solano blockchain is going to look for those details and it should be able to people populate that on the on the Block Explorer on wallet Etc because this will be the standard that those applications will use to find this information okay so this will be the token URI this is very important okay so we have everything and now the image is also decentralized beautiful okay now this right here if we go back into that path now that we uploaded this metadata Json I can grab this and this link is what we need to pass when we initialize the token when we initialize that program we will be passing the attributes using this metadata path that's it okay awesome so let's copy this link we will be using at the end of this video to provide metadata to this token okay let's copy it and I'm just going to save it let's make a new file here I'm just going to paste that and this will be my path to that file okay very important inside this file this metadata then the blockchain or the application should be able to find the image because we provided that image path inside this metadata all right awesome [Music] okay so now that we have the metadata ready to go let's build an anchor project we are going to be typing anchor in it and we are going to say SPL we built this project and then we will open Virtual Studio code and open this project directory so we have the project built now let's head to Virtual Studio code and open that directory perfect so we have the directory ready to go now let's go ahead and do the following I'm going to test the project by building this project this includes a sample program it includes the sample test and all that I just want to make sure that this project will build correctly okay so let's go ahead and do that going to open a new terminal and we'll do it right here okay so we are going to say let me take the opportunity to zoom in a little bit perfect we are going to say anchor build and we'll wait for this you don't know how to build the anchor environment I suggest you look at video number two because I explain how we set this up from scratch okay it's going to take a little bit of time okay and we are done and you can see that there's a warning but this is default don't worry don't need to worry about this okay awesome so we are good here we are going to build this program right so we are going to build this program we're going to take advantage of this file right here I am going to remove this existing program which is the default one right and we will Begin by importing the anchor SPL okay so this is what we need to do pay close attention to this I need to declare you use and by the way you see that this is autoc completing it's because I have co-pilot and copilot helps a lot but I want to build this so then you can see this from scratch okay so we are going to be typing anchor SPL okay and in order for me to bring the instructions and bring the types and all that I have to populate the cargo file with also the dependency for anchor SPL I have to Define that in the Caro Tom file and this will be this file right here under depend depes we have to also import the anchor SPL and that's how we are going to be able to have access to that particular dependency okay very important let's do that so what I'm going to do I'm going to head to the cargo Tom file and we are going to add a couple of lines here I'm going to explain to you what they are okay from the anchor L we also have to define the instruction to initialize only if needed okay so check this out it's very straightforward so what I'm going to do and by the way all the files that I'm writing here will be available in the GI Hub repo and you should find the link to that GitHub in this video description okay we are going to Define version because now we are going to pass some arguments to this dependency okay so it's going to be the version and we are just going to keep that same version which is going to be 030 okay now I can go ahead and delete this right also I want to import a feature the feature is going to be to initialize if needed okay so we're going to say feature and we are going to Define in it if needed okay and this should do the anchor Lang dependency now we are going to officially add the anchor SPL as the a dependency on the cardio Tom so when I do anchor bill it's going to look for that dependency and download it and provide that onto the program okay so we're going to type anchor SPL and we are basically using the same syntax here but the only difference is that on features we need to add certain features okay so it's going to be also the version 030 features the only feature that we want to add will be metadata now we are going to import the metaplex token metadata dependency as well so we're going to type MPL token metadata and we are going to Define this to be version 323 in the build I have to Define under id- build that I'm not only defining anchor Lang but also the anchor SPL there's two builds that I have to provide so it's going to be the anchor Lang and anchor SPL okay and that looks good okay awesome we're done here all right next item that I have to do I am going to make sure that under anchor pal I change this cluster provider to defet else I need to run my own simulated node so then I can test locally but we want to deploy this on the defet on the Solana defet so you have to make sure that this is specified here okay awesome cool okay so we are good here let's finally build the program so what I'm going to do I'm going to say use anchor SPL and let's start importing we are going to be importing quite a few items so I am going to open the bracket right here and from the anchor SPL we want to interact with number one is going to be the associated token and you can see that it auto completes it's going to be the associated undor token and then Associated tokens this is the instruction that we want to work with and now from metadata we are going to be interacting with metadata under the SPL anchor SP we are going to create metadata accounts but we want to make sure that we use version three which is a recent version and now we are going to also Define MPL token metadata okay and from here we're going to say types data V2 okay how do I know this the metaplex developer docs we should be able to find the information regarding this particular interface okay so I am going to just grab this I'm going to go a quick Google search okay so we can go over here let's see hopefully we got the information here I pretty sure that we have so we're going to say data V2 and we are going to scroll here we go so we have from the SDK we are going to select data V2 and then from here we have access to all arguments all those arguments that I have to be passing on the program okay you're going to see that don't worry so I need this in order for me to provide a metadata path on the program okay so let's go back all right we are going to provide create and I believe it's going to be metadata it's Al together create metadata account and this will be V3 and finally we will do metadata as metaplex close here and that's about it as far as the the metadata dependency so I am now going to add one more line and this line is going to be token we are defining token and this is where we obtain the interfaces that we are going to be allowing this to interact in this smart contract in this program it's going to be mint two it's going to be mint it's going to be mint 2 and it's going to be token and token account and you will see what this is all for and yep that's it that's basically it okay awesome so let me go back okay so let me explain Associated token from here we need the associated token we are going to be interacting with metadata and from there we are going to be importing into the program the metadata accounts V3 the MPL token metadata types data V2 and then create metadata accounts metadata as metaplex okay the token obviously mint two mint Min two token token account those are all that I need to interact with when we build this SPO contract okay now declare ID state the same all right so now let me break it down what will look like what this smart contract is going to look like or this program I have a very straight forward explanation we have two functions right so we are going to be defining two functions in this program one is going to initiate the token this is when we add the token metadata we define decimals as far as the numeric measurement this will be nine decimals for example we're adding that we're adding the name we're adding the symbol we're adding that particular information and we will Define the owner and all that so in order for me to do all this and store this on the program I have to define the function initiate token and inside this function we are going to be passing two arguments which are structs they're contexts that will Nest additional instructions that I need to pass as arguments so the first one is going to be initiate token so we are going to be defining a struct called initiate token or init token from there we will be passing let me see if I can zoom in a little bit better here okay I think this is good let me show you okay perfect so from here from the init token we are going to be passing mint this will be the token mint account the payer the rent the rent it's like the fee to hold accounts in this program in order for me to initiate any account I need to have a balance and this will be measured in lamp ports this is a measurement in Solana to measure fractions of a soul token those will be lorts the rent it's me making sure that my data in the program remains active because I have tokens to maintain the state in the Solana blockchain to be active and this is for me to initiate the account I have to fund that account with some lamp ports and this is basically a fractions of a sold token a Lamport is a measurement and I have fractions of Soul token in the account that will enable the account and initiate the account in the blockchain okay there's a lot more to it but that will be in a nutshell okay then obviously the system program this will be the main SPL system program in order for me to initiate this token I have to provide that value and I have to also provide the token program and the token metadata program all those attributes we are importing them from the anchor SPL okay the Anor SPL is going to give me everything there and I have to wrap everything and package onto that stru c in it token okay once we pass that we are also going to be passing the metadata because we are initiating this token when we create this token in the salana blockchain the initiation must provide all those values I have to provide those values in order for me to initiate the SPL and also I have to provide the metadata to initiate the token the metadata will have the name the symbol and you can see it right here we're passing data V2 all the arguments inside data V2 that will include the metadata name the symbol metadata URI the URI is the art weave path to the Json file that we uploaded previously okay so this will be the URI this is what we'll be pointing to in order for the blockchain to Index this particular program and the block explorers can find the metadata and all that the URI is very important it's like super important seller fee let's say you want to add some tax on any instruction in the program to like say sell tokens transfer tokens you can insert a percentage fee that will be paid to the developer of this contract right so the account of this contract will obtain developer fees or seller fees okay so anyone that does a sell or a transfer will have to pay this seller fee okay and you can Define this in our case we're just going to do zero because we're not going to do trading or anything we're just going to create the token and then we also have other metadata that we can provide which is creators Collections and users all this is part of the metaplex if you want to learn more about it read about data2 and this will be imported onto the program as well awesome now when we imported everything we have to contract okay we have this particular function which is initiate the token we are going to Define program what the program address is going to be is going to be from accounts token metadata program right anchor SPL we imported this and we are going to Define two account info the account will be the ID or the value of this token contract okay so the account is the address of this particular program or contract okay this is what it refers to the program account okay this will be the contract address or the token account okay good so far awesome and now we pass the payer so the payer will be something provided when I run this deployment when I initiate with this function when I call this function I will be passing to account in will be my address okay and the program owner is also going to be my address and the mint account so whoever can mint is my address so two account info will be my owner wallet the wallet that deployed the contract okay mint Authority whoever deployed the contract will be the mint Authority and the system program will be the system program in the SPL contract and rent will be the lamp ports that I need to provide in order for me to initiate this token okay and finally the signer so the signer is an argument that will will be generated using a seat phrase and you're going to see this once we write this on the smart contract okay so the seat phrase is basically onsign integer it could be a sign integer that will be provided or even string to generate a c phrase only with that c phrase I can initiate on this particular function I can send that c phrase to initiate this so when I make the call and you're going to see this when we do the test we have to provide that c phrase or the seed value so then we can run this so then we can sign this particular transaction don't worry I talking a lot here but it's for me to give you like a brief breakdown of how the functions are configured and now once we wrap we package everything into this particular variable or context same goes here we pass those two values as arguments to this interface or this instruction the create metadata accounts V3 which we imported from the anchor SPL we have to pass those values that we are generating that we are packing when we call this initiate token function and we will pass those arguments there we're also going to be passing additional arguments which is it's mutable false update Authority it's signer true so we are saying into this metadata accounts that anytime that we initiate an ATA this is where we initiate the ATA per wallet we are going to be basically creating those token account this is literally where we create that ATA all right so let's go ahead and build this initiate token function and we can go from there all right so let's do that all right so now I got to build a contract I'm going to copy and paste the syntax and we will go through it very quick so it's more efficient okay all right so now we officially initiate this token program and it's going to be called Netto theore token this will be the module or the initiation of this program and this is a rust argument for super okay it allows me to improve when we initiate or we interact with the functions if I want to explain this in detail I have to have another video to work with just this particular session but it's it's like to remove from being ambiguous I'm trying to find words to explain this but it's very very uh specific to the language okay and now we officially initiate okay so let's do that let's do pup function this matter fact I'm going to copy and paste and everything that you saw in the in the Whiteboard session it's basically here okay so I'm going to say pup fun initiate token let's talk about it okay so I'm going to remove this perfect so you see that the two arguments that we're passing the context in a token and the context for metadata we have to pass those arguments okay so we have to initiate token params which is another struct and the context that we are going to be declaring so before we continue on here I am going to be passing those arguments so let's build those structs now okay let's do that I am going to add this below here we have to still keep this this is to initialize our accounts I am not going to make modifications to that okay now we have in token params and you can see here this is the information that we are expecting metaplex we have to provide this so then we can initiate the metadata in this particular token SP contract okay in a token parameters we pass the name we pass string symbol and all that those are the properties inside the struct that we have have to populate with data once we initiate the token okay and we basically derive and we are going to be using anchor serialize anchor the serialize debug and clone those are all macros that I can use or types that I can use to interact with this particular data in the contract if I can clone if I want to clone that means that I will be using accessing data from this particular struct and I have to clone it so that I can reuse it in another function or another instruction on the same function and now the in a token struck which is a context okay so let me break this down for you so this particular context is deriving accounts because it's going to be interacting with every account that we call this contract in order for me to build an ATA and Associate this ATA to a wallet a new wallet let's say a new wallet is going to hold tokens we need to initiate this wallet which means I have to build an ATA which means that I have to initiate that account right so we are going to be passing in a token when we make that call we pass those arguments we make that call we interact with the wallet into the contract well you're going to see this because we have to write the test okay so basically we are saying account is mutable meaning that I can make changes to that particular entry or in this case to the particular account and we are passing the array it's an array of values that I'm going to be passing along this particular stroke so every account that I make calls here will be stored individually into its own little state in a token I'm going to say on its own state struct state now we are passing this is very important this is where we def find the seed seed like I mentioned is a value that we have to make sure that the value that we code in the smart contract or in the program I keep saying program and smart contract because I come from EVMS and this type of application is called a contract but in Solana is a program so bear with me okay uh bum this is related to the Anchor SPL program I not sure I have to research a bit I cannot give you an answer because I really not sure what bum does I should be reading more and then payer we're passing payer argument payer is the state of the wallet so every time we interact that will be basically the wallet then we will pass the mint and the decimal so I have to make sure that I pass under mint decimals so we Define the decimals for this token we are going to be using nine okay and the authority which is the mint Authority this will be the address of the mint Authority okay this will be stored here now we Define the account itself we are going to be passing an account this is where we enable that program we officially enable the program the token program and we Define those values as System Program this is all provided by the anchor SPL create token program token metadata Etc now it's deriving right from instruction init token prams which means that from the init token prams I will be interacting with this information and I will be passing some values into in it token okay awesome so I have init token right and now we are passing init token prams which is the second struct that we have right here all right awesome don't worry we're going to get to the fun part I know this is not that interesting or exciting but we have to talk about the theory okay all right so now that I have those two values I initiate this function to initiate the token this is this will be called every time that we do an ATA or we interact with this contract initially and also to initiate the smart contract or initiate the token program we will be returning a result now we are going to be defining seats so seats is going to be a combination of mint as bytes so we are converting this string as bytes we will store this in this particular VC or array and then we are also going to be defining the cont context bumps mint how do we obtain bumps mint from bumps mint from the context basically we have imported that context that we defined down below the contract so I'm going to show you right here and you can see here bump mint okay so we are grabbing mint bump from this particular context okay and we are importing this context into the function that's how we gain access onto this particular value okay signer we are storing seats inside signer as another array Okay so signer will be that seat phrase that will be the combination of this particular seat phrase and this particular value that is stored from the context okay this then will be packed onto this particular variable called token unor data which invokes data V2 from metaplex so from there we have the name we have the symbol URI seller creators and you can see here that I'm not specifying any collection any creators any users nothing it's even not no text okay all we are going to be providing is going to be the name the symbol and the URI if you want to make Chang if your token requires tax then you are going to be modifying this Etc and now we effectively build that metadata context okay so we pass the CPI context so from the context we pass new with signer this will be part of the instruction inside the CPI context for metadata and we pass those values just like showed you on the diagram on the visual representation right here okay are packing everything so then we can call metadata accounts V3 and pass those as arguments okay and then we can initiate or ini iiz this token program okay beautiful now we effectively pass the signer right because we are passing signer as the second argument inside metadata and then we pass those two values that we just decare right here and initiate this particular instruction create metadata accounts V3 this is imported from anchor we can see it right here and yeah we pass metadata token data false true if you take a look at metadata accounts V3 you are going to see here what is mutable false that means that the third argument here it's mutable we Define this to be false and update Authority signer equals true so this by default will be true once we pass that then we want to send a message hey token mint created successfully okay so this is where we officially initiate this program and we pass okay as a result which means that everything got executed correctly now let's do the second and final function mint tokens okay so let's do that with mint tokens way easier you can see it right here all we are going to create is one context to min the tokens okay and we are going to define the quantity so those are my two arguments when we call Min tokens when we call this function to Min tokens we are passing two arguments what arguments are we passing this context which we will create another stru to do this will be to Mint what it's going to require it is going to require let me see if I can zoom in here we go we are obtaining the mint account the second value will be the destination destination of what the destination that it's going to receive those tokens the payer who's going to pay for this transaction the rent this will be in lamp ports this will be autoc calculated all this is already prepackaged pre-wrapped all we have to do is pass the values and it will do the autoc calculation for us and all that okay the system program the main token main SPL program address the token program and the associated token program those addresses are all generated with the anchor SPL when we do the initiate okay this is straightforward okay now when we pass this context we are also going to be passing an unsigned integer and this will be the quantity so we pass the amount in this case we will be passing the amount as the value in the decimal measurement or in the units that we are going to be passing which means that if I Define this contract with a decimal of nine and I'm going to be transferring 10 tokens I got to make sure that the value that we pass as the argument is converted to nine decimal which is basically 10 plus 9 zeros that should convert that to nine decimals okay and then we are wrapping this into an instruction called mint 2 this is the instruction that we imported from the anchor SPL if we scroll to the contract I'm going to show you right here and we are going to be minting to right so we are minting to this will be part of the token inside the anchor SPL this is the token instruction then from there we can access Min to and so forth okay and when we interact with Min to what is expecting it is expecting again we're passing the context new with signer once again I am passing the signer as an argument because I have to make sure that I record who's the signer who is going to make the call the signer is whoever is making the call in this case if the owner of the program is the one that is calling this mint because it's only able to Mint tokens we don't want to allow anyone to Mint tokens but the owner of the contract then that will be the signer basically and now we pass those arguments as you saw with the initiate token it's going to be very similar okay authority to and Min those are the arguments inside the accounts that I have to pass okay under Min two when we work with accounts I will be passing this particular object with some properties the properties are going to be authority to amend and this will be the values okay the mint is going to be the mint amount defined to the sender in this case the signer of the particular function okay and that's about it I am going to now add this onto the contract and let me add that mint over here add it right here I want to show you so this will be the struct we are building that context and the account mint tokens and we will pass those arguments same as what we did with initiate token and you can see that it's slightly similar okay then we pass account for mint and this is where we initiate if needed right because if let's say the destination wallet that I will be passing those tokens is already initiated meaning that there's already an ATA generated and recorded on this program that means that I don't need to generate this account again okay which means that that's why we are looking for this okay then we pass the payer the mint account and the authority we Define the destination and we provide those values very similar to initiate to be honest and we have to build that new function to Mint token so we have initiate token we now have to add the function to Mint tokens so there you go co-pilot is actually autocom completing this on my behalf but it's slightly different from that grab the function I'm going to pass it down here and there we go okay so now we have the mint tokens and then we have the amount we have a return of result which is basically returning okay and then we wrap what we saw in the visual diagram that I showed you basically wrapping this into Min two and then we pass this Min two here as the object AR arent into this function that's it that's all we have to do in a summary initiate the token provide the metadata and then the other function to men the tokens very straightforward obviously there's a lot of things involved in this contract but to be honest it's very straightforward as far as the costs because the heavy lifting is been done with anchor SPL anchor SPL is giving you everything pre-wrapped all you have to do is pass the arguments and provide the details right that we are are going to be defining when we initiate the contract and so forth so now I have have to close obviously I have to close the program so I'm going to end it here so where is my last function here we go I'm going to say boom beautiful so now we have the program defined as Netto Dev underscore token and yeah we can go ahead and save this and now let's go ahead and build deploy and we will have the contract or the program deploy in the defet once we finish deploying we will go ahead and proceed with testing let's do it [Music] okie dokie so now that we have the contract ready one thing that I realize is when we build a project an anchor project we want to make sure that the contract name or the program name matches the project why because when we build this project when we type anchor build the project will generate a type file will generate some additional files that will be used to deploy the contract that being said I set up the program name to be called Netto def token and in reality we want to name this same as the project so in this case the project name will be the folder name right the folder the directory that we open in this case it's going to be SPL so we're going to type SPL we're going to save it so instead of me naming the program net toore token we want to make sure that we follow the same name as a project so then when the files are built are built exactly for that program name this doesn't affect the token name at all this is just locally to the project now let's go ahead and build it we are going to type anchor let me uh expand a little bit here so so you can all see perfect we're going to type anchor buil let's see if we run into any issues it's going and we have an issue let's see what that is uh bumps it's not implemented for Min tokens create root metadata oh this has to do with a cargo we set it up correctly and I have metadata oh I see what happened I see what I did wrong it's not feature it's features with s plural so let's save it and remember change this features it's plural so now let me save the file since we already built this with a different program and we have changed the program name to be the token contract I will delete this SPL Json file so we go under Target we are going to delete the IDL which is SPL Json so let me go ahead and delete this I'm pretty sure that I also have to delete types I deleted types I deleted the Json file that is located under the IDL let me go ahead and give it a shot again and hopefully we are good we are good so we know that now the bill is good now we have generated the uh IDL for the actual contract and now we have the right instructions we should be good now to deploy this and we have the types beautiful we have everything so now let me go ahead and deploy this and we're going to type anchor deploy and fingers cross let's see it's going woohoo we have deployed the program in the Solana defet awesome let's build a test that will initialize this program and we should provide that metadata path the path to the Json file that we uploaded to artwe at the beginning of this video so with that said I got to do the following let's work on the test so right now the test that we have is the one that was built default when we initialize the project we are not going to be using this absolutely not because this is not what we want but we are going to take advantage of some stuff that is already done for us okay so in this case in order for me to build a test I have to import some dependencies one of the dependencies to perform unit test is to implement Coral XYZ this is part of the anchor framework I am going to also import Solana web 3 because we are going to make calls into that program I have to install the Solana web 3 SDK I'm going to say mpmi Salon web 3 yes enter and wait for that beautiful so now I can effectively import that so I am going to type import wall card as web3 we're going to import everything from Solana web 3js don't really need a program I am also going to be working with decimals and I have to do some math in order for me to calculate the actual value when I transfer tokens which means that I have to work with another library in this case is going to be with big numbers so I am going to install that I'm going to say mpmi BN that's that's it cool and now I'm going to say import we're going to Define this to be BN and as a matter of fact I do have that from the coral xyc as well I can do that as well I'm just going to use the one that I installed but you can use any other flavor so I got that I am also going to be doing assert for testing I can assert a condition else throw me a an exception saying you know failed because XYZ and that's about it I don't need this by the way this doesn't need to be a module that's it add this on the top beautiful so now we are starting the test so let me start by describing we're just going to keep describe and this we can say SPL uh program test we can describe this test to be SPL program test and now let's start I will be invoking the SPL workspace in this case the work space will be the name of the program so we are going to type anchor program this is how we point to the program in this anchor project and anchor. program and now I can Define the SPL that's it so this is how we invoke that from program so we're going to be using this anchor anchor uh from the coral xyc testing Suite so I am going to be declaring program and now we can call that program that interface and I can interact with the program itself aka the contract now we need to pass a seed for the metadata so we are going to be defining metadata and we are going to say metad dator seed or this will be a string that will be then converted onto a seat that is used to make update or change the metadata in the contract this contract is upgradeable meaning that I can make changes there's certain things that are mutable but in order for me to interact and make changes I need to pass that seed the correct seed so that I can make the appropriate change in this case we are passing the seat for metadata because we're going to be interacting with that metadata so I'm going to just say that it's going to be metadata this will be the Str value for that c phrase again follow the lead now we're going to say constant and now this is very important we are going to be providing the value of the metaplex token metadata program this is the program that is associated to the metaplex metadata make sure you provide the value this is the value that we will provide by default I'm going to copy and paste because I have everything built in I think it's going to be easier for us to do that than just type stuff so you can see here token metadata program ID now what we do we initialize a new Constructor we call Web 3 that we imported from the SD okay now we are going to be passing the value of the token metadata program where did I get this information from you know what let's grab this let's go to Google and let's search for it and you are going to see that this is going to be the default metaplex token metadata program ID and we can see here we go to the GitHub page for metaplex I am going to search for that value and sure enough here he goes so this will be the program address this is the default program address for the metaplex npl token metadata all right so let me go back good so far all right so we are just defining the variables that I need to make those calls now if you remember in the program let me go back to the program remember when we pass seat this particular string must match when I make the call to the function to initialize the token program I have to pass that exact same seat phrase which means that I have to wrap this string and then pass it as it is on my call so then it gets updated correctly so because it's expecting this particular string value so I'm going to say con now we're going to be passing that Min seat and what is the value that is is expecting mint now the moment that we are going to declare that metadata so first thing I'm going to declare payer which will be my wallet or the owner of the contract anyone that interacts with the program will be the payer and now I have to Define that from the program is going to be the provider and now the public key this will be the address of the payer we are passing that as the argument now let's define the man data constant metadata right and we are going to say the name for value and what was the name net to Def SP rewards token cool now the next item is going to be what symbol what's the symbol N2 to the r beautiful now the URI where do we get this information this is the URI that points to the Json file that we store in R weave okay let's go ahead and find that out so we go on our um this case aord account and the metadata Json entry that we have here we will just hit that I the information I'm going to click here and then it's going to show me the path to that Json file I'm going to copy that we have copied that let me go back and we are providing this Insight here beautiful so we have the URI and finally we are going to be passing the decimals setting this token unit to be nine decimals so we are going to say decimals and we are going to pass nine beautiful with this we should obtain the metadata and the token should be initialized and now when we initialize this token or this program we want to Mint something so we are going to be minting a supply this mint an initial supply of 10 tokens and we will send those 10 tokens to the owner of this program in this case the the wallet that I'm going to use to initialize the contract program we're going to say const want to type mint amount and we're going to say 10 just do 10 now we are going to wrap this and we are effectively calling web 3 I'm going to explain to you what this is this is going to be that mint value that we pass onto the context to initiate the token so if we go here and we scroll down you can see it right here this is what we're defining basically we're passing the values for Min so let me go back so we're going to say web three and we're going to be passing public key and now we have the function to find the program address we want to obtain the public key of the program address this will be the mint account this will be the address that I need to interact in order for me to Mint those stokens and the first argument uh is already prepopulated because I'm using copilot but that's actually the right syntax so I'm going to explain to you so buffer from mint seat we are passing mint SE which is expected in the seat phrase so if we go back here let me show you seats mint as bites and we are passing also bumps mint so if we go back here we go buffer for mint and we pass the program ID as the second argument we're wrapping the values for seed and under mint and this will be passed to the context and will be stored there and now we have to pass another one which in this case is going to be the metadata address because we have to also WRA that metadata seed here and I have to provide those two values so then I can interact with metaplex and update the token metadata so let me just copy and paste to be more efficient and and I will explain to you what this is all right so now we are doing exactly the same thing very similar to what we did with the mint and by the way this should should be synced there there you go awesome so this should be sync all the files that I'm writing they will be all completed in the GitHub repo you should just download and deploy so we did the metadata ads we got the buffer we got the token metadata program ID Min to buffer token metadata program ID so we are passing this argument we're converting this to be a buffer this will be basically a function that allows me to return that representation in big endian and now we can officially initiate this test we're going to type it and we can Define something and we are going to be doing the test so let me see what copilot did for me uh let's see very close it's not it but very close to it this is kind of scary to me to say the least so let me replace that with the values that I need I'm going to explain to you what this test is going to do graub this and we're just going to paste this and now I am going to add more stuff that I need to so when we start with do it we start that test the first test is to initialize this token I'm going to say initialize and the first I got to wrap I got to store under info the connection and then obtain the token account information this will be the info if that means if this program check this out if this program was already initialized what is going to happen is this should return a value of the shoot retainer value that is not undefined and then will just stop from executing it's just going to stop the initialization if it's not initialized then else we're just going to continue we're going to initialize this program first thing I got to to build that context I got to provide all the details that the contract or the program is expecting under context and you can see it right here actually you can see it right here metadata context so we're providing that on the test we're going to say metadata pass the metadata address which we already declare here right we're passing the mint which we already declare everything that we already have declared except with the rent this is provided with using the SD we don't have to worry about obtaining the rent value we just provide this same with the system program these are all default values by the way this should not even be here now we are going to finalize this test here continue here with what we are going to now build that transaction we are going to wrap all the values for the context so that I can make the call and initiate this token contract we initiate pass the arguments pass everything now we can confirm the transaction we pass the hash which was everything wrapped we wrapped all the information we wrapped the context that we built previously and under TX hash we build that envelope for that transaction and then we pass that as the execution here to confirm this transaction once the transaction gets confirmed then we can obtain a link this will be basically a link that sends me to the florer and allows me to see more information about the transaction and now basically at the end the token program has been initialized and it's available in the blockchain and we should already even have tokens available for us that's the first test we have written the first test to initialize the program now I got to describe the second test the second test is to Mint tokens so we are going to be minting some tokens let's uh take a look at this and the second test will be to Mint the tokens that I'm going to be wrapping is going to be the destination which will be the destination wallet that will receive those tokens in this case it's going to be the deployer the owner of this program so we pass mint mint will be the token contract or the token program ID value of public key of this program this SPL token and then we'll pass the owner in this case the payer address my wallet the wallet I'm going to use to initiate this contract this will be the owner and now let's Define initial balance so this is how we obtain the initial balance in the token Supply right so we are defining this variable obtain the current balance this is the function that will get me the token balance from the contract or from the program right so this right here program provider connection we call the defnet then we initiate this function get token account balance destination we pass the wallet and now we obtain that initial amount we know now how much was that initial value we pass balance value converted into unsign integers else that means if that wallet has no balance that token account is not initialized it's brand new token account which will be because we have never ever minted any tokens when we initiate this test this will be the first time that this wallet will have an ATA Associated on the contract and we are going to be defining this initial balance to remain at zero because there's no tokens and now we are wrapping the call we are wrapping the context to Mint remember what we did with initiate token we are going to be doing the same thing with mint we are doing a similar call I'm going to grab all this information and explain to you we're almost done with the test well we're almost done writing the test we haven't done the actual test now the context very similar to what we ended up doing with initiate we have to pass all those values in the context so then we can properly call the program and provide those values and execute the function very important those are all arguments expected to build that context and make that one call and provide all that information to the program during that transaction then we have transaction hash this is how we build that envelope once again we pass in this case we're passing Min tokens this will be the function in the program that we are going to be invoking what is the argument we are passing this is where we use big numbers so we are going to be using big numbers from this module this library right here and we're passing that we are passing that big number will be mint amount which we defined earlier when we initialized this test and then times 10 this is how we convert to the decimal unit that we specified in the metadata in this case we specify nine so in order for me to convert this integer mint amount to that decimal nine I have to multiply by 10 then decimals and now we pass the context again we have to wrap this entire context with all the information that the program makes expecting under accounts and then we make the call to the RPC the RPC will be the defet provider now we effectively send the transaction we send that envelope with everything packed confirm transaction and if everything goes well we should have the hash available for us so that we can see this on the Block Explorer and at the end we want to know if we got the balance updated so let's do one last call the last call I just want to obtain the post balance so I got to confirm that this is for me a check this is a test that will validate if the post balance that we obtain as reading that program matches the initial amount and the mint amount because the post balance has to be increased we should obtain an increased amount but it has to match what I already have before plus the new mint amount then that tells me it is 100% confirmed that we minted those tokens because the balance updated it's for me a way to validate and test this call okay we are done with the test so let me go ahead and save it and once we save it I am going to run it and see what will happen so let me do the following I'm going to grab first all this I'm going to say a let me format it so it looks prettier perfect awesome again all this will be in the GitHub rebook right so I'm going to save it and fingers cross let's see if you can run it so I'm going to say test now let me go ahead and move this a little bit up and anchor test and see fingers crossed it's going so we failed probably the syntax here okay so it says that the declared program ID does not match the actual program ID if we run into this issue it means that under Target IDL we have to update this with the right address so I'm wondering if this is the right address I think this is the right address which the right address is not going to be the one that we have in the contract so I'm going to copy this address I'm going to go back into declare ID when to replace this this will be inside the actual program so I'm replacing this ID here let me make sure that we don't have this elsewhere this is not correct the right type so we are updating types SPL so make sure that the address matches the address the program ID same goes under Target IDL make sure that it also matches and also under the program itself let me give it a shot let see if uh we are look at this time let me go back anchor test and hopefully for the rest it's doing something it looks like it's going to do it here we go initialize pass awesome and we Min the tokens so we have initialized this project this token is officially active in the salana death net so we should have tokens we have the tokens and we have initialized this program this is the program perfect now I'm wondering if I can see this in my asset list so we got the URI this is the right URI we got the data so we know that this is looking good so let me copy this let me make sure that when we open this link and sure enough this is the right path if we click on the image boom this is the image this looks good so we got this now we got decimals 9 we got all the information that we provided I'm wondering if I can see this token in my wallet and sure enough I can see [Music] it okay now we know that we obtain tokens so now the final task that we are going to do is that we are building a function to transfer tokens from one wallet to another in this case from my wallet that I have right here the owner of the program we are going to be transferring to a new wallet completely different wallet which means that we have to build the ATA account and we can perform the transfer we're going to do a JavaScript function that will allow me to do that and then I can incorporate that function and run it through an inventory of wallets and do an airdrop now that we confirm that we have the tokens in our wallet wallet what I'm going to do I'm going to build a JavaScript function to transfer tokens to a new wallet which means that the function must create or must generate that ATA account for that new wallet and then we proceed and transfer those tokens let's do it let me go ahead and create a file this file is going to be call S transfer. JS let me bring this down okay I need to import Solana web3js so I have to work with the Solana web3js SDK and I'm also going to be importing the Solana SPL token SDK in order for me to act with the program itself okay so we're going to be making web three calls into that SPL program let me go ahead and add both and let me scroll and I'm going to show you by the way I'm going to do press enter here so then you can see what we are bringing in okay so we are bringing key pair transaction connection public key all those classes from the web 3js SDK and I'm also going to be using the get Associated token address the create transfer instruction and the associated token account instruction this function create transfer check instruction that a function to transfer tokens this function create Associated token account instruction is to create the ATA okay awesome so let's continue right so I have my dependencies imported one last dependency is base 58 so the information when we have to send data into an SPL program or most of the calls in the Solana program I have to convert those values into base 58 I am going to be using from the coral AC test from the test environment I am going to be using using BS 58 okay okay so I'm going to add this here awesome all right why do I need BS 58 in order for me to Mint and send tokens to anyone I need to be the myth Authority which means that my wallet must be the minth authority I have to wrap the private key which has the full rights to make calls and interact with the contract or the program which means that I have to obtain the private key of the developer wallet and either I obtain that as a string or I obtain that from the program in base 58 then I convert that to string and we are to do that now okay so in order for me to find that information I'm going to go here anchor Tom okay here we go so if we hover over anchor Tom file the anchor Tom file at the root of the project we are going to see under provider wallet this is the path to that wallet if we look for this right so what I'm going to do here I'm going to grab this right I'm going to copy it and I am going to clear this I'm going to clear this real quick and I'm going to say cat I want to say cat I'm going to paste and there we go so we have effectively display the contents of that wallet this information that we have right here this will be the private key in base 58 okay I need to convert this to string by the way I I will be converting this to string so I have to use that base 58 tool that we imported into our script so I'm going to say copy right check this out I'm going to close this okay and what I'm going to do I'm going to say constant private key in 58 and I'm going to say paste I'm going to paste that the contents that I got there we go so this will be everything integer okay now I can grab this private key variable and I can pass BS 58 and I convert that to string and I should be obtaining the values in string okay so check this out so I'm going to say now I'm going to say constant string private key I'm going to use uh camel case here I'm going to say equals now we're going to use Bas 58 BS 58 and code and then we can pass private key 58 okay now we're passing this here and now if I run this I should obtain the values in string okay so let's do that I'm going to say con log s strr private key cool awesome so now let me open the terminal and give it a shot okay so I'm going to say node and then the name of the script in this case it's going to be SPL transfer and it doesn't say uh SPL token okay so probably I'm missing this dependency so I'm going to go ahead and install it real quick I'm going to copy I'm going to say n i I'm going to paste boom wait for that boom we have install the dependency now let's give it a shot again boom we got the key this will be the private key and string okay so let's copy that now at least we don't need this anymore okay so what I'm going to do instead we are now going to save that as my owner so I'm going to say owner and now we can just pass the string value that we obtained boom there you go so we got now the owner this will be the developer wallet that is associated to this project okay awesome next the next thing that I got to do I have to convert the string value of the SPL token address the program ID into public key so I have to use that from the Solana web3js so we will be using public key and we will be creating this as the this public key class okay so I am going to do the following I'm going to say SPL token and we are going to now Define this to be new public key and we can go ahead and pass the address of the program okay so what's the address of the program let's go here to my program itself and grab this address copy and we are going to head here and we're going to go and paste beautiful so now we have that next thing I have to create the key pair for my developer wallet in this case the owner that we have right here now that I have the private key and string I can go ahead and build that key pair so I'm going to say Source wallet okay this will be the source of the call and we are going to Define this we're going to be using key pair from the Solana 3j I'm going to say from Secret Key okay and we can go ahead and pass BS 58 we have to decode that we're going to say decode and now we pass owner okay this is how we wrap that in cool okay so now we have the key pair for Source wallet next we are going to be defining connection this will be the RPC URL for the defnet so we're going to say connection equals new and now we use connection from the SDK and now we pass the string value for the defnet URL okay we're going to go ahead and pass the API the RPC URL to interact with defnet under connection so now we have this ready to go and finally we need the destination wallet okay so in this case we need destination wallet so let's wrap that destination address this is just going to be the public key we don't need the private key okay this is just the public key so it's going to be desk wallet and now we have to also initiate this as a public key and then we have to pass the value of that destination wallet so what I'm going to do I'm going to generate a new wallet using the Phantom wallet and then we'll use that address here okay so okay so I'm going to add a new wallet I'm going to create a new account and boom we got that new account this is a new account I'm going to go ahead and copy this address and we are going to pass that to the file okay here under destination wallet perfect so this new account that I created has no tokens this brand new account there's no tokens Associated I can actually show you right so make sure that we have it you can see here I have no tokens in our program okay now we're going to say the amount of tokens that we going to be passing Let's test with you know tokens we're going to pass two tokens okay we're just going to pass two tokens I have a total of 10 tokens that I minted um we're just going to pass two okay let's let's build that function to transfer and I will run the function and show you that it's going to fail because it doesn't have an ATA okay this I'm going to do this on purpose okay so how do we do a transfer function I'm going to say constant Solana transfer SP this will be the name we're going to call this async we are now going to be passing arguments now I got to calc the amount of tokens and convert that to nine decimals okay so I'm going to say let amount we pass tokens which we already defined times 10 to9 okay awesome now we have to do the following we have to obtain the ATA for the source wallet and we also have to find the ATA for the destination wallet I can generate the values without having to initiate the ATA which means that I can obtain the values without actually create it on the program right so how do we do that we are going to say Source wallet ATA right and we are going to Define this to be await and now get Associated token address right and what arguments do I have to provide check this out I have to provide the address of the program SPL token this will be the first argument the token program then I have to pass the source wallet this will be the second argument public key from the key pair we have to obtain the public key Source wallet which we Define from the key pair now we say public key we pass the public key and finally allow owner of curve we are just going to Define this to be false okay we're not going to Define this to be true and this value right here should give me the ATA address of this Source wallet okay so if I do the following right I am going to console log and let's see if it works Source wallet ATA okay and I am going to run this Solana transfer SPL and boom and now I'm going to open my terminal and see what we get so I'm going to say node SPL transfer boom okay so this will be the a address of my source wallet the def wallet okay so now that I have this I also have to calculate the destination wallet even though I don't have the token account address created we can obtain the values even though that it's not created okay so now I'm going to say I just copy the same syntax because it's going to follow the same thing the only thing that's going to be here we're going to call this destination wallet ATA right and now we pass instead of source wallet we are just going to pass the destination wallet which we have right here okay boom okay awesome so we got both so we have generated the atas now next thing now those values I have to pass them as base 58 which means that I have to do this check this out I got to do let Source ATA we're going to convert this to um to base 58 so I'm going to say let's Source ATA and we're going to say Source wallet ATA to base 58 okay and I got to do the same thing with the destination one okay so I'm going to say this I'm want to copy want to paste I'm going to say d ATA here we go and now we pass D here beautiful so we have passed those two values that we already generated here to base 58 uh I'm going to delete this cool we're we're getting there we're almost done here now we are effectively building that transfer function okay so we are going to say try because I know it's going to fail it's going to fail on purpose because I want to show you that we need to determine if there's no ATA Associated this is going to fail but then send me to a function or trigger a function to generate the ATA and try it again and this should work okay so we are defining let transaction we're going to create a transaction here we're going to say new transaction this is part of the uh SPL program uh right here from the 3js I should say and now we're going to say transaction now that we have initialized that transaction we're going to say transaction we are going to say add and this is where we build that transaction first thing that I got to provide is the ATA as public key okay so I have to pass that in so I'm going to say new public key and we are going to say Source ATA right and we can say you know we can hover here and we can say we can see the transaction instructions but basically it's requiring me to send first who's the payer what's the contract address as Bill token this will be the contract address now I have to define the destination as well as a public key and now we're passing destination ATA which we generated right now we are going to say I have to pass the payer as public key string so I'm going to say Source wallet. public key okay I got to pass the amount obviously the amount of tokens already converted into nine decimals and finally I'm going to pass the decimal value which is nine okay I buil that transaction envelope now I got to send that transaction right so in order for me to send it transactions I'm going to say let TX equals await going to say connection and now we are going to say send transaction okay and what we pass we pass transaction that's going to be the first argument boom and we have to send the second argument will be the source wallet as the key pair which we defined earlier right here okay this will be the wallet that I'm going to be using because it has a private key to pay for that transaction and execute the transaction right and then I'm going to say console log to validate and I'm I going to say tokens transfer successfully okay I'm going to say receip and we pass what's going to return from TX will be the hash of the transaction and we will obtain that transaction hash and display it on the log on the console okay all righty and we to say return right and then if this fails which it will fail then I want to do this cache and we will write the logic but first going to say just return I want to run this and show you that is going to fail and then we will write the function to generate that ATA all right awesome let's test it out and I I know that it's going to fail because this account is brand new this wallet is brand new it hasn't been initialized in the program so as a matter of fact I'm going to do this I'm going to say catch the error and I want to console log that error see what we get okay so I'm going to go to terminal new and we are going to say uh node SPL transfer and we have a probably a syntax issue so let me see where that is it's saying on 3121 let's see what that's about oh oops okay I see what's up uh I need to provide the actual function to transfer I did the transaction and I added the details but I didn't I didn't wrap this in the actual function okay so let me do it so now I got to say create transfer check the instruction duh okay all right so now I'm going to open this and I can add all the information and now we are waiting to close this cool now let's give it a shot again okay so we are now adding under transaction we initialize this transaction here then add then now we can pass the transaction instruction that I got to do which is create transfer check instruction okay so now I'm going to save it and give a shot again it's going to fail of course it's failed invalid account data for instruction we expected this to happen all right so let's fix that so what needs to happen is when we try when we try this and it fails we are going to catch the error and here we can insert the call to generate that ATA and try it again okay we can do that so let's do that what I'm going to do I'm going to do right above here that function to generate the ATA so I'm going to say constant gen ATA right we're going to say async and let's define that function right so let's begin first thing I got to do I got to obtain ATA of the source wallet that is going to generate that destination ATA that is going to trigger that call remember this is not going to be the destination wallet the destination wallet could be anyone and we want to transfer tokens to that wallet so they are not going to be the ones who are going to initiate this call we are going to which means that I have to also obtain the source ATA and then send the call okay which means that I can grab this information to also generate that okay so in this case I am going to say Source this will be the at the destination ATA I should say okay so in this case we're going to grab change this to be at okay we we want to find the value of that ATA and then we are going to pass the SPL program and instead of source wallet we want to pass the destination wallet because we want to obtain the value for that ATA and we are going to keep this in false okay now I am going to build that transaction by way let's just take advantage of this I'm going to say let transaction we going to grab all this right and we are just going to modify it to generate the ATA okay so we're going to say new transaction now we got to change this this is not going be the transfer check instruction this is going to be the generate the ATA so it's going to be create Associated token account instruction this is how we generate that ATA now we pass what we are going to be passing first value is going to be Source wallet because this is going to be the payer for this transaction which in this case is going to be me do public key right we are going to pass ATA right it's not going to be the token it's going to be ATA we then pass destination wallet as the public key right here we got to pass that it's going be this okay we pass destination wallet and finally fin we are going to pass token because it's going to be Associated to that program boom okay and now this is how you create that ATA generate that ATA for each destination account that you want to pass and now I got to say connection send transaction okay and this is basically the same thing and now console log I'm going to pass at generated successfully okay and we are passing the receive that's fine so we're going say successfully and receive okay but here's the thing in order for me to transfer the token I need to wait for that ATA to be confirmed in the salon of blocking which means that we have to give it a couple of seconds so the ATA has been validated has been confirmed and then the program has the ATA else it's just going to Loop rerunning the function because it's going to say well I'm going to try this Solana transfer SPL we're going to pass this to be ran again but if we are not holding until the blockchain confirms that a new ATA was generated then it's just going to keep trying and trying and trying and trying we have to wait for this to be fully generated and fully validated and confirmed on the program so then we can retry sending the tokens what I can do I can pass a timer that holds 15 seconds let's say we stop for 15 seconds then we try it again okay and that should finalize the function okay so let's do that so now that we have this right we are going to say return true and then we are going to cat that and and hold the transaction from continuing okay okay so we got gen now we have to call it in the catch so let's go ahead here and do it we are going to say let generate ATA now we are going to wait for that gen ATA right and if this function completed successfully right we obtain that in the console then return true now we want to wait okay if narrate ATA then go ahead and stop we try it again okay which means that I am going to pass a timer I got a timer here right so we're passing this timer this timer is just 15 seconds then what do I need to do I got to run this Solana transfer SPL once again okay so let's do that Solana transfer SPL and if everything goes well return done okay then now I can effectively remove this I don't need this return right and that's it that then that should do it then it's going to error out it's going to catch the error but then now it's going to generate the ATA because probably the error is because it doesn't have an ATA has generated then generates the ATA we get confirmation if it's true then go ahead and hold 15 seconds wait for 15 seconds so the transaction has been validated in the blockchain then go ahead and try to transfer those tokens again let's see how that goes going to save this node SPL transfer and fingers crossed here we go create ATA has been done now we should wait for that transfer boom we are done done awesome awesome awesome we have generated the ATA we transferred the tokens and that's it now let's take a look at the wallet the wallet should have received those end to the r SPL tokens there we go awesome there we go all righty we have completed the mission we have built an SPL token contract we have deployed the contract we have Meed tokens and we have transfer tokens to a destination wallet I hope you like this tutorial and if you do give it a thumbs up subscribe if you haven't subscribed too hey and we'll see you on the next video bye
Up Next

IPFS and Blockchain Tutorial: Build a React DApp with Solid
@syedmuhammaddanish
2.8K views•2024-08-16

Torrent File Format & Bencoding: A Technical Deep Dive
@AsliEngineering
12.5K views•2022-08-08

Implementing ERC-6551 Token Bound Accounts | Smart Contract Tutorial
@net2dev
670 views•2024-02-02

Understanding Ethereum: A Comprehensive Beginner's Overview
@99Bitcoins
3.1M views•2018-06-26
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Blockchain & Crypto







![Fundermentals: Accounts, Instructions and Transactions [Solana Basics Day2] - Feb 7th '26](https://i.ytimg.com/vi_webp/fXKyOrudpgA/maxresdefault.webp)










![[팟캐스트] 파이 네트워크 양자 프로토콜 V25 가동 & EVM 브릿지 오픈! Web3 자금 흐름의 핵심?](https://i.ytimg.com/vi/5EIXv-m-jiI/sddefault.jpg)



![All-in-one Metadata with Token22 [Solana Tutorial] - Oct 21st '23](https://i.ytimg.com/vi_webp/uDVk3mmnUUU/maxresdefault.webp)



![CRYPTO HODLERS...CAN’T BELIEVE THIS IS HAPPENING [LEAKED VIDEO]](https://i.ytimg.com/vi/FDsBgp92AQU/maxresdefault.jpg)








![GIRL SAILING ALONE OFF-GRID [ep 70]](https://i.ytimg.com/vi/CgZ8-Lb_7LI/maxresdefault.jpg)


