There are two ways to make a frontend for your smart contracts, namely the everscale-inpage-provider with the VenonWallet/EverWallet or the EverSdk AppKit JS.
EverSdk is good if you want to create a standalone app, such as your wallet or a game. It's also great for writing server applications. But it's not suitable for writing web applications because you needto store users' keys. And just storing them on the website isn't considered secure, because any malicious extension or XSS vulnerability on your website will allow you to steal the keys. But in some simple cases, such as a tic-tac-toe game where you just throw in a few cents for gas, you can use them on the frontend. Basically, to write a frontend with it, you should have enough EverSdk examples from"Smart Contracts" + documentation EverSdk and AppKit JS
We'll look at how to write a frontend for an application using everscale-inpage-provider. This is very similar to writing an application with web3.js.
To connect the wallet, we will be using the library Venom-connect, inspired by web3 modal. Currently, it supports connecting two wallets - VenomWallet/EverWallet(both extension and mobile), and returns an instance of everscale-inpage-provider.
You already know almost everything you need to know about making frontend for your smart contracts
(if not, refer to section on smart contracts). Same library, same API. Only the keys and accounts aren't managed by you,
but by the extension. You can also use 'everscale-standalone-client' as a fallback to pull data from the blockchain in
case the person hasn't connected the wallet or the extension isn't installed yet. Another difference is that it's not
recommended deploying a smart-contracts by sending stateInit directly from the user's wallets, as not all wallet types
support sending stateInit. Instead, you need to write factories and call the deploy(...)
method of factory to deploy
a smart-contract.
As an example of a frontend, we'll write a simple application for our tip3 token dice game. You can check out a full sample implementation in React here.
And this we'll go step by step, from start to finish. Please install VenomWallet, switch it to testnet and get test coins as follows.
First, we initialize Venom-connect. You can find a description of all possible parameters in the library's documentation.
import { Address, ProviderRpcClient } from "everscale-inpage-provider"; import { EverscaleStandaloneClient } from "everscale-standalone-client"; import { VenomConnect } from "venom-connect"; const venomConnect = new VenomConnect({ theme: 'dark', // light checkNetworkId: 1000, // 1000 - venom testnet, 1 - venom mainnet providersOptions: { venomwallet: { links: { // you can override links to the extensions/application there }, walletWaysToConnect: [ { // NPM package everscale inpage provider package: ProviderRpcClient, packageOptions: { fallback: VenomConnect.getPromise("venomwallet", "extension") || (() => Promise.reject()), forceUseFallback: true, }, // You can define fallback for standalone client, // to be able to fetch data from BC withour connect a walelt. // packageOptionsStandalone: { // // fallback: standaloneFallback, // // forceUseFallback: true, // }, // Setup id: "extension", type: "extension", }, ], defaultWalletWaysToConnect: [ // List of enabled options "mobile", "ios", "android", ], }, // EverWallet everwallet: { links: {}, walletWaysToConnect: [ { // NPM package package: ProviderRpcClient, packageOptions: { fallback: VenomConnect.getPromise("everwallet", "extension") || (() => Promise.reject()), forceUseFallback: true, }, // packageOptionsStandalone: { // fallback: standaloneFallback, // forceUseFallback: true, // }, id: "extension", type: "extension", }, ], defaultWalletWaysToConnect: [ // List of enabled options "mobile", "ios", "android", ], }, }, });
We always start our interaction with the wallet by checking if the user has a wallet installed:
// return provider or undefined const provider = await venomConnect.checkAuth();
If the user doesn't have a wallet installed, ask him to install.
For simplicity, we'll use the provider without https://github.com/broxus/everscale-standalone-client. It can be used to pull data from blockchain without having a wallet attached. Let's get a current provider state.
const provider = await venomConnect.checkAuth(); const currentProviderState = await provider?.getProviderState(); console.log(currentProviderState);
Two permissions are supported in the wallets at the moment. These are:
Let's ask the user connect the wallet, venom connect ask for both permission by default:
venomConnect.on('extension-auth', async function (provider) { // Save provider instance there // Because this can be not the same provider you got in // await venomConnect.checkAuth() (if any) // in case user has both extension installed // or connected via mobile app. const currentProviderState = await provider?.getProviderState(); console.log(currentProviderState); }); venomConnect.connect();
// To disconnect, you can use await venomConnect.disconnect();
After we get the permissions, we can interact with the wallet and receive data from the blockchain. Our cube game contract
is deployed in the testnet, so let's check what networkId
we have in it
// Subscribe to network changed event const networkSubscriber = await provider.subscribe('networkChanged'); networkSubscriber.on('data', (event) => { // track changes in the network id if (event.networkId === 1000) { // We are on the testnet now } else { // Still not on the testnet } }); // You can use await networkSubscriber.unsubscribe(); to cancel the subscription const currentProviderState = await provider.getProviderState(); if (currentProviderState.networkId !== 1000) { // Wait until user will change the network. // We already asked venom connect to check the network id // So user will see popup "Change network or connect different wallet" } else { // Everything is okay }
In the next article, we will look at how to interact with smart contracts.