This guide will walk you through the process of integrating Cosmos Wallets into your Para Modal and Para-enabled application, allowing you to onboard new users and connect with existing users who may already have external wallets like Keplr, Leap and more.

Prerequisites

Before integrating wallet connections, ensure you have an existing Para project with the Para Modal set up. If you haven’t set up Para yet, follow one of our Framework Setup guides like this React + Vite guide.

Setting up Cosmos Wallets

Para integrates with leading Cosmos wallets including Keplr and Leap. Our integration leverages a modified fork of the graz React library.

1

Install dependencies

Install the required packages alongside your existing Para dependencies:

2

Import components

Import the necessary wallet connectors and chain configurations:

main.tsx
import { useState } from "react";
import { ParaCosmosProvider, keplrWallet, leapWallet } from "@getpara/cosmos-wallet-connectors";
import { cosmoshub, osmosis } from "@getpara/graz/chains";
import { type ChainInfo } from "keplr-wallet/types";

If you encounter type issues with @getpara/graz/chains, you’ll need to generate the chain files. You can:

  1. Add a postinstall script to your package.json:
{
  "scripts": {
    "postinstall": "graz --generate"
  }
}
  1. Or run npx graz --generate manually after installation
3

Configure chains

Set up your Cosmos chain configurations with the necessary RPC and REST endpoints. You can extend the existing chain configurations with your custom endpoints:

main.tsx
const cosmosChains: ChainInfo[] = [
  {
    ...cosmoshub,
    rpc: "https://rpc.cosmos.directory/cosmoshub", // Replace with your RPC endpoint
    rest: "https://rest.cosmos.directory/cosmoshub", // Replace with your REST endpoint
  },
  {
    ...osmosis,
    rpc: "https://rpc.cosmos.directory/osmosis",
    rest: "https://rest.cosmos.directory/osmosis",
  },
];
4

Configure the provider

Similar to the Cosmos and Solana providers, configure the ParaCosmosProvider component by wrapping your application content in the ParaCosmosProvider component. Pass in the required configuration props:

main.tsx
export const App = () => {
  const [chainId, setChainId] = useState<string>(cosmoshub.chainId);

  return (
    <ParaCosmosProvider
      chains={cosmosChains}
      wallets={[keplrWallet, leapWallet]}
      selectedChainId={chainId}
      onSwitchChain={(chainId) => {
        setChainId(chainId);
      }}
      multiChain
      walletConnect={{ options: { projectId: "..." } }}>
      {/* Your app content and existing ParaModal */}
    </ParaCosmosProvider>
  );
};

For the ParaCosmosProvider wrapping you don’t need to include a QueryClientProvider as the provider already includes one.

Provider Configuration

ParaCosmosProvider
component
required

The ParaCosmosProvider is built on top of

graz's GrazProvider

and supports all of its configuration options.

Advanced Provider Pattern

Setting up a dedicated provider component that encapsulates all the necessary providers and modal state management is considered a best practice. This pattern makes it easier to manage the modal state globally and handle session management throughout your application.

Creating a Custom Provider

To create a custom provider, you can follow the example below. This provider will manage the modal state and handle chain switching.

CosmosProvider.tsx
import { createContext, useContext, useState } from "react";
import { ParaCosmosProvider, keplrWallet, leapWallet } from "@getpara/cosmos-wallet-connectors";
import { cosmoshub, osmosis } from "@getpara/graz/chains";
import { ParaModal } from "@getpara/modal";
import { type ChainInfo } from "keplr-wallet/types";

const CosmosContext = createContext({
  openModal: () => {},
  closeModal: () => {},
  isOpen: false,
  chainId: "",
  setChainId: (chainId: string) => {},
});

export const useWeb3Modal = () => useContext(CosmosContext);

export const CosmosProvider = ({ children }) => {
  const [isOpen, setIsOpen] = useState(false);
  const [chainId, setChainId] = useState(cosmoshub.chainId);

  const openModal = () => setIsOpen(true);
  const closeModal = () => setIsOpen(false);

  const cosmosChains: ChainInfo[] = [
    {
      ...cosmoshub,
      rpc: "https://rpc.cosmos.directory/cosmoshub",
      rest: "https://rest.cosmos.directory/cosmoshub",
    },
    {
      ...osmosis,
      rpc: "https://rpc.cosmos.directory/osmosis",
      rest: "https://rest.cosmos.directory/osmosis",
    },
  ];

  return (
    <CosmosContext.Provider value={{ openModal, closeModal, isOpen, chainId, setChainId }}>
      <ParaCosmosProvider
        chains={cosmosChains}
        wallets={[keplrWallet, leapWallet]}
        selectedChainId={chainId}
        onSwitchChain={setChainId}
        multiChain>
        <ParaModal
          isOpen={isOpen}
          onClose={closeModal}
        />
        {children}
      </ParaCosmosProvider>
    </CosmosContext.Provider>
  );
};

Server-Side Rendering Considerations

When using Next.js or other SSR frameworks, proper client-side initialization is crucial since web3 functionality relies on browser APIs. There are two main approaches:

  1. Using the 'use client' directive in Next.js 13+:

    • Add the directive at the component level where browser APIs are needed
    • Ensures the CosmosProvider component and its dependencies only run on the client
    • Maintains better code splitting and page performance
  2. Using dynamic imports:

    • Lazily loads the provider component
    • Automatically handles client-side only code
    • Provides fallback options during loading

Configuring the Para Modal

After setting up your providers you need to configure the ParaModal component to display the external wallets and authentication options to your users. You need to pass in the externalWallets and authLayout configuration options to the ParaModal component to control which of the wallets show in the modal that were specified in the provider configuration.

1

Set the modal props

<ParaModal
 externalWallets={["KEPLR", "LEAP",...]}
 authLayout={["AUTH_FULL","EXTERNAL_FULL"]}
 theme={{
   mode: "light",
   foregroundColor: "#000000",
   backgroundColor: "#FFFFFF",
   accentColor: "#007AFF"
 }}
 logo={yourLogoUrl}
 appName="Your App Name"
  para={para}
/>

Modal Props Config

Modal prop options for customizing the Para Modal are included below. For advanced customization options, refer to Customization Guide.

ParaModalProps
component
required

Examples

For an example of what the Para External Wallets Modal might look like in your application, check out our live demo:

For an example code implementation using Cosmos Wallets, check out our GitHub repository:

Next Steps

Now that you have integrated Cosmos wallets into your Para Modal, you can explore more advanced features like signing using the Para SDK with popular libraries like CosmJS.