Modular query system with extensions for each Cosmos SDK module. Enables strongly-typed queries for chain state including accounts, balances, staking, governance, and more.
Base query client that can be extended with module-specific query methods.
/**
* Base query client for ABCI queries
*/
class QueryClient {
constructor(cometClient: CometClient);
/** Create client with multiple extensions (overloaded 0-18 times) */
static withExtensions<T extends Record<string, any>[]>(
cometClient: CometClient,
...extensionSetups: QueryExtensionSetup<T>[]
): QueryClient & UnionToIntersection<T[number]>;
/** Execute raw ABCI query */
async queryAbci(path: string, request: Uint8Array, desiredHeight?: number): Promise<QueryAbciResponse>;
}
interface QueryAbciResponse {
/** Response data bytes */
readonly value: Uint8Array;
/** Block height at which query was executed */
readonly height: number;
}
interface ProtobufRpcClient {
/** Execute protobuf RPC request */
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
}
type QueryExtensionSetup<P> = (base: QueryClient) => P;
interface QueryStoreResponse {
/** Response data bytes */
readonly value: Uint8Array;
/** Block height at which query was executed */
readonly height: number;
/** Proof data (if requested) */
readonly proof?: Uint8Array;
}Usage Examples:
import { QueryClient, setupBankExtension, setupStakingExtension } from "@cosmjs/stargate";
import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
// Connect to tendermint
const tmClient = await Tendermint34Client.connect("https://rpc.cosmos.network:443");
// Create client with extensions
const client = QueryClient.withExtensions(
tmClient,
setupBankExtension,
setupStakingExtension
);
// Now client has bank and staking query methods
const balance = await client.bank.balance("cosmos1abc...", "uatom");
const validators = await client.staking.validators("", undefined);Utility functions for working with query clients and protobuf data.
/**
* Create a protobuf RPC client from a QueryClient
* @param base - Base QueryClient instance
* @returns ProtobufRpcClient for making raw protobuf requests
*/
function createProtobufRpcClient(base: QueryClient): ProtobufRpcClient;
/**
* Create pagination request for queries
* @param paginationKey - Optional pagination key from previous response
* @returns PageRequest for paginated queries
*/
function createPagination(paginationKey?: Uint8Array): PageRequest;
/**
* Decode Cosmos SDK decimal from protobuf
* @param input - String or bytes containing decimal value
* @returns Decimal with 18 fractional digits
*/
function decodeCosmosSdkDecFromProto(input: string | Uint8Array): Decimal;
/**
* Convert various integer types to bigint
* @param value - String, number, or Uint64 value
* @returns BigInt representation
*/
function longify(value: string | number | Uint64): bigint;Usage Examples:
import {
QueryClient,
createProtobufRpcClient,
createPagination,
decodeCosmosSdkDecFromProto
} from "@cosmjs/stargate";
// Create protobuf RPC client for custom queries
const rpcClient = createProtobufRpcClient(queryClient);
const response = await rpcClient.request(
"cosmos.bank.v1beta1.Query",
"Balance",
requestBytes
);
// Use pagination for large result sets
let nextKey: Uint8Array | undefined;
do {
const pagination = createPagination(nextKey);
const response = await client.bank.totalSupply(pagination.key);
// Process results...
nextKey = response.pagination?.nextKey;
} while (nextKey?.length);
// Decode SDK decimal values
const decimalValue = decodeCosmosSdkDecFromProto("123456789012345678");
console.log(decimalValue.toString()); // "0.123456789012345678"Authentication module queries for account information.
interface AuthExtension {
readonly auth: {
/** Get account information by address */
readonly account: (address: string) => Promise<Any | null>;
};
}
/** Setup auth extension for QueryClient */
function setupAuthExtension(base: QueryClient): AuthExtension;Usage Examples:
const client = QueryClient.withExtensions(tmClient, setupAuthExtension);
// Get account info
const accountAny = await client.auth.account("cosmos1abc123...");
if (accountAny) {
const account = accountFromAny(accountAny);
console.log(account.accountNumber, account.sequence);
}Bank module queries for token balances and supply information.
interface BankExtension {
readonly bank: {
/** Get single token balance */
readonly balance: (address: string, denom: string) => Promise<Coin>;
/** Get all token balances for an address */
readonly allBalances: (address: string) => Promise<Coin[]>;
/** Get total supply of all tokens */
readonly totalSupply: (paginationKey?: Uint8Array) => Promise<QueryTotalSupplyResponse>;
/** Get supply of a specific token */
readonly supplyOf: (denom: string) => Promise<Coin>;
/** Get metadata for a specific denomination */
readonly denomMetadata: (denom: string) => Promise<Metadata>;
/** Get metadata for all denominations */
readonly denomsMetadata: () => Promise<Metadata[]>;
};
}
/** Setup bank extension for QueryClient */
function setupBankExtension(base: QueryClient): BankExtension;Usage Examples:
const client = QueryClient.withExtensions(tmClient, setupBankExtension);
// Get specific balance
const atomBalance = await client.bank.balance("cosmos1abc...", "uatom");
// Get all balances
const allBalances = await client.bank.allBalances("cosmos1abc...");
// Get total supply
const totalSupply = await client.bank.totalSupply();
// Get denomination metadata
const atomMetadata = await client.bank.denomMetadata("uatom");Staking module queries for validators, delegations, and staking parameters.
type BondStatusString = "" | "BOND_STATUS_UNBONDED" | "BOND_STATUS_UNBONDING" | "BOND_STATUS_BONDED";
interface StakingExtension {
readonly staking: {
/** Get delegation between delegator and validator */
delegation: (delegatorAddress: string, validatorAddress: string) => Promise<QueryDelegationResponse>;
/** Get all delegations for a delegator */
delegatorDelegations: (delegatorAddress: string, paginationKey?: Uint8Array) => Promise<QueryDelegatorDelegationsResponse>;
/** Get unbonding delegations for a delegator */
delegatorUnbondingDelegations: (delegatorAddress: string, paginationKey?: Uint8Array) => Promise<QueryDelegatorUnbondingDelegationsResponse>;
/** Get specific validator for a delegator */
delegatorValidator: (delegatorAddress: string, validatorAddress: string) => Promise<QueryDelegatorValidatorResponse>;
/** Get all validators for a delegator */
delegatorValidators: (delegatorAddress: string, paginationKey?: Uint8Array) => Promise<QueryDelegatorValidatorsResponse>;
/** Get historical staking information */
historicalInfo: (height: number) => Promise<QueryHistoricalInfoResponse>;
/** Get staking module parameters */
params: () => Promise<QueryParamsResponse>;
/** Get bonded pool information */
pool: () => Promise<QueryPoolResponse>;
/** Get redelegations */
redelegations: (delegatorAddress: string, sourceValidatorAddress: string, destinationValidatorAddress: string, paginationKey?: Uint8Array) => Promise<QueryRedelegationsResponse>;
/** Get unbonding delegation between delegator and validator */
unbondingDelegation: (delegatorAddress: string, validatorAddress: string) => Promise<QueryUnbondingDelegationResponse>;
/** Get specific validator information */
validator: (validatorAddress: string) => Promise<QueryValidatorResponse>;
/** Get delegations for a specific validator */
validatorDelegations: (validatorAddress: string, paginationKey?: Uint8Array) => Promise<QueryValidatorDelegationsResponse>;
/** Get validators by bond status */
validators: (status: BondStatusString, paginationKey?: Uint8Array) => Promise<QueryValidatorsResponse>;
/** Get unbonding delegations for a validator */
validatorUnbondingDelegations: (validatorAddress: string, paginationKey?: Uint8Array) => Promise<QueryValidatorUnbondingDelegationsResponse>;
};
}
/** Setup staking extension for QueryClient */
function setupStakingExtension(base: QueryClient): StakingExtension;Usage Examples:
const client = QueryClient.withExtensions(tmClient, setupStakingExtension);
// Get all validators
const validators = await client.staking.validators("", undefined);
// Get specific validator
const validator = await client.staking.validator("cosmosvaloper1abc...");
// Get delegation
const delegation = await client.staking.delegation("cosmos1delegator...", "cosmosvaloper1validator...");
// Get delegator's delegations
const delegations = await client.staking.delegatorDelegations("cosmos1delegator...");Governance module queries for proposals, votes, and governance parameters.
type GovParamsType = "deposit" | "tallying" | "voting";
type GovProposalId = string | number | Uint64;
interface GovExtension {
readonly gov: {
/** Get governance parameters by type */
readonly params: (parametersType: GovParamsType) => Promise<QueryParamsResponse>;
/** Get proposals with optional filters */
readonly proposals: (proposalStatus: ProposalStatus, depositor: string, voter: string, paginationKey?: Uint8Array) => Promise<QueryProposalsResponse>;
/** Get specific proposal */
readonly proposal: (proposalId: GovProposalId) => Promise<QueryProposalResponse>;
/** Get deposits for a proposal */
readonly deposits: (proposalId: GovProposalId, paginationKey?: Uint8Array) => Promise<QueryDepositsResponse>;
/** Get specific deposit for a proposal */
readonly deposit: (proposalId: GovProposalId, depositorAddress: string) => Promise<QueryDepositResponse>;
/** Get tally results for a proposal */
readonly tally: (proposalId: GovProposalId) => Promise<QueryTallyResultResponse>;
/** Get votes for a proposal */
readonly votes: (proposalId: GovProposalId, paginationKey?: Uint8Array) => Promise<QueryVotesResponse>;
/** Get specific vote for a proposal */
readonly vote: (proposalId: GovProposalId, voterAddress: string) => Promise<QueryVoteResponse>;
};
}
/** Setup gov extension for QueryClient */
function setupGovExtension(base: QueryClient): GovExtension;Usage Examples:
const client = QueryClient.withExtensions(tmClient, setupGovExtension);
// Get all proposals
const proposals = await client.gov.proposals(ProposalStatus.PROPOSAL_STATUS_UNSPECIFIED, "", "", undefined);
// Get specific proposal
const proposal = await client.gov.proposal(1);
// Get tally for proposal
const tally = await client.gov.tally(1);
// Get votes for proposal
const votes = await client.gov.votes(1);Distribution module queries for rewards and distribution parameters.
interface DistributionExtension {
readonly distribution: {
/** Get distribution module parameters */
params: () => Promise<QueryParamsResponse>;
/** Get validator outstanding rewards */
validatorOutstandingRewards: (validatorAddress: string) => Promise<QueryValidatorOutstandingRewardsResponse>;
/** Get validator commission */
validatorCommission: (validatorAddress: string) => Promise<QueryValidatorCommissionResponse>;
/** Get validator slashes */
validatorSlashes: (validatorAddress: string, startingHeight: number, endingHeight: number, paginationKey?: Uint8Array) => Promise<QueryValidatorSlashesResponse>;
/** Get delegation rewards */
delegationRewards: (delegatorAddress: string, validatorAddress: string) => Promise<QueryDelegationRewardsResponse>;
/** Get total delegation rewards */
delegationTotalRewards: (delegatorAddress: string) => Promise<QueryDelegationTotalRewardsResponse>;
/** Get delegator validators */
delegatorValidators: (delegatorAddress: string) => Promise<QueryDelegatorValidatorsResponse>;
/** Get delegator withdraw address */
delegatorWithdrawAddress: (delegatorAddress: string) => Promise<QueryDelegatorWithdrawAddressResponse>;
/** Get community pool */
communityPool: () => Promise<QueryCommunityPoolResponse>;
};
}
/** Setup distribution extension for QueryClient */
function setupDistributionExtension(base: QueryClient): DistributionExtension;Transaction module queries for transaction information and simulation.
interface TxExtension {
readonly tx: {
/** Get transaction by hash */
getTx: (txId: string) => Promise<GetTxResponse>;
/** Simulate transaction execution */
simulate: (messages: readonly Any[], memo: string | undefined, signer: Pubkey, sequence: number) => Promise<SimulateResponse>;
};
}
/** Setup tx extension for QueryClient */
function setupTxExtension(base: QueryClient): TxExtension;Inter-Blockchain Communication module queries.
interface IbcExtension {
readonly ibc: {
/** IBC client queries */
readonly client: {
/** Get client state */
clientState: (clientId: string) => Promise<QueryClientStateResponse>;
/** Get client states */
clientStates: (paginationKey?: Uint8Array) => Promise<QueryClientStatesResponse>;
/** Get consensus state */
consensusState: (clientId: string, revisionNumber: number, revisionHeight: number, latestHeight?: boolean) => Promise<QueryConsensusStateResponse>;
};
/** IBC connection queries */
readonly connection: {
/** Get connection */
connection: (connectionId: string) => Promise<QueryConnectionResponse>;
/** Get connections */
connections: (paginationKey?: Uint8Array) => Promise<QueryConnectionsResponse>;
/** Get client connections */
clientConnections: (clientId: string) => Promise<QueryClientConnectionsResponse>;
};
/** IBC channel queries */
readonly channel: {
/** Get channel */
channel: (portId: string, channelId: string) => Promise<QueryChannelResponse>;
/** Get channels */
channels: (paginationKey?: Uint8Array) => Promise<QueryChannelsResponse>;
/** Get connection channels */
connectionChannels: (connection: string, paginationKey?: Uint8Array) => Promise<QueryConnectionChannelsResponse>;
};
/** IBC transfer queries */
readonly transfer: {
/** Get denomination trace */
denomTrace: (hash: string) => Promise<QueryDenomTraceResponse>;
/** Get denomination traces */
denomTraces: (paginationKey?: Uint8Array) => Promise<QueryDenomTracesResponse>;
/** Get transfer parameters */
params: () => Promise<QueryParamsResponse>;
};
};
}
/** Setup IBC extension for QueryClient */
function setupIbcExtension(base: QueryClient): IbcExtension;Mint module queries for inflation and mint parameters.
interface MintExtension {
readonly mint: {
/** Get mint module parameters */
params: () => Promise<QueryParamsResponse>;
/** Get current inflation rate */
inflation: () => Promise<QueryInflationResponse>;
/** Get annual provisions */
annualProvisions: () => Promise<QueryAnnualProvisionsResponse>;
};
}
type MintParams = {
/** The denomination of the token being minted */
mintDenom: string;
/** Target annual inflation rate */
inflationRateChange: string;
/** Maximum annual inflation rate */
inflationMax: string;
/** Minimum annual inflation rate */
inflationMin: string;
/** Target bonded token ratio */
goalBonded: string;
/** Number of blocks per year */
blocksPerYear: bigint;
};
/** Setup mint extension for QueryClient */
function setupMintExtension(base: QueryClient): MintExtension;Authorization module queries for grants and permissions.
interface AuthzExtension {
readonly authz: {
/** Get grants between granter and grantee for specific message type */
readonly grants: (granter: string, grantee: string, msgTypeUrl: string, paginationKey?: Uint8Array) => Promise<QueryGrantsResponse>;
/** Get all grants for a grantee */
readonly granteeGrants: (grantee: string, paginationKey?: Uint8Array) => Promise<QueryGranteeGrantsResponse>;
/** Get all grants by a granter */
readonly granterGrants: (granter: string, paginationKey?: Uint8Array) => Promise<QueryGranterGrantsResponse>;
};
}
/** Setup authz extension for QueryClient */
function setupAuthzExtension(base: QueryClient): AuthzExtension;Fee grant module queries for allowances.
interface FeegrantExtension {
readonly feegrant: {
/** Get fee allowance between granter and grantee */
readonly allowance: (granter: string, grantee: string) => Promise<QueryAllowanceResponse>;
/** Get all allowances for a grantee */
readonly allowances: (grantee: string, paginationKey?: Uint8Array) => Promise<QueryAllowancesResponse>;
};
}
/** Setup feegrant extension for QueryClient */
function setupFeegrantExtension(base: QueryClient): FeegrantExtension;Slashing module queries for validator signing information.
interface SlashingExtension {
readonly slashing: {
/** Get signing info for a specific validator */
signingInfo: (consAddress: string) => Promise<QuerySigningInfoResponse>;
/** Get signing info for all validators */
signingInfos: (paginationKey?: Uint8Array) => Promise<QuerySigningInfosResponse>;
/** Get slashing module parameters */
params: () => Promise<QueryParamsResponse>;
};
}
/** Setup slashing extension for QueryClient */
function setupSlashingExtension(base: QueryClient): SlashingExtension;/** Create pagination request object */
function createPagination(paginationKey?: Uint8Array): PageRequest;
/** Create protobuf RPC client from QueryClient */
function createProtobufRpcClient(base: QueryClient): ProtobufRpcClient;
/** Convert string or number to bigint */
function longify(value: string | number | Uint64): bigint;
/** Decode Cosmos SDK decimal from protobuf */
function decodeCosmosSdkDecFromProto(input: string | Uint8Array): Decimal;
/** Convert address string to address bytes */
function toAccAddress(address: string): Uint8Array;interface SearchPair {
/** Search key */
readonly key: string;
/** Search value */
readonly value: string | number | bigint;
}
/** Transaction search query (string or key-value pairs) */
type SearchTxQuery = string | readonly SearchPair[];
/** Type guard for SearchPair array */
function isSearchTxQueryArray(query: SearchTxQuery): query is readonly SearchPair[];Usage Examples:
// String query
const stringQuery = "message.sender='cosmos1abc...'";
// Key-value query
const kvQuery = [
{ key: "message.sender", value: "cosmos1abc..." },
{ key: "transfer.amount", value: "1000000" }
];
// Search transactions
const txs = await client.searchTx(stringQuery);
const moreTxs = await client.searchTx(kvQuery);