How to connect your frontend to Cosmos blockchain

First of all, to interact with cosmos ecosystem you need a wallet. You can find possible wallets available here. Keplr wallet is the most widely used wallet and their API integration is easy to use and is well-typed.

Install Keplr wallet extension to your browser and create an account if you haven't already registered.

Let's bootstrap a website using strangelove's starter template that already has typescript, eslint, prettier and chakra UI.

git clone <https://github.com/strangelove-ventures/strangestarter.git> cosmos-frontend

Install packages using pnpm

cd ./cosmos-frontend
pnpm install
pnpm dev

Okay now after we have our repo bootstrapped, let’s create a simple UI for connecting to a wallet and a dashboard.

// website/pages/index.tsx
import { Box, Button, Center, HStack, Stack, Tag, TagLabel, TagLeftIcon, Text } from "@chakra-ui/react";
export default function HomePage() {
return (
<Center minH="100vh">
<Stack bgColor="whiteAlpha.100" boxShadow="md" maxW="md" p={4} rounded="md" spacing={4} w="full">
<HStack>
<Tag>
<TagLeftIcon as={Box} bgColor="red.500" boxSize={3} rounded="full" />
<TagLabel>Disconnected</TagLabel>
</Tag>
</HStack>
<Text>
Active chain id: <b>Chain</b>
</Text>
<Text>
Name: <b>Kiki</b>
</Text>
<Text noOfLines={1} wordBreak="break-all">
Address: <b>...</b>
</Text>
<HStack align="end" pt={4}>
<Button>Connect Wallet</Button>
</HStack>
</Stack>
</Center>
);
}

You'll have something like this:

To use Keplr's API you can reference their API documentation. We need to manage the states, like if user already connected, create offlineSigner and other complex states.

Luckily Strangelove created a package called graz that abstracts the complexity of the Keplr API and wraps it into React hooks. From the documentation website it has features like:

  • πŸͺ 20+ hooks for interfacing with wallets, clients, signers, etc. (connecting, view balances, send tokens, etc.)

  • πŸ’³ Multiple wallet supports (Keplr & Leap wallet)

  • βš™οΈ Generate mainnet & testnet ChainInfo

  • πŸ“š Built-in caching, request deduplication, and all the good stuff from @tanstack/react-query and zustand

  • πŸ”„ Auto refresh on wallet and network change

  • πŸ‘ Fully typed and tree-shakeable

So let's install graz to our project

pnpm website install graz

Wrap our app with GrazProvider and set default chain to cosmoshub or what ever you like

// website/pages/_app.tsx
import { ChakraProvider } from "@chakra-ui/react";
import type { AppProps } from "next/app";
import { theme } from "styles/theme";
import { Layout } from "ui/layout";
import { GrazProvider, mainnetChains } from "graz";
export default function CustomApp({ Component, pageProps }: AppProps) {
return (
<ChakraProvider resetCSS theme={theme}>
<GrazProvider
grazOptions={{
defaultChain: mainnetChains.cosmoshub,
}}
>
<Layout>
<Component {...pageProps} />
</Layout>
</GrazProvider>
</ChakraProvider>
);
}

Connect and disconnect

graz provides a mutation hook that we can use to connect and disconnect so you don't need to maintain the logic of these functions, simply use useConnect() and useDisconnect() to have connecting functionality.

To check if the user is already connected or not graz has a hook called useAccount(). One of the return objects is isConnected.

// website/pages/index.tsx
import { Box, Button, Center, HStack, Stack, Tag, TagLabel, TagLeftIcon, Text } from "@chakra-ui/react";
import { useAccount, useConnect, useDisconnect } from "graz";
export default function HomePage() {
const { isConnected } = useAccount();
const { connect } = useConnect();
const { disconnect } = useDisconnect();
return (
<Center minH="100vh">
<Stack bgColor="whiteAlpha.100" boxShadow="md" maxW="md" p={4} rounded="md" spacing={4} w="full">
<HStack>
<Tag>
<TagLeftIcon as={Box} bgColor={isConnected ? "green.500" : "red.500"} boxSize={3} rounded="full" />
<TagLabel>{isConnected ? "Connected" : "Disconnected"}</TagLabel>
</Tag>
</HStack>
<Text>
Active chain id: <b>Chain</b>
</Text>
<Text>
Name: <b>Kiki</b>
</Text>
<Text noOfLines={1} wordBreak="break-all">
Address: <b>...</b>
</Text>
<HStack align="end" pt={4}>
<Button onClick={() => (isConnected ? disconnect() : connect())}>
{isConnected ? "Disconnect" : "Connect Wallet"}
</Button>
</HStack>
</Stack>
</Center>
);
}

Show connected information

After we have connection functionality, we should display the connection information. We can get the connected account information from useAccount() and the current active chain from useActiveChain().

// website/pages/index.tsx
import { Box, Button, Center, HStack, Stack, Tag, TagLabel, TagLeftIcon, Text } from "@chakra-ui/react";
import { useAccount, useActiveChain, useConnect, useDisconnect } from "graz";
export default function HomePage() {
const { isConnected, data: account } = useAccount();
const { connect } = useConnect();
const { disconnect } = useDisconnect();
const activeChain = useActiveChain();
return (
<Center minH="100vh">
<Stack bgColor="whiteAlpha.100" boxShadow="md" maxW="md" p={4} rounded="md" spacing={4} w="full">
<HStack>
<Tag>
<TagLeftIcon as={Box} bgColor={isConnected ? "green.500" : "red.500"} boxSize={3} rounded="full" />
<TagLabel>{isConnected ? "Connected" : "Disconnected"}</TagLabel>
</Tag>
</HStack>
<Text>
Active chain id: <b>{activeChain?.chainId}</b>
</Text>
<Text>
Name: <b>{account?.name}</b>
</Text>
<Text noOfLines={1} wordBreak="break-all">
Address: <b>{account?.bech32Address}</b>
</Text>
<HStack align="end" pt={4}>
<Button onClick={() => (isConnected ? disconnect() : connect())}>
{isConnected ? "Disconnect" : "Connect Wallet"}
</Button>
</HStack>
</Stack>
</Center>
);
}

Congratulations now your app is connected to the cosmos ecosystem

When you connect with graz's useConnect() it automatically generates offlineSigners, Clients, SigningClients. You can get the details from useOfflineSigners(), useClients() and useSigningClients() if you want to interact with those things.

graz has many useful hooks such as useBalances() to view balances, useSendTokens() to send tokens, useBalanceStaked() to see how many tokens are staked, and many more! You can see it on the documentation https://graz.strange.love

Source code: https://github.com/codingki/cosmos-frontend

Preview: https://cosmos-frontend-graz.vercel.app/

Read More Like This


Market Watch Jan 6, 2023

Market Watch Jan 6, 2023

Jan 06, 2023

Retrospectives: Sustaining the Practice

Retrospectives: Sustaining the Practice

Nov 28, 2022

Building a Human Centered Wallet

Building a Human Centered Wallet

Jul 06, 2022