From 17c2aecd99abe49a6cc69e167c709174c392d264 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Wed, 22 Mar 2023 18:30:07 +0100 Subject: [PATCH] starting to add vesting tests (#3134) * starting to add vesting tests * adding more vesting client tests * starting to add vesting tests & merging develop * adding more vesting client tests * fix linting * Revert "Merge conflicts" This reverts commit 0beb025a620d11194271d2c822d71245368cbdc5. * fix linting errors * fix linting errors * removing only adding skip --------- Co-authored-by: fmtabbara --- clients/validator/src/index.ts | 109 +++++++++++++- clients/validator/src/nyxd-querier.ts | 138 ++++++++++++++++- clients/validator/src/query-client.ts | 96 +++++++++++- clients/validator/src/signing-client.ts | 96 +++++++++++- .../validator/src/tests/expectedResponses.ts | 82 +++++++++- .../src/tests/query/vestingQueries.test.ts | 142 +++++++++++++++++- sdk/typescript/.eslintrc.js | 2 +- ts-packages/types/src/types/global.ts | 48 ++++++ 8 files changed, 695 insertions(+), 18 deletions(-) diff --git a/clients/validator/src/index.ts b/clients/validator/src/index.ts index e11d24525f..a43baaf51d 100644 --- a/clients/validator/src/index.ts +++ b/clients/validator/src/index.ts @@ -22,6 +22,7 @@ import { MixNodeDetails, MixNodeRewarding, MixOwnershipResponse, + OriginalVestingResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedGatewayResponse, @@ -32,10 +33,11 @@ import { RewardingParams, StakeSaturationResponse, UnbondedMixnodeResponse, + VestingAccountInfo, + ContractState, VestingAccountsCoinPaged, VestingAccountsPaged, DelegationTimes, Delegations, Period, VestingAccountNode } from '@nymproject/types'; import QueryClient from './query-client'; import SigningClient, { ISigningClient } from './signing-client'; -import { ContractState } from './types/shared'; export interface INymClient { readonly mixnetContract: string; @@ -204,7 +206,7 @@ export default class ValidatorClient implements INymClient { let mixNodes: UnbondedMixnodeResponse[] = []; const limit = 50; let startAfter; - for (;;) { + for (; ;) { // eslint-disable-next-line no-await-in-loop const pagedResponse: PagedUnbondedMixnodesResponse = await this.client.getUnbondedMixNodes( this.mixnetContract, @@ -227,7 +229,7 @@ export default class ValidatorClient implements INymClient { let mixNodes: MixNodeBond[] = []; const limit = 50; let startAfter; - for (;;) { + for (; ;) { // eslint-disable-next-line no-await-in-loop const pagedResponse: PagedMixNodeBondResponse = await this.client.getMixNodeBonds( this.mixnetContract, @@ -249,7 +251,7 @@ export default class ValidatorClient implements INymClient { let mixNodes: MixNodeDetails[] = []; const limit = 50; let startAfter; - for (;;) { + for (; ;) { // eslint-disable-next-line no-await-in-loop const pagedResponse: PagedMixNodeDetailsResponse = await this.client.getMixNodesDetailed( this.mixnetContract, @@ -281,7 +283,7 @@ export default class ValidatorClient implements INymClient { let delegations: Delegation[] = []; const limit = 250; let startAfter; - for (;;) { + for (; ;) { // eslint-disable-next-line no-await-in-loop const pagedResponse: PagedMixDelegationsResponse = await this.client.getMixNodeDelegationsPaged( this.mixnetContract, @@ -304,7 +306,7 @@ export default class ValidatorClient implements INymClient { let delegations: Delegation[] = []; const limit = 250; let startAfter; - for (;;) { + for (; ;) { // eslint-disable-next-line no-await-in-loop const pagedResponse: PagedDelegatorDelegationsResponse = await this.client.getDelegatorDelegationsPaged( this.mixnetContract, @@ -327,7 +329,7 @@ export default class ValidatorClient implements INymClient { let delegations: Delegation[] = []; const limit = 250; let startAfter; - for (;;) { + for (; ;) { // eslint-disable-next-line no-await-in-loop const pagedResponse: PagedAllDelegationsResponse = await this.client.getAllDelegationsPaged( this.mixnetContract, @@ -514,4 +516,97 @@ export default class ValidatorClient implements INymClient { this.assertSigning(); return (this.client as ISigningClient).updateContractStateParams(this.mixnetContract, newParams, fee, memo); } + + + // VESTING + // TODO - MOVE TO A DIFFERENT FILE + + + public async getVestingAccountsPaged(): Promise { + return this.client.getVestingAccountsPaged(this.vestingContract); + } + + public async getVestingAmountsAccountsPaged(): Promise { + return this.client.getVestingAmountsAccountsPaged(this.vestingContract); + } + + public async getLockedTokens(vestingAccountAddress: string): Promise { + return this.client.getLockedTokens(this.vestingContract, vestingAccountAddress); + } + + public async getSpendableTokens(vestingAccountAddress: string): Promise { + return this.client.getSpendableTokens(this.vestingContract, vestingAccountAddress); + } + + public async getVestedTokens(vestingAccountAddress: string): Promise { + return this.client.getVestedTokens(this.vestingContract, vestingAccountAddress); + } + + public async getVestingTokens(vestingAccountAddress: string): Promise { + return this.client.getVestingTokens(this.vestingContract, vestingAccountAddress); + } + + public async getSpendableVestedTokens(vestingAccountAddress: string): Promise { + return this.client.getSpendableVestedTokens(this.vestingContract, vestingAccountAddress); + } + + public async getSpendableRewards(vestingAccountAddress: string): Promise { + return this.client.getSpendableRewards(this.vestingContract, vestingAccountAddress); + } + + public async getDelegatedCoins(vestingAccountAddress: string): Promise { + return this.client.getDelegatedCoins(this.vestingContract, vestingAccountAddress); + } + + public async getPledgedCoins(vestingAccountAddress: string): Promise { + return this.client.getPledgedCoins(this.vestingContract, vestingAccountAddress); + } + + public async getStakedCoins(vestingAccountAddress: string): Promise { + return this.client.getStakedCoins(this.vestingContract, vestingAccountAddress); + } + + public async getWithdrawnCoins(vestingAccountAddress: string): Promise { + return this.client.getWithdrawnCoins(this.vestingContract, vestingAccountAddress); + } + + public async getStartTime(vestingAccountAddress: string): Promise { + return this.client.getStartTime(this.vestingContract, vestingAccountAddress); + } + + public async getEndTime(vestingAccountAddress: string): Promise { + return this.client.getEndTime(this.vestingContract, vestingAccountAddress); + } + + public async getOriginalVestingDetails(vestingAccountAddress: string): Promise { + return this.client.getOriginalVestingDetails(this.vestingContract, vestingAccountAddress); + } + + public async getHistoricStakingRewards(vestingAccountAddress: string): Promise { + return this.client.getHistoricStakingRewards(this.vestingContract, vestingAccountAddress); + } + + public async getAccountDetails(address: string): Promise { + return this.client.getAccountDetails(this.vestingContract, address); + } + + public async getMixnode(address: string): Promise { + return this.client.getMixnode(this.vestingContract, address); + } + + public async getGateway(address: string): Promise { + return this.client.getGateway(this.vestingContract, address); + } + + public async getDelegationTimes(mix_id: number, delegatorAddress: string): Promise { + return this.client.getDelegationTimes(this.vestingContract, mix_id, delegatorAddress); + } + + public async getAllDelegations(): Promise { + return this.client.getAllDelegations(this.vestingContract); + } + + public async getCurrentVestingPeriod(address: string): Promise { + return this.client.getCurrentVestingPeriod(this.vestingContract, address); + } } diff --git a/clients/validator/src/nyxd-querier.ts b/clients/validator/src/nyxd-querier.ts index 0e34493c2e..7fe09a4896 100644 --- a/clients/validator/src/nyxd-querier.ts +++ b/clients/validator/src/nyxd-querier.ts @@ -4,8 +4,8 @@ */ // eslint-disable-next-line import/no-cycle import { INyxdQuery } from './query-client'; -import { Delegation, RewardingParams, StakeSaturationResponse } from '@nymproject/types'; import { + Delegation, OriginalVestingResponse, RewardingParams, StakeSaturationResponse, VestingAccountInfo, UnbondedMixnodeResponse, GatewayOwnershipResponse, MixnetContractVersion, @@ -18,8 +18,10 @@ import { PagedMixNodeDetailsResponse, PagedUnbondedMixnodesResponse, LayerDistribution, + ContractState, VestingAccountsCoinPaged, VestingAccountsPaged, DelegationTimes, Delegations, Period, VestingAccountNode } from '@nymproject/types'; -import { ContractState, SmartContractQuery } from './types/shared'; +import { SmartContractQuery } from './types/shared'; +import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin'; export default class NyxdQuerier implements INyxdQuery { client: SmartContractQuery; @@ -188,4 +190,136 @@ export default class NyxdQuerier implements INyxdQuery { vesting_account_address: vestingAccountAddress, }); } + + getVestingAccountsPaged(vestingContractAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_accounts_paged: {} + }); + } + + getVestingAmountsAccountsPaged(vestingContractAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_accounts_vesting_coins_paged: {} + }); + } + + getLockedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + locked_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getSpendableTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + spendable_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getVestedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_vested_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getVestingTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_vesting_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getSpendableVestedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_spendable_vested_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getSpendableRewards(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_spendable_reward_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getDelegatedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_delegated_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getPledgedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_pledged_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getStakedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_staked_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getWithdrawnCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_withdrawn_coins: { vesting_account_address: vestingAccountAddress } + }); + } + + getStartTime(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_start_time: { vesting_account_address: vestingAccountAddress } + }); + } + + getEndTime(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_end_time: { vesting_account_address: vestingAccountAddress } + }); + } + + getOriginalVestingDetails(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_original_vesting: { vesting_account_address: vestingAccountAddress } + }); + } + + getHistoricStakingRewards(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_historical_vesting_staking_reward: { vesting_account_address: vestingAccountAddress } + }); + } + + getAccountDetails(vestingContractAddress: string, address: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_account: { address: address } + }); + } + + getMixnode(vestingContractAddress: string, address: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_mixnode: { address: address } + }); + } + + getGateway(vestingContractAddress: string, address: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_gateway: { address: address } + }); + } + + getDelegationTimes(vestingContractAddress: string, mix_id: number, address: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_delegation_times: { mix_id: mix_id, address: address } + }); + } + + getAllDelegations(vestingContractAddress: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_all_delegations: {} + }); + } + + getCurrentVestingPeriod(vestingContractAddress: string, address: string): Promise { + return this.client.queryContractSmart(vestingContractAddress, { + get_current_vesting_period: { address: address } + }); + } } diff --git a/clients/validator/src/query-client.ts b/clients/validator/src/query-client.ts index 319c46f80e..23fa68be83 100644 --- a/clients/validator/src/query-client.ts +++ b/clients/validator/src/query-client.ts @@ -20,11 +20,15 @@ import { UnbondedMixnodeResponse, MixNodeBond, MixNodeRewarding, + OriginalVestingResponse, + VestingAccountInfo, + ContractState, VestingAccountsCoinPaged, VestingAccountsPaged, DelegationTimes, Delegations, Period, VestingAccountNode } from '@nymproject/types'; import NymApiQuerier, { INymApiQuery } from './nym-api-querier'; -import { ContractState, ICosmWasmQuery } from './types/shared'; +import { ICosmWasmQuery } from './types/shared'; import { RewardingParams } from '@nymproject/types'; import { Tendermint34Client } from '@cosmjs/tendermint-rpc'; +import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin'; export interface INyxdQuery { // nym-specific implemented inside NymQuerier @@ -68,7 +72,7 @@ export interface INyxdQuery { getMixnodeRewardingDetails(mixnetContractAddress: string, mixId: number): Promise; } -export interface IQueryClient extends ICosmWasmQuery, INyxdQuery, INymApiQuery {} +export interface IQueryClient extends ICosmWasmQuery, INyxdQuery, INymApiQuery { } export default class QueryClient extends CosmWasmClient implements IQueryClient { private nyxdQuerier: NyxdQuerier; @@ -199,4 +203,92 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient getSpendableCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { return this.nyxdQuerier.getSpendableCoins(vestingContractAddress, vestingAccountAddress); } + + getVestingAccountsPaged(vestingContractAddress: string): Promise { + return this.nyxdQuerier.getVestingAccountsPaged(vestingContractAddress); + } + + getVestingAmountsAccountsPaged(vestingContractAddress: string): Promise { + return this.nyxdQuerier.getVestingAmountsAccountsPaged(vestingContractAddress); + } + + getLockedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getLockedTokens(vestingContractAddress, vestingAccountAddress); + } + + getSpendableTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getSpendableTokens(vestingContractAddress, vestingAccountAddress); + } + + getVestedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getVestedTokens(vestingContractAddress, vestingAccountAddress); + } + + getVestingTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getVestingTokens(vestingContractAddress, vestingAccountAddress); + } + + getSpendableVestedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getSpendableVestedTokens(vestingContractAddress, vestingAccountAddress); + } + + getSpendableRewards(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getSpendableRewards(vestingContractAddress, vestingAccountAddress); + } + + getDelegatedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getDelegatedCoins(vestingContractAddress, vestingAccountAddress); + } + + getPledgedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getPledgedCoins(vestingContractAddress, vestingAccountAddress); + } + + getStakedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getStakedCoins(vestingContractAddress, vestingAccountAddress); + } + + getWithdrawnCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getWithdrawnCoins(vestingContractAddress, vestingAccountAddress); + } + + getStartTime(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getStartTime(vestingContractAddress, vestingAccountAddress); + } + + getEndTime(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getEndTime(vestingContractAddress, vestingAccountAddress); + } + + getOriginalVestingDetails(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getOriginalVestingDetails(vestingContractAddress, vestingAccountAddress); + } + + getHistoricStakingRewards(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getHistoricStakingRewards(vestingContractAddress, vestingAccountAddress); + } + + getAccountDetails(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getAccountDetails(vestingContractAddress, address); + } + + getMixnode(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getMixnode(vestingContractAddress, address); + } + + getGateway(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getGateway(vestingContractAddress, address); + } + + getDelegationTimes(vestingContractAddress: string, mix_id: number, delegatorAddress: string): Promise { + return this.nyxdQuerier.getDelegationTimes(vestingContractAddress, mix_id, delegatorAddress); + } + + getAllDelegations(vestingContractAddress: string): Promise { + return this.nyxdQuerier.getAllDelegations(vestingContractAddress); + } + + getCurrentVestingPeriod(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getCurrentVestingPeriod(vestingContractAddress, address); + } } diff --git a/clients/validator/src/signing-client.ts b/clients/validator/src/signing-client.ts index d750eefcd2..946f848da4 100644 --- a/clients/validator/src/signing-client.ts +++ b/clients/validator/src/signing-client.ts @@ -29,6 +29,7 @@ import { MixNodeDetails, MixNodeRewarding, MixOwnershipResponse, + OriginalVestingResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedGatewayResponse, @@ -38,9 +39,10 @@ import { PagedUnbondedMixnodesResponse, RewardingParams, UnbondedMixnodeResponse, + VestingAccountInfo, + ContractState, VestingAccountsCoinPaged, VestingAccountsPaged, DelegationTimes, Delegations, Period, VestingAccountNode } from '@nymproject/types'; import NymApiQuerier from './nym-api-querier'; -import { ContractState } from './types/shared'; // methods exposed by `SigningCosmWasmClient` export interface ICosmWasmSigning { @@ -243,7 +245,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig // query related: getContractVersion(mixnetContractAddress: string): Promise { - return this.getContractVersion(mixnetContractAddress); + return this.nyxdQuerier.getContractVersion(mixnetContractAddress); } getMixNodeBonds( @@ -508,4 +510,94 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig memo, ); } + + // vesting related + + getVestingAccountsPaged(vestingContractAddress: string): Promise { + return this.nyxdQuerier.getVestingAccountsPaged(vestingContractAddress); + }; + + getVestingAmountsAccountsPaged(vestingContractAddress: string): Promise { + return this.nyxdQuerier.getVestingAmountsAccountsPaged(vestingContractAddress); + } + + getLockedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getLockedTokens(vestingContractAddress, vestingAccountAddress); + } + + getSpendableTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getSpendableTokens(vestingContractAddress, vestingAccountAddress); + } + + getVestedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getVestedTokens(vestingContractAddress, vestingAccountAddress); + } + + getVestingTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getVestingTokens(vestingContractAddress, vestingAccountAddress); + } + + getSpendableVestedTokens(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getSpendableVestedTokens(vestingContractAddress, vestingAccountAddress); + } + + getSpendableRewards(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getSpendableRewards(vestingContractAddress, vestingAccountAddress); + } + + getDelegatedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getDelegatedCoins(vestingContractAddress, vestingAccountAddress); + } + + getPledgedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getPledgedCoins(vestingContractAddress, vestingAccountAddress); + } + + getStakedCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getStakedCoins(vestingContractAddress, vestingAccountAddress); + } + + getWithdrawnCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getWithdrawnCoins(vestingContractAddress, vestingAccountAddress); + } + + getStartTime(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getStartTime(vestingContractAddress, vestingAccountAddress); + } + + getEndTime(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getEndTime(vestingContractAddress, vestingAccountAddress); + } + + getOriginalVestingDetails(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getOriginalVestingDetails(vestingContractAddress, vestingAccountAddress); + } + + getHistoricStakingRewards(vestingContractAddress: string, vestingAccountAddress: string): Promise { + return this.nyxdQuerier.getHistoricStakingRewards(vestingContractAddress, vestingAccountAddress); + } + + getAccountDetails(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getAccountDetails(vestingContractAddress, address); + } + + getMixnode(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getMixnode(vestingContractAddress, address); + } + + getGateway(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getGateway(vestingContractAddress, address); + } + + getDelegationTimes(vestingContractAddress: string, mix_id: number, delegatorAddress: string): Promise { + return this.nyxdQuerier.getDelegationTimes(vestingContractAddress, mix_id, delegatorAddress); + } + + getAllDelegations(vestingContractAddress: string): Promise { + return this.nyxdQuerier.getAllDelegations(vestingContractAddress); + } + + getCurrentVestingPeriod(vestingContractAddress: string, address: string): Promise { + return this.nyxdQuerier.getCurrentVestingPeriod(vestingContractAddress, address); + } } diff --git a/clients/validator/src/tests/expectedResponses.ts b/clients/validator/src/tests/expectedResponses.ts index 876f61e866..74b7d02b4a 100644 --- a/clients/validator/src/tests/expectedResponses.ts +++ b/clients/validator/src/tests/expectedResponses.ts @@ -1,8 +1,9 @@ +import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin'; import expect from 'expect'; export const amountDemon = { - amount: expect.any(String), - denom: expect.any(String) + denom: expect.any(String), + amount: expect.any(String) } export const delegation = { @@ -159,7 +160,6 @@ export const layerDistribution = { layer3: expect.any(Number) } - export const intervalRewardParams = { reward_pool: expect.any(Number), staking_supply: expect.any(Number), @@ -176,3 +176,79 @@ export const rewardingParams = { rewarded_set_size: expect.any(Number), active_set_size: expect.any(Number) } + +export const VestAccounts = [{ + account_id: expect.any(String), + owner: expect.any(String) +}] + +export const VestAccountCoin = [{ + account_id: expect.any(String), + owner: expect.any(String), + still_vesting: Coin +}] + +export const vestingAccountsPaged = { + accounts: VestAccounts, + start_next_after: expect.any(String) +} + +export const VestingCoinAccounts = { + accounts: VestAccountCoin, + start_next_after: expect.any(String) +} + +export const OriginalVestingDetails = { + amount: Coin, + number_of_periods: expect.any(Number), + period_duration: expect.any(Number) +} + +export const PledgeCap = { + percent: expect.any(String) || null, +}; + +export const Periods = [{ + period_seconds: expect.any(Number), + start_time: expect.any(Number), +}] + +export const VestingAccountDetails = { + owner_address: expect.any(String), + staking_address: expect.any(String) || null, + start_time: expect.any(String), + periods: Periods, + coin: Coin, + storage_key: expect.any(Number), + pledge_cap: PledgeCap +} + +export const Node = { + amount: Coin, + block_time: expect.any(String) +} + +export type VestingPeriod = 'Before' | { In: number } | 'After'; + +export const DelegationTimestamps = [ + expect.any(Number) +] + +export const DelegatorTimes = { + owner: expect.any(String), + account_id: expect.any(Number), + mix_id: expect.any(Number), + delegation_timestamps: DelegationTimestamps +} + +export const DelegationBlock = [{ + account_id: expect.any(Number), + amount: expect.any(String), + block_timestamp: expect.any(Number), + mix_id: expect.any(Number) +}] + +export const Delegations = { + delegations: DelegationBlock, + start_next_after: expect.any(String) || null +} diff --git a/clients/validator/src/tests/query/vestingQueries.test.ts b/clients/validator/src/tests/query/vestingQueries.test.ts index 2cbe4f5088..4fec1521cb 100644 --- a/clients/validator/src/tests/query/vestingQueries.test.ts +++ b/clients/validator/src/tests/query/vestingQueries.test.ts @@ -1,5 +1,6 @@ import expect from 'expect'; import ValidatorClient from '../../index'; +import { amountDemon, Delegations, DelegatorTimes, Node, OriginalVestingDetails, VestingAccountDetails, vestingAccountsPaged, VestingCoinAccounts, VestingPeriod } from '../expectedResponses'; const dotenv = require('dotenv'); @@ -19,10 +20,149 @@ describe('Vesting queries', () => { ); }); + const vesting_account_address = 'n14juvj7llvx8eppypnqj6xlrgwss9wfrcuy0nkv'; + const mixnodeowner = 'n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70'; + const gatewayowner = 'n1un9cuvw9e3xqratmde4j55ucksev0dkeruq800'; + const mix_id = 79; + it('can query for contract version', async () => { const contract = await client.getVestingContractVersion(); expect(contract).toBeTruthy(); }); - it('can get the balance on the account', () => {}); + // TODO see if we can use AccountEntry type here instead + it('can get all accounts paged', async () => { + const accounts = await client.getVestingAccountsPaged(); + expect(Object.keys(accounts)).toEqual(Object.keys(vestingAccountsPaged)); + expect(accounts).toBeTruthy(); + }); + + it('can get coins for all accounts paged', async () => { + const accounts = await client.getVestingAmountsAccountsPaged(); + expect(Object.keys(accounts)).toEqual(Object.keys(VestingCoinAccounts)); + expect(accounts).toBeTruthy(); + }); + + it('can get locked tokens for an account', async () => { + const locked = await client.getLockedTokens(vesting_account_address); + expect(Object.keys(locked)).toEqual(Object.keys(amountDemon)); + expect(locked).toBeTruthy(); + }); + + it('can get spendable tokens for an account', async () => { + const spendable = await client.getSpendableTokens(vesting_account_address); + expect(Object.keys(spendable)).toEqual(Object.keys(amountDemon)); + expect(spendable).toBeTruthy(); + }); + + it('can get vested tokens for an account', async () => { + const vested = await client.getVestedTokens(vesting_account_address); + expect(Object.keys(vested)).toEqual(Object.keys(amountDemon)); + expect(vested).toBeTruthy(); + }); + + it('can get vesting tokens for an account', async () => { + const vesting = await client.getVestingTokens(vesting_account_address); + expect(Object.keys(vesting)).toEqual(Object.keys(amountDemon)); + expect(vesting).toBeTruthy(); + }); + + it('can get spendable vested tokens for an account', async () => { + const spendable = await client.getSpendableVestedTokens(vesting_account_address); + expect(Object.keys(spendable)).toEqual(Object.keys(amountDemon)); + expect(spendable).toBeTruthy(); + }); + + it('can get spendable rewards for an account', async () => { + const rewards = await client.getSpendableRewards(vesting_account_address); + expect(Object.keys(rewards)).toEqual(Object.keys(amountDemon)); + expect(rewards).toBeTruthy(); + }); + + it('can get delegated coins', async () => { + const delegated = await client.getDelegatedCoins(vesting_account_address); + expect(Object.keys(delegated)).toEqual(Object.keys(amountDemon)); + expect(delegated).toBeTruthy(); + }); + + it('can get pledged coins', async () => { + const pledged = await client.getPledgedCoins(vesting_account_address); + expect(Object.keys(pledged)).toEqual(Object.keys(amountDemon)); + expect(pledged).toBeTruthy(); + }); + + it('can get staked coins', async () => { + const staked = await client.getStakedCoins(vesting_account_address); + expect(Object.keys(staked)).toEqual(Object.keys(amountDemon)); + expect(staked).toBeTruthy(); + }); + + it('can get withdrawn coins', async () => { + const withdrawn = await client.getWithdrawnCoins(vesting_account_address); + expect(Object.keys(withdrawn)).toEqual(Object.keys(amountDemon)); + expect(withdrawn).toBeTruthy(); + }); + + it('can get start time of an account', async () => { + const time = await client.getStartTime(vesting_account_address); + expect(typeof time).toBe("string"); + expect(time).toBeTruthy(); + }); + + it('can get end time of an account', async () => { + const time = await client.getEndTime(vesting_account_address); + expect(typeof time).toBe("string"); + expect(time).toBeTruthy(); + }); + + it('can get account original vesting details', async () => { + const original = await client.getOriginalVestingDetails(vesting_account_address); + expect(Object.keys(original)).toEqual(Object.keys(OriginalVestingDetails)); + expect(original).toBeTruthy(); + }); + + it('can get historic vesting staking rewards', async () => { + const rewards = await client.getHistoricStakingRewards(vesting_account_address); + expect(Object.keys(rewards)).toEqual(Object.keys(amountDemon)); + expect(rewards).toBeTruthy(); + }); + + // TODO see if we can use "VestingAccountInfo" type here instead + it('can get account details', async () => { + const account = await client.getAccountDetails(vesting_account_address); + expect(Object.keys(account)).toEqual(Object.keys(VestingAccountDetails)); + expect(account).toBeTruthy(); + }); + + // TODO add option for if account has no mixnode and expected is null + it('can get mixnode', async () => { + const mixnode = await client.getMixnode(mixnodeowner); + expect(Object.keys(mixnode)).toEqual(Object.keys(Node)); + expect(mixnode).toBeTruthy(); + }); + + // TODO add option for if account has no gateway and expected is null + it.skip('can get gateway', async () => { + const gateway = await client.getGateway(gatewayowner); + expect(Object.keys(gateway)).toEqual(Object.keys(Node)); + expect(gateway).toBeTruthy(); + }); + + it('can get delegations times', async () => { + const delegation = await client.getDelegationTimes(mix_id, mixnodeowner); + expect(Object.keys(delegation)).toEqual(Object.keys(DelegatorTimes)); + expect(delegation).toBeTruthy(); + }); + + it('can get all delegations', async () => { + const delegation = await client.getAllDelegations(); + expect(Object.keys(delegation)).toEqual(Object.keys(Delegations)); + expect(delegation).toBeTruthy(); + }); + + it('can get current vesting period', async () => { + const period = await client.getCurrentVestingPeriod(gatewayowner); + expect(period).toEqual(expect.anything() as unknown as VestingPeriod); + expect(period).toBeTruthy(); + }); }); diff --git a/sdk/typescript/.eslintrc.js b/sdk/typescript/.eslintrc.js index 213b29beb1..040935b3bd 100644 --- a/sdk/typescript/.eslintrc.js +++ b/sdk/typescript/.eslintrc.js @@ -27,7 +27,7 @@ module.exports = { 'plugin:jest/recommended', 'plugin:jest/style', ], - ignorePatterns: ['dist/**/*', 'dist', 'node_modules'], + ignorePatterns: ['dist/**/*', 'dist', 'node_modules', '**/wasm/worker.js'], rules: { 'jest/prefer-strict-equal': 'error', 'jest/prefer-to-have-length': 'warn', diff --git a/ts-packages/types/src/types/global.ts b/ts-packages/types/src/types/global.ts index c949456494..bcd08f738a 100644 --- a/ts-packages/types/src/types/global.ts +++ b/ts-packages/types/src/types/global.ts @@ -150,3 +150,51 @@ export type LayerDistribution = { layer2: number; layer3: number; }; + +export interface ContractState { + owner: string; + rewarding_validator_address: string; + vesting_contract_address: string; + rewarding_denom: string; + params: ContractStateParams; +} + +export type VestingAccountNode = { + amount: Coin; + block_time: string; +}; + +export interface VestAccounts { + account_id: string; + owner: string; +} + +export interface VestingAccountsPaged { + accounts: VestAccounts[]; + start_next_after: string; +} + +export interface VestingAccountsCoinPaged { + account_id: string; + owner: string; + still_vesting: Coin; +} + +export interface DelegationTimes { + account_id: number; + delegation_timestamps: []; + mix_id: number; + owner: string; +} + +export interface DelegationBlock { + account_id: number; + amount: string; + block_timestamp: number; + mix_id: number; +} + +export interface Delegations { + delegations: DelegationBlock[]; + start_next_after: string | null; +}