Skip to main content

Taquito dApp SDK for TypeScript

Introduction

Interacting with the Tezos blockchain can be done using the Tezos CLI. However, it is not suitable for dapps since it needs to be integrated into web interfaces.

Fortunately, the Tezos ecosystem offers libraries in several languages that enable developers to build efficient Dapps. Taquito is one of these: it is a Typescript library developed and maintained by ECAD Labs. This library offers developers all of the everyday interactions with the blockchain: retrieving information about a Tezos network, sending a transaction, contract origination and interactions such as calling an entrypoint and fetching the storage, delegation, fetching metadata, etc.

A lot of wallets in the Tezos ecosystem also use the Taquito library to function.

A full reference is available here.

Installation

The Taquito library is made of several modules:

The main module is @taquito/taquito, it will be used for most actions. The other modules are used by the @taquito/taquito methods as complementary features, but can also be used separately.

You can install Taquito from NPM:

$ npm install @taquito/taquito

Taquito configuration

General setup

We first need to configure Taquito with an RPC URL (to communicate with a Tezos node).

To do that we use the TezosToolkit: it is the "facade class that surfaces all of the libraries capability and allows its configuration". When instantiated, it requires an RPC URL.

Here, we will use the Ghostnet RPC URL offered for free by ECAD Labs at https://ghostnet.ecadinfra.com.

import { TezosToolkit } from '@taquito/taquito'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')

Wallet setup

First, download the @taquito/beacon-wallet package from NPM:

npm install @taquito/beacon-wallet

Next, import the BeaconWallet class and create a new instance by passing an object with the different options required by the Beacon SDK. After creating the instance of the wallet, you can request permission from the user to connect their wallet before passing the wallet instance to the wallet provider in the TezosToolkit provided by Taquito:

import { TezosToolkit } from '@taquito/taquito'
import { BeaconWallet, NetworkType } from '@taquito/beacon-wallet'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')
const options = {
name: 'MyAwesomeDapp',
iconUrl: 'https://tezostaquito.io/img/favicon.svg',
preferredNetwork: 'ghostnet',
eventHandlers: {
PERMISSION_REQUEST_SUCCESS: {
handler: async (data) => {
console.log('permission data:', data)
},
},
},
}
const wallet = new BeaconWallet(options)
await wallet.requestPermissions({
network: { type: NetworkType.GHOSTNET },
})
Tezos.setWalletProvider(wallet)

Getting data from the Tezos blockchain

Taquito provides methods to get different types of data from the Tezos blockchain, for example, the balance of an implicit account, the storage of a contract or token metadata.

Note: querying data from the blockchain doesn't create a new transaction.

Getting the balance of an account

Taquito allows developers to get the current balance in tez of an implicit account. The getBalance method is available on the instance of the TezosToolkit and requires a parameter of type string that represents the address of the account.

The returned value is of type BigNumber:

import { TezosToolkit } from '@taquito/taquito'
import { BeaconWallet } from '@taquito/beacon-wallet'
import type { BigNumber } from 'bignumber.js'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')
const wallet = new BeaconWallet(OPTIONS)
await wallet.requestPermissions({ network: { type: NetworkType.GHOSTNET } })
Tezos.setWalletProvider(wallet)
// gets the user's address
const userAddress = await wallet.getPKH()
// gets their balance
const balance: BigNumber = await Tezos.tz.getBalance(userAddress)

Getting the storage of a contract

One of the distinctive features of the Tezos blockchain is having the storage of smart contracts publicly available.

Taquito provides an easy way to get the storage of any contract and exposes it as a JavaScript value:

import { TezosToolkit } from '@taquito/taquito'
const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')
// creates the contract abstraction required to get the storage
const contract = await Tezos.wallet.at(CONTRACT_ADDRESS)
// returns the storage of the contract
const storage = await contract.storage()

Getting token metadata

Taquito also provides a library to get token metadata, which can be very useful when you build a dapp that handles NFTs. Without Taquito, you would have to fetch the location of the metadata from the contract, understand where the metadata is stored, fetch it and parse it. Taquito does all of that for you:

