From e7df090ea7bf3d115b8e51865d8461ac6543d171 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 11 Feb 2020 09:35:55 +0100 Subject: [PATCH] Add CosmWasmClient.execute --- packages/sdk/src/cosmwasmclient.spec.ts | 45 +++++++++++++++++++ packages/sdk/src/cosmwasmclient.ts | 57 ++++++++++++++++++++++++- packages/sdk/types/cosmwasmclient.d.ts | 9 ++++ 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/packages/sdk/src/cosmwasmclient.spec.ts b/packages/sdk/src/cosmwasmclient.spec.ts index a513d2f3..10aadfe1 100644 --- a/packages/sdk/src/cosmwasmclient.spec.ts +++ b/packages/sdk/src/cosmwasmclient.spec.ts @@ -109,4 +109,49 @@ describe("CosmWasmClient", () => { expect(contractAddress1).not.toEqual(contractAddress2); }); }); + + describe("execute", () => { + it("works", async () => { + pendingWithoutCosmos(); + const pen = await Secp256k1Pen.fromMnemonic(faucet.mnemonic); + const client = CosmWasmClient.makeWritable(httpUrl, faucet.address, async signBytes => { + return encodeSecp256k1Signature(pen.pubkey, await pen.createSignature(signBytes)); + }); + const codeId = await client.upload(getRandomizedHackatom()); + + // instantiate + const transferAmount: readonly Coin[] = [ + { + amount: "233444", + denom: "ucosm", + }, + { + amount: "5454", + denom: "ustake", + }, + ]; + const beneficiaryAddress = makeRandomAddress(); + const contractAddress = await client.instantiate( + codeId, + { + verifier: faucet.address, + beneficiary: beneficiaryAddress, + }, + undefined, + transferAmount, + ); + + // execute + const result = await client.execute(contractAddress, {}); + const [firstLog] = result.logs; + expect(firstLog.log).toEqual(`released funds to ${beneficiaryAddress}`); + + // Verify token transfer from contract to beneficiary + const rest = new RestClient(httpUrl); + const beneficiaryBalance = (await rest.authAccounts(beneficiaryAddress)).result.value.coins; + expect(beneficiaryBalance).toEqual(transferAmount); + const contractBalance = (await rest.authAccounts(contractAddress)).result.value.coins; + expect(contractBalance).toEqual([]); + }); + }); }); diff --git a/packages/sdk/src/cosmwasmclient.ts b/packages/sdk/src/cosmwasmclient.ts index acf17400..bbdc63e3 100644 --- a/packages/sdk/src/cosmwasmclient.ts +++ b/packages/sdk/src/cosmwasmclient.ts @@ -1,9 +1,16 @@ import { Encoding } from "@iov/encoding"; import { makeSignBytes, marshalTx } from "./encoding"; -import { findAttribute, parseLogs } from "./logs"; +import { findAttribute, Log, parseLogs } from "./logs"; import { RestClient } from "./restclient"; -import { Coin, MsgInstantiateContract, MsgStoreCode, StdFee, StdSignature } from "./types"; +import { + Coin, + MsgExecuteContract, + MsgInstantiateContract, + MsgStoreCode, + StdFee, + StdSignature, +} from "./types"; export interface SigningCallback { (signBytes: Uint8Array): Promise; @@ -144,4 +151,50 @@ export class CosmWasmClient { const contractAddressAttr = findAttribute(logs, "message", "contract_address"); return contractAddressAttr.value; } + + public async execute( + contractAddress: string, + handleMsg: object, + memo?: string, + transferAmount?: readonly Coin[], + ): Promise<{ readonly logs: readonly Log[] }> { + const normalizedMemo = memo || ""; + const executeMsg: MsgExecuteContract = { + type: "wasm/execute", + value: { + sender: this.senderAddress, + contract: contractAddress, + msg: handleMsg, + // eslint-disable-next-line @typescript-eslint/camelcase + sent_funds: transferAmount || [], + }, + }; + const fee: StdFee = { + amount: [ + { + amount: "5000000", + denom: "ucosm", + }, + ], + gas: "89000000", + }; + + const account = (await this.restClient.authAccounts(this.senderAddress)).result.value; + const chainId = await this.chainId(); + const signBytes = makeSignBytes([executeMsg], fee, chainId, normalizedMemo, account); + const signature = await this.signCallback(signBytes); + const signedTx = { + msg: [executeMsg], + fee: fee, + memo: normalizedMemo, + signatures: [signature], + }; + const result = await this.restClient.postTx(marshalTx(signedTx)); + if (result.code) { + throw new Error(`Error when posting tx. Code: ${result.code}; Raw log: ${result.raw_log}`); + } + return { + logs: parseLogs(result.logs), + }; + } } diff --git a/packages/sdk/types/cosmwasmclient.d.ts b/packages/sdk/types/cosmwasmclient.d.ts index face62a6..5a07c95f 100644 --- a/packages/sdk/types/cosmwasmclient.d.ts +++ b/packages/sdk/types/cosmwasmclient.d.ts @@ -1,3 +1,4 @@ +import { Log } from "./logs"; import { Coin, StdSignature } from "./types"; export interface SigningCallback { (signBytes: Uint8Array): Promise; @@ -19,4 +20,12 @@ export declare class CosmWasmClient { memo?: string, transferAmount?: readonly Coin[], ): Promise; + execute( + contractAddress: string, + handleMsg: object, + memo?: string, + transferAmount?: readonly Coin[], + ): Promise<{ + readonly logs: readonly Log[]; + }>; }