622 lines
20 KiB
TypeScript
622 lines
20 KiB
TypeScript
import {
|
|
ExecuteResult,
|
|
InstantiateOptions,
|
|
InstantiateResult,
|
|
MigrateResult,
|
|
UploadResult,
|
|
} from '@cosmjs/cosmwasm-stargate';
|
|
import { Bip39, Random } from '@cosmjs/crypto';
|
|
import { DirectSecp256k1HdWallet, EncodeObject } from '@cosmjs/proto-signing';
|
|
import { Coin, coin as cosmosCoin, DeliverTxResponse, isDeliverTxFailure, StdFee } from '@cosmjs/stargate';
|
|
import {
|
|
ContractStateParams,
|
|
Delegation,
|
|
Gateway,
|
|
GatewayBond,
|
|
GatewayOwnershipResponse,
|
|
LayerDistribution,
|
|
MixnetContractVersion,
|
|
MixNode,
|
|
MixNodeBond,
|
|
MixNodeCostParams,
|
|
MixNodeDetails,
|
|
MixNodeRewarding,
|
|
MixOwnershipResponse,
|
|
OriginalVestingResponse,
|
|
PagedAllDelegationsResponse,
|
|
PagedDelegatorDelegationsResponse,
|
|
PagedGatewayResponse,
|
|
PagedMixDelegationsResponse,
|
|
PagedMixNodeBondResponse,
|
|
PagedMixNodeDetailsResponse,
|
|
PagedUnbondedMixnodesResponse,
|
|
RewardingParams,
|
|
StakeSaturationResponse,
|
|
UnbondedMixnodeResponse,
|
|
VestingAccountInfo,
|
|
ContractState, VestingAccountsCoinPaged, VestingAccountsPaged, DelegationTimes, Delegations, Period, VestingAccountNode, DelegationBlock
|
|
} from '@nymproject/types';
|
|
import QueryClient from './query-client';
|
|
import SigningClient, { ISigningClient } from './signing-client';
|
|
// import { DelegationBlock } from './types/shared';
|
|
|
|
export interface INymClient {
|
|
readonly mixnetContract: string;
|
|
readonly vestingContract: string;
|
|
}
|
|
|
|
export default class ValidatorClient implements INymClient {
|
|
readonly client: SigningClient | QueryClient;
|
|
|
|
private readonly denom: string;
|
|
|
|
private readonly prefix: string;
|
|
|
|
readonly mixnetContract: string;
|
|
|
|
readonly vestingContract: string;
|
|
|
|
readonly mainnetDenom = 'unym';
|
|
|
|
readonly mainnetPrefix = 'n';
|
|
|
|
private constructor(
|
|
client: SigningClient | QueryClient,
|
|
prefix: string,
|
|
mixnetContract: string,
|
|
vestingContract: string,
|
|
denom: string,
|
|
) {
|
|
this.client = client;
|
|
this.prefix = prefix;
|
|
this.denom = `u${denom}`;
|
|
|
|
this.mixnetContract = mixnetContract;
|
|
this.vestingContract = vestingContract;
|
|
}
|
|
|
|
static async connect(
|
|
mnemonic: string,
|
|
nyxdUrl: string,
|
|
nymApiUrl: string,
|
|
prefix: string,
|
|
mixnetContract: string,
|
|
vestingContract: string,
|
|
denom: string,
|
|
): Promise<ValidatorClient> {
|
|
const wallet = await ValidatorClient.buildWallet(mnemonic, prefix);
|
|
|
|
const signingClient = await SigningClient.connectWithNymSigner(wallet, nyxdUrl, nymApiUrl, prefix, denom);
|
|
return new ValidatorClient(signingClient, prefix, mixnetContract, vestingContract, denom);
|
|
}
|
|
|
|
static async connectForQuery(
|
|
nyxdUrl: string,
|
|
nymApiUrl: string,
|
|
prefix: string,
|
|
mixnetContract: string,
|
|
vestingContract: string,
|
|
denom: string,
|
|
): Promise<ValidatorClient> {
|
|
const queryClient = await QueryClient.connectWithNym(nyxdUrl, nymApiUrl);
|
|
return new ValidatorClient(queryClient, prefix, mixnetContract, vestingContract, denom);
|
|
}
|
|
|
|
public get address(): string {
|
|
if (this.client instanceof SigningClient) {
|
|
return this.client.clientAddress;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
private assertSigning() {
|
|
if (this.client instanceof QueryClient) {
|
|
throw new Error('Tried to perform signing action with a query client!');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generates a random mnemonic, useful for creating new accounts.
|
|
* @returns a fresh mnemonic.
|
|
*/
|
|
static randomMnemonic(): string {
|
|
return Bip39.encode(Random.getBytes(32)).toString();
|
|
}
|
|
|
|
/**
|
|
* @param mnemonic A mnemonic from which to generate a public/private keypair.
|
|
* @param prefix the bech32 address prefix (human readable part)
|
|
* @returns the address for this client wallet
|
|
*/
|
|
static async mnemonicToAddress(mnemonic: string, prefix: string): Promise<string> {
|
|
const wallet = await ValidatorClient.buildWallet(mnemonic, prefix);
|
|
const [{ address }] = await wallet.getAccounts();
|
|
return address;
|
|
}
|
|
|
|
static async buildWallet(mnemonic: string, prefix: string): Promise<DirectSecp256k1HdWallet> {
|
|
const signerOptions = { prefix };
|
|
return DirectSecp256k1HdWallet.fromMnemonic(mnemonic, signerOptions);
|
|
}
|
|
|
|
async getBalance(address: string): Promise<Coin> {
|
|
return this.client.getBalance(address, this.denom);
|
|
}
|
|
|
|
async getCachedGateways(): Promise<GatewayBond[]> {
|
|
return this.client.getCachedGateways();
|
|
}
|
|
|
|
async getCachedMixnodes(): Promise<MixNodeBond[]> {
|
|
return this.client.getCachedMixnodes();
|
|
}
|
|
|
|
async getStakeSaturation(mixId: number): Promise<StakeSaturationResponse> {
|
|
return this.client.getStakeSaturation(this.mixnetContract, mixId);
|
|
}
|
|
|
|
async getActiveMixnodes(): Promise<MixNodeDetails[]> {
|
|
return this.client.getActiveMixnodes();
|
|
}
|
|
|
|
async getUnbondedMixNodeInformation(mixId: number): Promise<UnbondedMixnodeResponse> {
|
|
return this.client.getUnbondedMixNodeInformation(this.mixnetContract, mixId);
|
|
}
|
|
|
|
async getRewardedMixnodes(): Promise<MixNodeBond[]> {
|
|
return this.client.getRewardedMixnodes();
|
|
}
|
|
|
|
async getMixnodeRewardingDetails(mixId: number): Promise<MixNodeRewarding> {
|
|
return this.client.getMixnodeRewardingDetails(this.mixnetContract, mixId);
|
|
}
|
|
|
|
async getOwnedMixnode(address: string): Promise<MixOwnershipResponse> {
|
|
return this.client.getOwnedMixnode(this.mixnetContract, address);
|
|
}
|
|
|
|
async ownsGateway(address: string): Promise<GatewayOwnershipResponse> {
|
|
return this.client.ownsGateway(this.mixnetContract, address);
|
|
}
|
|
|
|
async getLayerDistribution(): Promise<LayerDistribution> {
|
|
return this.client.getLayerDistribution(this.mixnetContract);
|
|
}
|
|
|
|
public async getMixnetContractSettings(): Promise<ContractState> {
|
|
return this.client.getStateParams(this.mixnetContract);
|
|
}
|
|
|
|
public async getMixnetContractVersion(): Promise<MixnetContractVersion> {
|
|
return this.client.getContractVersion(this.mixnetContract);
|
|
}
|
|
|
|
public async getVestingContractVersion(): Promise<MixnetContractVersion> {
|
|
return this.client.getContractVersion(this.vestingContract);
|
|
}
|
|
|
|
public async getSpendableCoins(vestingAccountAddress: string): Promise<MixnetContractVersion> {
|
|
return this.client.getSpendableCoins(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getRewardParams(): Promise<RewardingParams> {
|
|
return this.client.getRewardParams(this.mixnetContract);
|
|
}
|
|
|
|
async getUnbondedMixNodes(): Promise<UnbondedMixnodeResponse[]> {
|
|
let mixNodes: UnbondedMixnodeResponse[] = [];
|
|
const limit = 50;
|
|
let startAfter;
|
|
for (; ;) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const pagedResponse: PagedUnbondedMixnodesResponse = await this.client.getUnbondedMixNodes(
|
|
this.mixnetContract,
|
|
limit,
|
|
startAfter,
|
|
);
|
|
|
|
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
|
startAfter = pagedResponse.start_next_after;
|
|
// if `start_next_after` is not set, we're done
|
|
if (!startAfter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mixNodes;
|
|
}
|
|
|
|
public async getMixNodeBonds(): Promise<MixNodeBond[]> {
|
|
let mixNodes: MixNodeBond[] = [];
|
|
const limit = 50;
|
|
let startAfter;
|
|
for (; ;) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const pagedResponse: PagedMixNodeBondResponse = await this.client.getMixNodeBonds(
|
|
this.mixnetContract,
|
|
limit,
|
|
startAfter,
|
|
);
|
|
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
|
startAfter = pagedResponse.start_next_after;
|
|
// if `start_next_after` is not set, we're done
|
|
if (!startAfter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mixNodes;
|
|
}
|
|
|
|
public async getMixNodesDetailed(): Promise<MixNodeDetails[]> {
|
|
let mixNodes: MixNodeDetails[] = [];
|
|
const limit = 50;
|
|
let startAfter;
|
|
for (; ;) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const pagedResponse: PagedMixNodeDetailsResponse = await this.client.getMixNodesDetailed(
|
|
this.mixnetContract,
|
|
limit,
|
|
startAfter,
|
|
);
|
|
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
|
startAfter = pagedResponse.start_next_after;
|
|
// if `start_next_after` is not set, we're done
|
|
if (!startAfter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return mixNodes;
|
|
}
|
|
|
|
public async getAllNyxdGateways(): Promise<GatewayBond[]> {
|
|
const pagedResponse: PagedGatewayResponse = await this.client.getGatewaysPaged(this.mixnetContract);
|
|
return pagedResponse.nodes;
|
|
}
|
|
|
|
/**
|
|
* Gets list of all delegations towards particular mixnode.
|
|
*
|
|
* @param mix_id identity of the node to which the delegation was sent
|
|
*/
|
|
public async getAllNyxdSingleMixnodeDelegations(mix_id: number): Promise<Delegation[]> {
|
|
let delegations: Delegation[] = [];
|
|
const limit = 250;
|
|
let startAfter;
|
|
for (; ;) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const pagedResponse: PagedMixDelegationsResponse = await this.client.getMixNodeDelegationsPaged(
|
|
this.mixnetContract,
|
|
mix_id,
|
|
limit,
|
|
startAfter,
|
|
);
|
|
delegations = delegations.concat(pagedResponse.delegations);
|
|
startAfter = pagedResponse.start_next_after;
|
|
// if `start_next_after` is not set, we're done
|
|
if (!startAfter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return delegations;
|
|
}
|
|
|
|
public async getAllNyxdDelegatorDelegations(delegator: string): Promise<Delegation[]> {
|
|
let delegations: Delegation[] = [];
|
|
const limit = 250;
|
|
let startAfter;
|
|
for (; ;) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const pagedResponse: PagedDelegatorDelegationsResponse = await this.client.getDelegatorDelegationsPaged(
|
|
this.mixnetContract,
|
|
delegator,
|
|
limit,
|
|
startAfter,
|
|
);
|
|
delegations = delegations.concat(pagedResponse.delegations);
|
|
startAfter = pagedResponse.start_next_after;
|
|
// if `start_next_after` is not set, we're done
|
|
if (!startAfter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return delegations;
|
|
}
|
|
|
|
public async getAllNyxdDelegations(): Promise<Delegation[]> {
|
|
let delegations: Delegation[] = [];
|
|
const limit = 250;
|
|
let startAfter;
|
|
for (; ;) {
|
|
// eslint-disable-next-line no-await-in-loop
|
|
const pagedResponse: PagedAllDelegationsResponse = await this.client.getAllDelegationsPaged(
|
|
this.mixnetContract,
|
|
limit,
|
|
startAfter,
|
|
);
|
|
delegations = delegations.concat(pagedResponse.delegations);
|
|
startAfter = pagedResponse.start_next_after;
|
|
// if `start_next_after` is not set, we're done
|
|
if (!startAfter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return delegations;
|
|
}
|
|
|
|
public async getDelegationDetails(mix_id: number, delegator: string): Promise<Delegation> {
|
|
return this.client.getDelegationDetails(this.mixnetContract, mix_id, delegator);
|
|
}
|
|
|
|
/**
|
|
* Generate a minimum gateway bond required to create a fresh mixnode.
|
|
*
|
|
* @returns a `Coin` instance containing minimum amount of coins to pledge a gateway.
|
|
*/
|
|
public async minimumMixnodePledge(): Promise<Coin> {
|
|
const stateParams = await this.getMixnetContractSettings();
|
|
// we trust the contract to return a valid number
|
|
return cosmosCoin(stateParams.params.minimum_mixnode_pledge, this.prefix);
|
|
}
|
|
|
|
/**
|
|
* Generate a minimum gateway bond required to create a fresh gateway.
|
|
*
|
|
* @returns a `Coin` instance containing minimum amount of coins to pledge a gateway.
|
|
*/
|
|
public async minimumGatewayPledge(): Promise<Coin> {
|
|
const stateParams = await this.getMixnetContractSettings();
|
|
// we trust the contract to return a valid number
|
|
return cosmosCoin(stateParams.params.minimum_gateway_pledge, this.prefix);
|
|
}
|
|
|
|
public async send(
|
|
recipientAddress: string,
|
|
coins: readonly Coin[],
|
|
fee: StdFee | 'auto' | number = 'auto',
|
|
memo?: string,
|
|
): Promise<DeliverTxResponse> {
|
|
this.assertSigning();
|
|
|
|
const result = await (this.client as ISigningClient).sendTokens(this.address, recipientAddress, coins, fee, memo);
|
|
if (isDeliverTxFailure(result)) {
|
|
throw new Error(
|
|
`Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`,
|
|
);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public async executeCustom(
|
|
signerAddress: string,
|
|
messages: readonly EncodeObject[],
|
|
fee: StdFee | 'auto' | number = 'auto',
|
|
memo?: string,
|
|
): Promise<DeliverTxResponse> {
|
|
this.assertSigning();
|
|
|
|
const result = await (this.client as ISigningClient).signAndBroadcast(signerAddress, messages, fee, memo);
|
|
if (isDeliverTxFailure(result)) {
|
|
throw new Error(
|
|
`Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`,
|
|
);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public async upload(
|
|
senderAddress: string,
|
|
wasmCode: Uint8Array,
|
|
fee: StdFee | 'auto' | number = 'auto',
|
|
memo?: string,
|
|
): Promise<UploadResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).upload(senderAddress, wasmCode, fee, memo);
|
|
}
|
|
|
|
public async instantiate(
|
|
senderAddress: string,
|
|
codeId: number,
|
|
initMsg: Record<string, unknown>,
|
|
label: string,
|
|
fee: StdFee | 'auto' | number = 'auto',
|
|
options?: InstantiateOptions,
|
|
): Promise<InstantiateResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).instantiate(senderAddress, codeId, initMsg, label, fee, options);
|
|
}
|
|
|
|
public async migrate(
|
|
senderAddress: string,
|
|
contractAddress: string,
|
|
codeId: number,
|
|
migrateMsg: Record<string, unknown>,
|
|
fee: StdFee | 'auto' | number = 'auto',
|
|
memo?: string,
|
|
): Promise<MigrateResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).migrate(senderAddress, contractAddress, codeId, migrateMsg, fee, memo);
|
|
}
|
|
|
|
public async bondMixNode(
|
|
mixNode: MixNode,
|
|
ownerSignature: string,
|
|
costParams: MixNodeCostParams,
|
|
pledge: Coin,
|
|
fee?: StdFee | 'auto' | number,
|
|
memo?: string,
|
|
): Promise<ExecuteResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).bondMixNode(
|
|
this.mixnetContract,
|
|
mixNode,
|
|
costParams,
|
|
ownerSignature,
|
|
pledge,
|
|
fee,
|
|
memo,
|
|
);
|
|
}
|
|
|
|
public async unbondMixNode(fee?: StdFee | 'auto' | number, memo?: string): Promise<ExecuteResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).unbondMixNode(this.mixnetContract, fee, memo);
|
|
}
|
|
|
|
public async bondGateway(
|
|
gateway: Gateway,
|
|
ownerSignature: string,
|
|
pledge: Coin,
|
|
fee?: StdFee | 'auto' | number,
|
|
memo?: string,
|
|
): Promise<ExecuteResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).bondGateway(this.mixnetContract, gateway, ownerSignature, pledge, fee, memo);
|
|
}
|
|
|
|
public async unbondGateway(fee?: StdFee | 'auto' | number, memo?: string): Promise<ExecuteResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).unbondGateway(this.mixnetContract, fee, memo);
|
|
}
|
|
|
|
public async delegateToMixNode(
|
|
mixId: number,
|
|
amount: Coin,
|
|
fee?: StdFee | 'auto' | number,
|
|
memo?: string,
|
|
): Promise<ExecuteResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).delegateToMixNode(this.mixnetContract, mixId, amount, fee, memo);
|
|
}
|
|
|
|
public async undelegateFromMixNode(
|
|
mixId: number,
|
|
fee?: StdFee | 'auto' | number,
|
|
memo?: string,
|
|
): Promise<ExecuteResult> {
|
|
return (this.client as ISigningClient).undelegateFromMixNode(this.mixnetContract, mixId, fee, memo);
|
|
}
|
|
|
|
public async updateMixnodeConfig(
|
|
mixId: number,
|
|
fee: StdFee | 'auto' | number,
|
|
profitPercentage: number,
|
|
): Promise<ExecuteResult> {
|
|
return (this.client as ISigningClient).updateMixnodeConfig(this.mixnetContract, mixId, profitPercentage, fee);
|
|
}
|
|
|
|
public async updateContractStateParams(
|
|
newParams: ContractStateParams,
|
|
fee?: StdFee | 'auto' | number,
|
|
memo?: string,
|
|
): Promise<ExecuteResult> {
|
|
this.assertSigning();
|
|
return (this.client as ISigningClient).updateContractStateParams(this.mixnetContract, newParams, fee, memo);
|
|
}
|
|
|
|
|
|
// VESTING
|
|
// TODO - MOVE TO A DIFFERENT FILE
|
|
|
|
|
|
public async getVestingAccountsPaged(): Promise<VestingAccountsPaged> {
|
|
return this.client.getVestingAccountsPaged(this.vestingContract);
|
|
}
|
|
|
|
public async getVestingAmountsAccountsPaged(): Promise<VestingAccountsCoinPaged> {
|
|
return this.client.getVestingAmountsAccountsPaged(this.vestingContract);
|
|
}
|
|
|
|
public async getLockedTokens(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getLockedTokens(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getSpendableTokens(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getSpendableTokens(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getVestedTokens(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getVestedTokens(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getVestingTokens(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getVestingTokens(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getSpendableVestedTokens(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getSpendableVestedTokens(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getSpendableRewards(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getSpendableRewards(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getDelegatedCoins(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getDelegatedCoins(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getPledgedCoins(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getPledgedCoins(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getStakedCoins(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getStakedCoins(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getWithdrawnCoins(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getWithdrawnCoins(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getStartTime(vestingAccountAddress: string): Promise<string> {
|
|
return this.client.getStartTime(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getEndTime(vestingAccountAddress: string): Promise<string> {
|
|
return this.client.getEndTime(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getOriginalVestingDetails(vestingAccountAddress: string): Promise<OriginalVestingResponse> {
|
|
return this.client.getOriginalVestingDetails(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getHistoricStakingRewards(vestingAccountAddress: string): Promise<Coin> {
|
|
return this.client.getHistoricStakingRewards(this.vestingContract, vestingAccountAddress);
|
|
}
|
|
|
|
public async getAccountDetails(address: string): Promise<VestingAccountInfo> {
|
|
return this.client.getAccountDetails(this.vestingContract, address);
|
|
}
|
|
|
|
public async getMixnode(address: string): Promise<VestingAccountNode> {
|
|
return this.client.getMixnode(this.vestingContract, address);
|
|
}
|
|
|
|
public async getGateway(address: string): Promise<VestingAccountNode> {
|
|
return this.client.getGateway(this.vestingContract, address);
|
|
}
|
|
|
|
public async getDelegationTimes(mix_id: number, delegatorAddress: string): Promise<DelegationTimes> {
|
|
return this.client.getDelegationTimes(this.vestingContract, mix_id, delegatorAddress);
|
|
}
|
|
|
|
public async getAllDelegations(): Promise<Delegations> {
|
|
return this.client.getAllDelegations(this.vestingContract);
|
|
}
|
|
|
|
public async getDelegation(address: string, mix_id: number): Promise<DelegationBlock> {
|
|
return this.client.getDelegation(this.vestingContract, address, mix_id );
|
|
}
|
|
|
|
public async getTotalDelegationAmount(address: string, mix_id: number, block_timestamp_sec: number): Promise<Coin> {
|
|
return this.client.getTotalDelegationAmount(this.vestingContract, address, mix_id, block_timestamp_sec);
|
|
}
|
|
|
|
public async getCurrentVestingPeriod(address: string): Promise<Period> {
|
|
return this.client.getCurrentVestingPeriod(this.vestingContract, address);
|
|
}
|
|
}
|