import invariant from "invariant"; import { useMemo } from "react"; import { BigNumber } from "bignumber.js"; import { FIGMENT_NEAR_VALIDATOR_ADDRESS } from "@ledgerhq/coin-near/constants"; import { mapStakingPositions } from "@ledgerhq/coin-near/logic"; import { NearValidatorItem, Transaction, NearMappedStakingPosition, NearAccount, } from "@ledgerhq/coin-near/types"; import { getCurrentNearPreloadData } from "@ledgerhq/coin-near/preload"; import { getAccountCurrency } from "../../account"; export function useNearMappedStakingPositions(account: NearAccount): NearMappedStakingPosition[] { const { validators } = getCurrentNearPreloadData(); const stakingPositions = account.nearResources?.stakingPositions; invariant(stakingPositions, "near: stakingPositions is required"); const unit = getAccountCurrency(account).units[0]; return useMemo(() => { const mappedStakingPositions = mapStakingPositions(stakingPositions || [], validators, unit); return mappedStakingPositions; }, [stakingPositions, validators, unit]); } export function useNearStakingPositionsQuerySelector( account: NearAccount, transaction: Transaction, ): { options: NearMappedStakingPosition[]; value: NearMappedStakingPosition | undefined; } { const stakingPositions = useNearMappedStakingPositions(account); const options = useMemo( () => stakingPositions.filter(sp => transaction.mode === "unstake" ? sp.staked.gt(0) : sp.available.gt(0), ), [stakingPositions, transaction], ); const selectedValidatorAddress = transaction.recipient; const value = useMemo( () => stakingPositions.find(({ validatorId }) => validatorId === selectedValidatorAddress), [stakingPositions, selectedValidatorAddress], ); return { options, value, }; } export function useLedgerFirstShuffledValidatorsNear(search: string) { const { validators: unorderedValidators } = getCurrentNearPreloadData(); const validators = reorderValidators(unorderedValidators); return useMemo(() => { if (validators.length === 0 || !search || search === "") { return validators; } const lowercaseSearch = search.toLowerCase(); const filtered = validators.filter(validator => validator.validatorAddress?.toLowerCase().includes(lowercaseSearch), ); return filtered; }, [validators, search]); } function reorderValidators(validators: NearValidatorItem[]): NearValidatorItem[] { const sortedValidators = validators.sort((a, b) => new BigNumber(b.tokens).minus(new BigNumber(a.tokens)).toNumber(), ); // move Ledger validator to the first position const ledgerValidator = sortedValidators.find( v => v.validatorAddress === FIGMENT_NEAR_VALIDATOR_ADDRESS, ); if (ledgerValidator) { const sortedValidatorsLedgerFirst = sortedValidators.filter( v => v.validatorAddress !== FIGMENT_NEAR_VALIDATOR_ADDRESS, ); sortedValidatorsLedgerFirst.unshift(ledgerValidator); return sortedValidatorsLedgerFirst; } return sortedValidators; }