@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
98 lines (79 loc) • 3.08 kB
text/typescript
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<NearMappedStakingPosition[]>(
() =>
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;
}