diff --git a/src/abis/core-mx-liveliness-stake.abi.json b/src/abis/core-mx-liveliness-stake.abi.json index 01c53a8..8ad05f0 100644 --- a/src/abis/core-mx-liveliness-stake.abi.json +++ b/src/abis/core-mx-liveliness-stake.abi.json @@ -1,511 +1,587 @@ { - "buildInfo": { - "rustc": { - "version": "1.78.0", - "commitHash": "9b00956e56009bab2aa15d7bff10916599e3d6d6", - "commitDate": "2024-04-29", - "channel": "Stable", - "short": "rustc 1.78.0 (9b00956e5 2024-04-29)" - }, - "contractCrate": { - "name": "core-mx-liveliness-stake", - "version": "0.0.0" - }, - "framework": { - "name": "multiversx-sc", - "version": "0.51.1" - } - }, - "name": "CoreMxLivelinessStake", - "constructor": { - "inputs": [], - "outputs": [] - }, - "upgradeConstructor": { - "inputs": [], - "outputs": [] - }, - "endpoints": [ - { - "name": "claimRewards", - "mutability": "mutable", - "inputs": [ - { - "name": "address", - "type": "optional
", - "multi_arg": true - } - ], - "outputs": [] - }, - { - "name": "stakeRewards", - "mutability": "mutable", - "inputs": [ - { - "name": "token_identifier", - "type": "TokenIdentifier" - } - ], - "outputs": [] - }, - { - "name": "setContractStateActive", - "mutability": "mutable", - "inputs": [], - "outputs": [] - }, - { - "name": "setContractStateInactive", - "mutability": "mutable", - "inputs": [], - "outputs": [] - }, - { - "name": "setMaxApr", - "mutability": "mutable", - "inputs": [ - { - "name": "max_apr", - "type": "BigUint" - } - ], - "outputs": [] - }, - { - "name": "setRewardsTokenIdentifier", - "mutability": "mutable", - "inputs": [ - { - "name": "token_identifier", - "type": "TokenIdentifier" - } - ], - "outputs": [] - }, - { - "name": "setPerBlockRewardAmount", - "mutability": "mutable", - "inputs": [ - { - "name": "per_block_amount", - "type": "BigUint" - } - ], - "outputs": [] - }, - { - "name": "topUpRewards", - "mutability": "mutable", - "payableInTokens": ["*"], - "inputs": [], - "outputs": [] - }, - { - "name": "withdrawRewards", - "mutability": "mutable", - "inputs": [ - { - "name": "amount", - "type": "BigUint" - } - ], - "outputs": [] - }, - { - "name": "startProduceRewards", - "mutability": "mutable", - "inputs": [], - "outputs": [] - }, - { - "name": "endProduceRewards", - "mutability": "mutable", - "inputs": [], - "outputs": [] - }, - { - "name": "setBondContractAddress", - "mutability": "mutable", - "inputs": [ - { - "name": "bond_contract_address", - "type": "Address" - } - ], - "outputs": [] - }, - { - "name": "setAdministrator", - "onlyOwner": true, - "mutability": "mutable", - "inputs": [ - { - "name": "administrator", - "type": "Address" - } - ], - "outputs": [] - }, - { - "name": "getContractState", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "State" - } - ] - }, - { - "name": "rewardsState", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "State" - } - ] - }, - { - "name": "getAdministrator", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "Address" - } - ] - }, - { - "name": "bondContractAddress", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "Address" - } - ] - }, - { - "name": "generateAggregatedRewards", - "mutability": "mutable", - "inputs": [], - "outputs": [] - }, - { - "name": "rewardsReserve", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "BigUint" - } - ] - }, - { - "name": "accumulatedRewards", - "mutability": "readonly", - "inputs": [], - "outputs": [ - { - "type": "BigUint" - } - ] - }, - { - "name": "rewardsTokenIdentifier", - "mutability": "readonly", - "inputs": [], - "outputs": [ + "buildInfo": { + "rustc": { + "version": "1.78.0", + "commitHash": "9b00956e56009bab2aa15d7bff10916599e3d6d6", + "commitDate": "2024-04-29", + "channel": "Stable", + "short": "rustc 1.78.0 (9b00956e5 2024-04-29)" + }, + "contractCrate": { + "name": "core-mx-liveliness-stake", + "version": "0.0.0" + }, + "framework": { + "name": "multiversx-sc", + "version": "0.51.1" + } + }, + "name": "CoreMxLivelinessStake", + "constructor": { + "inputs": [], + "outputs": [] + }, + "upgradeConstructor": { + "inputs": [], + "outputs": [] + }, + "endpoints": [ + { + "name": "claimRewards", + "mutability": "mutable", + "inputs": [ + { + "name": "address", + "type": "optional
", + "multi_arg": true + } + ], + "outputs": [] + }, { - "type": "TokenIdentifier" - } - ] - }, - { - "name": "rewardsPerBlock", - "mutability": "readonly", - "inputs": [], - "outputs": [ + "name": "setAddressRewardsPerShare", + "mutability": "mutable", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [] + }, { - "type": "BigUint" - } - ] - }, - { - "name": "lastRewardBlockNonce", - "mutability": "readonly", - "inputs": [], - "outputs": [ + "name": "stakeRewards", + "mutability": "mutable", + "inputs": [ + { + "name": "token_identifier", + "type": "TokenIdentifier" + } + ], + "outputs": [] + }, { - "type": "u64" - } - ] - }, - { - "name": "rewardsPerShare", - "mutability": "readonly", - "inputs": [], - "outputs": [ + "name": "setContractStateActive", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, { - "type": "BigUint" - } - ] - }, - { - "name": "addressLastRewardPerShare", - "mutability": "readonly", - "inputs": [ + "name": "setContractStateInactive", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, { - "name": "address", - "type": "Address" - } - ], - "outputs": [ + "name": "setMaxApr", + "mutability": "mutable", + "inputs": [ + { + "name": "max_apr", + "type": "BigUint" + } + ], + "outputs": [] + }, { - "type": "BigUint" - } - ] - }, - { - "name": "maxApr", - "mutability": "readonly", - "inputs": [], - "outputs": [ + "name": "setRewardsTokenIdentifier", + "mutability": "mutable", + "inputs": [ + { + "name": "token_identifier", + "type": "TokenIdentifier" + } + ], + "outputs": [] + }, { - "type": "BigUint" - } - ] - }, - { - "name": "claimableRewards", - "mutability": "readonly", - "inputs": [ + "name": "setPerBlockRewardAmount", + "mutability": "mutable", + "inputs": [ + { + "name": "per_block_amount", + "type": "BigUint" + } + ], + "outputs": [] + }, { - "name": "caller", - "type": "Address" + "name": "topUpRewards", + "mutability": "mutable", + "payableInTokens": [ + "*" + ], + "inputs": [], + "outputs": [] }, { - "name": "opt_bypass_liveliness", - "type": "Option" - } - ], - "outputs": [ + "name": "withdrawRewards", + "mutability": "mutable", + "inputs": [ + { + "name": "amount", + "type": "BigUint" + } + ], + "outputs": [] + }, { - "type": "BigUint" - } - ] - }, - { - "name": "contractDetails", - "mutability": "readonly", - "inputs": [], - "outputs": [ + "name": "startProduceRewards", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, { - "type": "ContractDetails" - } - ] - } - ], - "events": [ - { - "identifier": "set_administrator_event", - "inputs": [ - { - "name": "administrator", - "type": "Address", - "indexed": true - } - ] - }, - { - "identifier": "contract_state_event", - "inputs": [ + "name": "endProduceRewards", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, { - "name": "state", - "type": "State", - "indexed": true - } - ] - }, - { - "identifier": "max_apr", - "inputs": [ + "name": "setBondContractAddress", + "mutability": "mutable", + "inputs": [ + { + "name": "bond_contract_address", + "type": "Address" + } + ], + "outputs": [] + }, { - "name": "max_apr", - "type": "BigUint", - "indexed": true - } - ] - }, - { - "identifier": "rewards_token_identifier", - "inputs": [ + "name": "setAdministrator", + "onlyOwner": true, + "mutability": "mutable", + "inputs": [ + { + "name": "administrator", + "type": "Address" + } + ], + "outputs": [] + }, { - "name": "token_identifier", - "type": "TokenIdentifier", - "indexed": true - } - ] - }, - { - "identifier": "per_block_reward_amount", - "inputs": [ + "name": "getContractState", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "State" + } + ] + }, { - "name": "per_block_amount", - "type": "BigUint", - "indexed": true - } - ] - }, - { - "identifier": "top_up_rewards_event", - "inputs": [ + "name": "rewardsState", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "State" + } + ] + }, { - "name": "amount", - "type": "BigUint", - "indexed": true - } - ] - }, - { - "identifier": "withdraw_rewards_event", - "inputs": [ + "name": "getAdministrator", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "Address" + } + ] + }, { - "name": "amount", - "type": "BigUint", - "indexed": true - } - ] - }, - { - "identifier": "rewards_state_event", - "inputs": [ + "name": "bondContractAddress", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "Address" + } + ] + }, { - "name": "state", - "type": "State", - "indexed": true - } - ] - }, - { - "identifier": "bond_contract_address", - "inputs": [ + "name": "generateAggregatedRewards", + "mutability": "mutable", + "inputs": [], + "outputs": [] + }, { - "name": "bond_contract_address", - "type": "Address", - "indexed": true - } - ] - }, - { - "identifier": "claim_rewards", - "inputs": [ + "name": "rewardsReserve", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] + }, { - "name": "caller", - "type": "Address", - "indexed": true + "name": "accumulatedRewards", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] }, { - "name": "rewards_amount", - "type": "BigUint", - "indexed": true + "name": "rewardsTokenIdentifier", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "TokenIdentifier" + } + ] }, { - "name": "timestamp", - "type": "u64", - "indexed": true + "name": "rewardsPerBlock", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] }, { - "name": "block_nonce", - "type": "u64", - "indexed": true + "name": "lastRewardBlockNonce", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "u64" + } + ] }, { - "name": "rewards_reserve", - "type": "BigUint", - "indexed": true + "name": "rewardsPerShare", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] }, { - "name": "accumulated_rewards", - "type": "BigUint", - "indexed": true + "name": "addressLastRewardPerShare", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + } + ], + "outputs": [ + { + "type": "BigUint" + } + ] }, { - "name": "current_rewards_per_share", - "type": "BigUint", - "indexed": true + "name": "maxApr", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "BigUint" + } + ] }, { - "name": "user_last_rewards_per_share", - "type": "BigUint", - "indexed": true + "name": "claimableRewards", + "mutability": "readonly", + "inputs": [ + { + "name": "caller", + "type": "Address" + }, + { + "name": "opt_bypass_liveliness", + "type": "Option" + } + ], + "outputs": [ + { + "type": "BigUint" + } + ] }, { - "name": "rewards_per_block", - "type": "BigUint", - "indexed": true - } - ] - } - ], - "esdtAttributes": [], - "hasCallback": false, - "types": { - "ContractDetails": { - "type": "struct", - "fields": [ + "name": "contractDetails", + "mutability": "readonly", + "inputs": [], + "outputs": [ + { + "type": "ContractDetails" + } + ] + }, { - "name": "rewards_reserve", - "type": "BigUint" + "name": "userDataOut", + "mutability": "readonly", + "inputs": [ + { + "name": "address", + "type": "Address" + }, + { + "name": "token_identifier", + "type": "TokenIdentifier" + } + ], + "outputs": [ + { + "type": "tuple" + } + ] + } + ], + "events": [ + { + "identifier": "set_administrator_event", + "inputs": [ + { + "name": "administrator", + "type": "Address", + "indexed": true + } + ] }, { - "name": "accumulated_rewards", - "type": "BigUint" + "identifier": "contract_state_event", + "inputs": [ + { + "name": "state", + "type": "State", + "indexed": true + } + ] }, { - "name": "rewards_token_identifier", - "type": "TokenIdentifier" + "identifier": "max_apr", + "inputs": [ + { + "name": "max_apr", + "type": "BigUint", + "indexed": true + } + ] }, { - "name": "rewards_per_block", - "type": "BigUint" + "identifier": "rewards_token_identifier", + "inputs": [ + { + "name": "token_identifier", + "type": "TokenIdentifier", + "indexed": true + } + ] }, { - "name": "rewards_per_share", - "type": "BigUint" + "identifier": "per_block_reward_amount", + "inputs": [ + { + "name": "per_block_amount", + "type": "BigUint", + "indexed": true + } + ] }, { - "name": "administrator", - "type": "Address" + "identifier": "top_up_rewards_event", + "inputs": [ + { + "name": "amount", + "type": "BigUint", + "indexed": true + } + ] }, { - "name": "bond_contract_address", - "type": "Address" + "identifier": "withdraw_rewards_event", + "inputs": [ + { + "name": "amount", + "type": "BigUint", + "indexed": true + } + ] }, { - "name": "last_reward_block_nonce", - "type": "u64" + "identifier": "rewards_state_event", + "inputs": [ + { + "name": "state", + "type": "State", + "indexed": true + } + ] }, { - "name": "max_apr", - "type": "BigUint" - } - ] - }, - "State": { - "type": "enum", - "variants": [ + "identifier": "bond_contract_address", + "inputs": [ + { + "name": "bond_contract_address", + "type": "Address", + "indexed": true + } + ] + }, { - "name": "Inactive", - "discriminant": 0 + "identifier": "claim_rewards", + "inputs": [ + { + "name": "caller", + "type": "Address", + "indexed": true + }, + { + "name": "rewards_amount", + "type": "BigUint", + "indexed": true + }, + { + "name": "timestamp", + "type": "u64", + "indexed": true + }, + { + "name": "block_nonce", + "type": "u64", + "indexed": true + }, + { + "name": "rewards_reserve", + "type": "BigUint", + "indexed": true + }, + { + "name": "accumulated_rewards", + "type": "BigUint", + "indexed": true + }, + { + "name": "current_rewards_per_share", + "type": "BigUint", + "indexed": true + }, + { + "name": "user_last_rewards_per_share", + "type": "BigUint", + "indexed": true + }, + { + "name": "rewards_per_block", + "type": "BigUint", + "indexed": true + } + ] }, { - "name": "Active", - "discriminant": 1 + "identifier": "address_rewards_per_share_event", + "inputs": [ + { + "name": "address", + "type": "Address", + "indexed": true + }, + { + "name": "rewards_per_share", + "type": "BigUint", + "indexed": true + } + ] + } + ], + "esdtAttributes": [], + "hasCallback": false, + "types": { + "ContractDetails": { + "type": "struct", + "fields": [ + { + "name": "rewards_reserve", + "type": "BigUint" + }, + { + "name": "accumulated_rewards", + "type": "BigUint" + }, + { + "name": "rewards_token_identifier", + "type": "TokenIdentifier" + }, + { + "name": "rewards_per_block", + "type": "BigUint" + }, + { + "name": "rewards_per_share", + "type": "BigUint" + }, + { + "name": "administrator", + "type": "Address" + }, + { + "name": "bond_contract_address", + "type": "Address" + }, + { + "name": "last_reward_block_nonce", + "type": "u64" + }, + { + "name": "max_apr", + "type": "BigUint" + } + ] + }, + "State": { + "type": "enum", + "variants": [ + { + "name": "Inactive", + "discriminant": 0 + }, + { + "name": "Active", + "discriminant": 1 + } + ] + }, + "UserData": { + "type": "struct", + "fields": [ + { + "name": "total_staked_amount", + "type": "BigUint" + }, + { + "name": "user_staked_amount", + "type": "BigUint" + }, + { + "name": "liveliness_score", + "type": "BigUint" + }, + { + "name": "accumulated_rewards", + "type": "BigUint" + }, + { + "name": "accumulated_rewards_bypass", + "type": "BigUint" + }, + { + "name": "vault_nonce", + "type": "u64" + } + ] } - ] } - } } diff --git a/src/common/utils.ts b/src/common/utils.ts index 89b0471..f2cd450 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -17,7 +17,8 @@ import { NftType, Offer, Refund, - State + State, + UserData } from '../interfaces'; import { EnvironmentsEnum, dataMarshalUrlOverride } from '../config'; @@ -137,12 +138,23 @@ export function parseLivelinessStakeConfiguration( accumulatedRewards: BigNumber(value.accumulated_rewards), rewardsTokenIdentifier: value.rewards_token_identifier.toString(), lastRewardBlockNonce: value.last_reward_block_nonce.toNumber(), - maxApr: BigNumber(value.max_apr).div(10000).toNumber(), + maxApr: BigNumber(value.max_apr).div(100).toNumber(), administrator: value.administrator.toString(), bondContractAddress: value.bond_contract_address.toString() }; } +export function parseUserData(value: any): UserData { + return { + totalStakedAmount: BigNumber(value.total_staked_amount), + userStakedAmount: BigNumber(value.user_staked_amount), + livelinessScore: BigNumber(value.liveliness_score).div(100).toNumber(), + accumulatedRewards: BigNumber(value.accumulated_rewards), + accumulatedRewardsBypass: BigNumber(value.accumulated_rewards_bypass), + vaultNonce: value.vault_nonce.toNumber() + }; +} + export function parseCompensation(value: any): Compensation { return { compensationId: value.compensation_id.toNumber(), diff --git a/src/interfaces.ts b/src/interfaces.ts index 6772ad9..7d41348 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -225,3 +225,12 @@ export interface ContractConfiguration { administratorAddress: string; taxToken: string; } + +export interface UserData { + totalStakedAmount: BigNumber.Value; + userStakedAmount: BigNumber.Value; + livelinessScore: number; + accumulatedRewards: BigNumber.Value; + accumulatedRewardsBypass: BigNumber.Value; + vaultNonce: number; +} diff --git a/src/liveliness-stake.ts b/src/liveliness-stake.ts index 980bbdd..395c464 100644 --- a/src/liveliness-stake.ts +++ b/src/liveliness-stake.ts @@ -18,9 +18,17 @@ import { } from './config'; import { Contract } from './contract'; import livelinessStakeAbi from './abis/core-mx-liveliness-stake.abi.json'; -import { LivelinessStakeConfiguration, State } from './interfaces'; +import { + ContractConfiguration, + LivelinessStakeConfiguration, + State, + UserData +} from './interfaces'; import { ErrContractQuery } from './errors'; -import { parseLivelinessStakeConfiguration } from './common/utils'; +import { + parseLivelinessStakeConfiguration, + parseUserData +} from './common/utils'; import BigNumber from 'bignumber.js'; import { Token } from 'nft.storage'; @@ -87,6 +95,41 @@ export class LivelinessStake extends Contract { } } + /** + * Returns the `user data out` for a given address + * @param address address to check user data out + * @param tokenIdentifier the token identifier of the Data Nft [default is the Data Nft token identifier based on {@link EnvironmentsEnum}] + */ + async getUserDataOut( + address: IAddress, + tokenIdentifier = dataNftTokenIdentifier[this.env as EnvironmentsEnum] + ): Promise<{ + contractDetails: LivelinessStakeConfiguration; + userData: UserData; + }> { + const interaction = this.contract.methodsExplicit.userDataOut([ + new AddressValue(address), + new TokenIdentifierValue(tokenIdentifier) + ]); + const query = interaction.buildQuery(); + const queryResponse = await this.networkProvider.queryContract(query); + const endpointDefinition = interaction.getEndpoint(); + const { firstValue, returnCode } = new ResultsParser().parseQueryResponse( + queryResponse, + endpointDefinition + ); + if (returnCode.isSuccess()) { + const returnValue = firstValue?.valueOf(); + const livelinessConfiguration = parseLivelinessStakeConfiguration( + returnValue.field0.valueOf() + ); + const userData = parseUserData(returnValue.field1.valueOf()); + return { contractDetails: livelinessConfiguration, userData }; + } else { + throw new ErrContractQuery('getUserDataOut', returnCode.toString()); + } + } + /** * Returns rewards state as a `State` enum */