From f239f86047c44d938170821117c6810992e7a554 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 9 Jul 2020 14:45:57 +0200 Subject: [PATCH 01/14] Add StakingExtension --- packages/sdk38/src/index.ts | 4 +++ packages/sdk38/src/lcdapi/index.ts | 6 ++++ packages/sdk38/src/lcdapi/staking.spec.ts | 43 +++++++++++++++++++++++ packages/sdk38/src/lcdapi/staking.ts | 36 +++++++++++++++++++ packages/sdk38/types/index.d.ts | 4 +++ packages/sdk38/types/lcdapi/index.d.ts | 6 ++++ packages/sdk38/types/lcdapi/staking.d.ts | 25 +++++++++++++ 7 files changed, 124 insertions(+) create mode 100644 packages/sdk38/src/lcdapi/staking.spec.ts create mode 100644 packages/sdk38/src/lcdapi/staking.ts create mode 100644 packages/sdk38/types/lcdapi/staking.d.ts diff --git a/packages/sdk38/src/index.ts b/packages/sdk38/src/index.ts index ff94bed94d..81ddccea1b 100644 --- a/packages/sdk38/src/index.ts +++ b/packages/sdk38/src/index.ts @@ -63,10 +63,14 @@ export { setupGovExtension, setupMintExtension, setupSlashingExtension, + setupStakingExtension, setupSupplyExtension, SlashingExtension, SlashingParametersResponse, SlashingSigningInfosResponse, + StakingExtension, + StakingParametersResponse, + StakingPoolResponse, SupplyExtension, TxsResponse, } from "./lcdapi"; diff --git a/packages/sdk38/src/lcdapi/index.ts b/packages/sdk38/src/lcdapi/index.ts index 742a2a1bae..b0dcbb5f7f 100644 --- a/packages/sdk38/src/lcdapi/index.ts +++ b/packages/sdk38/src/lcdapi/index.ts @@ -42,6 +42,12 @@ export { SlashingParametersResponse, SlashingSigningInfosResponse, } from "./slashing"; +export { + setupStakingExtension, + StakingExtension, + StakingParametersResponse, + StakingPoolResponse, +} from "./staking"; export { setupSupplyExtension, SupplyExtension, TotalSupplyAllResponse, TotalSupplyResponse } from "./supply"; // diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts new file mode 100644 index 0000000000..8810277e31 --- /dev/null +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -0,0 +1,43 @@ +/* eslint-disable @typescript-eslint/camelcase */ +import { nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd } from "../testutils.spec"; +import { LcdClient } from "./lcdclient"; +import { setupStakingExtension, StakingExtension } from "./staking"; + +function makeStakingClient(apiUrl: string): LcdClient & StakingExtension { + return LcdClient.withExtensions({ apiUrl }, setupStakingExtension); +} + +describe("StakingExtension", () => { + describe("pool", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.pool(); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + not_bonded_tokens: "0", + bonded_tokens: "250000000", + }, + }); + }); + }); + + describe("parameters", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.parameters(); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + unbonding_time: "1814400000000000", + max_validators: 100, + max_entries: 7, + historical_entries: 0, + bond_denom: "ustake", + }, + }); + }); + }); +}); diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts new file mode 100644 index 0000000000..081fe74d40 --- /dev/null +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -0,0 +1,36 @@ +import { LcdClient } from "./lcdclient"; + +export interface StakingPoolResponse { + readonly height: string; + readonly result: { + readonly not_bonded_tokens: string; + readonly bonded_tokens: string; + }; +} + +export interface StakingParametersResponse { + readonly height: string; + readonly result: { + readonly unbonding_time: string; + readonly max_validators: number; + readonly max_entries: number; + readonly historical_entries: number; + readonly bond_denom: string; + }; +} + +export interface StakingExtension { + readonly staking: { + readonly pool: () => Promise; + readonly parameters: () => Promise; + }; +} + +export function setupStakingExtension(base: LcdClient): StakingExtension { + return { + staking: { + pool: async () => base.get(`/staking/pool`), + parameters: async () => base.get(`/staking/parameters`), + }, + }; +} diff --git a/packages/sdk38/types/index.d.ts b/packages/sdk38/types/index.d.ts index 07e7a55436..7aaafa4067 100644 --- a/packages/sdk38/types/index.d.ts +++ b/packages/sdk38/types/index.d.ts @@ -61,10 +61,14 @@ export { setupGovExtension, setupMintExtension, setupSlashingExtension, + setupStakingExtension, setupSupplyExtension, SlashingExtension, SlashingParametersResponse, SlashingSigningInfosResponse, + StakingExtension, + StakingParametersResponse, + StakingPoolResponse, SupplyExtension, TxsResponse, } from "./lcdapi"; diff --git a/packages/sdk38/types/lcdapi/index.d.ts b/packages/sdk38/types/lcdapi/index.d.ts index 77819d6cf3..43ce0c211c 100644 --- a/packages/sdk38/types/lcdapi/index.d.ts +++ b/packages/sdk38/types/lcdapi/index.d.ts @@ -38,6 +38,12 @@ export { SlashingParametersResponse, SlashingSigningInfosResponse, } from "./slashing"; +export { + setupStakingExtension, + StakingExtension, + StakingParametersResponse, + StakingPoolResponse, +} from "./staking"; export { setupSupplyExtension, SupplyExtension, TotalSupplyAllResponse, TotalSupplyResponse } from "./supply"; export { BlockResponse, diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts new file mode 100644 index 0000000000..09f186e684 --- /dev/null +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -0,0 +1,25 @@ +import { LcdClient } from "./lcdclient"; +export interface StakingPoolResponse { + readonly height: string; + readonly result: { + readonly not_bonded_tokens: string; + readonly bonded_tokens: string; + }; +} +export interface StakingParametersResponse { + readonly height: string; + readonly result: { + readonly unbonding_time: string; + readonly max_validators: number; + readonly max_entries: number; + readonly historical_entries: number; + readonly bond_denom: string; + }; +} +export interface StakingExtension { + readonly staking: { + readonly pool: () => Promise; + readonly parameters: () => Promise; + }; +} +export declare function setupStakingExtension(base: LcdClient): StakingExtension; From 6baaa270c90096994a4ab7485a35cf530e2524d2 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 9 Jul 2020 15:11:57 +0200 Subject: [PATCH 02/14] Add placeholders for missing /staking routes --- packages/sdk38/src/lcdapi/staking.ts | 41 ++++++++++++++++++++++++ packages/sdk38/types/lcdapi/staking.d.ts | 2 ++ 2 files changed, 43 insertions(+) diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index 081fe74d40..ad83dd7db3 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -21,7 +21,48 @@ export interface StakingParametersResponse { export interface StakingExtension { readonly staking: { + // Get all delegations from a delegator + // /staking/delegators/{delegatorAddr}/delegations + + // Get all unbonding delegations from a delegator + // /staking/delegators/{delegatorAddr}/unbonding_delegations + + // Get all staking txs (i.e msgs) from a delegator + // /staking/delegators/{delegatorAddr}/txs + + // Query all validators that a delegator is bonded to + // /staking/delegators/{delegatorAddr}/validators + + // Query a validator that a delegator is bonded to + // /staking/delegators/{delegatorAddr}/validators/{validatorAddr} + + // Query a delegation between a delegator and a validator + // /staking/delegators/{delegatorAddr}/delegations/{validatorAddr} + + // Query all unbonding delegations between a delegator and a validator + // /staking/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} + + // Query redelegations (filters in query params) + // /staking/redelegations + + // Get all validators + // /staking/validators + + // Get a single validator info + // /staking/validators/{validatorAddr} + + // Get all delegations to a validator + // "/staking/validators/{validatorAddr}/delegations + + // Get all unbonding delegations from a validator + // /staking/validators/{validatorAddr}/unbonding_delegations + + // Get HistoricalInfo at a given height + // /staking/historical_info/{height} + + /** Get the current state of the staking pool */ readonly pool: () => Promise; + /** Get the current staking parameter values */ readonly parameters: () => Promise; }; } diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts index 09f186e684..acebf09258 100644 --- a/packages/sdk38/types/lcdapi/staking.d.ts +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -18,7 +18,9 @@ export interface StakingParametersResponse { } export interface StakingExtension { readonly staking: { + /** Get the current state of the staking pool */ readonly pool: () => Promise; + /** Get the current staking parameter values */ readonly parameters: () => Promise; }; } From c464d875dff9d96fa6a825493a3d52513a4094c1 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 9 Jul 2020 15:33:38 +0200 Subject: [PATCH 03/14] Add /staking/validators query --- packages/sdk38/src/lcdapi/lcdclient.ts | 4 +- packages/sdk38/src/lcdapi/staking.spec.ts | 50 ++++++++++++++++++++++ packages/sdk38/src/lcdapi/staking.ts | 49 ++++++++++++++++++++- packages/sdk38/types/lcdapi/lcdclient.d.ts | 2 +- packages/sdk38/types/lcdapi/staking.d.ts | 44 +++++++++++++++++++ 5 files changed, 144 insertions(+), 5 deletions(-) diff --git a/packages/sdk38/src/lcdapi/lcdclient.ts b/packages/sdk38/src/lcdapi/lcdclient.ts index 3ea8d84450..f62b14a163 100644 --- a/packages/sdk38/src/lcdapi/lcdclient.ts +++ b/packages/sdk38/src/lcdapi/lcdclient.ts @@ -219,8 +219,8 @@ export class LcdClient { this.broadcastMode = broadcastMode; } - public async get(path: string): Promise { - const { data } = await this.client.get(path).catch(parseAxiosError); + public async get(path: string, params?: Record): Promise { + const { data } = await this.client.get(path, { params }).catch(parseAxiosError); if (data === null) { throw new Error("Received null response from server"); } diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index 8810277e31..0a516d49a1 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -8,6 +8,56 @@ function makeStakingClient(apiUrl: string): LcdClient & StakingExtension { } describe("StakingExtension", () => { + describe("validators", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.validators(); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + consensus_pubkey: + "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", + jailed: false, + status: 2, + tokens: "250000000", + delegator_shares: "250000000.000000000000000000", + description: { + moniker: "testing", + identity: "", + website: "", + security_contact: "", + details: "", + }, + unbonding_height: "0", + unbonding_time: "1970-01-01T00:00:00Z", + commission: { + commission_rates: { + rate: "0.100000000000000000", + max_rate: "0.200000000000000000", + max_change_rate: "0.010000000000000000", + }, + update_time: "2020-06-03T06:01:17.4747987Z", + }, + min_self_delegation: "1", + }, + ], + }); + }); + + it("can filter by status", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.validators({ status: "unbonded" }); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [], + }); + }); + }); + describe("pool", () => { it("works", async () => { pendingWithoutWasmd(); diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index ad83dd7db3..365a56535b 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -1,5 +1,49 @@ import { LcdClient } from "./lcdclient"; +export interface StakingValidatorsParams { + /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ + readonly status?: "bonded" | "unbonded" | "unbonding"; + readonly page?: number; + readonly limit?: number; +} + +interface Validator { + readonly operator_address: string; + readonly consensus_pubkey: string; + readonly jailed: boolean; + /** + * Numeric bonding status + * + * @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 + */ + readonly status: number; + readonly tokens: string; + readonly delegator_shares: string; + readonly description: { + readonly moniker: string; + readonly identity: string; + readonly website: string; + readonly security_contact: string; + readonly details: string; + }; + readonly unbonding_height: string; + readonly unbonding_time: string; + readonly commission: { + readonly commission_rates: { + readonly rate: string; + readonly max_rate: string; + readonly max_change_rate: string; + }; + readonly update_time: string; + }; + readonly min_self_delegation: string; +} + +export interface StakingValidatorsResponse { + readonly height: string; + readonly result: readonly Validator[]; +} + export interface StakingPoolResponse { readonly height: string; readonly result: { @@ -45,8 +89,8 @@ export interface StakingExtension { // Query redelegations (filters in query params) // /staking/redelegations - // Get all validators - // /staking/validators + /** Get all validators */ + readonly validators: (options?: StakingValidatorsParams) => Promise; // Get a single validator info // /staking/validators/{validatorAddr} @@ -70,6 +114,7 @@ export interface StakingExtension { export function setupStakingExtension(base: LcdClient): StakingExtension { return { staking: { + validators: async (params?: StakingValidatorsParams) => base.get(`/staking/validators`, params), pool: async () => base.get(`/staking/pool`), parameters: async () => base.get(`/staking/parameters`), }, diff --git a/packages/sdk38/types/lcdapi/lcdclient.d.ts b/packages/sdk38/types/lcdapi/lcdclient.d.ts index ce67cc389a..7b275b0283 100644 --- a/packages/sdk38/types/lcdapi/lcdclient.d.ts +++ b/packages/sdk38/types/lcdapi/lcdclient.d.ts @@ -143,7 +143,7 @@ export declare class LcdClient { * @param broadcastMode Defines at which point of the transaction processing the postTx method (i.e. transaction broadcasting) returns */ constructor(apiUrl: string, broadcastMode?: BroadcastMode); - get(path: string): Promise; + get(path: string, params?: Record): Promise; post(path: string, params: any): Promise; blocksLatest(): Promise; blocks(height: number): Promise; diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts index acebf09258..bc0ca5b4c9 100644 --- a/packages/sdk38/types/lcdapi/staking.d.ts +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -1,4 +1,45 @@ import { LcdClient } from "./lcdclient"; +export interface StakingValidatorsParams { + /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ + readonly status?: "bonded" | "unbonded" | "unbonding"; + readonly page?: number; + readonly limit?: number; +} +interface Validator { + readonly operator_address: string; + readonly consensus_pubkey: string; + readonly jailed: boolean; + /** + * Numeric bonding status + * + * @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 + */ + readonly status: number; + readonly tokens: string; + readonly delegator_shares: string; + readonly description: { + readonly moniker: string; + readonly identity: string; + readonly website: string; + readonly security_contact: string; + readonly details: string; + }; + readonly unbonding_height: string; + readonly unbonding_time: string; + readonly commission: { + readonly commission_rates: { + readonly rate: string; + readonly max_rate: string; + readonly max_change_rate: string; + }; + readonly update_time: string; + }; + readonly min_self_delegation: string; +} +export interface StakingValidatorsResponse { + readonly height: string; + readonly result: readonly Validator[]; +} export interface StakingPoolResponse { readonly height: string; readonly result: { @@ -18,6 +59,8 @@ export interface StakingParametersResponse { } export interface StakingExtension { readonly staking: { + /** Get all validators */ + readonly validators: (options?: StakingValidatorsParams) => Promise; /** Get the current state of the staking pool */ readonly pool: () => Promise; /** Get the current staking parameter values */ @@ -25,3 +68,4 @@ export interface StakingExtension { }; } export declare function setupStakingExtension(base: LcdClient): StakingExtension; +export {}; From 04c753590401f2587caf4874472a0d74ca14a868 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 21 Jul 2020 13:48:19 +0200 Subject: [PATCH 04/14] sdk38: Update eslint overrides in LCD staking module --- packages/sdk38/src/lcdapi/staking.spec.ts | 2 +- packages/sdk38/src/lcdapi/staking.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index 0a516d49a1..b4edfb2c09 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/camelcase */ +/* eslint-disable @typescript-eslint/naming-convention */ import { nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd } from "../testutils.spec"; import { LcdClient } from "./lcdclient"; import { setupStakingExtension, StakingExtension } from "./staking"; diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index 365a56535b..6b370902f0 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import { LcdClient } from "./lcdclient"; export interface StakingValidatorsParams { From 4b34249d77dacbb063ad73d412f1ae05e095452f Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 21 Jul 2020 15:55:28 +0200 Subject: [PATCH 05/14] sdk38: Add additional staking validators test --- packages/sdk38/src/lcdapi/staking.spec.ts | 40 ++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index b4edfb2c09..93eb4fd9a2 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -47,7 +47,7 @@ describe("StakingExtension", () => { }); }); - it("can filter by status", async () => { + it("can filter by status with no results", async () => { pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); const response = await client.staking.validators({ status: "unbonded" }); @@ -56,6 +56,44 @@ describe("StakingExtension", () => { result: [], }); }); + + it("can filter by status with some results", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.validators({ status: "bonded" }); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + consensus_pubkey: + "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", + jailed: false, + status: 2, + tokens: "250000000", + delegator_shares: "250000000.000000000000000000", + description: { + moniker: "testing", + identity: "", + website: "", + security_contact: "", + details: "", + }, + unbonding_height: "0", + unbonding_time: "1970-01-01T00:00:00Z", + commission: { + commission_rates: { + rate: "0.100000000000000000", + max_rate: "0.200000000000000000", + max_change_rate: "0.010000000000000000", + }, + update_time: "2020-06-03T06:01:17.4747987Z", + }, + min_self_delegation: "1", + }, + ], + }); + }); }); describe("pool", () => { From 8e57338e24353eafcb638b941bf94ef80d46dda0 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 21 Jul 2020 18:21:39 +0200 Subject: [PATCH 06/14] sdk38: Fill out staking extension --- packages/sdk38/src/lcdapi/staking.spec.ts | 330 +++++++++++++++++++++- packages/sdk38/src/lcdapi/staking.ts | 195 ++++++++++--- packages/sdk38/types/lcdapi/staking.d.ts | 119 ++++++++ 3 files changed, 602 insertions(+), 42 deletions(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index 93eb4fd9a2..899831824f 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -1,5 +1,21 @@ +import { assert, sleep } from "@cosmjs/utils"; + +import { coin, coins } from "../coins"; +import { isPostTxFailure } from "../cosmosclient"; +import { makeSignBytes } from "../encoding"; +import { MsgDelegate } from "../msgs"; +import { SigningCosmosClient } from "../signingcosmosclient"; /* eslint-disable @typescript-eslint/naming-convention */ -import { nonNegativeIntegerMatcher, pendingWithoutWasmd, wasmd } from "../testutils.spec"; +import { + bigDecimalMatcher, + faucet, + nonNegativeIntegerMatcher, + pendingWithoutWasmd, + validatorAddress, + wasmd, + wasmdEnabled, +} from "../testutils.spec"; +import { Secp256k1Wallet } from "../wallet"; import { LcdClient } from "./lcdclient"; import { setupStakingExtension, StakingExtension } from "./staking"; @@ -8,6 +24,209 @@ function makeStakingClient(apiUrl: string): LcdClient & StakingExtension { } describe("StakingExtension", () => { + const defaultFee = { + amount: coins(25000, "ucosm"), + gas: "1500000", // 1.5 million + }; + + beforeAll(async () => { + if (wasmdEnabled()) { + const wallet = await Secp256k1Wallet.fromMnemonic(faucet.mnemonic); + const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, wallet, {}); + + const chainId = await client.getChainId(); + const msg: MsgDelegate = { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: faucet.address, + validator_address: validatorAddress, + amount: coin(25000, "ustake"), + }, + }; + const memo = "Test delegation for wasmd"; + const { accountNumber, sequence } = await client.getNonce(); + const signBytes = makeSignBytes([msg], defaultFee, chainId, memo, accountNumber, sequence); + const signature = await wallet.sign(faucet.address, signBytes); + const tx = { + msg: [msg], + fee: defaultFee, + memo: memo, + signatures: [signature], + }; + + const receipt = await client.postTx(tx); + assert(!isPostTxFailure(receipt)); + + await sleep(75); // wait until transactions are indexed + } + }); + + describe("delegatorDelegations", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.delegatorDelegations(faucet.address); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + shares: jasmine.stringMatching(bigDecimalMatcher), + balance: { denom: "ustake", amount: jasmine.stringMatching(nonNegativeIntegerMatcher) }, + }, + ], + }); + }); + }); + + describe("delegatorUnbondingDelegations", () => { + it("works", async () => { + // TODO: Set up a result for this test + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.delegatorUnbondingDelegations(faucet.address); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [], + }); + }); + }); + + describe("delegatorTransactions", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.delegatorTransactions(faucet.address); + expect(response.length).toEqual(3); + }); + }); + + describe("delegatorValidators", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.delegatorValidators(faucet.address); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + consensus_pubkey: + "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", + jailed: false, + status: 2, + tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), + delegator_shares: jasmine.stringMatching(bigDecimalMatcher), + description: { + moniker: "testing", + identity: "", + website: "", + security_contact: "", + details: "", + }, + unbonding_height: "0", + unbonding_time: "1970-01-01T00:00:00Z", + commission: { + commission_rates: { + rate: "0.100000000000000000", + max_rate: "0.200000000000000000", + max_change_rate: "0.010000000000000000", + }, + update_time: "2020-06-03T06:01:17.4747987Z", + }, + min_self_delegation: "1", + }, + ], + }); + }); + }); + + describe("delegatorValidator", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.delegatorValidator(faucet.address, validatorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + consensus_pubkey: + "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", + jailed: false, + status: 2, + tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), + delegator_shares: jasmine.stringMatching(bigDecimalMatcher), + description: { + moniker: "testing", + identity: "", + website: "", + security_contact: "", + details: "", + }, + unbonding_height: "0", + unbonding_time: "1970-01-01T00:00:00Z", + commission: { + commission_rates: { + rate: "0.100000000000000000", + max_rate: "0.200000000000000000", + max_change_rate: "0.010000000000000000", + }, + update_time: "2020-06-03T06:01:17.4747987Z", + }, + min_self_delegation: "1", + }, + }); + }); + }); + + describe("delegation", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.delegation(faucet.address, validatorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + delegator_address: faucet.address, + validator_address: validatorAddress, + shares: jasmine.stringMatching(bigDecimalMatcher), + balance: { denom: "ustake", amount: jasmine.stringMatching(nonNegativeIntegerMatcher) }, + }, + }); + }); + }); + + xdescribe("unbondingDelegation", () => { + it("works", async () => { + // TODO: Set up a result for this test + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.unbondingDelegation(faucet.address, validatorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + delegator_address: faucet.address, + validator_address: validatorAddress, + entries: [], + }, + }); + }); + }); + + describe("redelegations", () => { + it("works", async () => { + // TODO: Set up a result for this test + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.redelegations(); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [], + }); + }); + }); + describe("validators", () => { it("works", async () => { pendingWithoutWasmd(); @@ -22,8 +241,8 @@ describe("StakingExtension", () => { "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, status: 2, - tokens: "250000000", - delegator_shares: "250000000.000000000000000000", + tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), + delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { moniker: "testing", identity: "", @@ -70,8 +289,8 @@ describe("StakingExtension", () => { "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, status: 2, - tokens: "250000000", - delegator_shares: "250000000.000000000000000000", + tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), + delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { moniker: "testing", identity: "", @@ -96,6 +315,105 @@ describe("StakingExtension", () => { }); }); + describe("validator", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.validator(validatorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + consensus_pubkey: + "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", + jailed: false, + status: 2, + tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), + delegator_shares: jasmine.stringMatching(bigDecimalMatcher), + description: { + moniker: "testing", + identity: "", + website: "", + security_contact: "", + details: "", + }, + unbonding_height: "0", + unbonding_time: "1970-01-01T00:00:00Z", + commission: { + commission_rates: { + rate: "0.100000000000000000", + max_rate: "0.200000000000000000", + max_change_rate: "0.010000000000000000", + }, + update_time: "2020-06-03T06:01:17.4747987Z", + }, + min_self_delegation: "1", + }, + }); + }); + }); + + describe("validatorDelegations", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.validatorDelegations(validatorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [ + { + delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", + validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + shares: jasmine.stringMatching(bigDecimalMatcher), + balance: { denom: "ustake", amount: jasmine.stringMatching(nonNegativeIntegerMatcher) }, + }, + { + delegator_address: "cosmos1gjvanqxc774u6ed9thj4gpn9gj5zus5u57dxvq", + validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + shares: "250000000.000000000000000000", + balance: { denom: "ustake", amount: "250000000" }, + }, + ], + }); + }); + }); + + describe("validatorUnbondingDelegations", () => { + it("works", async () => { + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.validatorUnbondingDelegations(validatorAddress); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: [], + }); + }); + }); + + xdescribe("historicalInfo", () => { + it("works", async () => { + // TODO: Find a result for this test + pendingWithoutWasmd(); + const client = makeStakingClient(wasmd.endpoint); + const response = await client.staking.historicalInfo("100"); + expect(response).toEqual({ + height: jasmine.stringMatching(nonNegativeIntegerMatcher), + result: { + header: { + version: { + block: "", + app: "", + }, + height: 10, + chainId: "", + time: "", + }, + validators: [], + }, + }); + }); + }); + describe("pool", () => { it("works", async () => { pendingWithoutWasmd(); @@ -105,7 +423,7 @@ describe("StakingExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { not_bonded_tokens: "0", - bonded_tokens: "250000000", + bonded_tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), }, }); }); diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index 6b370902f0..efc238f568 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -1,4 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ +import { Coin } from "../coins"; +import { BlockHeader } from "../cosmosclient"; +import { SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; export interface StakingValidatorsParams { @@ -40,11 +43,107 @@ interface Validator { readonly min_self_delegation: string; } +interface Delegation { + readonly delegator_address: string; + readonly validator_address: string; + readonly shares: string; + readonly balance: Coin; +} + +export interface StakingDelegatorDelegationsResponse { + readonly height: string; + readonly result: readonly Delegation[]; +} + +interface UnbondingDelegationEntry { + readonly creation_height: string; + readonly completion_time: string; + readonly initial_balance: Coin; + readonly balance: Coin; +} + +interface UnbondingDelegation { + readonly delegator_address: string; + readonly validator_address: string; + readonly entries: readonly UnbondingDelegationEntry[]; +} + +export interface StakingDelegatorUnbondingDelegationsResponse { + readonly height: string; + readonly result: readonly UnbondingDelegation[]; +} + +export type StakingDelegatorTransactionsResponse = readonly SearchTxsResponse[]; + +export interface StakingDelegatorValidatorsResponse { + readonly height: string; + readonly result: readonly Validator[]; +} + +export interface StakingDelegatorValidatorResponse { + readonly height: string; + readonly result: Validator; +} + +export interface StakingDelegationResponse { + readonly height: string; + readonly result: Delegation; +} + +export interface StakingUnbondingDelegationResponse { + readonly height: string; + readonly result: UnbondingDelegation | null; +} + +interface RedelegationEntry { + readonly creation_height: string; + readonly completion_time: string; + readonly initial_balance: Coin; + readonly shares_dst: string; +} + +interface Redelegation { + readonly delegator_address: string; + readonly validator_src_address: string; + readonly validator_dst_address: string; + readonly entries: readonly RedelegationEntry[]; +} + +export interface StakingRedelegationsResponse { + readonly height: string; + readonly result: readonly Redelegation[]; +} + export interface StakingValidatorsResponse { readonly height: string; readonly result: readonly Validator[]; } +export interface StakingValidatorResponse { + readonly height: string; + readonly result: Validator; +} + +export interface StakingValidatorDelegationsResponse { + readonly height: string; + readonly result: readonly Delegation[]; +} + +export interface StakingValidatorUnbondingDelegationsResponse { + readonly height: string; + readonly result: readonly UnbondingDelegation[]; +} + +interface HistoricalInfo { + readonly header: BlockHeader; + readonly validators: readonly Validator[]; +} + +export interface StakingHistoricalInfoResponse { + readonly height: string; + readonly result: HistoricalInfo; +} + export interface StakingPoolResponse { readonly height: string; readonly result: { @@ -66,45 +165,47 @@ export interface StakingParametersResponse { export interface StakingExtension { readonly staking: { - // Get all delegations from a delegator - // /staking/delegators/{delegatorAddr}/delegations - - // Get all unbonding delegations from a delegator - // /staking/delegators/{delegatorAddr}/unbonding_delegations - - // Get all staking txs (i.e msgs) from a delegator - // /staking/delegators/{delegatorAddr}/txs - - // Query all validators that a delegator is bonded to - // /staking/delegators/{delegatorAddr}/validators - - // Query a validator that a delegator is bonded to - // /staking/delegators/{delegatorAddr}/validators/{validatorAddr} - - // Query a delegation between a delegator and a validator - // /staking/delegators/{delegatorAddr}/delegations/{validatorAddr} - - // Query all unbonding delegations between a delegator and a validator - // /staking/delegators/{delegatorAddr}/unbonding_delegations/{validatorAddr} - - // Query redelegations (filters in query params) - // /staking/redelegations - + /** Get all delegations from a delegator */ + readonly delegatorDelegations: (delegatorAddress: string) => Promise; + /** Get all unbonding delegations from a delegator */ + readonly delegatorUnbondingDelegations: ( + delegatorAddress: string, + ) => Promise; + /** Get all staking txs (i.e msgs) from a delegator */ + readonly delegatorTransactions: ( + delegatorAddress: string, + ) => Promise; + /** Query all validators that a delegator is bonded to */ + readonly delegatorValidators: (delegatorAddress: string) => Promise; + /** Query a validator that a delegator is bonded to */ + readonly delegatorValidator: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + /** Query a delegation between a delegator and a validator */ + readonly delegation: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + /** Query all unbonding delegations between a delegator and a validator */ + readonly unbondingDelegation: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + /** Query redelegations (filters in query params) */ + readonly redelegations: () => Promise; /** Get all validators */ readonly validators: (options?: StakingValidatorsParams) => Promise; - - // Get a single validator info - // /staking/validators/{validatorAddr} - + /** Get a single validator info */ + readonly validator: (validatorAddress: string) => Promise; // Get all delegations to a validator - // "/staking/validators/{validatorAddr}/delegations - - // Get all unbonding delegations from a validator - // /staking/validators/{validatorAddr}/unbonding_delegations - - // Get HistoricalInfo at a given height - // /staking/historical_info/{height} - + readonly validatorDelegations: (validatorAddress: string) => Promise; + /** Get all unbonding delegations from a validator */ + readonly validatorUnbondingDelegations: ( + validatorAddress: string, + ) => Promise; + /** Get HistoricalInfo at a given height */ + readonly historicalInfo: (height: string) => Promise; /** Get the current state of the staking pool */ readonly pool: () => Promise; /** Get the current staking parameter values */ @@ -115,7 +216,29 @@ export interface StakingExtension { export function setupStakingExtension(base: LcdClient): StakingExtension { return { staking: { + delegatorDelegations: async (delegatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/delegations`), + delegatorUnbondingDelegations: async (delegatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/unbonding_delegations`), + delegatorTransactions: async (delegatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/txs`), + delegatorValidators: async (delegatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/validators`), + delegatorValidator: async (delegatorAddress: string, validatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/validators/${validatorAddress}`), + delegation: async (delegatorAddress: string, validatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/delegations/${validatorAddress}`), + unbondingDelegation: async (delegatorAddress: string, validatorAddress: string) => + base.get(`/staking/delegators/${delegatorAddress}/unbonding_delegations/${validatorAddress}`), + redelegations: async () => base.get(`/staking/redelegations`), validators: async (params?: StakingValidatorsParams) => base.get(`/staking/validators`, params), + validator: async (validatorAddress: string) => base.get(`/staking/validators/${validatorAddress}`), + validatorDelegations: async (validatorAddress: string) => + base.get(`/staking/validators/${validatorAddress}/delegations + `), + validatorUnbondingDelegations: async (validatorAddress: string) => + base.get(`/staking/validators/${validatorAddress}/unbonding_delegations`), + historicalInfo: async (height: string) => base.get(`/staking/historical_info/${height}`), pool: async () => base.get(`/staking/pool`), parameters: async () => base.get(`/staking/parameters`), }, diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts index bc0ca5b4c9..fc50631f35 100644 --- a/packages/sdk38/types/lcdapi/staking.d.ts +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -1,3 +1,6 @@ +import { Coin } from "../coins"; +import { BlockHeader } from "../cosmosclient"; +import { SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; export interface StakingValidatorsParams { /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ @@ -36,10 +39,88 @@ interface Validator { }; readonly min_self_delegation: string; } +interface Delegation { + readonly delegator_address: string; + readonly validator_address: string; + readonly shares: string; + readonly balance: Coin; +} +export interface StakingDelegatorDelegationsResponse { + readonly height: string; + readonly result: readonly Delegation[]; +} +interface UnbondingDelegationEntry { + readonly creation_height: string; + readonly completion_time: string; + readonly initial_balance: Coin; + readonly balance: Coin; +} +interface UnbondingDelegation { + readonly delegator_address: string; + readonly validator_address: string; + readonly entries: readonly UnbondingDelegationEntry[]; +} +export interface StakingDelegatorUnbondingDelegationsResponse { + readonly height: string; + readonly result: readonly UnbondingDelegation[]; +} +export declare type StakingDelegatorTransactionsResponse = readonly SearchTxsResponse[]; +export interface StakingDelegatorValidatorsResponse { + readonly height: string; + readonly result: readonly Validator[]; +} +export interface StakingDelegatorValidatorResponse { + readonly height: string; + readonly result: Validator; +} +export interface StakingDelegationResponse { + readonly height: string; + readonly result: Delegation; +} +export interface StakingUnbondingDelegationResponse { + readonly height: string; + readonly result: UnbondingDelegation | null; +} +interface RedelegationEntry { + readonly creation_height: string; + readonly completion_time: string; + readonly initial_balance: Coin; + readonly shares_dst: string; +} +interface Redelegation { + readonly delegator_address: string; + readonly validator_src_address: string; + readonly validator_dst_address: string; + readonly entries: readonly RedelegationEntry[]; +} +export interface StakingRedelegationsResponse { + readonly height: string; + readonly result: readonly Redelegation[]; +} export interface StakingValidatorsResponse { readonly height: string; readonly result: readonly Validator[]; } +export interface StakingValidatorResponse { + readonly height: string; + readonly result: Validator; +} +export interface StakingValidatorDelegationsResponse { + readonly height: string; + readonly result: readonly Delegation[]; +} +export interface StakingValidatorUnbondingDelegationsResponse { + readonly height: string; + readonly result: readonly UnbondingDelegation[]; +} +interface HistoricalInfo { + readonly header: BlockHeader; + readonly validators: readonly Validator[]; +} +export interface StakingHistoricalInfoResponse { + readonly height: string; + readonly result: HistoricalInfo; +} export interface StakingPoolResponse { readonly height: string; readonly result: { @@ -59,8 +140,46 @@ export interface StakingParametersResponse { } export interface StakingExtension { readonly staking: { + /** Get all delegations from a delegator */ + readonly delegatorDelegations: (delegatorAddress: string) => Promise; + /** Get all unbonding delegations from a delegator */ + readonly delegatorUnbondingDelegations: ( + delegatorAddress: string, + ) => Promise; + /** Get all staking txs (i.e msgs) from a delegator */ + readonly delegatorTransactions: ( + delegatorAddress: string, + ) => Promise; + /** Query all validators that a delegator is bonded to */ + readonly delegatorValidators: (delegatorAddress: string) => Promise; + /** Query a validator that a delegator is bonded to */ + readonly delegatorValidator: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + /** Query a delegation between a delegator and a validator */ + readonly delegation: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + /** Query all unbonding delegations between a delegator and a validator */ + readonly unbondingDelegation: ( + delegatorAddress: string, + validatorAddress: string, + ) => Promise; + /** Query redelegations (filters in query params) */ + readonly redelegations: () => Promise; /** Get all validators */ readonly validators: (options?: StakingValidatorsParams) => Promise; + /** Get a single validator info */ + readonly validator: (validatorAddress: string) => Promise; + readonly validatorDelegations: (validatorAddress: string) => Promise; + /** Get all unbonding delegations from a validator */ + readonly validatorUnbondingDelegations: ( + validatorAddress: string, + ) => Promise; + /** Get HistoricalInfo at a given height */ + readonly historicalInfo: (height: string) => Promise; /** Get the current state of the staking pool */ readonly pool: () => Promise; /** Get the current staking parameter values */ From b1db53def8706ff7773e6af50e6f066a0f55a227 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 22 Jul 2020 10:29:30 +0200 Subject: [PATCH 07/14] sdk38: Export staking interfaces from lcdapi index --- packages/sdk38/src/lcdapi/index.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/sdk38/src/lcdapi/index.ts b/packages/sdk38/src/lcdapi/index.ts index b0dcbb5f7f..5a3fc58078 100644 --- a/packages/sdk38/src/lcdapi/index.ts +++ b/packages/sdk38/src/lcdapi/index.ts @@ -44,6 +44,19 @@ export { } from "./slashing"; export { setupStakingExtension, + StakingDelegatorDelegationsResponse, + StakingDelegatorUnbondingDelegationsResponse, + StakingDelegatorTransactionsResponse, + StakingDelegatorValidatorsResponse, + StakingDelegatorValidatorResponse, + StakingDelegationResponse, + StakingUnbondingDelegationResponse, + StakingRedelegationsResponse, + StakingValidatorsResponse, + StakingValidatorResponse, + StakingValidatorDelegationsResponse, + StakingValidatorUnbondingDelegationsResponse, + StakingHistoricalInfoResponse, StakingExtension, StakingParametersResponse, StakingPoolResponse, From a4187591ca4aa7d5760b18efa9167443ebe2c65e Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 22 Jul 2020 11:44:03 +0200 Subject: [PATCH 08/14] sdk38: Add undelegation tests and fix types --- packages/sdk38/src/lcdapi/staking.spec.ts | 122 +++++++++++++++------- packages/sdk38/src/lcdapi/staking.ts | 18 ++-- packages/sdk38/types/lcdapi/index.d.ts | 13 +++ packages/sdk38/types/lcdapi/staking.d.ts | 16 +-- 4 files changed, 114 insertions(+), 55 deletions(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index 899831824f..2fadf33276 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -3,11 +3,12 @@ import { assert, sleep } from "@cosmjs/utils"; import { coin, coins } from "../coins"; import { isPostTxFailure } from "../cosmosclient"; import { makeSignBytes } from "../encoding"; -import { MsgDelegate } from "../msgs"; +import { MsgDelegate, MsgUndelegate } from "../msgs"; import { SigningCosmosClient } from "../signingcosmosclient"; /* eslint-disable @typescript-eslint/naming-convention */ import { bigDecimalMatcher, + dateTimeStampMatcher, faucet, nonNegativeIntegerMatcher, pendingWithoutWasmd, @@ -35,27 +36,52 @@ describe("StakingExtension", () => { const client = new SigningCosmosClient(wasmd.endpoint, faucet.address, wallet, {}); const chainId = await client.getChainId(); - const msg: MsgDelegate = { - type: "cosmos-sdk/MsgDelegate", - value: { - delegator_address: faucet.address, - validator_address: validatorAddress, - amount: coin(25000, "ustake"), - }, - }; - const memo = "Test delegation for wasmd"; - const { accountNumber, sequence } = await client.getNonce(); - const signBytes = makeSignBytes([msg], defaultFee, chainId, memo, accountNumber, sequence); - const signature = await wallet.sign(faucet.address, signBytes); - const tx = { - msg: [msg], - fee: defaultFee, - memo: memo, - signatures: [signature], - }; + { + const msg: MsgDelegate = { + type: "cosmos-sdk/MsgDelegate", + value: { + delegator_address: faucet.address, + validator_address: validatorAddress, + amount: coin(25000, "ustake"), + }, + }; + const memo = "Test delegation for wasmd"; + const { accountNumber, sequence } = await client.getNonce(); + const signBytes = makeSignBytes([msg], defaultFee, chainId, memo, accountNumber, sequence); + const signature = await wallet.sign(faucet.address, signBytes); + const tx = { + msg: [msg], + fee: defaultFee, + memo: memo, + signatures: [signature], + }; - const receipt = await client.postTx(tx); - assert(!isPostTxFailure(receipt)); + const receipt = await client.postTx(tx); + assert(!isPostTxFailure(receipt)); + } + { + const msg: MsgUndelegate = { + type: "cosmos-sdk/MsgUndelegate", + value: { + delegator_address: faucet.address, + validator_address: validatorAddress, + amount: coin(10000, "ustake"), + }, + }; + const memo = "Test undelegation for wasmd"; + const { accountNumber, sequence } = await client.getNonce(); + const signBytes = makeSignBytes([msg], defaultFee, chainId, memo, accountNumber, sequence); + const signature = await wallet.sign(faucet.address, signBytes); + const tx = { + msg: [msg], + fee: defaultFee, + memo: memo, + signatures: [signature], + }; + + const receipt = await client.postTx(tx); + assert(!isPostTxFailure(receipt)); + } await sleep(75); // wait until transactions are indexed } @@ -82,13 +108,21 @@ describe("StakingExtension", () => { describe("delegatorUnbondingDelegations", () => { it("works", async () => { - // TODO: Set up a result for this test pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); const response = await client.staking.delegatorUnbondingDelegations(faucet.address); - expect(response).toEqual({ - height: jasmine.stringMatching(nonNegativeIntegerMatcher), - result: [], + expect(response.height).toMatch(nonNegativeIntegerMatcher); + expect(response.result.length).toEqual(1); + expect(response.result[0].delegator_address).toEqual("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"); + expect(response.result[0].validator_address).toEqual( + "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + ); + expect(response.result[0].entries.length).toBeGreaterThanOrEqual(1); + expect(response.result[0].entries[0]).toEqual({ + creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), + completion_time: jasmine.stringMatching(dateTimeStampMatcher), + initial_balance: "10000", + balance: "10000", }); }); }); @@ -197,19 +231,22 @@ describe("StakingExtension", () => { }); }); - xdescribe("unbondingDelegation", () => { + describe("unbondingDelegation", () => { it("works", async () => { - // TODO: Set up a result for this test pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); const response = await client.staking.unbondingDelegation(faucet.address, validatorAddress); - expect(response).toEqual({ - height: jasmine.stringMatching(nonNegativeIntegerMatcher), - result: { - delegator_address: faucet.address, - validator_address: validatorAddress, - entries: [], - }, + expect(response.height).toMatch(nonNegativeIntegerMatcher); + expect(response.result!.delegator_address).toEqual("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"); + expect(response.result!.validator_address).toEqual( + "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + ); + expect(response.result!.entries.length).toBeGreaterThanOrEqual(1); + expect(response.result!.entries[0]).toEqual({ + creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), + completion_time: jasmine.stringMatching(dateTimeStampMatcher), + initial_balance: "10000", + balance: "10000", }); }); }); @@ -383,9 +420,18 @@ describe("StakingExtension", () => { pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); const response = await client.staking.validatorUnbondingDelegations(validatorAddress); - expect(response).toEqual({ - height: jasmine.stringMatching(nonNegativeIntegerMatcher), - result: [], + expect(response.height).toMatch(nonNegativeIntegerMatcher); + expect(response.result.length).toEqual(1); + expect(response.result[0].delegator_address).toEqual("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"); + expect(response.result[0].validator_address).toEqual( + "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + ); + expect(response.result[0].entries.length).toBeGreaterThanOrEqual(1); + expect(response.result[0].entries[0]).toEqual({ + creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), + completion_time: jasmine.stringMatching(dateTimeStampMatcher), + initial_balance: "10000", + balance: "10000", }); }); }); @@ -422,7 +468,7 @@ describe("StakingExtension", () => { expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { - not_bonded_tokens: "0", + not_bonded_tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), bonded_tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), }, }); diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index efc238f568..063788fd06 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -4,13 +4,6 @@ import { BlockHeader } from "../cosmosclient"; import { SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; -export interface StakingValidatorsParams { - /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ - readonly status?: "bonded" | "unbonded" | "unbonding"; - readonly page?: number; - readonly limit?: number; -} - interface Validator { readonly operator_address: string; readonly consensus_pubkey: string; @@ -58,8 +51,8 @@ export interface StakingDelegatorDelegationsResponse { interface UnbondingDelegationEntry { readonly creation_height: string; readonly completion_time: string; - readonly initial_balance: Coin; - readonly balance: Coin; + readonly initial_balance: string; + readonly balance: string; } interface UnbondingDelegation { @@ -114,6 +107,13 @@ export interface StakingRedelegationsResponse { readonly result: readonly Redelegation[]; } +export interface StakingValidatorsParams { + /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ + readonly status?: "bonded" | "unbonded" | "unbonding"; + readonly page?: number; + readonly limit?: number; +} + export interface StakingValidatorsResponse { readonly height: string; readonly result: readonly Validator[]; diff --git a/packages/sdk38/types/lcdapi/index.d.ts b/packages/sdk38/types/lcdapi/index.d.ts index 43ce0c211c..6a06331d98 100644 --- a/packages/sdk38/types/lcdapi/index.d.ts +++ b/packages/sdk38/types/lcdapi/index.d.ts @@ -40,6 +40,19 @@ export { } from "./slashing"; export { setupStakingExtension, + StakingDelegatorDelegationsResponse, + StakingDelegatorUnbondingDelegationsResponse, + StakingDelegatorTransactionsResponse, + StakingDelegatorValidatorsResponse, + StakingDelegatorValidatorResponse, + StakingDelegationResponse, + StakingUnbondingDelegationResponse, + StakingRedelegationsResponse, + StakingValidatorsResponse, + StakingValidatorResponse, + StakingValidatorDelegationsResponse, + StakingValidatorUnbondingDelegationsResponse, + StakingHistoricalInfoResponse, StakingExtension, StakingParametersResponse, StakingPoolResponse, diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts index fc50631f35..57f2163434 100644 --- a/packages/sdk38/types/lcdapi/staking.d.ts +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -2,12 +2,6 @@ import { Coin } from "../coins"; import { BlockHeader } from "../cosmosclient"; import { SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; -export interface StakingValidatorsParams { - /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ - readonly status?: "bonded" | "unbonded" | "unbonding"; - readonly page?: number; - readonly limit?: number; -} interface Validator { readonly operator_address: string; readonly consensus_pubkey: string; @@ -52,8 +46,8 @@ export interface StakingDelegatorDelegationsResponse { interface UnbondingDelegationEntry { readonly creation_height: string; readonly completion_time: string; - readonly initial_balance: Coin; - readonly balance: Coin; + readonly initial_balance: string; + readonly balance: string; } interface UnbondingDelegation { readonly delegator_address: string; @@ -97,6 +91,12 @@ export interface StakingRedelegationsResponse { readonly height: string; readonly result: readonly Redelegation[]; } +export interface StakingValidatorsParams { + /** @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 */ + readonly status?: "bonded" | "unbonded" | "unbonding"; + readonly page?: number; + readonly limit?: number; +} export interface StakingValidatorsResponse { readonly height: string; readonly result: readonly Validator[]; From 88a2fd1a88a33010592f2a4a6c5cea2c7c50febf Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 22 Jul 2020 12:49:00 +0200 Subject: [PATCH 09/14] sdk38: Use BlockHeader type from lcdapi base in staking extension --- packages/sdk38/src/lcdapi/base.ts | 2 +- packages/sdk38/src/lcdapi/staking.ts | 3 +-- packages/sdk38/types/lcdapi/base.d.ts | 2 +- packages/sdk38/types/lcdapi/staking.d.ts | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/sdk38/src/lcdapi/base.ts b/packages/sdk38/src/lcdapi/base.ts index 2b7bd112ec..2e31b20aec 100644 --- a/packages/sdk38/src/lcdapi/base.ts +++ b/packages/sdk38/src/lcdapi/base.ts @@ -63,7 +63,7 @@ interface BlockId { // } } -interface BlockHeader { +export interface BlockHeader { readonly version: { readonly block: string; readonly app: string; diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index 063788fd06..e7b3b56769 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -1,7 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { Coin } from "../coins"; -import { BlockHeader } from "../cosmosclient"; -import { SearchTxsResponse } from "./base"; +import { BlockHeader, SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; interface Validator { diff --git a/packages/sdk38/types/lcdapi/base.d.ts b/packages/sdk38/types/lcdapi/base.d.ts index 8771acf4ae..437d252f1d 100644 --- a/packages/sdk38/types/lcdapi/base.d.ts +++ b/packages/sdk38/types/lcdapi/base.d.ts @@ -50,7 +50,7 @@ export interface NodeInfoResponse { interface BlockId { readonly hash: string; } -interface BlockHeader { +export interface BlockHeader { readonly version: { readonly block: string; readonly app: string; diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts index 57f2163434..1b66098b2a 100644 --- a/packages/sdk38/types/lcdapi/staking.d.ts +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -1,6 +1,5 @@ import { Coin } from "../coins"; -import { BlockHeader } from "../cosmosclient"; -import { SearchTxsResponse } from "./base"; +import { BlockHeader, SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; interface Validator { readonly operator_address: string; From bd6b90d5fd4ae854f25bba4a96d17e32361cc0c3 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 22 Jul 2020 12:52:31 +0200 Subject: [PATCH 10/14] sdk38: Update lcd staking extension tests --- packages/sdk38/src/lcdapi/staking.spec.ts | 33 ++++++++++++++++------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index 2fadf33276..4dc8810ec0 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -65,7 +65,7 @@ describe("StakingExtension", () => { value: { delegator_address: faucet.address, validator_address: validatorAddress, - amount: coin(10000, "ustake"), + amount: coin(100, "ustake"), }, }; const memo = "Test undelegation for wasmd"; @@ -121,8 +121,8 @@ describe("StakingExtension", () => { expect(response.result[0].entries[0]).toEqual({ creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), completion_time: jasmine.stringMatching(dateTimeStampMatcher), - initial_balance: "10000", - balance: "10000", + initial_balance: "100", + balance: "100", }); }); }); @@ -245,8 +245,8 @@ describe("StakingExtension", () => { expect(response.result!.entries[0]).toEqual({ creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), completion_time: jasmine.stringMatching(dateTimeStampMatcher), - initial_balance: "10000", - balance: "10000", + initial_balance: "100", + balance: "100", }); }); }); @@ -430,8 +430,8 @@ describe("StakingExtension", () => { expect(response.result[0].entries[0]).toEqual({ creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), completion_time: jasmine.stringMatching(dateTimeStampMatcher), - initial_balance: "10000", - balance: "10000", + initial_balance: "100", + balance: "100", }); }); }); @@ -441,7 +441,8 @@ describe("StakingExtension", () => { // TODO: Find a result for this test pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); - const response = await client.staking.historicalInfo("100"); + const currentHeight = (await client.blocksLatest()).block.header.height; + const response = await client.staking.historicalInfo(currentHeight); expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { @@ -450,9 +451,21 @@ describe("StakingExtension", () => { block: "", app: "", }, - height: 10, - chainId: "", + height: "", + chain_id: "", time: "", + last_commit_hash: "", + last_block_id: { + hash: "", + }, + data_hash: "", + validators_hash: "", + next_validators_hash: "", + consensus_hash: "", + app_hash: "", + last_results_hash: "", + evidence_hash: "", + proposer_address: "", }, validators: [], }, From fd736879f8dbbccbd28bfbaf1dd17473e9f41a0d Mon Sep 17 00:00:00 2001 From: willclarktech Date: Wed, 22 Jul 2020 15:35:59 +0200 Subject: [PATCH 11/14] sdk38: Update staking extension for review comments --- packages/sdk38/src/lcdapi/staking.spec.ts | 126 ++++++++++++---------- packages/sdk38/src/lcdapi/staking.ts | 21 ++-- packages/sdk38/types/lcdapi/staking.d.ts | 17 +-- 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index 4dc8810ec0..dad69be67c 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import { assert, sleep } from "@cosmjs/utils"; import { coin, coins } from "../coins"; @@ -5,7 +6,6 @@ import { isPostTxFailure } from "../cosmosclient"; import { makeSignBytes } from "../encoding"; import { MsgDelegate, MsgUndelegate } from "../msgs"; import { SigningCosmosClient } from "../signingcosmosclient"; -/* eslint-disable @typescript-eslint/naming-convention */ import { bigDecimalMatcher, dateTimeStampMatcher, @@ -18,7 +18,7 @@ import { } from "../testutils.spec"; import { Secp256k1Wallet } from "../wallet"; import { LcdClient } from "./lcdclient"; -import { setupStakingExtension, StakingExtension } from "./staking"; +import { BondStatus, setupStakingExtension, StakingExtension } from "./staking"; function makeStakingClient(apiUrl: string): LcdClient & StakingExtension { return LcdClient.withExtensions({ apiUrl }, setupStakingExtension); @@ -46,7 +46,7 @@ describe("StakingExtension", () => { }, }; const memo = "Test delegation for wasmd"; - const { accountNumber, sequence } = await client.getNonce(); + const { accountNumber, sequence } = await client.getSequence(); const signBytes = makeSignBytes([msg], defaultFee, chainId, memo, accountNumber, sequence); const signature = await wallet.sign(faucet.address, signBytes); const tx = { @@ -69,7 +69,7 @@ describe("StakingExtension", () => { }, }; const memo = "Test undelegation for wasmd"; - const { accountNumber, sequence } = await client.getNonce(); + const { accountNumber, sequence } = await client.getSequence(); const signBytes = makeSignBytes([msg], defaultFee, chainId, memo, accountNumber, sequence); const signature = await wallet.sign(faucet.address, signBytes); const tx = { @@ -96,8 +96,8 @@ describe("StakingExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { - delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + delegator_address: faucet.address, + validator_address: validatorAddress, shares: jasmine.stringMatching(bigDecimalMatcher), balance: { denom: "ustake", amount: jasmine.stringMatching(nonNegativeIntegerMatcher) }, }, @@ -110,20 +110,23 @@ describe("StakingExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); - const response = await client.staking.delegatorUnbondingDelegations(faucet.address); - expect(response.height).toMatch(nonNegativeIntegerMatcher); - expect(response.result.length).toEqual(1); - expect(response.result[0].delegator_address).toEqual("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"); - expect(response.result[0].validator_address).toEqual( - "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", - ); - expect(response.result[0].entries.length).toBeGreaterThanOrEqual(1); - expect(response.result[0].entries[0]).toEqual({ - creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), - completion_time: jasmine.stringMatching(dateTimeStampMatcher), - initial_balance: "100", - balance: "100", - }); + const { height, result } = await client.staking.delegatorUnbondingDelegations(faucet.address); + expect(height).toMatch(nonNegativeIntegerMatcher); + assert(result); + expect(result).toEqual([ + { + delegator_address: faucet.address, + validator_address: validatorAddress, + entries: jasmine.arrayContaining([ + { + creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), + completion_time: jasmine.stringMatching(dateTimeStampMatcher), + initial_balance: "100", + balance: "100", + }, + ]), + }, + ]); }); }); @@ -145,11 +148,11 @@ describe("StakingExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { - operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + operator_address: validatorAddress, consensus_pubkey: "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, - status: 2, + status: BondStatus.Bonded, tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { @@ -184,11 +187,11 @@ describe("StakingExtension", () => { expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { - operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + operator_address: validatorAddress, consensus_pubkey: "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, - status: 2, + status: BondStatus.Bonded, tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { @@ -235,18 +238,20 @@ describe("StakingExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); - const response = await client.staking.unbondingDelegation(faucet.address, validatorAddress); - expect(response.height).toMatch(nonNegativeIntegerMatcher); - expect(response.result!.delegator_address).toEqual("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"); - expect(response.result!.validator_address).toEqual( - "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", - ); - expect(response.result!.entries.length).toBeGreaterThanOrEqual(1); - expect(response.result!.entries[0]).toEqual({ - creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), - completion_time: jasmine.stringMatching(dateTimeStampMatcher), - initial_balance: "100", - balance: "100", + const { height, result } = await client.staking.unbondingDelegation(faucet.address, validatorAddress); + expect(height).toMatch(nonNegativeIntegerMatcher); + assert(result); + expect(result).toEqual({ + delegator_address: faucet.address, + validator_address: validatorAddress, + entries: jasmine.arrayContaining([ + { + creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), + completion_time: jasmine.stringMatching(dateTimeStampMatcher), + initial_balance: "100", + balance: "100", + }, + ]), }); }); }); @@ -273,11 +278,11 @@ describe("StakingExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { - operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + operator_address: validatorAddress, consensus_pubkey: "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, - status: 2, + status: BondStatus.Bonded, tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { @@ -321,11 +326,11 @@ describe("StakingExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { - operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + operator_address: validatorAddress, consensus_pubkey: "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, - status: 2, + status: BondStatus.Bonded, tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { @@ -360,11 +365,11 @@ describe("StakingExtension", () => { expect(response).toEqual({ height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: { - operator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + operator_address: validatorAddress, consensus_pubkey: "cosmosvalconspub1zcjduepqau36ht2r742jh230pxlu4wjmwcmkwpeqava80acphsu87vt5xlpqx6g7qh", jailed: false, - status: 2, + status: BondStatus.Bonded, tokens: jasmine.stringMatching(nonNegativeIntegerMatcher), delegator_shares: jasmine.stringMatching(bigDecimalMatcher), description: { @@ -399,14 +404,14 @@ describe("StakingExtension", () => { height: jasmine.stringMatching(nonNegativeIntegerMatcher), result: [ { - delegator_address: "cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6", - validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + delegator_address: faucet.address, + validator_address: validatorAddress, shares: jasmine.stringMatching(bigDecimalMatcher), balance: { denom: "ustake", amount: jasmine.stringMatching(nonNegativeIntegerMatcher) }, }, { delegator_address: "cosmos1gjvanqxc774u6ed9thj4gpn9gj5zus5u57dxvq", - validator_address: "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", + validator_address: validatorAddress, shares: "250000000.000000000000000000", balance: { denom: "ustake", amount: "250000000" }, }, @@ -419,20 +424,23 @@ describe("StakingExtension", () => { it("works", async () => { pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); - const response = await client.staking.validatorUnbondingDelegations(validatorAddress); - expect(response.height).toMatch(nonNegativeIntegerMatcher); - expect(response.result.length).toEqual(1); - expect(response.result[0].delegator_address).toEqual("cosmos1pkptre7fdkl6gfrzlesjjvhxhlc3r4gmmk8rs6"); - expect(response.result[0].validator_address).toEqual( - "cosmosvaloper1gjvanqxc774u6ed9thj4gpn9gj5zus5u32enqn", - ); - expect(response.result[0].entries.length).toBeGreaterThanOrEqual(1); - expect(response.result[0].entries[0]).toEqual({ - creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), - completion_time: jasmine.stringMatching(dateTimeStampMatcher), - initial_balance: "100", - balance: "100", - }); + const { height, result } = await client.staking.validatorUnbondingDelegations(validatorAddress); + expect(height).toMatch(nonNegativeIntegerMatcher); + assert(result); + expect(result).toEqual([ + { + delegator_address: faucet.address, + validator_address: validatorAddress, + entries: jasmine.arrayContaining([ + { + creation_height: jasmine.stringMatching(nonNegativeIntegerMatcher), + completion_time: jasmine.stringMatching(dateTimeStampMatcher), + initial_balance: "100", + balance: "100", + }, + ]), + }, + ]); }); }); diff --git a/packages/sdk38/src/lcdapi/staking.ts b/packages/sdk38/src/lcdapi/staking.ts index e7b3b56769..604e70472f 100644 --- a/packages/sdk38/src/lcdapi/staking.ts +++ b/packages/sdk38/src/lcdapi/staking.ts @@ -3,16 +3,22 @@ import { Coin } from "../coins"; import { BlockHeader, SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; +/** + * Numeric bonding status + * + * @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 + */ +export enum BondStatus { + Unbonded = 0, + Unbonding = 1, + Bonded = 2, +} + interface Validator { readonly operator_address: string; readonly consensus_pubkey: string; readonly jailed: boolean; - /** - * Numeric bonding status - * - * @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 - */ - readonly status: number; + readonly status: BondStatus; readonly tokens: string; readonly delegator_shares: string; readonly description: { @@ -233,8 +239,7 @@ export function setupStakingExtension(base: LcdClient): StakingExtension { validators: async (params?: StakingValidatorsParams) => base.get(`/staking/validators`, params), validator: async (validatorAddress: string) => base.get(`/staking/validators/${validatorAddress}`), validatorDelegations: async (validatorAddress: string) => - base.get(`/staking/validators/${validatorAddress}/delegations - `), + base.get(`/staking/validators/${validatorAddress}/delegations`), validatorUnbondingDelegations: async (validatorAddress: string) => base.get(`/staking/validators/${validatorAddress}/unbonding_delegations`), historicalInfo: async (height: string) => base.get(`/staking/historical_info/${height}`), diff --git a/packages/sdk38/types/lcdapi/staking.d.ts b/packages/sdk38/types/lcdapi/staking.d.ts index 1b66098b2a..bb046fad1d 100644 --- a/packages/sdk38/types/lcdapi/staking.d.ts +++ b/packages/sdk38/types/lcdapi/staking.d.ts @@ -1,16 +1,21 @@ import { Coin } from "../coins"; import { BlockHeader, SearchTxsResponse } from "./base"; import { LcdClient } from "./lcdclient"; +/** + * Numeric bonding status + * + * @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 + */ +export declare enum BondStatus { + Unbonded = 0, + Unbonding = 1, + Bonded = 2, +} interface Validator { readonly operator_address: string; readonly consensus_pubkey: string; readonly jailed: boolean; - /** - * Numeric bonding status - * - * @see https://github.com/cosmos/cosmos-sdk/blob/v0.38.5/types/staking.go#L43-L49 - */ - readonly status: number; + readonly status: BondStatus; readonly tokens: string; readonly delegator_shares: string; readonly description: { From 8f9884ecae9cad611210bb1cd7dcab40bac9ea44 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Thu, 23 Jul 2020 13:46:36 +0200 Subject: [PATCH 12/14] scripts: Update wasmd to v0.9.1 --- scripts/wasmd/env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/wasmd/env b/scripts/wasmd/env index 738980b3c3..02ca613f06 100644 --- a/scripts/wasmd/env +++ b/scripts/wasmd/env @@ -1,5 +1,5 @@ # Choose from https://hub.docker.com/r/cosmwasm/wasmd/tags REPOSITORY="cosmwasm/wasmd" -VERSION="v0.9.0-beta" +VERSION="v0.9.1" CONTAINER_NAME="wasmd" From 90efa7d59392da5af3be265aa6a3e50f3c85a922 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Thu, 23 Jul 2020 13:47:56 +0200 Subject: [PATCH 13/14] sdk38: Update staking extension historical info test --- packages/sdk38/src/lcdapi/staking.spec.ts | 36 ++++------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/packages/sdk38/src/lcdapi/staking.spec.ts b/packages/sdk38/src/lcdapi/staking.spec.ts index dad69be67c..dfe91717e9 100644 --- a/packages/sdk38/src/lcdapi/staking.spec.ts +++ b/packages/sdk38/src/lcdapi/staking.spec.ts @@ -444,40 +444,14 @@ describe("StakingExtension", () => { }); }); - xdescribe("historicalInfo", () => { - it("works", async () => { - // TODO: Find a result for this test + describe("historicalInfo", () => { + it("doesn't work yet", async () => { pendingWithoutWasmd(); const client = makeStakingClient(wasmd.endpoint); const currentHeight = (await client.blocksLatest()).block.header.height; - const response = await client.staking.historicalInfo(currentHeight); - expect(response).toEqual({ - height: jasmine.stringMatching(nonNegativeIntegerMatcher), - result: { - header: { - version: { - block: "", - app: "", - }, - height: "", - chain_id: "", - time: "", - last_commit_hash: "", - last_block_id: { - hash: "", - }, - data_hash: "", - validators_hash: "", - next_validators_hash: "", - consensus_hash: "", - app_hash: "", - last_results_hash: "", - evidence_hash: "", - proposer_address: "", - }, - validators: [], - }, - }); + return expectAsync(client.staking.historicalInfo(currentHeight)).toBeRejectedWithError( + /no historical info found \(HTTP 400\)/i, + ); }); }); From e18a95e80305fad9a20ccb6738c80d9d5d1d2a0f Mon Sep 17 00:00:00 2001 From: willclarktech Date: Thu, 23 Jul 2020 13:53:27 +0200 Subject: [PATCH 14/14] scripts: Fix env variable in wasmd/cli.sh --- scripts/wasmd/cli.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/wasmd/cli.sh b/scripts/wasmd/cli.sh index 804f8f3159..4b8e2474f3 100755 --- a/scripts/wasmd/cli.sh +++ b/scripts/wasmd/cli.sh @@ -16,6 +16,6 @@ docker run \ --mount type=volume,source=wasmcli_data,target=/root/.wasmcli \ -w "$HOME_DIR" \ --env "HOME=$HOME_DIR" \ - --net "container:$BLOCKCHAIN_CONTAINER_NAME" \ + --net "container:$CONTAINER_NAME" \ "$REPOSITORY:$VERSION" \ wasmcli "$@"