diff --git a/packages/stargate/src/modules/authz/queries.ts b/packages/stargate/src/modules/authz/queries.ts index 0dd2b53b6d..08d1f2f837 100644 --- a/packages/stargate/src/modules/authz/queries.ts +++ b/packages/stargate/src/modules/authz/queries.ts @@ -35,12 +35,16 @@ export function setupAuthzExtension(base: QueryClient): AuthzExtension { return { authz: { grants: async (granter: string, grantee: string, msgTypeUrl: string, paginationKey?: Uint8Array) => { - return await queryService.Grants({ + // TODO: remove this proof of concept + rpc.setMetadata(new Map([["x-cosmos-block-height", "123"]])); + const resp = await queryService.Grants({ granter: granter, grantee: grantee, msgTypeUrl: msgTypeUrl, pagination: createPagination(paginationKey), }); + rpc.clearMetadata(); + return resp; }, granteeGrants: async (grantee: string, paginationKey?: Uint8Array) => { return await queryService.GranteeGrants({ diff --git a/packages/stargate/src/queryclient/utils.ts b/packages/stargate/src/queryclient/utils.ts index 4afa373935..52ee0ea5f4 100644 --- a/packages/stargate/src/queryclient/utils.ts +++ b/packages/stargate/src/queryclient/utils.ts @@ -1,5 +1,5 @@ import { fromAscii, fromBech32 } from "@cosmjs/encoding"; -import { Decimal, Uint64 } from "@cosmjs/math"; +import { Decimal, Uint53, Uint64 } from "@cosmjs/math"; import { PageRequest } from "cosmjs-types/cosmos/base/query/v1beta1/pagination"; import Long from "long"; @@ -25,15 +25,46 @@ export function createPagination(paginationKey?: Uint8Array): PageRequest | unde return paginationKey ? PageRequest.fromPartial({ key: paginationKey }) : undefined; } +/** + * This interface is more or less a copy of + * https://github.com/confio/cosmjs-types/blob/v0.6.1/src/helpers.ts#L180-L182. + * + * It needs to be compatible to the `Rpc` client expected by the query services + * auto-generated in cosmjs-types. + */ export interface ProtobufRpcClient { + // See https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md. + // To keep things simple, we only support one items per key here. + setMetadata(md: Map): void; + // A version of setMetadata that clears all elements + clearMetadata(): void; + // Returns a copy of the current metadata + getMetadata(): Map; request(service: string, method: string, data: Uint8Array): Promise; } export function createProtobufRpcClient(base: QueryClient): ProtobufRpcClient { + const metadata = new Map(); return { + setMetadata: (md: Map) => { + // Override metadata without changing the reference + metadata.clear(); + for (const [k, v] of md.entries()) { + metadata.set(k, v); + } + }, + clearMetadata: () => { + metadata.clear(); + }, + getMetadata: (): Map => { + const copies = Array.from(metadata.entries()); + return new Map(copies); + }, request: async (service: string, method: string, data: Uint8Array): Promise => { + const cosmosBlockHeight = metadata.get("x-cosmos-block-height"); + const queryHeight = cosmosBlockHeight ? Uint53.fromString(cosmosBlockHeight).toNumber() : undefined; const path = `/${service}/${method}`; - const response = await base.queryAbci(path, data, undefined); + const response = await base.queryAbci(path, data, queryHeight); return response.value; }, };