Skip to content

Intuition

Current context

Nowadays, libraries like Web3.js and Ethers.js provide robust interfaces to interact with EVM blockchains from any Javascript environment.

Those libraries allow to abstract blockchain-related concepts like nodes, smart contracts, wallets, transactions, etc. as simple JS objects. Thanks to them we can already interact with blockchains from any popular web JS framework like React, VueJS, Angular, etc.

At writing time, React is the mainly used framework for DApps development.

DApp requirements / problems

So easily requesting EVM blockchain is solved by libraries mentioned above, but a DApp has many other requirements to work properly, here are some of them :

  • it has to detect and communicate with user's wallet
  • it has to track on-chain datas to display up-to-date content to users
  • it has to provides users with an easy way to interact with chain and contracts
  • it has to perform a lot of checks to ensure all those actions always remain safe

However very few libraries exist to help developers to fill those requirements, and it's especially true for VueJS : there is currently no complete library to achieve that.

Tulipe' approach

Tulipe provides developers with a fully simplified environment making the development of maintainable, robust and safe DApps a real piece of cake.

Firstly, the entire DApp configuration is managed in a single file called tulipe.config.js.

The DApp is represented by a dapp object. This object is initialized with everything required to safely interact with the networks, contracts and wallets defined by the developer in the tulipe.config.js file. By the way, Tulipe comes with 20+ EVM and 5+ wallets pre-configured allowing to use them by simply indicating their chain ID or wallet name in the tulipe.config.js file.

Then, all the safety checks are internally managed and developers are provided with tools called safers allowing them to write safe pieces of code by simply wrapping them in functions or components.

Also, chain watchers allows developer to efficiently track an on-chain data with a single line of code.

Finally, a lot of Vue components are included in order to provide developers with pre-made and robust components for the most common parts of a DApp : allowing them to focus more on the real innovation of their DApps.

All of those components are thought to be flexible and to allows developers to choose to be more or less free :

  • they are made of smaller components that can be used to re-build bigger custom components
  • 3 levels of styling are offered from "unstylized" to "opinionated", leaving the choice to developers of being more or less helped in the style of their DApp

Final words

Here are only exposed the major functionalities offered by Tulipe, there are much more in reality and you can find them in the rest of this documentation.

How does it tastes ? 😋

Firstly, you can configure your entire DApp frontend in a single file called tulipe.config.js.

js
export tulipeConfig = {
  networks: {
    id: 1
  },
  wallets: {
    id: "metamask"
  }
}
1
2
3
4
5
6
7
8

This minimalist configuration file make your DApp frontend support the Ethereum Mainnet network (chain ID : 1) and allows users to connect to it using the Metamask wallet.

Then, with Tulipe most of the things you need to build your DApp fronted is available the dapp object. This one can easily be imported from the tulipe package :

js
import { dapp } from "tulipe";
1

For example if you have configured a MyToken ERC20 contract in tulipe.config.js, you can access its Ethers.js object at :

js
dapp.contracts.MyToken
// Get the balance of userAddress
const userAddress = "0xf39Fd6e5..."
const userBalance = dapp.contracts.MyToken.balanceOf(userAddress)
1
2
3
4

And your DApp signer and provider are also accessible under the dapp object :

js
console.("Connected wallet address is : " + dapp.signer.address)
const block = dapp.provider.getBlock(123456)
1
2

You don't have anymore to deal with multiple manual instantiations.

Explanations

When your DApp initializes, Tulipe will populate the dapp object with all the networks, wallets and contracts you have configured, and much more !

Also, while a DApp has a very volatile context (eg. a user can connect/deconnect a wallet, chain connection can be lost, etc.) it may be difficult to always write safe code.

To solve that, Tulipe provides developers with many safers which helps making a piece of code safe by simply wrapping it in a method / component.

For example if we want to ensure our interaction with MyToken contract is safe in script :

html
<script setup>
import { dapp } from "tulipe";

const userAddress = "0xf39Fd6e5..."
let userBalance = $ref(null);

dapp.contracts.MyToken.onReadSafe(() => {
  // Will be executed only when MyToken contract will be safe to read
  userBalance = dapp.contracts.MyToken.balanceOf(userAddress)
})
</script>
1
2
3
4
5
6
7
8
9
10
11

Explanations

By wrapping our code in the dapp.contracts.MyToken.onReadSafe()method, we ensure that it will be executed only when the MyToken contract is safe to be read.

Or if we want to ensure our interaction with MyToken contract is safe in template :

html
<template>
  <dapp.contracts.MyToken.OnReadSafe>
    <!-- Will be rendered only when MyToken contract will be safe to read -->
    <p>Address : {{ userAddress }}</p>
    <p>Balance : {{ userBalance }}</p>
  </dapp.contracts.MyToken.OnReadSafe>
</template>
1
2
3
4
5
6
7

Explanations

By wrapping our content in the dapp.contracts.MyToken.OnReadSafecomponent, we ensure that it will be rendered only when the MyToken contract is safe to be read.

With Tulipe you can also track an on-chain data and it feels like using VueJS watchers methods (watch(), etc.)

Here is how we can track and display an always up-to-date balance to the user :

html
<script setup>
import { dapp } from "tulipe";

const userAddress = "0xf39Fd6e5..."
let userBalance = $ref(null);

dapp.contracts.MyToken.watch("balanceOf", [userAddress], (newValue) => {
  // Will be executed each time 'balanceOf' of 'userAddress' changes
  userBalance = newValue;
})
</script>

<template>
  <p>Your balance is : {{ userBalance }} MTK</p>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Explanations

The dapp.contracts.MyToken.watch() method allows to efficiently watch for mutations of an on-chain data and to run a given callback each time it occurs.

Tulipe offers a lot more things to makes safe DApp development a real piece of cake.

You can find them all on its documentations.

Released under the MIT License.