Comment on page
Frontend Tutorial
Create and deploy a simple frontend locally
Please complete Counter tutorial to deploy the counter smart contract before continuing with this page
In this tutorial, we'll go over how to:
- Set up your frontend project
- Connect to a Sei wallet
- Query and display the current count
- Execute the counter smart contract's
increment
function
To create a project from scratch we recommend using the typescript template from Vite, which makes development and debugging much easier.
yarn create vite my-counter-frontend --template react-ts
This will create a new folder with a React project that uses typescript. Open this folder in your favorite IDE.
From a terminal at the root of this project install the required project dependencies including @sei-js/core and @sei-js/react as well as some node polyfill libraries.
yarn && yarn add @sei-js/core @sei-js/react
or
npm install && npm install @sei-js/core @sei-js/react
Replace your
App.tsx
file with the following code to set up a SeiWalletProvider context, define your chain info, and set connection URLs.Typescript (highly recommended)
Javascript
import { SeiWalletProvider } from '@sei-js/react';
import './App.css';
import Home from './Home.tsx';
function App() {
return (
// Set up SeiWalletProvider for easy wallet connection and to use hooks in @sei-js/react
<SeiWalletProvider
chainConfiguration={{
chainId: 'atlantic-2',
restUrl: 'https://rest.atlantic-2.seinetwork.io',
rpcUrl: 'https://rpc.atlantic-2.seinetwork.io'
}}
wallets={['compass', 'fin']}>
<Home />
</SeiWalletProvider>
);
}
export default App;
import { SeiWalletProvider } from '@sei-js/react';
import './App.css';
import Home from './Home.jsx';
function App() {
return (
// Set up SeiWalletProvider for easy wallet connection and to use hooks in @sei-js/react
<SeiWalletProvider
chainConfiguration={{
chainId: 'atlantic-2',
restUrl: 'https://rest.atlantic-2.seinetwork.io',
rpcUrl: 'https://rpc.atlantic-2.seinetwork.io'
}}
wallets={['compass', 'fin']}>
<Home />
</SeiWalletProvider>
);
}
export default App;
Wallet Provider Setup
- Imports
SeiWalletProvider
from the@sei-js/react
package. - Wraps the
Home
component with theSeiWalletProvider
to provide the wallet context.
Chain Configuration
- Specifies the
chainConfiguration
prop inSeiWalletProvider
to set up the blockchain network:chainId
: Identifies the Sei network (in this case,atlantic-2
).restUrl
: REST URL for the Sei (You may need your own provider).rpcUrl
: RPC URL for the Sei (You may need your own provider).
Supported Wallets
- Sets up supported wallet types (
'compass', 'fin', 'leap', 'keplr'
) in thewallets
prop.
Create a new file called Home.tsx inside your
src
directory with the following code.Typescript (highly recommended)
Javascript
import { useCallback, useEffect, useState } from 'react';
import { useCosmWasmClient, useSigningCosmWasmClient, useWallet, WalletConnectButton } from '@sei-js/react';
const CONTRACT_ADDRESS = 'YOUR_COUNTER_CONTRACT ADDRESS'; // (atlantic-2 example) sei18g4g35mhy5s88nshpa6flvpj9ex6u88l6mhjmzjchnrfa7xr00js0gswru
function Home() {
const [count, setCount] = useState<number | undefined>();
const [error, setError] = useState<string>('');
const [isIncrementing, setIsIncrementing] = useState<boolean>(false);
// Helpful hook for getting the currently connected wallet and chain info
const { connectedWallet, accounts } = useWallet();
// For querying cosmwasm smart contracts
const { cosmWasmClient: queryClient } = useCosmWasmClient();
// For executing messages on cosmwasm smart contracts
const { signingCosmWasmClient: signingClient } = useSigningCosmWasmClient();
const fetchCount = useCallback(async () => {
const response = await queryClient?.queryContractSmart(CONTRACT_ADDRESS, { get_count: {} });
return response?.count;
}, [queryClient]);
useEffect(() => {
fetchCount().then(setCount);
}, [connectedWallet, fetchCount]);
const incrementCounter = async () => {
setIsIncrementing(true);
try {
const senderAddress = accounts[0].address;
// Build message content
const msg = { increment: {} };
// Define gas price and limit
const fee = {
amount: [{ amount: '0.1', denom: 'usei' }],
gas: '200000'
};
// Call smart contract execute msg
await signingClient?.execute(senderAddress, CONTRACT_ADDRESS, msg, fee);
// Updates the counter state again
const updatedCount = await fetchCount();
setCount(updatedCount);
setIsIncrementing(false);
setError('');
} catch (error) {
if (error instanceof Error) {
setError(error.message);
} else {
setError('unknown error');
}
setIsIncrementing(false);
}
};
// Helpful component for wallet connection
if (!connectedWallet) return <WalletConnectButton />;
return (
<div>
<h1>Count is: {count ? count : '---'}</h1>
<button disabled={isIncrementing} onClick={incrementCounter}>
{isIncrementing ? 'incrementing...' : 'increment'}
</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}
export default Home;
import { useCallback, useEffect, useState } from 'react';
import { useCosmWasmClient, useSigningCosmWasmClient, useWallet, WalletConnectButton } from '@sei-js/react';
const CONTRACT_ADDRESS = 'YOUR_COUNTER_CONTRACT ADDRESS'; // (atlantic-2 example) sei18g4g35mhy5s88nshpa6flvpj9ex6u88l6mhjmzjchnrfa7xr00js0gswru
function Home() {
const [count, setCount] = useState();
const [error, setError] = useState('');
const [isIncrementing, setIsIncrementing] = useState(false);
// Helpful hook for getting the currently connected wallet and chain info
const { connectedWallet, accounts } = useWallet();
// For querying cosmwasm smart contracts
const { cosmWasmClient: queryClient } = useCosmWasmClient();
// For executing messages on cosmwasm smart contracts
const { signingCosmWasmClient: signingClient } = useSigningCosmWasmClient();
const fetchCount = useCallback(async () => {
const response = await queryClient?.queryContractSmart(CONTRACT_ADDRESS, { get_count: {} });
return response?.count;
}, [queryClient]);
useEffect(() => {
fetchCount().then(setCount);
}, [connectedWallet, fetchCount]);
const incrementCounter = async () => {
setIsIncrementing(true);
try {
const senderAddress = accounts[0].address;
// Build message content
const msg = { increment: {} };
// Define gas price and limit
const fee = {
amount: [{ amount: '0.1', denom: 'usei' }],
gas: '200000'
};
// Call smart contract execute msg
await signingClient?.execute(senderAddress, CONTRACT_ADDRESS, msg, fee);
// Updates the counter state again
const updatedCount = await fetchCount();
setCount(updatedCount);
setIsIncrementing(false);
setError('');
} catch (error) {
if (error instanceof Error) {
setError(error.message);
} else {
setError('unknown error');
}
setIsIncrementing(false);
}
};
// Helpful component for wallet connection
if (!connectedWallet) return <WalletConnectButton />;
return (
<div>
<h1>Count is: {count ? count : '---'}</h1>
<button disabled={isIncrementing} onClick={incrementCounter}>
{isIncrementing ? 'incrementing...' : 'increment'}
</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
}
export default Home;
Render Logic
- If no wallet is connected, it shows a
WalletConnectButton
which is a pre built component inside @sei-js/react. - Otherwise, displays the counter value and an "Increment" button.
- Disables the increment button when a transaction is pending
- Catches and displays error messages, if any.
Wallet and Client Setup
- Utilizes
useWallet()
from@sei-js/react
to get the connected wallet and accounts. - Uses
useCosmWasmClient
anduseSigningCosmWasmClient
hooks from@sei-js/react
to instantiatequeryClient
andsigningClient
. The signing client can be used for querying, but it is not recommended to use a signing client when only a query client is needed.
Fetching Counter Value
fetchCount
function usesqueryClient.queryContractSmart
to query the smart contract (CONTRACT_ADDRESS)
with the query{ get_count: {} }
Incrementing Counter
incrementCounter
function:- Extracts
senderAddress
from the connected wallet's accounts. - Builds a message (
msg
) with{ increment: {} }
to be sent to the smart contract. - Specifies the transaction fee (
fee
) with gas price and gas limit. - Calls
signingClient.execute
to execute the contract with the built message and fee.
By leveraging @sei-js and its hooks, the component provides a way to connect to a wallet, query a CosmWasm smart contract to get the current counter state, and increment it with an execute message.
If you run this code as is, then it will throw an error - you need to tell it which contract to use. We have deployed a counter contract for you on the atlantic-2 testnet.
To use it, set
CONTRACT_ADDRESS
to sei18g4g35mhy5s88nshpa6flvpj9ex6u88l6mhjmzjchnrfa7xr00js0gswru
If this is your first time using Sei, you might see an error which says your account does not exist on chain.
You can claim some testnet tokens for development purposes here: https://atlantic-2.app.sei.io/faucet
Once you have funded your account, try the increment button again!
You have now created a simple website for querying and executing a smart contract on Sei!
Last modified 1mo ago