How to Build a Tezos Dapp Using Taquito and the Beacon SDK

Written by claudebarde | Published 2020/07/06
Tech Story Tags: tezos | blockchain | cryptocurrency | dapp-development | smart-contracts | dapps | how-to-build-a-tezos-dapp | hackernoon-top-story | web-monetization

TLDR How to Build a Tezos Dapp Using Taquito and the Beacon SDK. Use two of the hottest techs in Tezos development to build a dapp. The dapp we will build is extremely simple, it connects to a demo smart contract I deployed on Carthagenet (testnet) to test different features. We are going to use the Beacon extension in this tutorial to sign transactions but you can also use the wallet on your phone! You must have at least a basic knowledge of HTML/CSS/JS and of how the Tezos blockchain works.via the TL;DR App

Use two of the hottest techs in Tezos development to build a dapp

The landscape of dapp development on Tezos has evolved a lot these last six months. It went from a painful and long endeavour to a walk in the park. This change has been possible thanks to the introduction of powerful tools that allow developers to focus on providing value and functionalities to their dapps and to forget about the technicalities of plugging their dapp to the blockchain.
Taquito doesn’t need any introduction, it is the de-facto tool to connect your Tezos dapp to the blockchain. But don’t let its monopoly position lure you, it is an amazing tool and will make your job as a developer 100 times faster and easier. With a few lines of code, your dapp will be set up and connected to the blockchain and your smart contract. Taquito will do all the heavy lifting in the background so you don’t have to worry about it.
Beacon is a toolkit developed by Airgap that connects to a wallet (at the moment, to the AirGap Wallet) and signs transactions to be sent to the network. The stable version is pretty recent but already very promising. We are going to use the Beacon extension in this tutorial to sign transactions but you can also use the wallet on your phone! Beacon provides a simple yet sleek and efficient interface with a lot of information and customizable options!
For this tutorial, I chose vanilla JavaScript to write the dapp as it will give you all the information you need to use Taquito with the Beacon wallet and adapt the code to whichever framework you prefer. The dapp we will build is extremely simple, it connects to a demo smart contract I deployed on Carthagenet (testnet) to test different features, the dapp has a button to connect your wallet, a simple interface with information from the blockchain and the smart contract and it gives you two options to save data into the smart contract. In order to continue reading, you must have at least a basic knowledge of HTML/CSS/JS and of how the Tezos blockchain works.

Preparing the workspace

As this tutorial doesn’t focus on HTML or CSS, I prepared a boilerplate that you can download from Github so we can start writing some JavaScript more quickly 😉 You will find the whole project at this address. You can follow along with this tutorial and check the different parts in the .js file or you can delete this file and start from zero.
The first thing to do is to download the necessary packages. You can simply run npm install from the root of the project and check the package.json file. You will see there the two main dependencies that we need to create a Tezos dapp: 
@taquito/taquito ^6.3.1-beta.0 
and 
@taquito/beacon-wallet ^6.3.1-beta.0
. Those are the latest versions available at the time of this tutorial.
Note: you don’t need to install the 
@airgap/beacon-sdk
 as Taquito is going to do it for you!
If you check the HTML file, you will see that it is very simple, with a 
main
 tag that contains two 
divs
: one that will show the button to connect your wallet and one that will show the contract interface.
The 
style.css
 file contains basic styling information and you probably noticed a 
toast.css
 file that will be used later when we will override some features of the Beacon wallet.
At this point, you should have the Beacon extension installed in your browser. If you don’t, follow these instructions to install it. You will need it to interact with the smart contract from the dapp.

Connecting your wallet

Let’s start coding now 😅
Open a new JS file called “index.js”. First, let’s import the dependencies we need. If you checked the 
index.js
 file provided in the Github repo, you probably saw 
import "babel-polyfill"
 at the top. This is only required to use ES6 syntax with Parcel, the bundler used in this project.
Next, we import the two dependencies necessary for this project:
The first line imports the 
BeaconWallet
 class that we will need to create the 
wallet
 object. The second line imports the 
Tezos
 object from Taquito. This is a multipurpose object that we will use in different situations. You can also see that we initialize a variable called 
contractAddress
 that will hold the address of the contract we want to connect to (very useful during development when the address may change often).
When you run 
npm run dev
 and open a new window on 
http://localhost:1234
, you will be presented with a big teal button. This is the button you will click to connect your wallet. First, we have to connect it to the function that will initialize the wallet:
After that, we can start writing the different steps of the wallet initialization:
Note that the function must be asynchronous. The next step consists of setting up the 
Tezos
 object we imported earlier. We will tell it which network we want to connect to (Carthagenet here) by calling its 
setProvider
 method:
I generally recommend wrapping the steps of the wallet initialization or the transaction processes into a 
try ... catch ...
 statement because a lot of things can go wrong and it is crucial to inform your users if something doesn’t work as expected.
The 
Tezos
 singleton instance, i.e the object imported from 
@taquito/taquito
, (referred to as the 
TezosToolkit
 in the documentation) has a method called 
setProvider
 that accepts an object with different properties, one of which called 
rpc
 that must be a link to a Tezos node RPC interface. I generally use the one provided by SmartPy, but you can use the one you prefer.
Now that we told our dapp which network we want to connect to, it’s time to take care of the wallet! First, we create a new instance of the Beacon wallet with the class we imported from the library:
The new 
wallet
 object must be instantiated with an object containing different options. At the very least, you should provide a name for your dapp that will appear in the pop-up window to sign transactions. We will add more options later.
Setting up the name of your dapp in the wallet is an important detail for the general user experience as the users of your dapp will know the dapp they are using triggered the pop-up and not something else.
Then, you create a new wallet with 
new BeaconWallet(options)
. Once the new wallet is created, you can set the network you want to connect to by creating an object with a 
type
 property. By default, the Beacon wallet will connect to 
mainnet
 but you can also use the 
carthagenet
 value to connect to Carthagenet or 
custom
 to connect to a sandboxed node. If you wish, you can also specify the RPC URL to which you want to connect with the 
rpcUrl
 property (if not provided, the wallet will connect to its default RPC access point).
After you decided about the network, the 
wallet
 object offers a 
requestPermissions
 method that will request the permission to connect to the specified network and sign transactions on your behalf. Once allowed, your wallet is properly configured and ready to work! The last thing to do in this configuration step is to set the wallet as the default wallet for Taquito:
The new Wallet API provides a 
setWalletProvider
 method on the 
Tezos
 object that allows you to indicate to Taquito the wallet you want to use (after setting it up). From now on, Taquito will use the Beacon wallet to send transactions!

Updating the dapp interface

When you create a dapp, it is always recommended to give your users essential information about their account, like their address and their balance. This kind of feedback indicates that their wallet is properly set up and that the dapp is connected to the blockchain and their wallet.
After initializing the wallet, you can easily get the user’s address from 
wallet.permissions.address
. Once you have the address, you can get the user’s balance using the 
Tezos
 object provided by Taquito:
At the same time, it would be useful to keep the contract instance in memory so we can have easy access to it when sending a transaction to the blockchain. Once again, the versatile 
Tezos
 object will help us. Under the new Wallet API, using 
Tezos.wallet.at(contractAddress)
provides you with an abstraction of your smart contract. While we’re at it, we can use the same abstraction instance to get the storage of the contract and further update our dapp interface with data directly from the contract by calling the 
storage
 method on the contract instance:
Now in a real-life situation, you would probably use a framework to build your dapp, like React or Vue, but we are using vanilla JS here, so we have to manually update the DOM. I created a simple function that updates the text inside an HTML tag to follow the DRY (don’t repeat yourself) principle. First, we want to hide the “Connect” button and display the dapp interface, then update all the values with the data we got from the smart contract:
A few general observations here:
  1. I generally prefer keeping the user’s address and balance at the top level and accessible everywhere in the code in order to avoid unnecessary code to request the address and the balance multiple times. Most wallets dispatch events when a user signs in and out and you can intercept the events to modify the address or the balance (as we will see it later).
  2. The balance is always returned in microtez, which is great for calculations, but difficult to read for dapp users. Don’t forget to divide the balance by 
    1,000,000
     to get a more readable number. You can go the extra mile and round it up and use 
    toLocaleString("en-US")
     to make it nicer!
  3. Taquito keeps the values in the storage as properties of the object returned by 
    contractInstance.storage()
    . It is then very easy to access the values in the storage (except for maps and big maps that are a little more complex).

Updating the message in the smart contract

Now our dapp is ready to play with the smart contract!
The JavaScript file provided in the Github repository contains 3 functions to change the message in the smart contract and increment/decrement an integer value. We are going to write the 
changeMessage
 function here and you can try to write the 
increment
 and 
decrement
 functions yourself (leave a comment if you need help)!
First, we create a 
changeMessage
 function and attach it to the 
click
 event of the button with the 
update-message
 id:
