Skip to content

Latest commit

 

History

History
 
 

react

cosmos-kit

Cosmos Kit is a wallet adapter for developers to build apps that quickly and easily interact with Cosmos blockchains and wallets.

@cosmos-kit/react is the React integration for Cosmos Kit.

Installation

yarn add @cosmos-kit/react @cosmos-kit/core @cosmos-kit/keplr chain-registry

Provider

First, add the WalletProvider to your app, and include the supported chains and supported wallets:

import * as React from 'react';

import { ChakraProvider } from '@chakra-ui/react';
import { WalletProvider } from '@cosmos-kit/react';
import { chains, assets } from 'chain-registry';
import { wallets } from '@cosmos-kit/keplr';

function WalletApp() {
  return (
    <ChakraProvider theme={defaultTheme}>
      <WalletProvider
        chains={chains} // supported chains
        assetLists={assets} // supported asset lists
        wallets={wallets} // supported wallets
      >
        <YourWalletRelatedComponents />
      </WalletProvider>
    </ChakraProvider>
  );
}

Get wallet properties and functions using the useWallet hook:

import * as React from 'react';

import { useWallet } from "@cosmos-kit/react";

function Component ({ chainName }: { chainName?: string }) => {
    const walletManager = useWallet();

    // Get wallet properties
    const {
        currentChainName,
        currentWalletName,
        walletStatus,
        username,
        address,
        message,
      } = walletManager;

    // Get wallet functions
    const {
        connect,
        disconnect,
        openView,
        setCurrentChain,
    } = walletManager;

    // if `chainName` in component props, `setCurrentChain` in `useEffect`
    React.useEffect(() => {
        setCurrentChain(chainName);
    }, [chainName]);
}

Signing Clients

There two signing clients available via walletManager functions: getStargateClient() and getCosmWasmClient().

Using signing client in react component:

import * as React from 'react';
import { cosmos } from 'interchain';
import { StdFee } from '@cosmjs/amino';
import { useWallet } from "@cosmos-kit/react";

function Component () => {
    const walletManager = useWallet();
    const {
        getStargateClient,
        getCosmWasmClient,
        address,
      } = walletManager;

    const sendTokens = async () => {
      const stargateClient = await getStargateClient();
      if (!stargateClient || !address) {
          console.error('stargateClient undefined or address undefined.')
          return;
      }

      const { send } = cosmos.bank.v1beta1.MessageComposer.withTypeUrl;

      const msg = send({
        amount: [ { denom: 'uatom', amount: '1000' } ],
        toAddress: address, fromAddress: address
      });

      const fee: StdFee = { amount: [ { denom: 'uatom', amount: '864' } ], gas: '86364' };

      await stargateClient.signAndBroadcast(address, [msg], fee, memo);
    }
}

Customized signing client options

The default options are undefined. You can provide your own options in WalletProvider.

import * as React from 'react';

import { Chain } from '@chain-registry/types';
import { chains } from 'chain-registry';
import { GasPrice } from '@cosmjs/stargate';
import { getSigningCosmosClientOptions } from 'interchain';
import { SignerOptions } from '@cosmos-kit/core';
import { WalletProvider } from '@cosmos-kit/react';
import { wallets } from '@cosmos-kit/config';

// construct signer options
const signerOptions: SignerOptions = {
  stargate: (chain: Chain) => {
    // return corresponding stargate options or undefined
    return getSigningCosmosClientOptions();
  },
  cosmwasm: (chain: Chain) => {
    // return corresponding cosmwasm options or undefined
    switch (chain.chain_name) {
      case 'osmosis':
        return {
          gasPrice: GasPrice.fromString('0.0025uosmo'),
        };
      case 'juno':
        return {
          gasPrice: GasPrice.fromString('0.0025ujuno'),
        };
    }
  },
};

function WalletApp() {
  return (
    <WalletProvider
      chains={chains}
      wallets={wallets}
      signerOptions={signerOptions} // Provide signerOptions
    >
      <YourWalletRelatedComponents />
    </WalletProvider>
  );
}

The SignerOptions object has stargate and cosmwasm properties which are functions that return client options:

// in '@cosmos-kit/core'
import { SigningStargateClientOptions } from '@cosmjs/stargate';
import { SigningCosmWasmClientOptions } from '@cosmjs/cosmwasm-stargate';

export interface SignerOptions {
  stargate?: (chain: Chain) => SigningStargateClientOptions | undefined;
  cosmwasm?: (chain: Chain) => SigningCosmWasmClientOptions | undefined;
}

Customized Modal

You can bring your own UI. The WalletProvider provides a default modal for connection in @cosmos-kit/react.

import { DefaultModal } from '@cosmos-kit/react';

