In the previous lesson, we managed to get the balance checking mechanism to work on our front end and
our back end.
Now it's time to tackle this full set so that anyone can get some free tokens from the central pool,
just like how you claimed the free ICP tokens.
To do that, let's create a public function which will call pay out.
And this function is not going to take any inputs, but it is going to asynchronously return some piece
of text.
And by default, it's just going to return the words success.
This will then be able to be used when we call this function on the front end, and we can replace the
words inside the button here with whatever it is that we got returned.
So if it was successful to force it this amount to the user, then will replace this gimme gimme with
success.
So that's the purpose of that return.
Now, how do we get hold of who to send the money to or who to send the tokens to?
Well, in Mutoko there is something called a shared function, and this basically allows methods declared
inside an actor to be called by other actors.
Now, by default, all public methods are shared anyways, but there's something that we can use inside
this shared method that's really useful.
We can use it to identify the principal ID of the entity that called a particular function.
So we can do that by writing the key word shared and then adding a parameter called message.
And whenever something some canister or some user calls this method, then their principle ID is going
to be embedded inside this method parameter and it's the caller property.
That means we can use this to get hold of the entity that called a particular function.
And if we can get hold of that, well, then we can assign that principal ID a particular amount and
add them to our ledger in our balances hash map.
Let's go ahead and make this function shared.
And then inside the parentheses we add that parameter, which is called message.
Now let's go ahead and use our debug print to print out what is the message scholar in our case.
So we're going to use the debug print and then debug show.
I'm going to pass in the message dot called and we need to import debug in order to use it.
Now let's hit save and let's go ahead and deploy our canister with these updated changes.
And in our command line over here, we can call that method payout by writing DFCS canister call and
then the canister name is token and then the name of the function is called Pay Out and notice the way
that it's spelt.
Make sure that it matches what you've got in your main dot mutoko and then we can go ahead and hit enter.
Now, once that's done, you can see here we get the return of success, which doesn't really mean anything
because everything will return success right now.
But if you take a look at the panel where you've got your start, where you've got the simulated ICP
blockchain, you should be able to see the I.D. of the caller.
So in this case, the caller ID is my user, right?
If you match it up, you'll see that my user principal ID is this and that's what got printed out when
I printed the message dot column.
Now let's try something a little bit different.
Let's call this message from our frontend.
So inside our faucet gsx let's go ahead and tap into that function.
So let's first import everything that's inside our token bridge.
So import token from dot dot slash total slash declarations slash token.
And inside the async function to when the click is handled, we're going to use await token dot payout
and this is going to trigger this function but it's going to trigger it from the frontend.
So it's going to be the user that's using the website and then hopefully we should get this debug print
triggered down here.
Let's go ahead and hit save.
And because we just made some changes to the front end, not the backend, we can simply hit save and
it should refresh.
And now if I click on Gimme Gimme, then I go back to my command line.
You can see that this time there's a different principal ID that got printed, and this is the idea
of an anonymous user that's using the front and website instead of the actual user ID of myself.
So you can see, depending on who called that function, the message scholar will reflect the principal
ID of that user or canister.
We can use this fact to transfer that particular ID some tokens.
To do that, we can simply tap into our balances hash map and we can use the put method to put a key
and value pair in.
The key is going to be whoever it is that called this function.
So the principal ID of the message scholar and the value is going to be however amount we want to transfer
to them.
Now, inside my faucet, I've promised people that they can get 10,000 dang coins, so I often have
coin and token mixed it up.
So if you want you can change that to token.
It doesn't really matter, but the amount I've set is 10,000.
Let's go ahead and set that here as well.
So we're going to give whoever calls are payout method from the faucet, 10,000 tokens and we're going
to do that using balances dot put because we've got our check balance functionality already set up.
We can actually check to see if this works.
So if I go ahead and hit save and I deploy my updated code inside the pail function, then I can go
ahead and check what is the balance of my user's principal so I can paste that in that check balance.
And you can see this has 1 billion dang tokens, but I can also check the anonymous user who's actually
using this website.
If I paste that principal ID in here, click check balance.
You can see that this account has a balance of zero dying, but as soon as I click Gimme Gimme, which
will force 10,000 dang tokens into this account afterwards.
If I go ahead and click Check Balance, then you can see we successfully transferred 10,000 tokens into
this user's account.
So we've managed to get the force that functionality somewhat working.
Now there's a couple of user experience things I want to improve here.
The first thing I want to change is when I click on this button, it actually takes a little while to
perform this method because it's an update method.
Instead of a query method, it takes something like two 3 seconds and we don't want the user to be pressing
this continuously because it's just going to mess up our backend.
What we want to do is to be able to press it and then to disable the button until this functionality
has completed.
To do that we can go into our faucet frontend.
So the faucet dot.
And inside here we can set a new constant which alcohol is disables and the setter will be set disable
and this is going to need to use state.
So we're going to import that in here as well, which hopefully should happen automatically because
you're using the code and the initial state we're going to set it to is going to be false.
So we don't want the button to be disabled.
So this is the button, we've got the button ID, we've got the on click.
And I'm going to add one more, which is the disabled attribute and I'm going to set that equal to the
IS disabled state using the state hook up here.
So now as soon as the user clicks the button, we're going to set it to disabled.
So we're going to say set disable to true.
And then once the token payout has completed, then we can set the disabled back to false again.
Alternatively, you can actually just omit this line because well, you know, once they've clicked
at once, should they really be allowed to tap the false it many times so you could actually just keep
it disabled and we can see how this works on the front end.
Now if I click on it, you can see it turns gray.
I can't click on it any more.
And that means this button will stop working and I can't keep requesting dying to this account.
One last consideration is we've transferred 10,000 tokens to the message caller so the user of the website
right now, but what if they go ahead and spend that money and then they come back and they want to
get 10,000 tokens again?
Well, that shouldn't really be allowed because the idea is that you get 10,000 tokens to play with
and you can mess around with the website or do whatever it is you want with these tokens.
But it's not like an endless stream, right?
Because otherwise you're just giving people free money and it will really affect the token economics
of your particular token.
So let's add in a check into our main dolma token.
What we can check for is to see if inside our balances hash map, does this key actually exist?
We can use the get method to get hold of the value that's associated with messaged column.
And the way that the get method works, if you remember, is that if that key doesn't actually exist,
it will return null.
If it does exist, then it will return the associated value.
What we can check inside this if statement is if the balances don't get passing in the current message
caller is equal to null, then that means that this person has actually never requested any tokens.
They don't actually exist in our ledger.
In that case, we're going to go ahead and transfer them these 10,000 tokens.
They're starting tokens to play with.
But.
Otherwise we're going to say, well, actually, you've already claimed the tokens.
Right.
And now what we can do is we can output these two different pieces of text from our method.
And that means we can get hold of this result either success or already claimed on our frontend here.
And we can use that to set the button text right here.
If we go ahead and create a new constant code button text.
And we'll have a set text.
Then we can use date and set that to initially start with the gimme gimme and after they've pressed
on the button, however, we're going to change this.
Depending on whatever it is that we got back from this method, we can create a new concept called result
and set it equal to the outcome of this method.
And then we can use the set text setter to set the button tag to whatever we got back from the result
here and now, because we've updated the back end, let's test this out by first doing the deploy and
see if this actually works.
Remember that at the moment we have no persistence, so our balance is hash map gets overwritten every
single time we do do deploy.
That means if I take this user's principle id so this frontend uses principal ID and I check the balance.
It should have zero.
Dang.
If I go ahead and click Gimme Gimme then it should return with the result once it's done.
So it says it was successful.
And now if I check the balance again, it should now have 10,000.
Dang.
But if I try to click that button again, which I actually can't because it's disabled, but notice
that whenever you have a button that's disabled, if the user just refreshes the website, the state
will get reset.
But now if we check the false it again, it actually tells us, wait a minute, your user ID already
exists on our ledger.
So that means you've already claimed your tokens and you shouldn't be allowed to claim it again.
So we've now managed to create all four sent by giving 10,000 of our custom tokens to anyone using our
website.
And we've also added in some security and some user experience touches to make this work properly.
In the next lesson, we're going to tackle the last panel here, which is the transfer.
The idea is once you've claimed your 10,000 tokens or you can actually then transfer that from your
account to any other account.
Let's say that you didn't actually need your 10,000 and you wanted to transfer it to a friend who needed
2000 dying tokens, or you could do that using this transfer area.
So all of that and more on the on the next lesson.