From 520f32ed3687608f679b2ab7ae4fc3ab0d0521ae Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 13 Feb 2020 16:24:17 +0100 Subject: [PATCH] Add CosmWasmClient.queryContractRaw --- packages/sdk/src/cosmwasmclient.spec.ts | 64 +++++++++++++++++++++++++ packages/sdk/src/cosmwasmclient.ts | 13 +++++ packages/sdk/types/cosmwasmclient.d.ts | 7 +++ 3 files changed, 84 insertions(+) diff --git a/packages/sdk/src/cosmwasmclient.spec.ts b/packages/sdk/src/cosmwasmclient.spec.ts index 5862ae17..01dce878 100644 --- a/packages/sdk/src/cosmwasmclient.spec.ts +++ b/packages/sdk/src/cosmwasmclient.spec.ts @@ -1,3 +1,4 @@ +import { Bech32, Encoding } from "@iov/encoding"; import { assert } from "@iov/utils"; import { CosmWasmClient } from "./cosmwasmclient"; @@ -9,6 +10,8 @@ import cosmoshub from "./testdata/cosmoshub.json"; import { getRandomizedHackatom, makeRandomAddress } from "./testutils.spec"; import { Coin, CosmosSdkTx, MsgSend, StdFee } from "./types"; +const { fromUtf8, toAscii } = Encoding; + const httpUrl = "http://localhost:1317"; function cosmosEnabled(): boolean { @@ -35,6 +38,14 @@ const unusedAccount = { address: "cosmos1cjsxept9rkggzxztslae9ndgpdyt2408lk850u", }; +interface HackatomInstance { + readonly initMsg: { + readonly verifier: string; + readonly beneficiary: string; + }; + readonly address: string; +} + describe("CosmWasmClient", () => { describe("makeReadOnly", () => { it("can be constructed", () => { @@ -359,4 +370,57 @@ describe("CosmWasmClient", () => { expect(contractBalance).toEqual([]); }); }); + + describe("queryContractRaw", () => { + const configKey = toAscii("config"); + const otherKey = toAscii("this_does_not_exist"); + let contract: HackatomInstance | undefined; + + beforeAll(async () => { + if (cosmosEnabled()) { + pendingWithoutCosmos(); + const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, signBytes => pen.sign(signBytes)); + const codeId = await client.upload(getRandomizedHackatom()); + const initMsg = { verifier: makeRandomAddress(), beneficiary: makeRandomAddress() }; + const contractAddress = await client.instantiate(codeId, initMsg); + contract = { initMsg: initMsg, address: contractAddress }; + } + }); + + it("can query existing key", async () => { + pendingWithoutCosmos(); + assert(contract); + + const client = CosmWasmClient.makeReadOnly(httpUrl); + const raw = await client.queryContractRaw(contract.address, configKey); + assert(raw, "must get result"); + expect(JSON.parse(fromUtf8(raw))).toEqual({ + verifier: Array.from(Bech32.decode(contract.initMsg.verifier).data), + beneficiary: Array.from(Bech32.decode(contract.initMsg.beneficiary).data), + funder: Array.from(Bech32.decode(faucet.address).data), + }); + }); + + it("can query non-existent key", async () => { + pendingWithoutCosmos(); + assert(contract); + + const client = CosmWasmClient.makeReadOnly(httpUrl); + const raw = await client.queryContractRaw(contract.address, otherKey); + expect(raw).toBeNull(); + }); + + it("errors for non-existent contract", async () => { + pendingWithoutCosmos(); + assert(contract); + + const nonExistentAddress = makeRandomAddress(); + const client = CosmWasmClient.makeReadOnly(httpUrl); + await client.queryContractRaw(nonExistentAddress, configKey).then( + () => fail("must not succeed"), + error => expect(error).toMatch(`No contract with address ${nonExistentAddress}`), + ); + }); + }); }); diff --git a/packages/sdk/src/cosmwasmclient.ts b/packages/sdk/src/cosmwasmclient.ts index c94232fd..8645e845 100644 --- a/packages/sdk/src/cosmwasmclient.ts +++ b/packages/sdk/src/cosmwasmclient.ts @@ -294,4 +294,17 @@ export class CosmWasmClient { logs: result.logs, }; } + + /** + * Returns the data at the key if present (raw contract dependent storage data) + * or null if no data at this key. + * + * Promise is rejected when contract does not exist. + */ + public async queryContractRaw(address: string, key: Uint8Array): Promise { + // just test contract existence + const _info = await this.restClient.getContractInfo(address); + + return this.restClient.queryContractRaw(address, key); + } } diff --git a/packages/sdk/types/cosmwasmclient.d.ts b/packages/sdk/types/cosmwasmclient.d.ts index 14be80a8..81c2fecc 100644 --- a/packages/sdk/types/cosmwasmclient.d.ts +++ b/packages/sdk/types/cosmwasmclient.d.ts @@ -62,4 +62,11 @@ export declare class CosmWasmClient { memo?: string, transferAmount?: readonly Coin[], ): Promise; + /** + * Returns the data at the key if present (raw contract dependent storage data) + * or null if no data at this key. + * + * Promise is rejected when contract does not exist. + */ + queryContractRaw(address: string, key: Uint8Array): Promise; }