Skip to content

Commit 70bbf0d

Browse files
committed
fix starship test for interchainjs
1 parent fb8dcf1 commit 70bbf0d

File tree

3 files changed

+819
-0
lines changed

3 files changed

+819
-0
lines changed
Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
import './setup.test';
2+
3+
import { Asset } from '@chain-registry/types';
4+
import { generateMnemonic } from '@confio/relayer/build/lib/helpers';
5+
import { assertIsDeliverTxSuccess } from '@cosmjs/stargate';
6+
import {
7+
AminoGenericOfflineSigner,
8+
DirectGenericOfflineSigner,
9+
OfflineAminoSigner,
10+
OfflineDirectSigner,
11+
} from '@interchainjs/cosmos/types/wallet';
12+
import { Secp256k1HDWallet } from '@interchainjs/cosmos/wallets/secp256k1hd';
13+
import {
14+
ProposalStatus,
15+
TextProposal,
16+
VoteOption,
17+
} from 'interchainjs/cosmos/gov/v1beta1/gov';
18+
import {
19+
BondStatus,
20+
bondStatusToJSON,
21+
} from 'interchainjs/cosmos/staking/v1beta1/staking';
22+
import { fromBase64, toUtf8 } from '@interchainjs/utils';
23+
import { BigNumber } from 'bignumber.js';
24+
import { SigningClient as CosmosSigningClient } from '@interchainjs/cosmos/signing-client';
25+
import { useChain } from 'starshipjs';
26+
27+
import { waitUntil } from '../src';
28+
29+
import { createDelegate } from "interchainjs/cosmos/staking/v1beta1/tx.rpc.func";
30+
import { createSubmitProposal, createVote } from "interchainjs/cosmos/gov/v1beta1/tx.rpc.func";
31+
32+
import { createGetBalance } from "interchainjs/cosmos/bank/v1beta1/query.rpc.func";
33+
import { createGetProposal, createGetVote } from "interchainjs/cosmos/gov/v1beta1/query.rpc.func";
34+
import { createGetValidators } from "interchainjs/cosmos/staking/v1beta1/query.rpc.func";
35+
import { QueryBalanceRequest, QueryBalanceResponse } from 'interchainjs/cosmos/bank/v1beta1/query';
36+
import { QueryProposalRequest, QueryProposalResponse, QueryVoteRequest, QueryVoteResponse } from 'interchainjs/cosmos/gov/v1beta1/query';
37+
import { QueryValidatorsRequest, QueryValidatorsResponse } from 'interchainjs/cosmos/staking/v1beta1/query';
38+
39+
const cosmosHdPath = "m/44'/118'/0'/0/0";
40+
41+
describe('Governance tests for osmosis', () => {
42+
let directSigner: OfflineDirectSigner,
43+
aminoSigner: OfflineAminoSigner,
44+
denom: string,
45+
directAddress: string,
46+
aminoAddress: string;
47+
let commonPrefix: string,
48+
chainInfo,
49+
getCoin: () => Promise<Asset>,
50+
getRpcEndpoint: () => Promise<string>,
51+
creditFromFaucet;
52+
53+
let getBalance: (request: QueryBalanceRequest) => Promise<QueryBalanceResponse>;
54+
let getProposal: (request: QueryProposalRequest) => Promise<QueryProposalResponse>;
55+
let getVote: (request: QueryVoteRequest) => Promise<QueryVoteResponse>;
56+
let getValidators: (request: QueryValidatorsRequest) => Promise<QueryValidatorsResponse>;
57+
58+
// Variables used accross testcases
59+
let proposalId: string;
60+
let validatorAddress: string;
61+
62+
beforeAll(async () => {
63+
({ chainInfo, getCoin, getRpcEndpoint, creditFromFaucet } =
64+
useChain('osmosis'));
65+
denom = (await getCoin()).base;
66+
67+
commonPrefix = chainInfo?.chain?.bech32_prefix;
68+
69+
// Initialize wallet
70+
const directWallet = Secp256k1HDWallet.fromMnemonic(generateMnemonic(), [
71+
{
72+
prefix: commonPrefix,
73+
hdPath: cosmosHdPath,
74+
},
75+
]);
76+
const aminoWallet = Secp256k1HDWallet.fromMnemonic(generateMnemonic(), [
77+
{
78+
prefix: commonPrefix,
79+
hdPath: cosmosHdPath,
80+
},
81+
]);
82+
directSigner = directWallet.toOfflineDirectSigner();
83+
aminoSigner = aminoWallet.toOfflineAminoSigner();
84+
directAddress = (await directSigner.getAccounts())[0].address;
85+
aminoAddress = (await aminoSigner.getAccounts())[0].address;
86+
87+
// Create custom cosmos interchain client
88+
const rpcEndpoint = await getRpcEndpoint();
89+
getBalance = createGetBalance(rpcEndpoint);
90+
getProposal = createGetProposal(rpcEndpoint);
91+
getVote = createGetVote(rpcEndpoint);
92+
getValidators = createGetValidators(rpcEndpoint);
93+
94+
// Transfer osmosis to address
95+
await creditFromFaucet(directAddress);
96+
await creditFromFaucet(aminoAddress);
97+
}, 200000);
98+
99+
it('check address has tokens', async () => {
100+
const { balance } = await getBalance({
101+
address: directAddress,
102+
denom,
103+
});
104+
105+
expect(balance!.amount).toEqual('10000000000');
106+
}, 10000);
107+
108+
it('query validator address', async () => {
109+
const { validators } = await getValidators({
110+
status: bondStatusToJSON(BondStatus.BOND_STATUS_BONDED),
111+
});
112+
let allValidators = validators;
113+
if (validators.length > 1) {
114+
allValidators = validators.sort((a, b) =>
115+
new BigNumber(b.tokens).minus(new BigNumber(a.tokens)).toNumber()
116+
);
117+
}
118+
119+
expect(allValidators.length).toBeGreaterThan(0);
120+
121+
// set validator address to the first one
122+
validatorAddress = allValidators[0].operatorAddress;
123+
});
124+
125+
it('stake tokens to genesis validator', async () => {
126+
const signingClient = await CosmosSigningClient.connectWithSigner(
127+
await getRpcEndpoint(),
128+
new DirectGenericOfflineSigner(directSigner),
129+
{
130+
broadcast: {
131+
checkTx: true,
132+
deliverTx: true,
133+
useLegacyBroadcastTxCommit: true,
134+
},
135+
}
136+
);
137+
138+
const delegate = createDelegate(signingClient);
139+
140+
const { balance } = await getBalance({
141+
address: directAddress,
142+
denom,
143+
});
144+
145+
// Stake half of the tokens
146+
// eslint-disable-next-line no-undef
147+
const delegationAmount = (BigInt(balance!.amount) / BigInt(2)).toString();
148+
149+
const fee = {
150+
amount: [
151+
{
152+
denom,
153+
amount: '100000',
154+
},
155+
],
156+
gas: '550000',
157+
};
158+
159+
const result = await delegate(
160+
directAddress,
161+
{
162+
delegatorAddress: directAddress,
163+
validatorAddress: validatorAddress,
164+
amount: {
165+
amount: delegationAmount,
166+
denom: balance!.denom,
167+
},
168+
},
169+
fee,
170+
"delegate"
171+
);
172+
assertIsDeliverTxSuccess(result);
173+
}, 10000);
174+
175+
it('submit a txt proposal', async () => {
176+
const signingClient = await CosmosSigningClient.connectWithSigner(
177+
await getRpcEndpoint(),
178+
new DirectGenericOfflineSigner(directSigner),
179+
{
180+
broadcast: {
181+
checkTx: true,
182+
deliverTx: true,
183+
},
184+
}
185+
);
186+
187+
const submitProposal = createSubmitProposal(signingClient);
188+
189+
const contentMsg = TextProposal.fromPartial({
190+
title: 'Test Proposal',
191+
description: 'Test text proposal for the e2e testing',
192+
});
193+
194+
// Stake half of the tokens
195+
const fee = {
196+
amount: [
197+
{
198+
denom,
199+
amount: '100000',
200+
},
201+
],
202+
gas: '550000',
203+
};
204+
205+
const result = await submitProposal(
206+
directAddress,
207+
{
208+
proposer: directAddress,
209+
initialDeposit: [
210+
{
211+
amount: '1000000',
212+
denom: denom,
213+
},
214+
],
215+
content: {
216+
typeUrl: '/cosmos.gov.v1beta1.TextProposal',
217+
value: TextProposal.encode(contentMsg).finish(),
218+
},
219+
},
220+
fee,
221+
"submit proposal"
222+
);
223+
assertIsDeliverTxSuccess(result);
224+
225+
// Get proposal id from log events
226+
const proposalIdEvent = result.events.find(
227+
(event) => event.type === 'submit_proposal'
228+
);
229+
const proposalIdEncoded = proposalIdEvent!.attributes.find(
230+
(attr) => toUtf8(fromBase64(attr.key)) === 'proposal_id'
231+
)!.value;
232+
proposalId = toUtf8(fromBase64(proposalIdEncoded));
233+
234+
// eslint-disable-next-line no-undef
235+
expect(BigInt(proposalId)).toBeGreaterThan(BigInt(0));
236+
}, 200000);
237+
238+
it('query proposal', async () => {
239+
const result = await getProposal({
240+
proposalId: BigInt(proposalId),
241+
});
242+
243+
expect(result.proposal.proposalId.toString()).toEqual(proposalId);
244+
}, 10000);
245+
246+
it('vote on proposal using direct', async () => {
247+
// create direct address signing client
248+
const signingClient = await CosmosSigningClient.connectWithSigner(
249+
await getRpcEndpoint(),
250+
new DirectGenericOfflineSigner(directSigner),
251+
{
252+
broadcast: {
253+
checkTx: true,
254+
deliverTx: true,
255+
useLegacyBroadcastTxCommit: true,
256+
},
257+
}
258+
);
259+
260+
const vote = createVote(signingClient);
261+
262+
// Vote on proposal from genesis mnemonic address
263+
const fee = {
264+
amount: [
265+
{
266+
denom,
267+
amount: '100000',
268+
},
269+
],
270+
gas: '550000',
271+
};
272+
273+
const result = await vote(
274+
directAddress,
275+
{
276+
proposalId: BigInt(proposalId),
277+
voter: directAddress,
278+
option: VoteOption.VOTE_OPTION_YES,
279+
},
280+
fee,
281+
"vote"
282+
);
283+
assertIsDeliverTxSuccess(result);
284+
}, 10000);
285+
286+
it('verify direct vote', async () => {
287+
const { vote } = await getVote({
288+
proposalId: BigInt(proposalId),
289+
voter: directAddress,
290+
});
291+
292+
expect(vote.proposalId.toString()).toEqual(proposalId);
293+
expect(vote.voter).toEqual(directAddress);
294+
expect(vote.option).toEqual(VoteOption.VOTE_OPTION_YES);
295+
}, 10000);
296+
297+
it('vote on proposal using amino', async () => {
298+
// create amino address signing client
299+
const signingClient = await CosmosSigningClient.connectWithSigner(
300+
await getRpcEndpoint(),
301+
new AminoGenericOfflineSigner(aminoSigner),
302+
{
303+
broadcast: {
304+
checkTx: true,
305+
deliverTx: true,
306+
useLegacyBroadcastTxCommit: true,
307+
},
308+
}
309+
);
310+
311+
const vote = createVote(signingClient);
312+
313+
// Vote on proposal from genesis mnemonic address
314+
const fee = {
315+
amount: [
316+
{
317+
denom,
318+
amount: '100000',
319+
},
320+
],
321+
gas: '550000',
322+
};
323+
324+
const result = await vote(
325+
aminoAddress,
326+
{
327+
proposalId: BigInt(proposalId),
328+
voter: aminoAddress,
329+
option: VoteOption.VOTE_OPTION_NO,
330+
},
331+
fee,
332+
"vote"
333+
);
334+
assertIsDeliverTxSuccess(result);
335+
}, 10000);
336+
337+
it('verify amino vote', async () => {
338+
const { vote } = await getVote({
339+
proposalId: BigInt(proposalId),
340+
voter: aminoAddress,
341+
});
342+
343+
expect(vote.proposalId.toString()).toEqual(proposalId);
344+
expect(vote.voter).toEqual(aminoAddress);
345+
expect(vote.option).toEqual(VoteOption.VOTE_OPTION_NO);
346+
}, 10000);
347+
348+
it('wait for voting period to end', async () => {
349+
// wait for the voting period to end
350+
const { proposal } = await getProposal({
351+
proposalId: BigInt(proposalId),
352+
});
353+
354+
await expect(waitUntil(proposal.votingEndTime)).resolves.not.toThrow();
355+
}, 200000);
356+
357+
it('verify proposal passed', async () => {
358+
const { proposal } = await getProposal({
359+
proposalId: BigInt(proposalId),
360+
});
361+
362+
expect(proposal.status).toEqual(ProposalStatus.PROPOSAL_STATUS_PASSED);
363+
}, 10000);
364+
});

0 commit comments

Comments
 (0)