Create PoF for metadata handling in ProtobufRpcClient

This commit is contained in:
Simon Warta 2023-03-06 18:20:00 +01:00
parent 2b9b113f86
commit ed8ae0f982
2 changed files with 38 additions and 3 deletions

View File

@ -35,12 +35,16 @@ export function setupAuthzExtension(base: QueryClient): AuthzExtension {
return { return {
authz: { authz: {
grants: async (granter: string, grantee: string, msgTypeUrl: string, paginationKey?: Uint8Array) => { 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, granter: granter,
grantee: grantee, grantee: grantee,
msgTypeUrl: msgTypeUrl, msgTypeUrl: msgTypeUrl,
pagination: createPagination(paginationKey), pagination: createPagination(paginationKey),
}); });
rpc.clearMetadata();
return resp;
}, },
granteeGrants: async (grantee: string, paginationKey?: Uint8Array) => { granteeGrants: async (grantee: string, paginationKey?: Uint8Array) => {
return await queryService.GranteeGrants({ return await queryService.GranteeGrants({

View File

@ -1,5 +1,5 @@
import { fromAscii, fromBech32 } from "@cosmjs/encoding"; 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 { PageRequest } from "cosmjs-types/cosmos/base/query/v1beta1/pagination";
import Long from "long"; import Long from "long";
@ -25,15 +25,46 @@ export function createPagination(paginationKey?: Uint8Array): PageRequest | unde
return paginationKey ? PageRequest.fromPartial({ key: paginationKey }) : undefined; 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 { 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<string, string>): void;
// A version of setMetadata that clears all elements
clearMetadata(): void;
// Returns a copy of the current metadata
getMetadata(): Map<string, string>;
request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>; request(service: string, method: string, data: Uint8Array): Promise<Uint8Array>;
} }
export function createProtobufRpcClient(base: QueryClient): ProtobufRpcClient { export function createProtobufRpcClient(base: QueryClient): ProtobufRpcClient {
const metadata = new Map<string, string>();
return { return {
setMetadata: (md: Map<string, string>) => {
// Override metadata without changing the reference
metadata.clear();
for (const [k, v] of md.entries()) {
metadata.set(k, v);
}
},
clearMetadata: () => {
metadata.clear();
},
getMetadata: (): Map<string, string> => {
const copies = Array.from(metadata.entries());
return new Map(copies);
},
request: async (service: string, method: string, data: Uint8Array): Promise<Uint8Array> => { request: async (service: string, method: string, data: Uint8Array): Promise<Uint8Array> => {
const cosmosBlockHeight = metadata.get("x-cosmos-block-height");
const queryHeight = cosmosBlockHeight ? Uint53.fromString(cosmosBlockHeight).toNumber() : undefined;
const path = `/${service}/${method}`; const path = `/${service}/${method}`;
const response = await base.queryAbci(path, data, undefined); const response = await base.queryAbci(path, data, queryHeight);
return response.value; return response.value;
}, },
}; };