import { useState, useEffect, useMemo, useRef } from "react"; import type { PolkadotValidator, PolkadotNomination, PolkadotSearchFilter, PolkadotAccount, } from "@ledgerhq/coin-polkadot"; import { getCurrentPolkadotPreloadData, getPolkadotPreloadDataUpdates, } from "@ledgerhq/coin-polkadot/bridge/state"; import useMemoOnce from "../../hooks/useMemoOnce"; import { useBridgeSync } from "../../bridge/react"; const SYNC_REFRESH_RATE = 6000; // 6s - block time export function usePolkadotPreloadData() { const [state, setState] = useState(getCurrentPolkadotPreloadData); useEffect(() => { const sub = getPolkadotPreloadDataUpdates().subscribe(data => { setState(data); }); return () => sub.unsubscribe(); }, []); return state; } export const searchFilter: PolkadotSearchFilter = query => validator => { const terms = `${validator?.identity ?? ""} ${validator?.address ?? ""}`; return terms.toLowerCase().includes(query.toLowerCase().trim()); }; /** Hook to search and sort SR list according to initial votes and query */ export function useSortedValidators( search: string, validators: PolkadotValidator[], nominations: PolkadotNomination[], validatorSearchFilter: PolkadotSearchFilter = searchFilter, ): PolkadotValidator[] { const initialVotes = useMemoOnce(() => nominations.map(({ address }) => address)); const sortedVotes = useMemo( () => validators .filter(validator => initialVotes.includes(validator.address)) .concat(validators.filter(validator => !initialVotes.includes(validator.address))), [validators, initialVotes], ); const sr = useMemo( () => (search ? validators.filter(validatorSearchFilter(search)) : sortedVotes), [search, validators, sortedVotes, validatorSearchFilter], ); return sr; } /** * Sync account until "controller" is set - following a first bond. * * @param {*} account */ export function usePolkadotBondLoading(account: PolkadotAccount) { const controller = account.polkadotResources?.controller || null; const initialAccount = useRef(account); const [isLoading, setLoading] = useState(!controller); useEffect(() => { if (controller) { setLoading(false); } }, [controller]); const sync = useBridgeSync(); useEffect(() => { if (!isLoading) return; const interval = setInterval(() => { sync({ type: "SYNC_ONE_ACCOUNT", priority: 10, accountId: initialAccount.current.id, reason: "polkadot-bond-loading", }); }, SYNC_REFRESH_RATE); return () => clearInterval(interval); }, [initialAccount, sync, isLoading]); return isLoading; }