diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index 81aca4e1..62a65356 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { Bech32 } from "@cosmjs/encoding"; +import { Bech32, toHex } from "@cosmjs/encoding"; import { Uint64 } from "@cosmjs/math"; import { BaseAccount, decodeAny } from "@cosmjs/proto-signing"; import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; @@ -29,20 +29,11 @@ export class StargateClient { public async getSequence(address: string): Promise { const binAddress = Bech32.decode(address).data; - // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L29-L32 const accountKey = Uint8Array.from([0x01, ...binAddress]); + const responseData = await this.queryVerified("acc", accountKey); - const response = await this.tmClient.abciQuery({ - // we need the StoreKey for the module, not the module name - // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L12 - path: "/store/acc/key", - data: accountKey, - prove: false, - }); - - const { typeUrl, value } = decodeAny(response.value); - + const { typeUrl, value } = decodeAny(responseData); switch (typeUrl) { case "/cosmos.auth.BaseAccount": { const { account_number, sequence } = BaseAccount.decode(value); @@ -53,7 +44,6 @@ export class StargateClient { sequence: uint64FromProto(sequence).toNumber(), }; } - default: throw new Error(`Unsupported type: ${typeUrl}`); } @@ -62,4 +52,28 @@ export class StargateClient { public disconnect(): void { this.tmClient.disconnect(); } + + private async queryVerified(store: string, key: Uint8Array): Promise { + const response = await this.tmClient.abciQuery({ + // we need the StoreKey for the module, not the module name + // https://github.com/cosmos/cosmos-sdk/blob/8cab43c8120fec5200c3459cbf4a92017bb6f287/x/auth/types/keys.go#L12 + path: `/store/${store}/key`, + data: key, + prove: true, + }); + + if (response.code) { + throw new Error(`Query failed with (${response.code}): ${response.log}`); + } + + // TODO: better way to compare? + if (toHex(response.key) !== toHex(key)) { + throw new Error(`Response key ${toHex(response.key)} doesn't match query key ${toHex(key)}`); + } + + // TODO: implement proof verification + // https://github.com/CosmWasm/cosmjs/issues/347 + + return response.value; + } } diff --git a/packages/stargate/types/stargateclient.d.ts b/packages/stargate/types/stargateclient.d.ts index 7b5269d6..55abe8c4 100644 --- a/packages/stargate/types/stargateclient.d.ts +++ b/packages/stargate/types/stargateclient.d.ts @@ -8,4 +8,5 @@ export declare class StargateClient { private constructor(); getSequence(address: string): Promise; disconnect(): void; + private queryVerified; }