import { TezosToolkit } from '@taquito/taquito'
import { Tzip12Module, tzip12 } from '@taquito/tzip12'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')
Tezos.addExtension(new Tzip12Module())

const contract = await Tezos.contract.at(CONTRACT_ADDRESS, tzip12)
const tokenMetadata = await contract.tzip12().getTokenMetadata(TOKEN_ID)

Interacting with the Tezos blockchain

Taquito lets you interact with the Tezos blockchain in multiple ways, for example, by sending tez, originating new contracts, interacting with existing contracts or reading events emitted by a contract. Most of these interactions start with an instance of the TezosToolkit.

Sending tez

After creating an instance of the TezosToolkit, you can use the Contract API (for backend apps) or the Wallet API (for frontend apps) to access the transfer method and pass an object as a parameter with a to property for the recipient of the transfer and an amount property for the amount to be sent:

import { TezosToolkit } from '@taquito/taquito'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')
const op = await Tezos.contract.transfer({ to: ADDRESS, amount: 1 })
await op.confirmation()

Originating a contract

The origination of a new contract is also possible through the Contract API or the Wallet API with the originate method. It takes an object as a parameter with a code property for the Michelson code of the contract and a storage property for the initial storage of the contract:

import { TezosToolkit } from '@taquito/taquito'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')
const initialStorage = {
counter: 1,
admin: "tz1Me1MGhK7taay748h4gPnX2cXvbgL6xsYL
}
const op = await Tezos
.contract
.originate({
code: CONTRACT_CODE,
storage: initialStorage
})
await op.confirmation()
const { contractAddress } = op

Sending a contract call

One of the main features of your dapp is probably smart contract interactions.

After creating the contract abstraction for the contract you want to interact with, you can call one of the entrypoints available as a method on the methods property. The entrypoint method takes a parameter of the type expected by the contract and returns a contract call that can be executed by calling the send method:

import { TezosToolkit } from '@taquito/taquito'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')

const contract = await Tezos.wallet.at(CONTRACT_ADDRESS)
const op = await contract.methods.mint(3).send()
await op.confirmation()

Reading smart contract events

Contract events is a way for contracts to deliver event-like information to third-party (off-chain) applications. It can be emitted by using the EMIT instruction in Michelson.

Taquito provides a simple way for users to subscribe to certain events on the blockchain via the PollingSubscribeProvider.

import { TezosToolkit, PollingSubscribeProvider } from '@taquito/taquito'

const Tezos = new TezosToolkit('https://ghostnet.ecadinfra.com')

Tezos.setStreamProvider(
Tezos.getFactory(PollingSubscribeProvider)({
shouldObservableSubscriptionRetry: true,
pollingIntervalMilliseconds: 1500,
})
)

try {
const sub = Tezos.stream.subscribeEvent({
tag: 'tagName',
address: 'CONTRACT_ADDRESS',
})

sub.on('data', console.log)
} catch (e) {
console.log(e)
}

Best practices

One single TezosToolkit instance

You should make sure that you only have one instance of the TezosToolkit at all times in your app to avoid using the wrong one, which can have negative financial consequences for your users. Even if your app requires a change in the network or Tezos node, it is better to create a new instance of the TezosToolkit and stop using the previous one to prevent unexpected behaviours.

Contract API vs Wallet API

The Contract API is better suited for backend applications that don't require the manual signing of transactions, while the Wallet API is better suited for frontend applications that will interact with the users' wallets. The use of one or the other should be consistent within the same app to prevent unexpected behaviours.

methods vs methodsObject

The methodsObject property is better used in cases when the parameter for a contract call is a complex pair. You can use methods to pass single parameters or simple pairs.

Catching transaction errors

It is important to wrap contract calls and other transactions sent from the app inside a try... catch in order to handle transaction failures. Transactions fail more often than you think and you must handle it to provide visual feedback to your users and prevent unwanted behaviours like users clicking a button again even if the transaction already failed before.

More information

You can find more information about Taquito on the official website: Taquito