To define your own modal, you can input you modal component in WalletProvider props.

Required properties in your modal component:

import { WalletModalProps } from '@cosmos-kit/core';

// in `@cosmos-kit/core`
export interface WalletModalProps {
  isOpen: boolean;
  setOpen: Dispatch<boolean>;
}

A simple example to define your own modal:

import * as React from 'react';

import { WalletProvider, useWallet } from '@cosmos-kit/react';

// Define Modal Component
const MyModal = ({ isOpen, setOpen }: WalletModalProps) => {
  const walletManager = useWallet();

  function onCloseModal() {
    setOpen(false);
  }

  function onWalletClicked(name: string) {
    return async () => {
      console.info('Connecting ' + name);
      walletManager.setCurrentWallet(name);
      await walletManager.connect();
    };
  }

  return (
    <Modal isOpen={open} onClose={onCloseModal}>
      <ModalContent>
        <ModalHeader>Choose Wallet</ModalHeader>
        <ModalCloseButton />
        <ModalBody>
          {walletManager.wallets.map(({ name, prettyName }) => (
            <Button
              key={name}
              colorScheme="blue"
              variant="ghost"
              onClick={onWalletClicked(name)}
            >
              {prettyName}
            </Button>
          ))}
        </ModalBody>
      </ModalContent>
    </Modal>
  );
};

function WalletApp() {
  return (
    <WalletProvider
      chains={chains}
      wallets={wallets}
      walletModal={MyModal} // Provide walletModal
    >
      <YourWalletRelatedComponents />
    </WalletProvider>
  );
}

Customized Wallet Info

The simplest way to import wallets in WalletProvider is import { wallets } from '@cosmos-kit/keplr';. wallets is of type Wallet[], and the Wallet here is from import { Wallet } from '@cosmos-kit/core';.

export interface Wallet {
  name: WalletName;
  prettyName: string;
  isQRCode: boolean;
  downloads?: {
    default: string;
    desktop?: Icon[];
    tablet?: Icon[];
    mobile?: Icon[];
  };
  logo?: string;
  qrCodeLink?: string;
}

To define your own wallet info, such as icon, app name, as well as other props, you can construct wallets as follows.

import { KeplrExtensionWallet, KeplrMobileWallet } from '@cosmos-kit/keplr';

const keplrExtensionInfo: Wallet = {...};
const keplrMobileInfo: Wallet = {...};

const keplrExtension = new KeplrExtensionWallet(keplrExtensionInfo);
const KeplrMobile = new KeplrMobileWallet(keplrMobileInfo);

export const wallets = [keplrExtension, KeplrMobile];

The default value of keplrExtensionInfo and keplrMobileInfo can be seen from import { keplrExtensionInfo, keplrMobileInfo } from '@cosmos-kit/keplr';.

Options in WalletProvider

endpointOptions

Define preferred endpoints for each chain.

export type ChainName = string;

export interface Endpoints {
  rpc?: string[];
  rest?: string[];
}

export type EndpointOptions = Record<ChainName, Endpoints>;

e.g.

<WalletProvider
  ...
  endpointOptions={{
    osmosis: {
      rpc: ['http://test.com']
    }
  }}
>

viewOptions

Define automation for view. Optional

export interface ViewOptions {
  /**
   * if alwaysOpenView === true, always open view when `connect` or `disconnect` is called
   * if alwaysOpenView === false, only open view when necessary. e.g. current wallet is not defined, need to choose wallet in modal.
  */
  alwaysOpenView?: boolean;
  closeViewWhenWalletIsConnected?: boolean;
  closeViewWhenWalletIsDisconnected?: boolean;
  closeViewWhenWalletIsRejected?: boolean;
}

// default value
const viewOptions: ViewOptions = {
  alwaysOpenView: false,
  closeViewWhenWalletIsConnected: false,
  closeViewWhenWalletIsDisconnected: true,
  closeViewWhenWalletIsRejected: false,
};

storageOptions

Define local storage attributes. Optional

storage key: walletManager

storage value attributes:

  • currentWalletName
  • currentChainName
export interface StorageOptions {
  disabled?: boolean;
  duration?: number; // ms
  clearOnTabClose?: boolean;
}

// default value
const storageOptions: StorageOptions = {
  disabled: false,
  duration: 1800000, // half an hour
  clearOnTabClose: false
};

sessionOptions

Define connection session options. Optional

export interface SessionOptions {
  duration?: number; // ms
  killOnTabClose?: boolean;
}

// default value
  sessionOptions: SessionOptions = {
    duration: 1800000, // half an hour
    killOnTabClose: false,
  };

Credits

🛠 Built by Cosmology — if you like our tools, please consider delegating to our validator ⚛️

Code built with the help of these related projects: