UNPKG

@ledgerhq/coin-celo

Version:
147 lines (119 loc) 4.93 kB
import { CeloAccount, CeloPendingWithdrawal, CeloValidatorGroup, CeloVote, CeloVoteStatus, PendingStakingOperationAmounts, } from "./types/types"; import { BigNumber } from "bignumber.js"; import { Account, Operation, TokenAccount } from "@ledgerhq/types-live"; export const PRELOAD_MAX_AGE = 10 * 60 * 1000; // 10 minutes, used for max age in preload strategy const LEDGER_BY_FIGMENT_VALIDATOR_GROUP_ADDRESS = "0x0861a61Bf679A30680510EcC238ee43B82C5e843"; export const availablePendingWithdrawals = (account: CeloAccount): CeloPendingWithdrawal[] => { const { pendingWithdrawals } = account.celoResources || {}; return (pendingWithdrawals || []).filter( withdrawal => new Date(withdrawal.time.toNumber() * 1000) < new Date(), ); }; export const withdrawableBalance = (account: CeloAccount): BigNumber => availablePendingWithdrawals(account).reduce( (sum, withdrawal) => sum.plus(withdrawal.value), new BigNumber(0), ); export const hasWithdrawableBalance = (account: CeloAccount): boolean => withdrawableBalance(account).isGreaterThan(0); export const defaultValidatorGroupAddress = (): string => LEDGER_BY_FIGMENT_VALIDATOR_GROUP_ADDRESS; export const isDefaultValidatorGroupAddress = (address: string): boolean => address === LEDGER_BY_FIGMENT_VALIDATOR_GROUP_ADDRESS; export const isDefaultValidatorGroup = (validatorGroup: CeloValidatorGroup): boolean => isDefaultValidatorGroupAddress(validatorGroup.address); export const activatableVotes = (account: CeloAccount): CeloVote[] => { const { votes } = account.celoResources || {}; return (votes || []).filter(vote => vote.activatable); }; export const hasActivatableVotes = (account: CeloAccount): boolean => activatableVotes(account).length > 0; export const revokableVotes = (account: CeloAccount): CeloVote[] => { const { votes } = account.celoResources || {}; return (votes || []).filter(vote => vote.revokable); }; export const hasRevokableVotes = (account: CeloAccount): boolean => revokableVotes(account).length > 0; export const getVote = ( account: CeloAccount, validatorGroupAddress: string, index: number | null | undefined, ): CeloVote | undefined => { const { votes } = account.celoResources || {}; return votes?.find( revoke => revoke.validatorGroup === validatorGroupAddress && revoke.index === index, ); }; export const voteStatus = (vote: CeloVote): CeloVoteStatus => vote.type === "pending" && vote.activatable ? "awaitingActivation" : vote.type; export const fallbackValidatorGroup = (address: string): CeloValidatorGroup => ({ address: address, name: address, votes: new BigNumber(0), }); export const isAccountRegistrationPending = (account: CeloAccount): boolean => { // If there's a pending "REGISTER" operation and the // account's registration status is false, then // we know that the account is truly not registered yet. const isAccountRegistrationPending = !!account && account.pendingOperations.some(currentAccount => currentAccount.type === "REGISTER") && !account.celoResources?.registrationStatus; return isAccountRegistrationPending; }; const isOperationTrulyPending = (operation: Operation, activeOperations: Operation[]): boolean => { return !activeOperations.some(activeOperation => activeOperation.hash === operation.hash); }; export const getPendingStakingOperationAmounts = ( account: CeloAccount, ): PendingStakingOperationAmounts => { const operationAmounts = account.pendingOperations.reduce( (acc, currentOperation) => { if (currentOperation.type !== "VOTE" && currentOperation.type !== "LOCK") { return acc; } if (isOperationTrulyPending(currentOperation, account.operations)) { const value = new BigNumber(currentOperation.value); switch (currentOperation.type) { case "VOTE": return { ...acc, vote: acc.vote.plus(value), }; case "LOCK": return { ...acc, lock: acc.lock.plus(value), }; } } return acc; }, { vote: new BigNumber(0), lock: new BigNumber(0), }, ); return operationAmounts; }; const getValidatorGroupsByVotingActivity = ( validatorGroups: CeloValidatorGroup[], votes: CeloVote[], withVotes: boolean, ): CeloValidatorGroup[] => { return validatorGroups.filter(v => votes.some(d => d.validatorGroup === v.address) === withVotes); }; export const getValidatorGroupsWithVotes = ( validatorGroups: CeloValidatorGroup[], votes: CeloVote[] | null, ): CeloValidatorGroup[] => getValidatorGroupsByVotingActivity(validatorGroups, votes || [], true); export const getValidatorGroupsWithoutVotes = ( validatorGroups: CeloValidatorGroup[], votes: CeloVote[] | null = [], ): CeloValidatorGroup[] => getValidatorGroupsByVotingActivity(validatorGroups, votes || [], false);