Start Here
UniversalKit by ZetaChain provides a set of React components designed to make building universal applications easier.
The components are expected to work with Next.js (opens in a new tab), RainbowKit (opens in a new tab) and wagmi (opens in a new tab).
Start from a template (recommended):
git clone https://github.com/zeta-chain/template
cd template/web
yarn
Or add UniversalKit to your existing app:
yarn add @zetachain/universalkit
UniversalKit Provider
UniversalKit Provider is a React context provider that initializes and provides shared state between components.
To initialize the provider, wrap your application with the
UniversalKitProvider
:
import { UniversalKitProvider } from "@zetachain/universalkit";
<UniversalKitProvider>{children}</UniversalKitProvider>;
If you're using the template (opens in a new tab), the provider is already initialized.
ZetaChain Client
ZetaChain Client is a client that provides access to useful methods for interacting with ZetaChain. The client is powered by the Toolkit (opens in a new tab) library.
Some of the components require a ZetaChain Client to be passed as a prop. To
initialize the client, use the useZetaChainClient
hook:
import { useZetaChainClient } from "@zetachain/universalkit";
const client = useZetaChainClient({ network: "testnet", signer });
Instantiating a client manually allows you to configure it, for example, specifying a different RPC endpoint:
const client = useZetaChainClient({
signer,
network: "testnet",
chains: {
zeta_testnet: {
api: [
{
url: `https://zetachain-athens.g.allthatnode.com/archive/evm/${process.env.KEY}`,
type: "evm",
},
],
},
},
});
Bitcoin Wallet Provider
Bitcoin Wallet Provider is a React context provider that initializes and provides functionality for connecting a Bitcoin wallet to the application: address of the connected Bitcoin wallet, connection status, connected wallet type, method to connect a wallet, method to disconnect a wallet, and method to send a transaction.
import { useBitcoinWallet } from "@zetachain/universalkit";
const { address, loading, connectedWalletType, connectWallet, disconnect, sendTransaction } = useBitcoinWallet();
Connect Bitcoin
Connect Bitcoin is a component that allows users to connect their Bitcoin wallet to the application. Currently, OKX, XDEFI and UniSat wallets are supported.
After a Bitcoin wallet is connected, the current address becomes available from
the BitcoinWalletProvider
.
"use client";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import { ConnectBitcoin } from "@zetachain/universalkit";
const Page = () => {
return (
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">{/* Add components here */}</div>
</div>
</div>
);
};
export default Page;
Swap
The Swap component provides the following functionality:
- Swap between connected chains (for example, Ethereum and BNB)
- Deposit native gas and supported ERC-20 tokens from a connected chain to ZetaChain
- Withdraw ZRC-20 tokens from ZetaChain to a connected chain
- Send ZETA between chains
- Transfer native gas and ERC-20 tokens on connected chains
For cross-chain swaps the component depends on a universal swap contract. Complete the swap tutorial and deploy your own contract, or use the contract address from the example below. contract or use the contract address from the example below.
"use client";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import { Swap, useEthersSigner, useZetaChainClient, ConnectBitcoin, useBitcoinWallet } from "@zetachain/universalkit";
import { useAccount, useChainId, useWalletClient } from "wagmi";
const contract = "0xb459F14260D1dc6484CE56EB0826be317171e91F"; // universal swap contract
const Page = () => {
const account = useAccount();
const chainId = useChainId();
const { data: walletClient } = useWalletClient({ chainId });
const signer = useEthersSigner({ walletClient });
const client = useZetaChainClient({ network: "testnet", signer });
const { address: bitcoinAddress } = useBitcoinWallet();
return (
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">
{client && <Swap contract={contract} client={client} account={account} bitcoin={bitcoinAddress} />}
</div>
</div>
</div>
);
};
export default Page;
Balances
The Balances component provides a list of token balances on all chains connected to ZetaChain, with the ability to search the list and filter tokens by chain.
"use client";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import {
Balances,
useEthersSigner,
useZetaChainClient,
ConnectBitcoin,
useBitcoinWallet,
} from "@zetachain/universalkit";
import { useAccount, useChainId, useWalletClient } from "wagmi";
const Page = () => {
const account = useAccount();
const chainId = useChainId();
const { data: walletClient } = useWalletClient({ chainId });
const signer = useEthersSigner({ walletClient });
const client = useZetaChainClient({ network: "testnet", signer });
const { address: bitcoinAddress } = useBitcoinWallet();
return (
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">
{client && <Balances client={client} account={account} bitcoin={bitcoinAddress} />}
</div>
</div>
</div>
);
};
export default Page;
Profile
The Profile component resolves an address to a domain name and displays it as a button. For resolving addresses the component uses Space ID Web3 Name SDK (opens in a new tab).
"use client";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import { Profile, ConnectBitcoin } from "@zetachain/universalkit";
import { useAccount } from "wagmi";
const Page = () => {
const account = useAccount();
return (
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">
<Profile address={account.address} />
</div>
</div>
</div>
);
};
export default Page;
Staking Rewards
The Staking Rewards component displays the staked amount, number of tokens being unstaked, and the number of rewards earned. The component also allows users to claim staking rewards.
"use client";
import { ConnectButton } from "@rainbow-me/rainbowkit";
import {
StakingRewards,
useEthersSigner,
useZetaChainClient,
ConnectBitcoin,
useBitcoinWallet,
} from "@zetachain/universalkit";
import { useAccount, useChainId, useWalletClient } from "wagmi";
const Page = () => {
const account = useAccount();
const chainId = useChainId();
const { data: walletClient } = useWalletClient({ chainId });
const signer = useEthersSigner({ walletClient });
const client = useZetaChainClient({ network: "testnet", signer });
const { address: bitcoinAddress } = useBitcoinWallet();
return (
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">{client && <StakingRewards client={client} account={account} />}</div>
</div>
</div>
);
};
export default Page;