This is the right time to keep some user experience recommendations in mind. A lot of dapp users do not realize that it actually takes one minute to add a transaction to a block on mainnet (around 30 seconds on testnet) and some of them will lose patience and click multiple times on the confirmation button. This will create multiple transactions that they may accept thinking the first one didn’t go through. You must prevent that. When they confirm a transaction, you should disable the actionable parts of the interface and indicate to them clearly that they have to wait. This is the goal of the next two lines of code:
Now, your users cannot send a new transaction before the current one has gone through and they will see a little spinner that indicates that something is loading and they should wait 😊 At the same time, we get the message they entered in the input. If you wish, you can check if there is a message or if the string follows some rules.
Next, it is time to use Taquito again and send the transaction to save the message into the smart contract:
Here is what happens in a few lines of code:
  1. We use a 
    try ... catch ... finally ...
     statement to wrap the transaction. If the transaction fails for whatever reason, you MUST inform your users, so they can stop waiting and maybe fix the problem themselves.
  2. The contract instance we saved earlier exposes a 
    methods
     property that contains itself properties that reflect the entrypoints of the smart contract. In this case, we want to call 
    changeMessage
     which expects a string as a parameter. The result provides a 
    send
     method that will send the transaction to the Tezos node and returns a promise which resolves with a transaction operation object.
  3. After the transaction is sent, you must wait for its confirmation. The transaction operation object returned one line above provides a 
    confirmation
     method that just does that. If no parameter is provided, Taquito waits for 1 block confirmation. If you provide a number n as a parameter, Taquito will wait for 
    n
     block confirmations before executing the following lines.
  4. If the transaction fails, you get an 
    error
     object that you can use to display a message to your users.
  5. After the transaction goes through or fails, you want to return the interface to a working state by enabling the confirmation button and removing the spinner.
Once the transaction is confirmed, there are a few things that you can do:
  1. You can reset the value of the message. This is, in general, a good clue that something happened and the message is “gone”.
  2. You should refresh the storage. Although you could also just update the HTML tag containing the message from the storage, it is always better to get a fresh storage after a transaction in case something else changed during this one. If you use a framework, you probably have a state with a storage property and fetching a new storage will update all the data in the interface linked to the state.
  3. You can do some other minor updates, for example fetching the new balance of the user to reflect the gas cost debited for the transaction.

Customizing the Beacon SDK

The Beacon SDK offers multiple ways to customize the experience of your users with their wallet. Let’s check one of them here.
After the transaction is sent to update the smart contract, you can see a pop-up in the dapp giving you useful information about the transaction:
Maybe you don’t want this pop-up to appear and you want to provide a customized response, like a toast. Fear not, because it will literally take 2 minutes to do it!
Let’s go back in time. Do you remember how we created our new Beacon wallet? With 
new BeaconWallet(options)
. The 
options
 object contains the name of your dapp. It turns out, you can provide more options to customize your dapp! In this tutorial, we are going to use a toast to inform our users that the transaction has been successfully sent to the network!
In the HTML file, you can see the toast at the very bottom: 
<div id="toast">Some text...</div>
. In the JS file, let’s add a function that will display a message in the toast and that will show it and hide it after 3 seconds:
First, we delay the toast for 3 seconds because it will take roughly 2 seconds for the Beacon wallet window to close after you confirm the transaction. Then we update the message in the toast, we show it for 3 seconds before hiding it again.
Now, let’s go back to the wallet initialization options that should look like that:
We are going to add an 
eventHandlers
 property to the 
options
 object to tell Beacon what we want to do when the transaction request is sent successfully. The 
eventHandlers
 property accepts an object where you can set different properties according to the event you want to catch. Let’s see how it works for the event that’s dispatch when the request is successful:
The property must be one of the events listed in this enum from the Github repo. Each event handler accepts an object with a 
handler
 property that you can set to a promise which receives the event data. We use this promise to display our toast when the transaction is sent successfully. Here is the result:
Now, the default Beacon pop-up is gone and replaced with our toast. Using this very simple method, you can customize the response from the Beacon wallet, for example in case of an error or for different events like a connection to a wallet. You can also use it to change the user’s address and balance when they log in with a different address.

Conclusion

This very simple dapp was the occasion to showcase the strengths of two of the best tools you can use right now to build on Tezos: Taquito and the Beacon SDK. Both provide a wide range of features, a high level of customization and an interface that allows you, the developer, to write less code and focus more on the user experience than on the nitty-gritty of interacting with a Tezos node.
Taquito’s new Wallet API is a huge step forward in the direction of using different wallets to connect a dapp to the blockchain and the Beacon wallet finally provides a wallet solution for Tezos dapps that is safe, pleasant to look at and easy to use.
Now the ecosystem is finally ready to welcome more dapp developers, so let’s start building 👷‍♀️👷‍
👇
You can also get more information about the last release of Taquito and the Wallet API by reading Jev’s last post on the subject.

Written by claudebarde | Tezos smart contract and dapp developer 🌮
Published by HackerNoon on 2020/07/06