> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getpara.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup Cosmos Libraries

> Install and configure CosmJS for use with Para SDK on Cosmos chains

export const Link = ({href, label, newTab = false}) => {
  const [isHovered, setIsHovered] = useState(false);
  return <a href={href} target={newTab ? '_blank' : '_self'} rel={newTab ? 'noopener noreferrer' : undefined} className="not-prose inline-block relative text-black font-semibold cursor-pointer border-b-0 no-underline" onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)}>
      {label}
      <span className={`absolute left-0 bottom-0 w-full rounded-sm bg-gradient-to-r from-orange-600 to-purple-600 transition-all duration-300 ${isHovered ? 'h-0.5' : 'h-px'}`} />
    </a>;
};

Learn how to set up <Link href="https://github.com/cosmos/cosmjs" label="CosmJS" /> with Para SDK to interact with Cosmos-based blockchains.

## Prerequisites

<Card title="Para Setup Required" description="Set up Para instance and authenticate users first" href="/v3/react-native/quickstart" horizontal />

<Tabs>
  <Tab title="Proto Signer">
    Use the Proto signer for transaction operations like sending tokens, staking, and IBC transfers.

    ## Install

    ```bash theme={null}
    npm install @getpara/react-native-wallet @getpara/cosmjs-v0-integration @cosmjs/stargate
    ```

    <Info>`@getpara/cosmjs-v0-integration` is a separate package — install it alongside `@getpara/react-native-wallet`.</Info>

    ## Usage

    <Tabs>
      <Tab title="Hook (React)">
        Use the <Link label="useParaCosmjsProtoSigner" href="/v3/react-native/guides/hooks/use-para-cosmjs-proto-signer" /> hook to create a CosmJS `OfflineDirectSigner` for your user's Para embedded wallet or external wallet. The <Link label="useParaCosmjsSignAndBroadcast" href="/v3/react-native/guides/hooks/use-para-cosmjs-sign-and-broadcast" /> hook wraps `signAndBroadcast` in a React Query mutation.

        ```tsx theme={null}
        import { useParaCosmjsProtoSigner, useParaCosmjsSignAndBroadcast } from "@getpara/react-native-wallet/cosmos";
        import { SigningStargateClient, coins } from "@cosmjs/stargate";
        import { useState, useEffect } from "react";
        import { Text, TouchableOpacity } from "react-native";

        const RPC_URL = "https://rpc.cosmos.directory/cosmoshub";

        function SendTokens() {
          const { protoSigner, isLoading } = useParaCosmjsProtoSigner();
          const [client, setClient] = useState<SigningStargateClient>();

          useEffect(() => {
            if (protoSigner) {
              SigningStargateClient.connectWithSigner(RPC_URL, protoSigner).then(setClient);
            }
          }, [protoSigner]);

          const { signAndBroadcastAsync, isPending } = useParaCosmjsSignAndBroadcast(protoSigner, client);

          const handleSend = async () => {
            const result = await signAndBroadcastAsync({
              messages: [{ typeUrl: "/cosmos.bank.v1beta1.MsgSend", value: {
                fromAddress: protoSigner!.address,
                toAddress: "cosmos1...",
                amount: coins(1000000, "uatom"),
              }}],
              fee: { amount: coins(5000, "uatom"), gas: "200000" },
            });
            console.log("Tx hash:", result.transactionHash);
          };

          if (isLoading) return <Text>Loading...</Text>;
          return (
            <TouchableOpacity onPress={handleSend} disabled={isPending}>
              <Text>{isPending ? "Broadcasting..." : "Send 1 ATOM"}</Text>
            </TouchableOpacity>
          );
        }
        ```

        ### Wallet Resolution

        When no `address` or `walletId` is passed, the hook resolves the wallet in this order:

        1. **Selected wallet** — if the user selected a Cosmos wallet in the UI. If there is only one Cosmos wallet in the session, it is already selected by default
        2. **First Cosmos wallet** — the first available Cosmos wallet on the account

        To target a specific wallet:

        ```tsx theme={null}
        const { protoSigner } = useParaCosmjsProtoSigner({
          address: "cosmos1...",  // or walletId: "uuid-..."
          prefix: "osmo",  // optional chain prefix, defaults to "cosmos"
        });
        ```
      </Tab>

      <Tab title="Direct (Non-React)">
        Use `createParaProtoSigner` to create a signer directly.

        ```typescript theme={null}
        import { createParaProtoSigner } from "@getpara/cosmjs-v0-integration";
        import { SigningStargateClient } from "@cosmjs/stargate";
        import Para from "@getpara/core-sdk";

        const para = new Para("YOUR_API_KEY");
        // Authenticate first...

        const signer = createParaProtoSigner({ para, prefix: "cosmos" });
        const client = await SigningStargateClient.connectWithSigner(rpcUrl, signer);
        ```

        ### Wallet Resolution

        When no `address` or `walletId` is passed, the factory picks the first available Cosmos wallet. To target a specific wallet:

        ```typescript theme={null}
        const signer = createParaProtoSigner({ para, prefix: "cosmos", address: "cosmos1..." });
        ```
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Amino Signer">
    Use the Amino signer for message signing (ADR-036) and authentication flows.

    ## Install

    ```bash theme={null}
    npm install @getpara/react-native-wallet @getpara/cosmjs-v0-integration @cosmjs/amino
    ```

    ## Usage

    <Tabs>
      <Tab title="Hook (React)">
        Use the <Link label="useParaCosmjsAminoSigner" href="/v3/react-native/guides/hooks/use-para-cosmjs-amino-signer" /> hook to create a CosmJS `OfflineAminoSigner` for message signing (ADR-036) and authentication flows. The <Link label="useParaCosmjsSignAndBroadcast" href="/v3/react-native/guides/hooks/use-para-cosmjs-sign-and-broadcast" /> mutation hook also accepts an amino signer.

        ```tsx theme={null}
        import { useParaCosmjsAminoSigner } from "@getpara/react-native-wallet/cosmos";
        import { makeSignDoc } from "@cosmjs/amino";
        import { Text, Button } from "react-native";

        function SignMessage() {
          const { aminoSigner, isLoading } = useParaCosmjsAminoSigner();
          const address = aminoSigner?.address;

          const handleSign = async () => {
            if (!aminoSigner || !address) return;
            const signDoc = makeSignDoc(
              [{ type: "sign/MsgSignData", value: { signer: address, data: btoa("Hello!") } }],
              { amount: [], gas: "0" }, "cosmoshub-4", "", 0, 0,
            );
            const { signature } = await aminoSigner.signAmino(address, signDoc);
            console.log("Signature:", signature.signature);
          };

          if (isLoading) return <Text>Loading...</Text>;
          return <Button title="Sign Message" onPress={handleSign} />;
        }
        ```

        Wallet resolution works the same as the Proto signer hook.
      </Tab>

      <Tab title="Direct (Non-React)">
        ```typescript theme={null}
        import { createParaAminoSigner } from "@getpara/cosmjs-v0-integration";

        const signer = createParaAminoSigner({ para, prefix: "cosmos" });
        ```
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

