diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts index bbd7cdf5..e0e15981 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.spec.ts @@ -409,9 +409,8 @@ describe("CosmWasmClient", () => { assert(contract); const client = await CosmWasmClient.connect(wasmd.endpoint); - const { data } = await client.queryContractSmart(contract.address, { verifier: {} }); - const parsedData = JSON.parse(fromAscii(data)); - expect(parsedData).toEqual({ verifier: contract.initMsg.verifier }); + const result = await client.queryContractSmart(contract.address, { verifier: {} }); + expect(result).toEqual({ verifier: contract.initMsg.verifier }); }); it("errors for malformed query message", async () => { diff --git a/packages/cosmwasm-stargate/src/queries/wasm.spec.ts b/packages/cosmwasm-stargate/src/queries/wasm.spec.ts index a2696082..b251f4db 100644 --- a/packages/cosmwasm-stargate/src/queries/wasm.spec.ts +++ b/packages/cosmwasm-stargate/src/queries/wasm.spec.ts @@ -341,10 +341,8 @@ describe("WasmExtension", () => { assert(hackatomContractAddress); const client = await makeWasmClient(wasmd.endpoint); const request = { verifier: {} }; - const { data } = await client.unverified.wasm.queryContractSmart(hackatomContractAddress, request); - assert(data); - const parsedData = JSON.parse(fromAscii(data)); - expect(parsedData).toEqual({ verifier: alice.address0 }); + const result = await client.unverified.wasm.queryContractSmart(hackatomContractAddress, request); + expect(result).toEqual({ verifier: alice.address0 }); }); it("throws for invalid query requests", async () => { diff --git a/packages/cosmwasm-stargate/src/queries/wasm.ts b/packages/cosmwasm-stargate/src/queries/wasm.ts index 40dc6728..1fd7db7b 100644 --- a/packages/cosmwasm-stargate/src/queries/wasm.ts +++ b/packages/cosmwasm-stargate/src/queries/wasm.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { toAscii } from "@cosmjs/encoding"; +import { JsonObject } from "@cosmjs/cosmwasm-launchpad"; +import { fromUtf8, toAscii } from "@cosmjs/encoding"; import { QueryClient } from "@cosmjs/stargate"; import Long from "long"; @@ -12,7 +13,6 @@ type IQueryContractHistoryResponse = cosmwasm.wasm.v1beta1.IQueryContractHistory type IQueryContractInfoResponse = cosmwasm.wasm.v1beta1.IQueryContractInfoResponse; type IQueryContractsByCodeResponse = cosmwasm.wasm.v1beta1.IQueryContractsByCodeResponse; type IQueryRawContractStateResponse = cosmwasm.wasm.v1beta1.IQueryRawContractStateResponse; -type IQuerySmartContractStateResponse = cosmwasm.wasm.v1beta1.IQuerySmartContractStateResponse; const { Query } = cosmwasm.wasm.v1beta1; @@ -61,10 +61,7 @@ export interface WasmExtension { * Makes a smart query on the contract and parses the response as JSON. * Throws error if no such contract exists, the query format is invalid or the response is invalid. */ - readonly queryContractSmart: ( - address: string, - query: Record, - ) => Promise; + readonly queryContractSmart: (address: string, query: Record) => Promise; }; }; } @@ -117,7 +114,13 @@ export function setupWasmExtension(base: QueryClient): WasmExtension { queryContractSmart: async (address: string, query: Record) => { const request = { address: address, queryData: toAscii(JSON.stringify(query)) }; - return queryService.smartContractState(request); + const { data } = await queryService.smartContractState(request); + // By convention, smart queries must return a valid JSON document (see https://github.com/CosmWasm/cosmwasm/issues/144) + try { + return JSON.parse(fromUtf8(data)); + } catch (error) { + throw new Error("Contract did not return valid JSON data"); + } }, }, }, diff --git a/packages/cosmwasm-stargate/types/queries/wasm.d.ts b/packages/cosmwasm-stargate/types/queries/wasm.d.ts index 3b6c1249..c1f34a94 100644 --- a/packages/cosmwasm-stargate/types/queries/wasm.d.ts +++ b/packages/cosmwasm-stargate/types/queries/wasm.d.ts @@ -1,3 +1,4 @@ +import { JsonObject } from "@cosmjs/cosmwasm-launchpad"; import { QueryClient } from "@cosmjs/stargate"; import { cosmwasm } from "../codec"; declare type IQueryAllContractStateResponse = cosmwasm.wasm.v1beta1.IQueryAllContractStateResponse; @@ -7,7 +8,6 @@ declare type IQueryContractHistoryResponse = cosmwasm.wasm.v1beta1.IQueryContrac declare type IQueryContractInfoResponse = cosmwasm.wasm.v1beta1.IQueryContractInfoResponse; declare type IQueryContractsByCodeResponse = cosmwasm.wasm.v1beta1.IQueryContractsByCodeResponse; declare type IQueryRawContractStateResponse = cosmwasm.wasm.v1beta1.IQueryRawContractStateResponse; -declare type IQuerySmartContractStateResponse = cosmwasm.wasm.v1beta1.IQuerySmartContractStateResponse; export interface WasmExtension { readonly unverified: { readonly wasm: { @@ -53,10 +53,7 @@ export interface WasmExtension { * Makes a smart query on the contract and parses the response as JSON. * Throws error if no such contract exists, the query format is invalid or the response is invalid. */ - readonly queryContractSmart: ( - address: string, - query: Record, - ) => Promise; + readonly queryContractSmart: (address: string, query: Record) => Promise; }; }; }