Documentation Index
Fetch the complete documentation index at: https://docs.kiruse.dev/llms.txt
Use this file to discover all available pages before exploring further.
There are currently four types of queries in the CosmWasm integration. Three of these queries are
direct wrappers of RPC methods. The last is a non-RPC query for the CW2 standard:
Smart Queries
Smart Queries are the queries a developer defines as part of their smart contract. They are
typically JSON-encoded by convention, but a smart contract developer is technically free to choose
any other format - though they should prepare for the backlash from the wider community. ;)
import { Apophis, Cosmos } from '@apophis-sdk/cosmos';
import { CosmWasm, DefaultCosmWasmMiddlewares } from '@apophis-sdk/cosmwasm';
Apophis.use(...DefaultCosmWasmMiddlewares);
const network = await Cosmos.getNetworkFromRegistry('neutrontestnet');
const contract = 'neutron1...';
const data = await CosmWasm.query.smart<MyResponse>(network, contract, {
myQuery: {},
});
console.log(data); // typically, the response is already JSON-decoded by the RPC
Raw Queries
Raw Queries are extremely low-level and require knowledge of the storage layout of a smart
contract. In CosmWasm, state is stored as pairs of binary keys and binary serialized values. As
most smart contracts use cw-storage-plus, the format
of these keys is typically the same, and Apophis can simplify raw storage lookup. If you need to
access non-standard raw storage, you can still use the Cosmos.rest(network) endpoint directly.
import { Apophis, Cosmos } from '@apophis-sdk/cosmos';
import { CosmWasm, DefaultCosmWasmMiddlewares } from '@apophis-sdk/cosmwasm';
Apophis.use(...DefaultCosmWasmMiddlewares);
const network = await Cosmos.getNetworkFromRegistry('neutrontestnet');
const contract = 'neutron1...';
const data = await CosmWasm.query.raw(network, contract, ['my_state_key']);
console.log(data); // this data is binary. its meaning is specific to the smart contract.
The beauty of raw queries is that you can query any state item of a smart contract, including data
that it does not expose via smart queries. Often, smart contract developers expose only a small
surface of smart queries simply because they don’t think the additional data is interesting to the
consumer, or it would just blow out of proportion. With raw queries, you can query any state item
you’re interested in.
Apophis makes this vastly easier. State storage is a binary key-value pair. The key is typically a
specially encoded string array. Apophis can both encode and decode this string array for you. Or,
you can pass in a Uint8Array directly and it will be used as-is, in case your smart contract does
not use cw-storage-plus and thus does not adhere to the standard format.
State Queries
State Queries are related to Raw Queries. They facilitate iterating over the entire low-level
storage of a smart contract with pagination. However, as items of lists and maps are stored in
cw-storage-plus, the format of these keys is typically
the same, and Apophis can simplify raw storage lookup. If you need to
access non-standard raw storage, you can still use the Cosmos.rest(network) endpoint directly.
import { Apophis, Cosmos } from '@apophis-sdk/cosmos';
import { CosmWasm, DefaultCosmWasmMiddlewares } from '@apophis-sdk/cosmwasm';
Apophis.use(...DefaultCosmWasmMiddlewares);
const network = await Cosmos.getNetworkFromRegistry('neutrontestnet');
const contract = 'neutron1...';
let pagination: PaginationResponse;
do {
const response = await CosmWasm.query.state(network, contract, pagination?.nextKey);
console.log(response.items); // this data is binary. its meaning is specific to the smart contract.
pagination = response.pagination;
} while (pagination.nextKey);
State Queries are very rarely needed. They are an incredibly verbose way to query data, as the RPC
iterates over ALL state items of a smart contract, which includes all entries in a map. On its own,
it likely has no real use for Dapps, but it can be incredibly useful for debugging, introspection,
and reverse engineering.
About Key Paths
CosmWasm uses a simple key/value storage system - at the time of writing,
this was LevelDB. However, to support complex data structures
like maps and lists, the keys are prefixed and encoded to binary.
This encoding follows a simple algorithm conveniently accessible through 3 methods:
import { CosmWasm } from '@apophis-sdk/cosmwasm';
const key = CosmWasm.encodeKeypath(['array-prefix', 'item-index']);
const decoded = CosmWasm.decodeKeypath(key);
const maybeDecoded = CosmWasm.decodeKeypathMaybe(key);
encodeKeypath naturally encodes a keypath into a binary string. decodeKeypath is its inverse.
And decodeKeypathMaybe is a variant that returns null if the keypath is not valid rather than
throwing an error.
The encodeKeypath method is used under the hood by CosmWasm.query.raw.
Contract Info Queries
Contract Info Queries are non-RPC queries, i.e. they are not defined in the RPC directly but are
defined as a standard on a Raw Query through the CW2 standard.
CW2 defines the contract_info storage key, which contains the name and version of a smart
contract. Apophis simply fetches this value using its own Raw Query implementation. It contains
the name and version of the smart contract as defined by its developer (i.e. may contain untruths).
import { Apophis, Cosmos } from '@apophis-sdk/cosmos';
import { CosmWasm, DefaultCosmWasmMiddlewares } from '@apophis-sdk/cosmwasm';
Apophis.use(...DefaultCosmWasmMiddlewares);
const network = await Cosmos.getNetworkFromRegistry('neutrontestnet');
const contract = 'neutron1...';
const { contract, version } = await CosmWasm.query.contractInfo(network, contract);
console.log(contract, version);