From 0d6484648a3c8db72b2f2db377a9b243a521c3c8 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 14 Jul 2020 15:37:07 +0200 Subject: [PATCH 01/12] sdk38: Add gov parametersByType endpoint to lcd --- packages/sdk38/src/lcdapi/gov.spec.ts | 54 ++++++++++++++++ packages/sdk38/src/lcdapi/gov.ts | 92 +++++++++++++++++++++++++++ packages/sdk38/types/lcdapi/gov.d.ts | 70 ++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 packages/sdk38/src/lcdapi/gov.spec.ts create mode 100644 packages/sdk38/src/lcdapi/gov.ts create mode 100644 packages/sdk38/types/lcdapi/gov.d.ts diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts new file mode 100644 index 00000000..904199ff --- /dev/null +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/camelcase */ +import { nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd } from "../testutils.spec"; +import { GovExtension, GovParametersType, setupGovExtension } from "./gov"; +import { LcdClient } from "./lcdclient"; + +function makeGovClient(apiUrl: string): LcdClient & GovExtension { + return LcdClient.withExtensions({ apiUrl }, setupGovExtension); +} + +describe("GovExtension", () => { + describe("parametersByType", () => { + it("works for deposit", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const paramsType = GovParametersType.Deposit; + const response = await client.gov.parametersByType(paramsType); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + min_deposit: [{ denom: "ustake", amount: "10000000" }], + max_deposit_period: "172800000000000", + }, + }); + }); + + it("works for tallying", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const paramsType = GovParametersType.Tallying; + const response = await client.gov.parametersByType(paramsType); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + quorum: "0.334000000000000000", + threshold: "0.500000000000000000", + veto: "0.334000000000000000", + }, + }); + }); + + it("works for voting", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const paramsType = GovParametersType.Voting; + const response = await client.gov.parametersByType(paramsType); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + voting_period: "172800000000000", + }, + }); + }); + }); +}); diff --git a/packages/sdk38/src/lcdapi/gov.ts b/packages/sdk38/src/lcdapi/gov.ts new file mode 100644 index 00000000..d7c89e59 --- /dev/null +++ b/packages/sdk38/src/lcdapi/gov.ts @@ -0,0 +1,92 @@ +import { Coin } from "../coins"; +import { LcdClient } from "./lcdclient"; + +export enum GovParametersType { + Deposit = "deposit", + Tallying = "tallying", + Voting = "voting", +} + +export interface GovParametersDepositResponse { + readonly height: string; + readonly result: { + readonly min_deposit: readonly Coin[]; + readonly max_deposit_period: string; + }; +} + +export interface GovParametersTallyingResponse { + readonly height: string; + readonly result: { + readonly quorum: string; + readonly threshold: string; + readonly veto: string; + }; +} + +export interface GovParametersVotingResponse { + readonly height: string; + readonly result: { + readonly voting_period: string; + }; +} + +export type GovParametersByTypeResponse = + | GovParametersDepositResponse + | GovParametersTallyingResponse + | GovParametersVotingResponse; + +export interface GovProposalsResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovProposalsByIdResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovProposerResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovDepositsResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovDepositsByDepositorResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovTallyResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovVotesResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovVotesByVoterResponse { + readonly height: string; + readonly result: {}; +} + +export interface GovExtension { + readonly gov: { + readonly parametersByType: (parametersType: GovParametersType) => Promise; + }; +} + +export function setupGovExtension(base: LcdClient): GovExtension { + return { + gov: { + parametersByType: async (parametersType: GovParametersType) => + base.get(`/gov/parameters/${parametersType}`), + }, + }; +} diff --git a/packages/sdk38/types/lcdapi/gov.d.ts b/packages/sdk38/types/lcdapi/gov.d.ts new file mode 100644 index 00000000..9623f647 --- /dev/null +++ b/packages/sdk38/types/lcdapi/gov.d.ts @@ -0,0 +1,70 @@ +import { Coin } from "../coins"; +import { LcdClient } from "./lcdclient"; +export declare enum GovParametersType { + Deposit = "deposit", + Tallying = "tallying", + Voting = "voting", +} +export interface GovParametersDepositResponse { + readonly height: string; + readonly result: { + readonly min_deposit: readonly Coin[]; + readonly max_deposit_period: string; + }; +} +export interface GovParametersTallyingResponse { + readonly height: string; + readonly result: { + readonly quorum: string; + readonly threshold: string; + readonly veto: string; + }; +} +export interface GovParametersVotingResponse { + readonly height: string; + readonly result: { + readonly voting_period: string; + }; +} +export declare type GovParametersByTypeResponse = + | GovParametersDepositResponse + | GovParametersTallyingResponse + | GovParametersVotingResponse; +export interface GovProposalsResponse { + readonly height: string; + readonly result: {}; +} +export interface GovProposalsByIdResponse { + readonly height: string; + readonly result: {}; +} +export interface GovProposerResponse { + readonly height: string; + readonly result: {}; +} +export interface GovDepositsResponse { + readonly height: string; + readonly result: {}; +} +export interface GovDepositsByDepositorResponse { + readonly height: string; + readonly result: {}; +} +export interface GovTallyResponse { + readonly height: string; + readonly result: {}; +} +export interface GovVotesResponse { + readonly height: string; + readonly result: {}; +} +export interface GovVotesByVoterResponse { + readonly height: string; + readonly result: {}; +} +export interface GovExtension { + readonly gov: { + readonly parametersByType: (parametersType: GovParametersType) => Promise; + }; +} +export declare function setupGovExtension(base: LcdClient): GovExtension; From 275ff2fb5efc88b8dbb8a266050df4c817efe053 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 14 Jul 2020 15:57:32 +0200 Subject: [PATCH 02/12] sdk38: Add gov proposals endpoint to lcd --- packages/sdk38/src/lcdapi/gov.spec.ts | 12 ++++++++++++ packages/sdk38/src/lcdapi/gov.ts | 23 ++++++++++++++++++++++- packages/sdk38/types/lcdapi/gov.d.ts | 20 +++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 904199ff..7ec10cf6 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -51,4 +51,16 @@ describe("GovExtension", () => { }); }); }); + + describe("proposals", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const response = await client.gov.proposals(); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [], + }); + }); + }); }); diff --git a/packages/sdk38/src/lcdapi/gov.ts b/packages/sdk38/src/lcdapi/gov.ts index d7c89e59..2d9d78d2 100644 --- a/packages/sdk38/src/lcdapi/gov.ts +++ b/packages/sdk38/src/lcdapi/gov.ts @@ -36,9 +36,28 @@ export type GovParametersByTypeResponse = | GovParametersTallyingResponse | GovParametersVotingResponse; +export interface TallyResult { + readonly yes: string; + readonly abstain: string; + readonly no: string; + readonly no_with_veto: string; +} + +export interface TextProposal { + readonly proposal_id: number; + readonly title: string; + readonly description: string; + readonly proposal_type: string; + readonly proposal_status: string; + readonly final_tally_result: TallyResult; + readonly submit_time: string; + readonly total_deposit: readonly Coin[]; + readonly voting_start_time: string; +} + export interface GovProposalsResponse { readonly height: string; - readonly result: {}; + readonly result: readonly TextProposal[]; } export interface GovProposalsByIdResponse { @@ -79,6 +98,7 @@ export interface GovVotesByVoterResponse { export interface GovExtension { readonly gov: { readonly parametersByType: (parametersType: GovParametersType) => Promise; + readonly proposals: () => Promise; }; } @@ -87,6 +107,7 @@ export function setupGovExtension(base: LcdClient): GovExtension { gov: { parametersByType: async (parametersType: GovParametersType) => base.get(`/gov/parameters/${parametersType}`), + proposals: async () => base.get("/gov/proposals"), }, }; } diff --git a/packages/sdk38/types/lcdapi/gov.d.ts b/packages/sdk38/types/lcdapi/gov.d.ts index 9623f647..bdf24211 100644 --- a/packages/sdk38/types/lcdapi/gov.d.ts +++ b/packages/sdk38/types/lcdapi/gov.d.ts @@ -30,9 +30,26 @@ export declare type GovParametersByTypeResponse = | GovParametersDepositResponse | GovParametersTallyingResponse | GovParametersVotingResponse; +export interface TallyResult { + readonly yes: string; + readonly abstain: string; + readonly no: string; + readonly no_with_veto: string; +} +export interface TextProposal { + readonly proposal_id: number; + readonly title: string; + readonly description: string; + readonly proposal_type: string; + readonly proposal_status: string; + readonly final_tally_result: TallyResult; + readonly submit_time: string; + readonly total_deposit: readonly Coin[]; + readonly voting_start_time: string; +} export interface GovProposalsResponse { readonly height: string; - readonly result: {}; + readonly result: readonly TextProposal[]; } export interface GovProposalsByIdResponse { readonly height: string; @@ -65,6 +82,7 @@ export interface GovVotesByVoterResponse { export interface GovExtension { readonly gov: { readonly parametersByType: (parametersType: GovParametersType) => Promise; + readonly proposals: () => Promise; }; } export declare function setupGovExtension(base: LcdClient): GovExtension; From 158e108805463d4b49b585954481dd573aff28c6 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 11:12:21 +0200 Subject: [PATCH 03/12] sdk38: Add datetimestamp matcher in test utils --- packages/sdk38/src/testutils.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/sdk38/src/testutils.spec.ts b/packages/sdk38/src/testutils.spec.ts index 005fdc26..b6c80a73 100644 --- a/packages/sdk38/src/testutils.spec.ts +++ b/packages/sdk38/src/testutils.spec.ts @@ -17,6 +17,7 @@ export const tendermintIdMatcher = /^[0-9A-F]{64}$/; export const tendermintOptionalIdMatcher = /^([0-9A-F]{64}|)$/; export const tendermintAddressMatcher = /^[0-9A-F]{40}$/; export const tendermintShortHashMatcher = /^[0-9a-f]{40}$/; +export const dateTimeStampMatcher = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(?:\.[0-9]+)?Z$/; export const semverMatcher = /^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$/; // https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 From 09f9b1fd5fd6902722dad8fe922cd7f8c507c061 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 11:24:51 +0200 Subject: [PATCH 04/12] sdk38: Add submit proposal script to wasmd init --- scripts/wasmd/init.sh | 1 + scripts/wasmd/submit_proposal.js | 106 +++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100755 scripts/wasmd/submit_proposal.js diff --git a/scripts/wasmd/init.sh b/scripts/wasmd/init.sh index 8a64df01..d4ac08cf 100755 --- a/scripts/wasmd/init.sh +++ b/scripts/wasmd/init.sh @@ -19,3 +19,4 @@ SCRIPT_DIR="$(realpath "$(dirname "$0")")" "$SCRIPT_DIR/deploy_erc20.js" "$SCRIPT_DIR/deploy_nameservice.js" "$SCRIPT_DIR/deploy_staking.js" +"$SCRIPT_DIR/submit_proposal.js" diff --git a/scripts/wasmd/submit_proposal.js b/scripts/wasmd/submit_proposal.js new file mode 100755 index 00000000..4dd4ce3e --- /dev/null +++ b/scripts/wasmd/submit_proposal.js @@ -0,0 +1,106 @@ +#!/usr/bin/env node + +/* eslint-disable @typescript-eslint/camelcase */ +const { coins, Secp256k1Wallet, SigningCosmosClient, makeSignBytes } = require("@cosmjs/sdk38"); + +const httpUrl = "http://localhost:1317"; +const alice = { + mnemonic: "enlist hip relief stomach skate base shallow young switch frequent cry park", + address0: "cosmos14qemq0vw6y3gc3u3e0aty2e764u4gs5le3hada", +}; + +const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million +}; + +async function submitProposal(client, wallet) { + const chainId = await client.getChainId(); + const proposalMsg = { + type: "cosmos-sdk/MsgSubmitProposal", + value: { + content: { + type: "cosmos-sdk/TextProposal", + value: { + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal", + }, + }, + proposer: alice.address0, + initial_deposit: coins(25000000, "ustake"), + }, + }; + const proposalMemo = "Test proposal for wasmd"; + const { accountNumber: proposalAccountNumber, sequence: proposalSequence } = await client.getNonce(); + const proposalSignBytes = makeSignBytes( + [proposalMsg], + defaultFee, + chainId, + proposalMemo, + proposalAccountNumber, + proposalSequence, + ); + const proposalSignature = await wallet.sign(alice.address0, proposalSignBytes); + const proposalTx = { + msg: [proposalMsg], + fee: defaultFee, + memo: proposalMemo, + signatures: [proposalSignature], + }; + return client.postTx(proposalTx); +} + +async function submitVote(client, wallet, proposalId) { + const chainId = await client.getChainId(); + const voteMsg = { + type: "cosmos-sdk/MsgVote", + value: { + proposal_id: proposalId, + voter: alice.address0, + option: "Yes", + }, + }; + const voteMemo = "Test vote for wasmd"; + const { accountNumber: voteAccountNumber, sequence: voteSequence } = await client.getNonce(); + const voteSignBytes = makeSignBytes( + [voteMsg], + defaultFee, + chainId, + voteMemo, + voteAccountNumber, + voteSequence, + ); + const voteSignature = await wallet.sign(alice.address0, voteSignBytes); + const voteTx = { + msg: [voteMsg], + fee: defaultFee, + memo: voteMemo, + signatures: [voteSignature], + }; + return client.postTx(voteTx); +} + +async function main() { + const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic); + const client = new SigningCosmosClient(httpUrl, alice.address0, wallet, {}); + + const proposalReceipt = await submitProposal(client, wallet); + console.info(`Proposal submission succeeded. Receipt: ${JSON.stringify(proposalReceipt)}`); + + const proposalId = proposalReceipt.logs[0].events + .find(({ type }) => type === "submit_proposal") + .attributes.find(({ key }) => key === "proposal_id").value; + const voteReceipt = await submitVote(client, wallet, proposalId); + console.info(`Vote succeeded. Receipt: ${JSON.stringify(voteReceipt)}`); +} + +main().then( + () => { + console.info("Done submitting proposal."); + process.exit(0); + }, + (error) => { + console.error(error); + process.exit(1); + }, +); From f5aab614a6b99f73cf253ad7dfa6b436cdb3b899 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 11:28:12 +0200 Subject: [PATCH 05/12] sdk38: Add remaining gov endpoints to lcd --- packages/sdk38/src/lcdapi/gov.spec.ts | 164 +++++++++++++++++++++++++- packages/sdk38/src/lcdapi/gov.ts | 73 +++++++++--- packages/sdk38/types/lcdapi/gov.d.ts | 62 +++++++--- 3 files changed, 261 insertions(+), 38 deletions(-) diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 7ec10cf6..b5988036 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -1,8 +1,15 @@ /* eslint-disable @typescript-eslint/camelcase */ -import { nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd } from "../testutils.spec"; +import { + dateTimeStampMatcher, + nonNegativeIntegerMatcher, + pendingWithoutWasmd, + wasmd, +} from "../testutils.spec"; import { GovExtension, GovParametersType, setupGovExtension } from "./gov"; import { LcdClient } from "./lcdclient"; +const governorAddress = "cosmos14qemq0vw6y3gc3u3e0aty2e764u4gs5le3hada"; + function makeGovClient(apiUrl: string): LcdClient & GovExtension { return LcdClient.withExtensions({ apiUrl }, setupGovExtension); } @@ -59,7 +66,160 @@ describe("GovExtension", () => { const response = await client.gov.proposals(); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), - result: [], + result: [ + { + content: { + type: "cosmos-sdk/TextProposal", + value: { + title: "Test Proposal", + description: "This proposal proposes to test whether this proposal passes", + }, + }, + id: "1", + proposal_status: "VotingPeriod", + final_tally_result: Object({ yes: "0", abstain: "0", no: "0", no_with_veto: "0" }), + submit_time: jasmine.stringMatching(dateTimeStampMatcher), + deposit_end_time: jasmine.stringMatching(dateTimeStampMatcher), + total_deposit: [{ denom: "ustake", amount: "25000000" }], + voting_start_time: jasmine.stringMatching(dateTimeStampMatcher), + voting_end_time: jasmine.stringMatching(dateTimeStampMatcher), + }, + ], + }); + }); + }); + + describe("proposal", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.proposal(proposalId); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + content: { + type: "cosmos-sdk/TextProposal", + value: { + title: "Test Proposal", + description: "This proposal proposes to test whether this proposal passes", + }, + }, + id: proposalId, + proposal_status: "VotingPeriod", + final_tally_result: Object({ yes: "0", abstain: "0", no: "0", no_with_veto: "0" }), + submit_time: jasmine.stringMatching(dateTimeStampMatcher), + deposit_end_time: jasmine.stringMatching(dateTimeStampMatcher), + total_deposit: [{ denom: "ustake", amount: "25000000" }], + voting_start_time: jasmine.stringMatching(dateTimeStampMatcher), + voting_end_time: jasmine.stringMatching(dateTimeStampMatcher), + }, + }); + }); + }); + + describe("proposer", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.proposer(proposalId); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + proposal_id: proposalId, + proposer: governorAddress, + }, + }); + }); + }); + + describe("deposits", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.deposits(proposalId); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + proposal_id: proposalId, + depositor: governorAddress, + amount: [{ denom: "ustake", amount: "25000000" }], + }, + ], + }); + }); + }); + + describe("deposit", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.deposit(proposalId, governorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + proposal_id: proposalId, + depositor: governorAddress, + amount: [{ denom: "ustake", amount: "25000000" }], + }, + }); + }); + }); + + describe("tally", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.tally(proposalId); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + yes: "0", + abstain: "0", + no: "0", + no_with_veto: "0", + }, + }); + }); + }); + + describe("votes", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.votes(proposalId); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + proposal_id: proposalId, + voter: governorAddress, + option: "Yes", + }, + ], + }); + }); + }); + + describe("vote", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeGovClient(wasmd.endpoint); + const proposalId = "1"; + const response = await client.gov.vote(proposalId, governorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + voter: governorAddress, + proposal_id: proposalId, + option: "Yes", + }, }); }); }); diff --git a/packages/sdk38/src/lcdapi/gov.ts b/packages/sdk38/src/lcdapi/gov.ts index 2d9d78d2..8bf0dde9 100644 --- a/packages/sdk38/src/lcdapi/gov.ts +++ b/packages/sdk38/src/lcdapi/gov.ts @@ -36,69 +36,97 @@ export type GovParametersByTypeResponse = | GovParametersTallyingResponse | GovParametersVotingResponse; -export interface TallyResult { +export interface Tally { readonly yes: string; readonly abstain: string; readonly no: string; readonly no_with_veto: string; } -export interface TextProposal { - readonly proposal_id: number; - readonly title: string; - readonly description: string; - readonly proposal_type: string; +export interface Proposal { + readonly id: string; readonly proposal_status: string; - readonly final_tally_result: TallyResult; + readonly final_tally_result: Tally; readonly submit_time: string; readonly total_deposit: readonly Coin[]; + readonly deposit_end_time: string; readonly voting_start_time: string; + readonly voting_end_time: string; + readonly content: { + readonly type: string; + readonly value: { + readonly title: string; + readonly description: string; + }; + }; } export interface GovProposalsResponse { readonly height: string; - readonly result: readonly TextProposal[]; + readonly result: readonly Proposal[]; } -export interface GovProposalsByIdResponse { +export interface GovProposalResponse { readonly height: string; - readonly result: {}; + readonly result: Proposal; } export interface GovProposerResponse { readonly height: string; - readonly result: {}; + readonly result: { + readonly proposal_id: string; + readonly proposer: string; + }; +} + +export interface Deposit { + readonly amount: readonly Coin[]; + readonly proposal_id: string; + readonly depositor: string; } export interface GovDepositsResponse { readonly height: string; - readonly result: {}; + readonly result: readonly Deposit[]; } -export interface GovDepositsByDepositorResponse { +export interface GovDepositResponse { readonly height: string; - readonly result: {}; + readonly result: Deposit; } export interface GovTallyResponse { readonly height: string; - readonly result: {}; + readonly result: Tally; +} + +export interface Vote { + readonly voter: string; + readonly proposal_id: string; + readonly option: string; } export interface GovVotesResponse { readonly height: string; - readonly result: {}; + readonly result: readonly Vote[]; } -export interface GovVotesByVoterResponse { +export interface GovVoteResponse { readonly height: string; - readonly result: {}; + readonly result: Vote; } export interface GovExtension { readonly gov: { readonly parametersByType: (parametersType: GovParametersType) => Promise; readonly proposals: () => Promise; + readonly proposal: (proposalId: string) => Promise; + readonly proposer: (proposalId: string) => Promise; + readonly deposits: (proposalId: string) => Promise; + readonly deposit: (proposalId: string, depositorAddress: string) => Promise; + readonly tally: (proposalId: string) => Promise; + readonly votes: (proposalId: string) => Promise; + readonly vote: (proposalId: string, voterAddress: string) => Promise; }; } @@ -108,6 +136,15 @@ export function setupGovExtension(base: LcdClient): GovExtension { parametersByType: async (parametersType: GovParametersType) => base.get(`/gov/parameters/${parametersType}`), proposals: async () => base.get("/gov/proposals"), + proposal: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}`), + proposer: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}/proposer`), + deposits: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}/deposits`), + deposit: async (proposalId: string, depositorAddress: string) => + base.get(`/gov/proposals/${proposalId}/deposits/${depositorAddress}`), + tally: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}/tally`), + votes: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}/votes`), + vote: async (proposalId: string, voterAddress: string) => + base.get(`/gov/proposals/${proposalId}/votes/${voterAddress}`), }, }; } diff --git a/packages/sdk38/types/lcdapi/gov.d.ts b/packages/sdk38/types/lcdapi/gov.d.ts index bdf24211..67e41362 100644 --- a/packages/sdk38/types/lcdapi/gov.d.ts +++ b/packages/sdk38/types/lcdapi/gov.d.ts @@ -30,59 +30,85 @@ export declare type GovParametersByTypeResponse = | GovParametersDepositResponse | GovParametersTallyingResponse | GovParametersVotingResponse; -export interface TallyResult { +export interface Tally { readonly yes: string; readonly abstain: string; readonly no: string; readonly no_with_veto: string; } -export interface TextProposal { - readonly proposal_id: number; - readonly title: string; - readonly description: string; - readonly proposal_type: string; +export interface Proposal { + readonly id: string; readonly proposal_status: string; - readonly final_tally_result: TallyResult; + readonly final_tally_result: Tally; readonly submit_time: string; readonly total_deposit: readonly Coin[]; + readonly deposit_end_time: string; readonly voting_start_time: string; + readonly voting_end_time: string; + readonly content: { + readonly type: string; + readonly value: { + readonly title: string; + readonly description: string; + }; + }; } export interface GovProposalsResponse { readonly height: string; - readonly result: readonly TextProposal[]; + readonly result: readonly Proposal[]; } -export interface GovProposalsByIdResponse { +export interface GovProposalResponse { readonly height: string; - readonly result: {}; + readonly result: Proposal; } export interface GovProposerResponse { readonly height: string; - readonly result: {}; + readonly result: { + readonly proposal_id: string; + readonly proposer: string; + }; +} +export interface Deposit { + readonly amount: readonly Coin[]; + readonly proposal_id: string; + readonly depositor: string; } export interface GovDepositsResponse { readonly height: string; - readonly result: {}; + readonly result: readonly Deposit[]; } -export interface GovDepositsByDepositorResponse { +export interface GovDepositResponse { readonly height: string; - readonly result: {}; + readonly result: Deposit; } export interface GovTallyResponse { readonly height: string; - readonly result: {}; + readonly result: Tally; +} +export interface Vote { + readonly voter: string; + readonly proposal_id: string; + readonly option: string; } export interface GovVotesResponse { readonly height: string; - readonly result: {}; + readonly result: readonly Vote[]; } -export interface GovVotesByVoterResponse { +export interface GovVoteResponse { readonly height: string; - readonly result: {}; + readonly result: Vote; } export interface GovExtension { readonly gov: { readonly parametersByType: (parametersType: GovParametersType) => Promise; readonly proposals: () => Promise; + readonly proposal: (proposalId: string) => Promise; + readonly proposer: (proposalId: string) => Promise; + readonly deposits: (proposalId: string) => Promise; + readonly deposit: (proposalId: string, depositorAddress: string) => Promise; + readonly tally: (proposalId: string) => Promise; + readonly votes: (proposalId: string) => Promise; + readonly vote: (proposalId: string, voterAddress: string) => Promise; }; } export declare function setupGovExtension(base: LcdClient): GovExtension; From 55917c6cbff6d078c6ea18c4e63e722bfcee9256 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 11:30:34 +0200 Subject: [PATCH 06/12] sdk38: Export gov types and setup function --- packages/sdk38/src/index.ts | 11 +++++++++++ packages/sdk38/src/lcdapi/index.ts | 13 +++++++++++++ packages/sdk38/types/index.d.ts | 11 +++++++++++ packages/sdk38/types/lcdapi/index.d.ts | 13 +++++++++++++ 4 files changed, 48 insertions(+) diff --git a/packages/sdk38/src/index.ts b/packages/sdk38/src/index.ts index 4233a729..7d20f0e0 100644 --- a/packages/sdk38/src/index.ts +++ b/packages/sdk38/src/index.ts @@ -28,6 +28,16 @@ export { BlockResponse, BroadcastMode, EncodeTxResponse, + GovExtension, + GovParametersByTypeResponse, + GovProposalsResponse, + GovProposalResponse, + GovProposerResponse, + GovDepositsResponse, + GovDepositResponse, + GovTallyResponse, + GovVotesResponse, + GovVoteResponse, LcdApiArray, LcdClient, MintAnnualProvisionsResponse, @@ -40,6 +50,7 @@ export { SearchTxsResponse, setupAuthExtension, setupBankExtension, + setupGovExtension, setupMintExtension, setupSlashingExtension, setupSupplyExtension, diff --git a/packages/sdk38/src/lcdapi/index.ts b/packages/sdk38/src/lcdapi/index.ts index 11ef100e..f536e0ea 100644 --- a/packages/sdk38/src/lcdapi/index.ts +++ b/packages/sdk38/src/lcdapi/index.ts @@ -4,6 +4,19 @@ export { AuthExtension, AuthAccountsResponse, setupAuthExtension } from "./auth"; export { BankBalancesResponse, BankExtension, setupBankExtension } from "./bank"; +export { + GovExtension, + GovParametersByTypeResponse, + GovProposalsResponse, + GovProposalResponse, + GovProposerResponse, + GovDepositsResponse, + GovDepositResponse, + GovTallyResponse, + GovVotesResponse, + GovVoteResponse, + setupGovExtension, +} from "./gov"; export { MintAnnualProvisionsResponse, MintExtension, diff --git a/packages/sdk38/types/index.d.ts b/packages/sdk38/types/index.d.ts index 4fd2a02e..67ed9f49 100644 --- a/packages/sdk38/types/index.d.ts +++ b/packages/sdk38/types/index.d.ts @@ -26,6 +26,16 @@ export { BlockResponse, BroadcastMode, EncodeTxResponse, + GovExtension, + GovParametersByTypeResponse, + GovProposalsResponse, + GovProposalResponse, + GovProposerResponse, + GovDepositsResponse, + GovDepositResponse, + GovTallyResponse, + GovVotesResponse, + GovVoteResponse, LcdApiArray, LcdClient, MintAnnualProvisionsResponse, @@ -38,6 +48,7 @@ export { SearchTxsResponse, setupAuthExtension, setupBankExtension, + setupGovExtension, setupMintExtension, setupSlashingExtension, setupSupplyExtension, diff --git a/packages/sdk38/types/lcdapi/index.d.ts b/packages/sdk38/types/lcdapi/index.d.ts index d22a29b4..c89c0ed8 100644 --- a/packages/sdk38/types/lcdapi/index.d.ts +++ b/packages/sdk38/types/lcdapi/index.d.ts @@ -1,5 +1,18 @@ export { AuthExtension, AuthAccountsResponse, setupAuthExtension } from "./auth"; export { BankBalancesResponse, BankExtension, setupBankExtension } from "./bank"; +export { + GovExtension, + GovParametersByTypeResponse, + GovProposalsResponse, + GovProposalResponse, + GovProposerResponse, + GovDepositsResponse, + GovDepositResponse, + GovTallyResponse, + GovVotesResponse, + GovVoteResponse, + setupGovExtension, +} from "./gov"; export { MintAnnualProvisionsResponse, MintExtension, From a00c5e8f8da41c118ac4d685e69890bb237226d0 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 15:11:24 +0200 Subject: [PATCH 07/12] sdk38: Move proposal submission into test script --- packages/sdk38/src/lcdapi/gov.spec.ts | 158 ++++++++++++++++++++------ scripts/wasmd/init.sh | 1 - scripts/wasmd/submit_proposal.js | 106 ----------------- 3 files changed, 121 insertions(+), 144 deletions(-) delete mode 100755 scripts/wasmd/submit_proposal.js diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index b5988036..451bade5 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -1,20 +1,114 @@ /* eslint-disable @typescript-eslint/camelcase */ +import { sleep } from "@cosmjs/utils"; + +import { coins } from "../coins"; +import { isPostTxFailure } from "../cosmosclient"; +import { makeSignBytes } from "../encoding"; +import { SigningCosmosClient } from "../signingcosmosclient"; import { dateTimeStampMatcher, nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd, + wasmdEnabled, } from "../testutils.spec"; +import { Secp256k1Wallet } from "../wallet"; import { GovExtension, GovParametersType, setupGovExtension } from "./gov"; import { LcdClient } from "./lcdclient"; -const governorAddress = "cosmos14qemq0vw6y3gc3u3e0aty2e764u4gs5le3hada"; - function makeGovClient(apiUrl: string): LcdClient & GovExtension { return LcdClient.withExtensions({ apiUrl }, setupGovExtension); } describe("GovExtension", () => { + const httpUrl = "http://localhost:1317"; + const alice = { + mnemonic: "enlist hip relief stomach skate base shallow young switch frequent cry park", + address0: "cosmos14qemq0vw6y3gc3u3e0aty2e764u4gs5le3hada", + }; + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + let proposalId: string; + + beforeAll(async () => { + if (wasmdEnabled()) { + const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic); + const client = new SigningCosmosClient(httpUrl, alice.address0, wallet, {}); + + const chainId = await client.getChainId(); + const proposalMsg = { + type: "cosmos-sdk/MsgSubmitProposal", + value: { + content: { + type: "cosmos-sdk/TextProposal", + value: { + description: "This proposal proposes to test whether this proposal passes", + title: "Test Proposal", + }, + }, + proposer: alice.address0, + initial_deposit: coins(25000000, "ustake"), + }, + }; + const proposalMemo = "Test proposal for wasmd"; + const { accountNumber: proposalAccountNumber, sequence: proposalSequence } = await client.getNonce(); + const proposalSignBytes = makeSignBytes( + [proposalMsg], + defaultFee, + chainId, + proposalMemo, + proposalAccountNumber, + proposalSequence, + ); + const proposalSignature = await wallet.sign(alice.address0, proposalSignBytes); + const proposalTx = { + msg: [proposalMsg], + fee: defaultFee, + memo: proposalMemo, + signatures: [proposalSignature], + }; + + const proposalReceipt = await client.postTx(proposalTx); + if (isPostTxFailure(proposalReceipt)) { + throw new Error("Proposal submission failed"); + } + proposalId = proposalReceipt.logs[0].events + .find(({ type }) => type === "submit_proposal")! + .attributes.find(({ key }) => key === "proposal_id")!.value; + + const voteMsg = { + type: "cosmos-sdk/MsgVote", + value: { + proposal_id: proposalId, + voter: alice.address0, + option: "Yes", + }, + }; + const voteMemo = "Test vote for wasmd"; + const { accountNumber: voteAccountNumber, sequence: voteSequence } = await client.getNonce(); + const voteSignBytes = makeSignBytes( + [voteMsg], + defaultFee, + chainId, + voteMemo, + voteAccountNumber, + voteSequence, + ); + const voteSignature = await wallet.sign(alice.address0, voteSignBytes); + const voteTx = { + msg: [voteMsg], + fee: defaultFee, + memo: voteMemo, + signatures: [voteSignature], + }; + await client.postTx(voteTx); + + await sleep(75); // wait until transactions are indexed + } + }); + describe("parametersByType", () => { it("works for deposit", async () => { pendingWithoutWasmd(); @@ -64,27 +158,24 @@ describe("GovExtension", () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); const response = await client.gov.proposals(); - expect(response).toEqual({ - height: jasmine.stringMatching(nonNegativeIntegerMatcher), - result: [ - { - content: { - type: "cosmos-sdk/TextProposal", - value: { - title: "Test Proposal", - description: "This proposal proposes to test whether this proposal passes", - }, - }, - id: "1", - proposal_status: "VotingPeriod", - final_tally_result: Object({ yes: "0", abstain: "0", no: "0", no_with_veto: "0" }), - submit_time: jasmine.stringMatching(dateTimeStampMatcher), - deposit_end_time: jasmine.stringMatching(dateTimeStampMatcher), - total_deposit: [{ denom: "ustake", amount: "25000000" }], - voting_start_time: jasmine.stringMatching(dateTimeStampMatcher), - voting_end_time: jasmine.stringMatching(dateTimeStampMatcher), + expect(response.height).toMatch(nonNegativeIntegerMatcher); + expect(response.result.length).toBeGreaterThanOrEqual(1); + expect(response.result[response.result.length - 1]).toEqual({ + content: { + type: "cosmos-sdk/TextProposal", + value: { + title: "Test Proposal", + description: "This proposal proposes to test whether this proposal passes", }, - ], + }, + id: proposalId, + proposal_status: "VotingPeriod", + final_tally_result: { yes: "0", abstain: "0", no: "0", no_with_veto: "0" }, + submit_time: jasmine.stringMatching(dateTimeStampMatcher), + deposit_end_time: jasmine.stringMatching(dateTimeStampMatcher), + total_deposit: [{ denom: "ustake", amount: "25000000" }], + voting_start_time: jasmine.stringMatching(dateTimeStampMatcher), + voting_end_time: jasmine.stringMatching(dateTimeStampMatcher), }); }); }); @@ -93,7 +184,6 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; const response = await client.gov.proposal(proposalId); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), @@ -107,7 +197,7 @@ describe("GovExtension", () => { }, id: proposalId, proposal_status: "VotingPeriod", - final_tally_result: Object({ yes: "0", abstain: "0", no: "0", no_with_veto: "0" }), + final_tally_result: { yes: "0", abstain: "0", no: "0", no_with_veto: "0" }, submit_time: jasmine.stringMatching(dateTimeStampMatcher), deposit_end_time: jasmine.stringMatching(dateTimeStampMatcher), total_deposit: [{ denom: "ustake", amount: "25000000" }], @@ -122,13 +212,12 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; const response = await client.gov.proposer(proposalId); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { proposal_id: proposalId, - proposer: governorAddress, + proposer: alice.address0, }, }); }); @@ -138,14 +227,13 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; const response = await client.gov.deposits(proposalId); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { proposal_id: proposalId, - depositor: governorAddress, + depositor: alice.address0, amount: [{ denom: "ustake", amount: "25000000" }], }, ], @@ -157,13 +245,12 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; - const response = await client.gov.deposit(proposalId, governorAddress); + const response = await client.gov.deposit(proposalId, alice.address0); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { proposal_id: proposalId, - depositor: governorAddress, + depositor: alice.address0, amount: [{ denom: "ustake", amount: "25000000" }], }, }); @@ -174,7 +261,6 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; const response = await client.gov.tally(proposalId); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), @@ -192,14 +278,13 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; const response = await client.gov.votes(proposalId); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { proposal_id: proposalId, - voter: governorAddress, + voter: alice.address0, option: "Yes", }, ], @@ -211,12 +296,11 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const proposalId = "1"; - const response = await client.gov.vote(proposalId, governorAddress); + const response = await client.gov.vote(proposalId, alice.address0); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { - voter: governorAddress, + voter: alice.address0, proposal_id: proposalId, option: "Yes", }, diff --git a/scripts/wasmd/init.sh b/scripts/wasmd/init.sh index d4ac08cf..8a64df01 100755 --- a/scripts/wasmd/init.sh +++ b/scripts/wasmd/init.sh @@ -19,4 +19,3 @@ SCRIPT_DIR="$(realpath "$(dirname "$0")")" "$SCRIPT_DIR/deploy_erc20.js" "$SCRIPT_DIR/deploy_nameservice.js" "$SCRIPT_DIR/deploy_staking.js" -"$SCRIPT_DIR/submit_proposal.js" diff --git a/scripts/wasmd/submit_proposal.js b/scripts/wasmd/submit_proposal.js deleted file mode 100755 index 4dd4ce3e..00000000 --- a/scripts/wasmd/submit_proposal.js +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env node - -/* eslint-disable @typescript-eslint/camelcase */ -const { coins, Secp256k1Wallet, SigningCosmosClient, makeSignBytes } = require("@cosmjs/sdk38"); - -const httpUrl = "http://localhost:1317"; -const alice = { - mnemonic: "enlist hip relief stomach skate base shallow young switch frequent cry park", - address0: "cosmos14qemq0vw6y3gc3u3e0aty2e764u4gs5le3hada", -}; - -const defaultFee = { - amount: coins(25000, "ucosm"), - gas: "1500000", // 1.5 million -}; - -async function submitProposal(client, wallet) { - const chainId = await client.getChainId(); - const proposalMsg = { - type: "cosmos-sdk/MsgSubmitProposal", - value: { - content: { - type: "cosmos-sdk/TextProposal", - value: { - description: "This proposal proposes to test whether this proposal passes", - title: "Test Proposal", - }, - }, - proposer: alice.address0, - initial_deposit: coins(25000000, "ustake"), - }, - }; - const proposalMemo = "Test proposal for wasmd"; - const { accountNumber: proposalAccountNumber, sequence: proposalSequence } = await client.getNonce(); - const proposalSignBytes = makeSignBytes( - [proposalMsg], - defaultFee, - chainId, - proposalMemo, - proposalAccountNumber, - proposalSequence, - ); - const proposalSignature = await wallet.sign(alice.address0, proposalSignBytes); - const proposalTx = { - msg: [proposalMsg], - fee: defaultFee, - memo: proposalMemo, - signatures: [proposalSignature], - }; - return client.postTx(proposalTx); -} - -async function submitVote(client, wallet, proposalId) { - const chainId = await client.getChainId(); - const voteMsg = { - type: "cosmos-sdk/MsgVote", - value: { - proposal_id: proposalId, - voter: alice.address0, - option: "Yes", - }, - }; - const voteMemo = "Test vote for wasmd"; - const { accountNumber: voteAccountNumber, sequence: voteSequence } = await client.getNonce(); - const voteSignBytes = makeSignBytes( - [voteMsg], - defaultFee, - chainId, - voteMemo, - voteAccountNumber, - voteSequence, - ); - const voteSignature = await wallet.sign(alice.address0, voteSignBytes); - const voteTx = { - msg: [voteMsg], - fee: defaultFee, - memo: voteMemo, - signatures: [voteSignature], - }; - return client.postTx(voteTx); -} - -async function main() { - const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmosClient(httpUrl, alice.address0, wallet, {}); - - const proposalReceipt = await submitProposal(client, wallet); - console.info(`Proposal submission succeeded. Receipt: ${JSON.stringify(proposalReceipt)}`); - - const proposalId = proposalReceipt.logs[0].events - .find(({ type }) => type === "submit_proposal") - .attributes.find(({ key }) => key === "proposal_id").value; - const voteReceipt = await submitVote(client, wallet, proposalId); - console.info(`Vote succeeded. Receipt: ${JSON.stringify(voteReceipt)}`); -} - -main().then( - () => { - console.info("Done submitting proposal."); - process.exit(0); - }, - (error) => { - console.error(error); - process.exit(1); - }, -); From c5cc8fd0db2fefa949ad60d080335d432e1d071d Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 15:15:45 +0200 Subject: [PATCH 08/12] sdk38: Rename gov.parameters --- packages/sdk38/src/index.ts | 2 +- packages/sdk38/src/lcdapi/gov.spec.ts | 8 ++++---- packages/sdk38/src/lcdapi/gov.ts | 7 +++---- packages/sdk38/src/lcdapi/index.ts | 2 +- packages/sdk38/types/index.d.ts | 2 +- packages/sdk38/types/lcdapi/gov.d.ts | 4 ++-- packages/sdk38/types/lcdapi/index.d.ts | 2 +- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/sdk38/src/index.ts b/packages/sdk38/src/index.ts index 7d20f0e0..d9dd90ce 100644 --- a/packages/sdk38/src/index.ts +++ b/packages/sdk38/src/index.ts @@ -29,7 +29,7 @@ export { BroadcastMode, EncodeTxResponse, GovExtension, - GovParametersByTypeResponse, + GovParametersResponse, GovProposalsResponse, GovProposalResponse, GovProposerResponse, diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 451bade5..1f79c221 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -109,12 +109,12 @@ describe("GovExtension", () => { } }); - describe("parametersByType", () => { + describe("parameters", () => { it("works for deposit", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); const paramsType = GovParametersType.Deposit; - const response = await client.gov.parametersByType(paramsType); + const response = await client.gov.parameters(paramsType); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { @@ -128,7 +128,7 @@ describe("GovExtension", () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); const paramsType = GovParametersType.Tallying; - const response = await client.gov.parametersByType(paramsType); + const response = await client.gov.parameters(paramsType); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { @@ -143,7 +143,7 @@ describe("GovExtension", () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); const paramsType = GovParametersType.Voting; - const response = await client.gov.parametersByType(paramsType); + const response = await client.gov.parameters(paramsType); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { diff --git a/packages/sdk38/src/lcdapi/gov.ts b/packages/sdk38/src/lcdapi/gov.ts index 8bf0dde9..8c73fc40 100644 --- a/packages/sdk38/src/lcdapi/gov.ts +++ b/packages/sdk38/src/lcdapi/gov.ts @@ -31,7 +31,7 @@ export interface GovParametersVotingResponse { }; } -export type GovParametersByTypeResponse = +export type GovParametersResponse = | GovParametersDepositResponse | GovParametersTallyingResponse | GovParametersVotingResponse; @@ -118,7 +118,7 @@ export interface GovVoteResponse { export interface GovExtension { readonly gov: { - readonly parametersByType: (parametersType: GovParametersType) => Promise; + readonly parameters: (parametersType: GovParametersType) => Promise; readonly proposals: () => Promise; readonly proposal: (proposalId: string) => Promise; readonly proposer: (proposalId: string) => Promise; @@ -133,8 +133,7 @@ export interface GovExtension { export function setupGovExtension(base: LcdClient): GovExtension { return { gov: { - parametersByType: async (parametersType: GovParametersType) => - base.get(`/gov/parameters/${parametersType}`), + parameters: async (parametersType: GovParametersType) => base.get(`/gov/parameters/${parametersType}`), proposals: async () => base.get("/gov/proposals"), proposal: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}`), proposer: async (proposalId: string) => base.get(`/gov/proposals/${proposalId}/proposer`), diff --git a/packages/sdk38/src/lcdapi/index.ts b/packages/sdk38/src/lcdapi/index.ts index f536e0ea..80bd53b7 100644 --- a/packages/sdk38/src/lcdapi/index.ts +++ b/packages/sdk38/src/lcdapi/index.ts @@ -6,7 +6,7 @@ export { AuthExtension, AuthAccountsResponse, setupAuthExtension } from "./auth" export { BankBalancesResponse, BankExtension, setupBankExtension } from "./bank"; export { GovExtension, - GovParametersByTypeResponse, + GovParametersResponse, GovProposalsResponse, GovProposalResponse, GovProposerResponse, diff --git a/packages/sdk38/types/index.d.ts b/packages/sdk38/types/index.d.ts index 67ed9f49..4f22dbbc 100644 --- a/packages/sdk38/types/index.d.ts +++ b/packages/sdk38/types/index.d.ts @@ -27,7 +27,7 @@ export { BroadcastMode, EncodeTxResponse, GovExtension, - GovParametersByTypeResponse, + GovParametersResponse, GovProposalsResponse, GovProposalResponse, GovProposerResponse, diff --git a/packages/sdk38/types/lcdapi/gov.d.ts b/packages/sdk38/types/lcdapi/gov.d.ts index 67e41362..b7f3f8fd 100644 --- a/packages/sdk38/types/lcdapi/gov.d.ts +++ b/packages/sdk38/types/lcdapi/gov.d.ts @@ -26,7 +26,7 @@ export interface GovParametersVotingResponse { readonly voting_period: string; }; } -export declare type GovParametersByTypeResponse = +export declare type GovParametersResponse = | GovParametersDepositResponse | GovParametersTallyingResponse | GovParametersVotingResponse; @@ -100,7 +100,7 @@ export interface GovVoteResponse { } export interface GovExtension { readonly gov: { - readonly parametersByType: (parametersType: GovParametersType) => Promise; + readonly parameters: (parametersType: GovParametersType) => Promise; readonly proposals: () => Promise; readonly proposal: (proposalId: string) => Promise; readonly proposer: (proposalId: string) => Promise; diff --git a/packages/sdk38/types/lcdapi/index.d.ts b/packages/sdk38/types/lcdapi/index.d.ts index c89c0ed8..b9f984ac 100644 --- a/packages/sdk38/types/lcdapi/index.d.ts +++ b/packages/sdk38/types/lcdapi/index.d.ts @@ -2,7 +2,7 @@ export { AuthExtension, AuthAccountsResponse, setupAuthExtension } from "./auth" export { BankBalancesResponse, BankExtension, setupBankExtension } from "./bank"; export { GovExtension, - GovParametersByTypeResponse, + GovParametersResponse, GovProposalsResponse, GovProposalResponse, GovProposerResponse, From 8f7b2f0ab927b96dbd58790bc4fb5e00cec1eda8 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 15:47:53 +0200 Subject: [PATCH 09/12] sdk38: Use test faucet in gov module test --- packages/sdk38/src/lcdapi/gov.spec.ts | 31 ++++++++++++--------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 1f79c221..56278a0f 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -7,6 +7,7 @@ import { makeSignBytes } from "../encoding"; import { SigningCosmosClient } from "../signingcosmosclient"; import { dateTimeStampMatcher, + faucet, nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd, @@ -22,10 +23,6 @@ function makeGovClient(apiUrl: string): LcdClient & GovExtension { describe("GovExtension", () => { const httpUrl = "http://localhost:1317"; - const alice = { - mnemonic: "enlist hip relief stomach skate base shallow young switch frequent cry park", - address0: "cosmos14qemq0vw6y3gc3u3e0aty2e764u4gs5le3hada", - }; const defaultFee = { amount: coins(25000, "ucosm"), gas: "1500000", // 1.5 million @@ -34,8 +31,8 @@ describe("GovExtension", () => { beforeAll(async () => { if (wasmdEnabled()) { - const wallet = await Secp256k1Wallet.fromMnemonic(alice.mnemonic); - const client = new SigningCosmosClient(httpUrl, alice.address0, wallet, {}); + const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic); + const client = new SigningCosmosClient(httpUrl, faucet.address, wallet, {}); const chainId = await client.getChainId(); const proposalMsg = { @@ -48,7 +45,7 @@ describe("GovExtension", () => { title: "Test Proposal", }, }, - proposer: alice.address0, + proposer: faucet.address, initial_deposit: coins(25000000, "ustake"), }, }; @@ -62,7 +59,7 @@ describe("GovExtension", () => { proposalAccountNumber, proposalSequence, ); - const proposalSignature = await wallet.sign(alice.address0, proposalSignBytes); + const proposalSignature = await wallet.sign(faucet.address, proposalSignBytes); const proposalTx = { msg: [proposalMsg], fee: defaultFee, @@ -82,7 +79,7 @@ describe("GovExtension", () => { type: "cosmos-sdk/MsgVote", value: { proposal_id: proposalId, - voter: alice.address0, + voter: faucet.address, option: "Yes", }, }; @@ -96,7 +93,7 @@ describe("GovExtension", () => { voteAccountNumber, voteSequence, ); - const voteSignature = await wallet.sign(alice.address0, voteSignBytes); + const voteSignature = await wallet.sign(faucet.address, voteSignBytes); const voteTx = { msg: [voteMsg], fee: defaultFee, @@ -217,7 +214,7 @@ describe("GovExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { proposal_id: proposalId, - proposer: alice.address0, + proposer: faucet.address, }, }); }); @@ -233,7 +230,7 @@ describe("GovExtension", () => { result: [ { proposal_id: proposalId, - depositor: alice.address0, + depositor: faucet.address, amount: [{ denom: "ustake", amount: "25000000" }], }, ], @@ -245,12 +242,12 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const response = await client.gov.deposit(proposalId, alice.address0); + const response = await client.gov.deposit(proposalId, faucet.address); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { proposal_id: proposalId, - depositor: alice.address0, + depositor: faucet.address, amount: [{ denom: "ustake", amount: "25000000" }], }, }); @@ -284,7 +281,7 @@ describe("GovExtension", () => { result: [ { proposal_id: proposalId, - voter: alice.address0, + voter: faucet.address, option: "Yes", }, ], @@ -296,11 +293,11 @@ describe("GovExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeGovClient(wasmd.endpoint); - const response = await client.gov.vote(proposalId, alice.address0); + const response = await client.gov.vote(proposalId, faucet.address); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { - voter: alice.address0, + voter: faucet.address, proposal_id: proposalId, option: "Yes", }, From 9f651cd305ea8ffd42f938e02c2f8573aa2637ce Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 17:01:26 +0200 Subject: [PATCH 10/12] sdk38: Switch to eslint naming-convention rule in gov module --- packages/sdk38/src/lcdapi/gov.spec.ts | 2 +- packages/sdk38/src/lcdapi/gov.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 56278a0f..6804e1bd 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/camelcase */ +/* eslint-disable @typescript-eslint/naming-convention */ import { sleep } from "@cosmjs/utils"; import { coins } from "../coins"; diff --git a/packages/sdk38/src/lcdapi/gov.ts b/packages/sdk38/src/lcdapi/gov.ts index 8c73fc40..f7b46635 100644 --- a/packages/sdk38/src/lcdapi/gov.ts +++ b/packages/sdk38/src/lcdapi/gov.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import { Coin } from "../coins"; import { LcdClient } from "./lcdclient"; From 79afed49af619cc1bb5fa784c29bdb81a2ef696d Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 15 Jul 2020 17:24:47 +0200 Subject: [PATCH 11/12] sdk38: Use wasmd.endpoint in gov module test --- packages/sdk38/src/lcdapi/gov.spec.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 6804e1bd..88fd35f9 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -22,7 +22,6 @@ function makeGovClient(apiUrl: string): LcdClient & GovExtension { } describe("GovExtension", () => { - const httpUrl = "http://localhost:1317"; const defaultFee = { amount: coins(25000, "ucosm"), gas: "1500000", // 1.5 million @@ -32,7 +31,7 @@ describe("GovExtension", () => { beforeAll(async () => { if (wasmdEnabled()) { const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic); - const client = new SigningCosmosClient(httpUrl, faucet.address, wallet, {}); + const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, wallet, {}); const chainId = await client.getChainId(); const proposalMsg = { From c8ba1fd574cf83894e5e65c33ba5c6e09184b62d Mon Sep 17 00:00:00 2001 From: willclarktech Date: Thu, 16 Jul 2020 11:07:59 +0200 Subject: [PATCH 12/12] sdk38: Use assert util in gov module test --- packages/sdk38/src/lcdapi/gov.spec.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/sdk38/src/lcdapi/gov.spec.ts b/packages/sdk38/src/lcdapi/gov.spec.ts index 88fd35f9..594be5d5 100644 --- a/packages/sdk38/src/lcdapi/gov.spec.ts +++ b/packages/sdk38/src/lcdapi/gov.spec.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { sleep } from "@cosmjs/utils"; +import { assert, sleep } from "@cosmjs/utils"; import { coins } from "../coins"; import { isPostTxFailure } from "../cosmosclient"; @@ -67,9 +67,7 @@ describe("GovExtension", () => { }; const proposalReceipt = await client.postTx(proposalTx); - if (isPostTxFailure(proposalReceipt)) { - throw new Error("Proposal submission failed"); - } + assert(!isPostTxFailure(proposalReceipt)); proposalId = proposalReceipt.logs[0].events .find(({ type }) => type === "submit_proposal")! .attributes.find(({ key }) => key === "proposal_id")!.value;