From ad778c0ba926b0ddaf2843d16ec755ccea6e56d4 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 24 Nov 2020 12:22:20 +0000 Subject: [PATCH 1/4] cosmwasm: Use launchpad endpoint in tests --- .../src/signingcosmwasmclient.spec.ts | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/packages/cosmwasm/src/signingcosmwasmclient.spec.ts b/packages/cosmwasm/src/signingcosmwasmclient.spec.ts index c0a917d6..48978cb8 100644 --- a/packages/cosmwasm/src/signingcosmwasmclient.spec.ts +++ b/packages/cosmwasm/src/signingcosmwasmclient.spec.ts @@ -26,8 +26,6 @@ import { unused, } from "./testutils.spec"; -const httpUrl = "http://localhost:1317"; - function makeWasmClient(apiUrl: string): LcdClient & AuthExtension & WasmExtension { return LcdClient.withExtensions({ apiUrl }, setupAuthExtension, setupWasmExtension); } @@ -36,14 +34,14 @@ describe("SigningCosmWasmClient", () => { describe("makeReadOnly", () => { it("can be constructed", async () => { const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); expect(client).toBeTruthy(); }); it("can be constructed with custom gas price", async () => { const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); const gasPrice = GasPrice.fromString("3.14utest"); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet, gasPrice); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet, gasPrice); const openedClient = (client as unknown) as PrivateSigningCosmWasmClient; expect(openedClient.fees).toEqual({ upload: { @@ -108,7 +106,13 @@ describe("SigningCosmWasmClient", () => { const gasLimits = { send: 160000, }; - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet, undefined, gasLimits); + const client = new SigningCosmWasmClient( + launchpad.endpoint, + alice.address0, + wallet, + undefined, + gasLimits, + ); const openedClient = (client as unknown) as PrivateSigningCosmWasmClient; expect(openedClient.fees).toEqual({ upload: { @@ -174,7 +178,13 @@ describe("SigningCosmWasmClient", () => { const gasLimits = { send: 160000, }; - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet, gasPrice, gasLimits); + const client = new SigningCosmWasmClient( + launchpad.endpoint, + alice.address0, + wallet, + gasPrice, + gasLimits, + ); const openedClient = (client as unknown) as PrivateSigningCosmWasmClient; expect(openedClient.fees).toEqual({ upload: { @@ -239,7 +249,7 @@ describe("SigningCosmWasmClient", () => { it("always uses authAccount implementation", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const openedClient = (client as unknown) as PrivateCosmWasmClient; const blockLatestSpy = spyOn(openedClient.lcdClient, "blocksLatest").and.callThrough(); @@ -257,7 +267,7 @@ describe("SigningCosmWasmClient", () => { it("works", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const wasm = getHackatom().data; const { codeId, @@ -276,7 +286,7 @@ describe("SigningCosmWasmClient", () => { it("can set builder and source", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const hackatom = getHackatom(); const meta: UploadMeta = { @@ -295,7 +305,7 @@ describe("SigningCosmWasmClient", () => { it("works with transfer amount", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId } = await client.upload(getHackatom().data); const transferAmount = [coin(1234, "ucosm"), coin(321, "ustake")]; @@ -313,7 +323,7 @@ describe("SigningCosmWasmClient", () => { }, ); - const lcdClient = makeWasmClient(httpUrl); + const lcdClient = makeWasmClient(launchpad.endpoint); const balance = (await lcdClient.auth.account(contractAddress)).result.value.coins; expect(balance).toEqual(transferAmount); }); @@ -321,7 +331,7 @@ describe("SigningCosmWasmClient", () => { it("works with admin", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId } = await client.upload(getHackatom().data); const beneficiaryAddress = makeRandomAddress(); @@ -335,7 +345,7 @@ describe("SigningCosmWasmClient", () => { { admin: unused.address }, ); - const lcdClient = makeWasmClient(httpUrl); + const lcdClient = makeWasmClient(launchpad.endpoint); const contract = await lcdClient.wasm.getContractInfo(contractAddress); assert(contract); expect(contract.admin).toEqual(unused.address); @@ -344,7 +354,7 @@ describe("SigningCosmWasmClient", () => { it("can instantiate one code multiple times", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId } = await client.upload(getHackatom().data); const contractAddress1 = await client.instantiate( @@ -371,7 +381,7 @@ describe("SigningCosmWasmClient", () => { it("can update an admin", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId } = await client.upload(getHackatom().data); const beneficiaryAddress = makeRandomAddress(); @@ -387,7 +397,7 @@ describe("SigningCosmWasmClient", () => { }, ); - const lcdClient = makeWasmClient(httpUrl); + const lcdClient = makeWasmClient(launchpad.endpoint); const state1 = await lcdClient.wasm.getContractInfo(contractAddress); assert(state1); expect(state1.admin).toEqual(alice.address0); @@ -404,7 +414,7 @@ describe("SigningCosmWasmClient", () => { it("can clear an admin", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId } = await client.upload(getHackatom().data); const beneficiaryAddress = makeRandomAddress(); @@ -420,7 +430,7 @@ describe("SigningCosmWasmClient", () => { }, ); - const lcdClient = makeWasmClient(httpUrl); + const lcdClient = makeWasmClient(launchpad.endpoint); const state1 = await lcdClient.wasm.getContractInfo(contractAddress); assert(state1); expect(state1.admin).toEqual(alice.address0); @@ -437,7 +447,7 @@ describe("SigningCosmWasmClient", () => { it("can can migrate from one code ID to another", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId: codeId1 } = await client.upload(getHackatom().data); const { codeId: codeId2 } = await client.upload(getHackatom().data); @@ -454,7 +464,7 @@ describe("SigningCosmWasmClient", () => { }, ); - const lcdClient = makeWasmClient(httpUrl); + const lcdClient = makeWasmClient(launchpad.endpoint); const state1 = await lcdClient.wasm.getContractInfo(contractAddress); assert(state1); expect(state1.admin).toEqual(alice.address0); @@ -475,7 +485,7 @@ describe("SigningCosmWasmClient", () => { it("works", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const { codeId } = await client.upload(getHackatom().data); // instantiate @@ -504,7 +514,7 @@ describe("SigningCosmWasmClient", () => { }); // Verify token transfer from contract to beneficiary - const lcdClient = makeWasmClient(httpUrl); + const lcdClient = makeWasmClient(launchpad.endpoint); const beneficiaryBalance = (await lcdClient.auth.account(beneficiaryAddress)).result.value.coins; expect(beneficiaryBalance).toEqual(transferAmount); const contractBalance = (await lcdClient.auth.account(contractAddress)).result.value.coins; @@ -516,7 +526,7 @@ describe("SigningCosmWasmClient", () => { it("works", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); // instantiate const transferAmount = coins(7890, "ucosm"); @@ -543,7 +553,7 @@ describe("SigningCosmWasmClient", () => { it("works", async () => { pendingWithoutLaunchpad(); const wallet = await Secp256k1HdWallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmWasmClient(httpUrl, alice.address0, wallet); + const client = new SigningCosmWasmClient(launchpad.endpoint, alice.address0, wallet); const msg: MsgDelegate = { type: "cosmos-sdk/MsgDelegate", From db6e58520631408ac6d643d46bf45bab243a7529 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 24 Nov 2020 12:35:15 +0000 Subject: [PATCH 2/4] cosmwasm: Add cw3 contract execution failure checks --- packages/cosmwasm/src/cw3cosmwasmclient.spec.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/cosmwasm/src/cw3cosmwasmclient.spec.ts b/packages/cosmwasm/src/cw3cosmwasmclient.spec.ts index 3b2888f5..35905656 100644 --- a/packages/cosmwasm/src/cw3cosmwasmclient.spec.ts +++ b/packages/cosmwasm/src/cw3cosmwasmclient.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { makeCosmoshubPath, Secp256k1HdWallet } from "@cosmjs/launchpad"; -import { assert, sleep } from "@cosmjs/utils"; +import { assert } from "@cosmjs/utils"; import { Cw3CosmWasmClient, Vote } from "./cw3cosmwasmclient"; import { @@ -257,6 +257,11 @@ describe("Cw3CosmWasmClient", () => { ]); const { proposals } = await voter.reverseProposals({ limit: 1 }); const proposalId = proposals[0].id; + + await expectAsync(proposer.executeMultisigProposal(proposalId)).toBeRejectedWithError( + /proposal must have passed and not yet been executed/i, + ); + const voteResult = await voter.voteMultisigProposal(proposalId, Vote.Yes); expect(voteResult).toBeTruthy(); @@ -314,7 +319,9 @@ describe("Cw3CosmWasmClient", () => { const vote2Result = await voter2.voteMultisigProposal(proposalId, Vote.No); expect(vote2Result).toBeTruthy(); - await sleep(2000); + await expectAsync(proposer.executeMultisigProposal(proposalId)).toBeRejectedWithError( + /proposal must have passed and not yet been executed/i, + ); const closeResult = await proposer.closeMultisigProposal(proposalId); expect(closeResult).toBeTruthy(); From 62f1410b92dfa3470247cec856f48f917b31c8bd Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 24 Nov 2020 12:43:42 +0000 Subject: [PATCH 3/4] cosmwasm: Query contract account by default in Cw3CosmWasmClient --- packages/cosmwasm/src/cw3cosmwasmclient.ts | 9 +++++++-- packages/cosmwasm/types/cw3cosmwasmclient.d.ts | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/cosmwasm/src/cw3cosmwasmclient.ts b/packages/cosmwasm/src/cw3cosmwasmclient.ts index bfde5a36..e3f75e13 100644 --- a/packages/cosmwasm/src/cw3cosmwasmclient.ts +++ b/packages/cosmwasm/src/cw3cosmwasmclient.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { BroadcastMode, GasLimits, GasPrice, OfflineSigner } from "@cosmjs/launchpad"; +import { Account } from "./cosmwasmclient"; import { CosmWasmFeeTable, ExecuteResult, SigningCosmWasmClient } from "./signingcosmwasmclient"; export type Expiration = @@ -75,17 +76,21 @@ export class Cw3CosmWasmClient extends SigningCosmWasmClient { public constructor( apiUrl: string, - senderAddress: string, + signerAddress: string, signer: OfflineSigner, cw3ContractAddress: string, gasPrice?: GasPrice, gasLimits?: Partial>, broadcastMode?: BroadcastMode, ) { - super(apiUrl, senderAddress, signer, gasPrice, gasLimits, broadcastMode); + super(apiUrl, signerAddress, signer, gasPrice, gasLimits, broadcastMode); this.cw3ContractAddress = cw3ContractAddress; } + public getAccount(address?: string): Promise { + return super.getAccount(address || this.cw3ContractAddress); + } + public getThreshold(): Promise { return this.queryContractSmart(this.cw3ContractAddress, { threshold: {} }); } diff --git a/packages/cosmwasm/types/cw3cosmwasmclient.d.ts b/packages/cosmwasm/types/cw3cosmwasmclient.d.ts index 529f34f8..11cbdc99 100644 --- a/packages/cosmwasm/types/cw3cosmwasmclient.d.ts +++ b/packages/cosmwasm/types/cw3cosmwasmclient.d.ts @@ -1,4 +1,5 @@ import { BroadcastMode, GasLimits, GasPrice, OfflineSigner } from "@cosmjs/launchpad"; +import { Account } from "./cosmwasmclient"; import { CosmWasmFeeTable, ExecuteResult, SigningCosmWasmClient } from "./signingcosmwasmclient"; export declare type Expiration = | { @@ -63,13 +64,14 @@ export declare class Cw3CosmWasmClient extends SigningCosmWasmClient { private readonly cw3ContractAddress; constructor( apiUrl: string, - senderAddress: string, + signerAddress: string, signer: OfflineSigner, cw3ContractAddress: string, gasPrice?: GasPrice, gasLimits?: Partial>, broadcastMode?: BroadcastMode, ); + getAccount(address?: string): Promise; getThreshold(): Promise; getProposal(proposalId: number): Promise; listProposals({ startAfter, limit }?: StartAfterNumberPaginationOptions): Promise; From 2b6f658fb61a5bd4a921942fe421c93daa327114 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 24 Nov 2020 12:44:56 +0000 Subject: [PATCH 4/4] cosmwasm: Expose Cw3CosmWasmClient.cw3ContractAddress --- packages/cosmwasm/src/cw3cosmwasmclient.ts | 2 +- packages/cosmwasm/types/cw3cosmwasmclient.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cosmwasm/src/cw3cosmwasmclient.ts b/packages/cosmwasm/src/cw3cosmwasmclient.ts index e3f75e13..4a8e3879 100644 --- a/packages/cosmwasm/src/cw3cosmwasmclient.ts +++ b/packages/cosmwasm/src/cw3cosmwasmclient.ts @@ -72,7 +72,7 @@ interface StartAfterStringPaginationOptions { } export class Cw3CosmWasmClient extends SigningCosmWasmClient { - private readonly cw3ContractAddress: string; + public readonly cw3ContractAddress: string; public constructor( apiUrl: string, diff --git a/packages/cosmwasm/types/cw3cosmwasmclient.d.ts b/packages/cosmwasm/types/cw3cosmwasmclient.d.ts index 11cbdc99..b2391227 100644 --- a/packages/cosmwasm/types/cw3cosmwasmclient.d.ts +++ b/packages/cosmwasm/types/cw3cosmwasmclient.d.ts @@ -61,7 +61,7 @@ interface StartAfterStringPaginationOptions { readonly limit?: number; } export declare class Cw3CosmWasmClient extends SigningCosmWasmClient { - private readonly cw3ContractAddress; + readonly cw3ContractAddress: string; constructor( apiUrl: string, signerAddress: string,