Cosmos - gRPC

Cosmos gRPC is a high-performance, strongly-typed interface for interacting with Cosmos SDK chains using Protocol Buffers and HTTP/2. This guide shows how to connect to Tatum’s Cosmos gRPC endpoint, authenticate with an API key, set up a Node.js environment with required .proto files, and execute common queries like retrieving balances or staking data.

Cosmos gRPC provides a high-performance, strongly-typed interface for interacting with the Cosmos Hub and other SDK-based chains. Unlike REST, gRPC uses Protocol Buffers and HTTP/2, making it the industry standard for building scalable wallets, indexers, and backend services.

With Tatum’s Cosmos gRPC endpoint, you can:

Cosmos Mainnet gRPC endpoint

For Tendermint RPC and the full network list, see Cosmos RPC.

Test Cosmos in Postman

Use the collections below to try gRPC calls against Tatum’s Cosmos gateway.

Cosmos Mainnet gRPC Postman collection

  1. Get your API key: Use your standard Tatum API key. For gRPC, this is passed via the x-api-key header (see Authentication below).
  2. Import the collection: Open Postman using the button below to access the Cosmos gRPC-over-HTTPS collection.
  3. Configure variables: Set host and API key per the collection’s instructions
  4. Start testing: Call standard Cosmos SDK methods (for example, GetNodeInfo or AllBalances) as provided in the collection.

Getting Started

Set Up Your Environment

