From 8763c88f30b6e133697434482f77a88b38a9c382 Mon Sep 17 00:00:00 2001 From: Milan Steiner <69144826+msteiner96@users.noreply.github.com> Date: Wed, 16 Mar 2022 11:14:14 +0100 Subject: [PATCH] Add Authz queries to QueryClient (#1089) * Add Authz queries to QueryClient * Rename 'pagination' to 'pagionationKey' * Typo in Changelog * Adding test for authz query * Fix Typo * Fix tests * Update packages/stargate/src/modules/authz/queries.spec.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Improve authz query test * Improve authz queries * Let's use a random address for grantee in tests * Beautify tests * Update packages/stargate/src/modules/authz/queries.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update packages/stargate/src/modules/authz/queries.spec.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> * Update packages/stargate/src/modules/authz/queries.spec.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- CHANGELOG.md | 2 + .../src/modules/authz/queries.spec.ts | 103 ++++++++++++++++++ .../stargate/src/modules/authz/queries.ts | 36 ++++++ packages/stargate/src/testutils.spec.ts | 8 +- 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 packages/stargate/src/modules/authz/queries.spec.ts create mode 100644 packages/stargate/src/modules/authz/queries.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ba8167b2bb..85f5b08142 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to dependencies. This should also reduce the bundle size as only the English wordlist is shipped. ([#966]) - @cosmjs/cli: Rename binary `cosmwasm-cli` to `cosmjs-cli` ([#1033]). +- @cosmjs/stargate: Added Authz queries. ([#1080]). - @cosmjs/stargate & @cosmjs/cosmwasm-stargate: Removed default types from AminoTypes. ([#1079]) - @cosmjs/cosmwasm-stargate: getCodes() automatically loops through all @@ -65,6 +66,7 @@ and this project adheres to [#1077]: https://github.com/cosmos/cosmjs/issues/1077 [#1078]: https://github.com/cosmos/cosmjs/issues/1078 [#1079]: https://github.com/cosmos/cosmjs/issues/1079 +[#1080]: https://github.com/cosmos/cosmjs/issues/1080 ### Removed diff --git a/packages/stargate/src/modules/authz/queries.spec.ts b/packages/stargate/src/modules/authz/queries.spec.ts new file mode 100644 index 0000000000..2cf3316bbe --- /dev/null +++ b/packages/stargate/src/modules/authz/queries.spec.ts @@ -0,0 +1,103 @@ +import { makeCosmoshubPath } from "@cosmjs/amino"; +import { coins, DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { Tendermint34Client } from "@cosmjs/tendermint-rpc"; +import { assertDefined, sleep } from "@cosmjs/utils"; +import { GenericAuthorization } from "cosmjs-types/cosmos/authz/v1beta1/authz"; + +import { QueryClient } from "../../queryclient"; +import { SigningStargateClient } from "../../signingstargateclient"; +import { assertIsDeliverTxSuccess } from "../../stargateclient"; +import { + defaultSigningClientOptions, + faucet, + makeRandomAddress, + pendingWithoutSimapp44, + simapp, + simapp44Enabled, +} from "../../testutils.spec"; +import { AuthzExtension, setupAuthzExtension } from "./queries"; + +async function makeClientWithAuthz( + rpcUrl: string, +): Promise<[QueryClient & AuthzExtension, Tendermint34Client]> { + const tmClient = await Tendermint34Client.connect(rpcUrl); + return [QueryClient.withExtensions(tmClient, setupAuthzExtension), tmClient]; +} + +describe("AuthzExtension", () => { + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + const granter1Address = faucet.address1; + const grantee1Address = makeRandomAddress(); + + const grantedMsg = "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"; + + beforeAll(async () => { + if (simapp44Enabled()) { + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(faucet.mnemonic, { + // Use address 1 and 2 instead of 0 to avoid conflicts with other delegation tests + // This must match `voterAddress` above. + hdPaths: [makeCosmoshubPath(1), makeCosmoshubPath(2)], + }); + const client = await SigningStargateClient.connectWithSigner( + simapp.tendermintUrl, + wallet, + defaultSigningClientOptions, + ); + + const grantMsg = { + typeUrl: "/cosmos.authz.v1beta1.MsgGrant", + value: { + granter: granter1Address, + grantee: grantee1Address, + grant: { + authorization: { + typeUrl: "/cosmos.authz.v1beta1.GenericAuthorization", + value: GenericAuthorization.encode( + GenericAuthorization.fromPartial({ + msg: grantedMsg, + }), + ).finish(), + }, + }, + }, + }; + const grantResult = await client.signAndBroadcast( + granter1Address, + [grantMsg], + defaultFee, + "Test grant for simd", + ); + assertIsDeliverTxSuccess(grantResult); + await sleep(75); // wait until transactions are indexed + + client.disconnect(); + } + }); + + describe("grants", () => { + it("works", async () => { + pendingWithoutSimapp44(); + const [client, tmClient] = await makeClientWithAuthz(simapp.tendermintUrl); + const response = await client.authz.grants(granter1Address, grantee1Address, ""); + expect(response.grants.length).toEqual(1); + const grant = response.grants[0]; + + // Needs to respond with a grant + assertDefined(grant.authorization); + + // Needs to be GenericAuthorization to decode it below + expect(grant.authorization.typeUrl).toEqual("/cosmos.authz.v1beta1.GenericAuthorization"); + + // Decode the message + const msgDecoded = GenericAuthorization.decode(grant.authorization.value).msg; + + // Check if its the same one then we granted + expect(msgDecoded).toEqual(grantedMsg); + + tmClient.disconnect(); + }); + }); +}); diff --git a/packages/stargate/src/modules/authz/queries.ts b/packages/stargate/src/modules/authz/queries.ts new file mode 100644 index 0000000000..9c548e6fe4 --- /dev/null +++ b/packages/stargate/src/modules/authz/queries.ts @@ -0,0 +1,36 @@ +import { QueryClientImpl, QueryGrantsResponse } from "cosmjs-types/cosmos/authz/v1beta1/query"; + +import { createPagination, createProtobufRpcClient, QueryClient } from "../../queryclient"; + +export interface AuthzExtension { + readonly authz: { + readonly grants: ( + granter: string, + grantee: string, + msgTypeUrl: string, + paginationKey?: Uint8Array, + ) => Promise; + }; +} + +export function setupAuthzExtension(base: QueryClient): AuthzExtension { + // Use this service to get easy typed access to query methods + // This cannot be used for proof verification + const rpc = createProtobufRpcClient(base); + const queryService = new QueryClientImpl(rpc); + + return { + authz: { + grants: async (granter: string, grantee: string, msgTypeUrl: string, paginationKey?: Uint8Array) => { + const response = await queryService.Grants({ + granter: granter, + grantee: grantee, + msgTypeUrl: msgTypeUrl, + pagination: createPagination(paginationKey), + }); + + return response; + }, + }, + }; +} diff --git a/packages/stargate/src/testutils.spec.ts b/packages/stargate/src/testutils.spec.ts index e48db7d451..3f184c8b0a 100644 --- a/packages/stargate/src/testutils.spec.ts +++ b/packages/stargate/src/testutils.spec.ts @@ -27,9 +27,15 @@ export function simappEnabled(): boolean { return simapp42Enabled() || simapp44Enabled(); } +export function pendingWithoutSimapp44(): void { + if (!simapp44Enabled()) { + return pending("Set SIMAPP44_ENABLED to enable Simapp based tests"); + } +} + export function pendingWithoutSimapp42(): void { if (!simapp42Enabled()) { - return pending("Set SIMAPP44_ENABLED to enable Simapp based tests"); + return pending("Set SIMAPP42_ENABLED to enable Simapp based tests"); } }