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.
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 theas Taquito is going to do it for you!@airgap/beacon-sdk
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.
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!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,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!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).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:
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.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.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.error
object that you can use to display a message to your users.Once the transaction is confirmed, there are a few things that you can do:
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.
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.