This guide uses Node.js with macOS to interact with the Cosmos gRPC gateway. Because gRPC is strictly typed, you must manage .proto files to define the communication contract.

  1. Install Node.js (version 18+)
    brew install node
    node -v
  2. Install grpcurl:
    Highly recommended for smoke testing your endpoint and API key.
    brew install grpcurl
  3. Create your project and install dependencies:
    mkdir tatum-cosmos-grpc && cd tatum-cosmos-grpc
    npm init -y
    npm install @grpc/grpc-js @grpc/proto-loader
  4. Set up Protobuf definitions:
    Cosmos gRPC requires service definitions. Create the directory structure in your home folder (~) or project root:
    # Create directory structure
    mkdir -p proto/cosmos/bank/v1beta1 \
             proto/cosmos/base/v1beta1 \
             proto/cosmos/base/query/v1beta1 \
             proto/cosmos/msg/v1 \
             proto/cosmos/query/v1 \
             proto/cosmos_proto \
             proto/google/api \
             proto/gogoproto \
             proto/amino
    
    # Download Core Bank definitions
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/cosmos/bank/v1beta1/query.proto > proto/cosmos/bank/v1beta1/query.proto
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/cosmos/bank/v1beta1/bank.proto > proto/cosmos/bank/v1beta1/bank.proto
    
    # Download Base, Msg, & Query dependencies
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/cosmos/base/v1beta1/coin.proto > proto/cosmos/base/v1beta1/coin.proto
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/cosmos/base/query/v1beta1/pagination.proto > proto/cosmos/base/query/v1beta1/pagination.proto
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/cosmos/msg/v1/msg.proto > proto/cosmos/msg/v1/msg.proto
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/cosmos/query/v1/query.proto > proto/cosmos/query/v1/query.proto
    
    # Download Third-party Metadata (Critical for resolution)
    curl -s https://raw.githubusercontent.com/googleapis/googleapis/master/google/api/annotations.proto > proto/google/api/annotations.proto
    curl -s https://raw.githubusercontent.com/googleapis/googleapis/master/google/api/http.proto > proto/google/api/http.proto
    curl -s https://raw.githubusercontent.com/cosmos/gogoproto/main/gogoproto/gogo.proto > proto/gogoproto/gogo.proto
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-proto/main/proto/cosmos_proto/cosmos.proto > proto/cosmos_proto/cosmos.proto
    curl -s https://raw.githubusercontent.com/cosmos/cosmos-sdk/main/proto/amino/amino.proto > proto/amino/amino.proto
  5. Verify your connection with grpcurl:
    • Tatum-specific: The gRPC endpoint is cosmos-mainnet-grpc.gateway.tatum.io:443 (Mainnet).
    • Authentication: uses the x-api-key header passed as metadata. Port 443 is required for SSL.
    grpcurl \
      -H "x-api-key: YOUR_API_KEY" \
      cosmos-mainnet-grpc.gateway.tatum.io:443 \
      cosmos.base.tendermint.v1beta1.Service/GetNodeInfo
    Expected response format:
    {
      "defaultNodeInfo": {
        "protocolVersion": {
          "p2p": "8",
          "block": "11"
        },
        "defaultNodeId": "0b8bf4c894418453cfeb45d57eec6036bb863cff",
        "listenAddr": "tcp://0.0.0.0:26656",
        "network": "cosmoshub-4",
        "version": "0.38.19",
        "channels": "QCAhIiMwOGBhAA==",
        "moniker": "ndl-archival-b@eu",
        "other": {
          "txIndex": "on",
          "rpcAddress": "tcp://0.0.0.0:26657"
        }
      },
    //[...]
    🚧

    Attention

    • If you receive a JSON response containing node information, your endpoint and API key are working correctly.
    • If this step fails, no amount of Node.js code will fix it. Confirm your environment setup and credentials.

Quick start checklist

Before making your first production call, confirm:

  • Successful Smoke Test: You can call GetNodeInfo successfully using grpcurl with the x-api-key header.
  • Full Dependency Chain: Your proto folder contains cosmos_proto, amino, and gogoproto folders. Without these, the loader will fail on ENOENT errors.
  • SSL Configuration: You are using grpc.credentials.createSsl() to connect via port 443 (non-TLS connections will be rejected).
  • Error Handling: Your application handles gRPC-specific error codes (e.g., Code 14: Unavailable for network issues or Code 16: Unauthenticated for key issues).
  • Pro-Tip: Why all the files? Cosmos Protobufs are modular. The Bank module imports the Base module, which in turn imports cosmos_proto for metadata and amino for legacy compatibility. The @grpc/proto-loader must have all these files locally to build the request "contract."

Authentication in Node.js

  1. Get the Cosmos gRPC URL
  2. Get an API Key from the Tatum Dashboard.
  3. Configure your client with the endpoint and x-api-key:
const grpc = require('@grpc/grpc-js');

const ENDPOINT = "cosmos-mainnet-grpc.gateway.tatum.io:443";
const API_KEY = "YOUR_API_KEY";

const meta = new grpc.Metadata();
meta.add('x-api-key', API_KEY);

Example Requests

Retrieve account balances

The following script opens a connection to the Bank module to query a wallet's current balances.

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const path = require('path');

const PROTO_FILE = path.join(__dirname, 'proto/cosmos/bank/v1beta1/query.proto');

async function main() {
  const packageDefinition = protoLoader.loadSync(PROTO_FILE, {
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true,
    includeDirs: [path.join(__dirname, 'proto')]
  });

  const cosmosProto = grpc.loadPackageDefinition(packageDefinition).cosmos.bank.v1beta1;
  const client = new cosmosProto.Query('cosmos-mainnet-grpc.gateway.tatum.io:443', grpc.credentials.createSsl());

  const meta = new grpc.Metadata();
  meta.add('x-api-key', 'YOUR_API_KEY');

  const request = { address: "cosmos15480746979255644783" };

  client.AllBalances(request, meta, (err, response) => {
    if (err) {
      console.error("RPC Error:", err.message);
      return;
    }
    console.log("Balances:", JSON.stringify(response.balances, null, 2));
  });
}

main().catch(console.error);

Retrieve all balances

Use this to fetch the total coin balance for an account across all denominations.

const request = {
  "address": "cosmos1..."
};

Retrieve staking delegations

Requires cosmos/staking/v1beta1/query.proto. Use this to monitor where an account has bonded its ATOM.

const request = {
  "delegator_addr": "cosmos1..."
};

Troubleshooting & Dependencies

Working with Cosmos gRPC in Node.js often involves managing a complex web of modular dependencies. If your script fails, it is likely due to one of the following:

  1. The ENOENT (Missing File) Loop

    Because .proto files use import statements, loading a single file like query.proto triggers a chain reaction.

    • The Symptom: Error: ENOENT: no such file or directory pointing to cosmos/msg/v1/msg.proto or pagination.proto.
    • The Cause: One of the "hidden" dependencies required by the Bank module is missing from your local directory.
    • The Fix: Ensure your proto directory exactly matches the nested structure in the setup guide. If the loader asks for a new file, you must create the folder and curl the raw file from the official Cosmos SDK GitHub.
  2. Common Connection Issues

    • Auth failures: Ensure the header name is exactly x-api-key and you are using the correct Mainnet/Testnet key.
    • Port 443 & SSL: Tatum requires SSL on port 443. Insecure connections (standard on local nodes via port 9090) will be rejected. Always use grpc.credentials.createSsl().
    • Timeouts: gRPC calls may require a deadline. Use client.waitForReady() to ensure the connection is established before querying.