## Metro Configuration

`@cosmjs/crypto` depends on `libsodium-wrappers-sumo`, a WASM-based cryptography library that is incompatible with React Native. Since Para handles signing server-side via MPC, this library is not needed at runtime. However, Metro will still bundle it and crash when the WASM module loads.

To fix this, stub out the module in your `metro.config.js` using a custom `resolveRequest`:

```js metro.config.js theme={null}
const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

const emptyModule = require.resolve('./lib/empty-module.js');

// libsodium-wrappers-sumo uses WASM which doesn't work in React Native.
// Since Para signs via MPC, this module is not needed.
// We must use resolveRequest (not extraNodeModules) because the package
// is installed in node_modules and extraNodeModules only acts as a fallback.
const stubbedModules = new Set(['libsodium-wrappers-sumo']);
const originalResolveRequest = config.resolver.resolveRequest;
config.resolver.resolveRequest = (context, moduleName, platform) => {
  if (stubbedModules.has(moduleName)) {
    return { type: 'sourceFile', filePath: emptyModule };
  }
  if (originalResolveRequest) {
    return originalResolveRequest(context, moduleName, platform);
  }
  return context.resolveRequest(context, moduleName, platform);
};

module.exports = config;
```

Create the empty module stub:

```js lib/empty-module.js theme={null}
module.exports = {};
```

<Warning>
  Using `extraNodeModules` will **not** work for this case. Metro's `extraNodeModules` only acts as a
  fallback when a module can't be found. Since `libsodium-wrappers-sumo` is installed as a transitive
  dependency of `@cosmjs/crypto`, Metro resolves it from `node_modules` before checking
  `extraNodeModules`. The `resolveRequest` override intercepts resolution before that happens.
</Warning>

## Next Steps

<CardGroup cols={3}>
  <Card title="Configure RPC" description="Set up custom RPC endpoints for different chains" href="/v3/react-native/guides/web3-operations/cosmos/configure-rpc" icon="server" />

  <Card title="Query Balances" description="Check token balances on Cosmos chains" href="/v3/react-native/guides/web3-operations/cosmos/query-balances" icon="coins" />

  <Card title="Send Tokens" description="Transfer tokens between accounts" href="/v3/react-native/guides/web3-operations/cosmos/send-tokens" icon="paper-plane" />
</CardGroup>
