From 4aa3e97945dd084a41bbdab197dc5a3a7b10fd02 Mon Sep 17 00:00:00 2001 From: Luis Perrone Date: Wed, 1 Jan 2025 23:03:38 -0500 Subject: [PATCH] Add claim modal and fix bugs --- .../HotspotService/pages/ClaimTokensPage.tsx | 49 +++---- .../HotspotService/pages/ExplorerPage.tsx | 16 ++- src/app/services/ServiceSheet.tsx | 16 ++- src/assets/svgs/bluetoothOnboard.svg | 11 ++ src/assets/svgs/hntIconNew.svg | 4 + src/components/BalanceText.tsx | 25 ++-- src/components/SegmentedControl.tsx | 5 +- src/components/ServiceNavBar.tsx | 5 +- src/components/SideDrawer.tsx | 5 +- src/config/locales/en.ts | 3 + src/config/storage/AppStorageProvider.tsx | 4 +- .../screens/iot/ConnectViaBluetoothScreen.tsx | 4 +- .../screens/iot/WifiSettings.tsx | 16 ++- src/features/hotspots/HotspotDetails.tsx | 3 +- src/features/hotspots/HotspotPage.tsx | 2 +- src/features/wallet/TokensScreen.tsx | 4 + .../components/UnclaimedRewardsBanner.tsx | 128 ++++++++++++++++++ src/hooks/useSwipe.ts | 19 ++- src/utils/solanaUtils.ts | 58 +++++--- 19 files changed, 293 insertions(+), 84 deletions(-) create mode 100644 src/assets/svgs/bluetoothOnboard.svg create mode 100644 src/assets/svgs/hntIconNew.svg create mode 100644 src/features/wallet/components/UnclaimedRewardsBanner.tsx diff --git a/src/app/services/HotspotService/pages/ClaimTokensPage.tsx b/src/app/services/HotspotService/pages/ClaimTokensPage.tsx index 15a280b37..65812c324 100644 --- a/src/app/services/HotspotService/pages/ClaimTokensPage.tsx +++ b/src/app/services/HotspotService/pages/ClaimTokensPage.tsx @@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next' import { Image, RefreshControl } from 'react-native' import MobileIcon from '@assets/svgs/mobileIconNew.svg' import IotIcon from '@assets/svgs/iotIconNew.svg' -import HntIcon from '@assets/svgs/hnt.svg' +import HntIcon from '@assets/svgs/hntIconNew.svg' import TouchableContainer from '@components/TouchableContainer' import BalanceText from '@components/BalanceText' import useHotspots from '@hooks/useHotspots' @@ -30,6 +30,7 @@ import { ReAnimatedBox } from '@components/AnimatedBox' import { FadeIn, FadeOut } from 'react-native-reanimated' import { RootState } from '@store/rootReducer' import { useSelector } from 'react-redux' +import { useBottomSpacing } from '@hooks/useBottomSpacing' const ClaimTokensPage = () => { const { t } = useTranslation() @@ -39,6 +40,7 @@ const ClaimTokensPage = () => { const { showModal } = useModal() const solBalance = useBN(useSolOwnedAmount(wallet).amount) const colors = useColors() + const bottomSpacing = useBottomSpacing() const hasEnoughSol = useMemo(() => { return (solBalance || new BN(0)).gt(new BN(MIN_BALANCE_THRESHOLD)) @@ -57,8 +59,9 @@ const ClaimTokensPage = () => { const contentContainerStyle = useMemo(() => { return { padding: spacing['2xl'], + paddingBottom: bottomSpacing, } - }, [spacing]) + }, [spacing, bottomSpacing]) const totalPendingIot = useMemo(() => { if (!pendingIotRewards) return 0 @@ -67,7 +70,7 @@ const ClaimTokensPage = () => { const totalPendingHnt = useMemo(() => { if (!pendingHntRewards) return 0 - return toNumber(pendingHntRewards, 6) + return toNumber(pendingHntRewards, 8) }, [pendingHntRewards]) const totalPendingMobile = useMemo(() => { @@ -164,12 +167,31 @@ const ClaimTokensPage = () => { {t('ClaimTokensPage.subtitle')} + + + + + + + HNT + + + + {totalPendingMobile > 0 && ( { )} - - - - - - - HNT - - - - { - const { hotspotsWithMeta } = useHotspots() + const { hotspotsWithMeta, loading } = useHotspots() const spacing = useSpacing() const [userLocation, setUserLocation] = useState() const [showTotalHotspotPuck, setShowTotalHotspotPuck] = useState(false) @@ -67,12 +68,21 @@ const ExplorerPage = () => { ) }, [showTotalHotspotPuck, hotspotsWithMeta, spacing]) + if (loading) { + return ( + + + + ) + } + return ( { if (mobileInfoAcc) { return parseH3BNLocation(mobileInfoAcc.info.location).reverse() } - }, [hotspot]) + }, [iotInfoAcc?.info?.location, mobileInfoAcc?.info?.location]) if (!result) return null diff --git a/src/app/services/ServiceSheet.tsx b/src/app/services/ServiceSheet.tsx index b78cdc698..0c77935e1 100644 --- a/src/app/services/ServiceSheet.tsx +++ b/src/app/services/ServiceSheet.tsx @@ -40,6 +40,7 @@ import { RootState } from '@store/rootReducer' import StickersPage from '@features/stickers/StickersPage' import { StickerProvider } from '@features/stickers/StickerContext' import { useSwipe } from '@hooks/useSwipe' +import useHaptic from '@hooks/useHaptic' import { ServiceSheetNavigationProp } from './serviceSheetTypes' type ServiceSheetProps = { @@ -62,6 +63,7 @@ const ServiceSheet = ({ const spacing = useSpacing() const bottomSheetStyle = useBackgroundStyle('primaryText') const borderRadii = useBorderRadii() + const { triggerImpact } = useHaptic() const { rootSheetPosition } = useSelector((state: RootState) => state.app) @@ -69,7 +71,7 @@ const ServiceSheet = ({ setIsExpanded(true) }, []) - const { onTouchStart, onTouchEnd } = useSwipe(undefined, onSwipeRight, 6) + const { onTouchStart, onTouchEnd } = useSwipe(undefined, onSwipeRight, 2.5) const onRoute = useCallback( (value: string) => { @@ -108,13 +110,14 @@ const ServiceSheet = ({ ) const onDrawerPress = useCallback(() => { + triggerImpact('light') setIsExpanded((s) => !s) changeNavigationBarColor( isExpanded ? colors.primaryText : colors.primaryBackground, undefined, true, ) - }, [colors, isExpanded]) + }, [colors, isExpanded, triggerImpact]) const onWalletIconPress = useCallback(() => { if (currentService === 'wallets' && bottomSheetOpen) { @@ -123,9 +126,16 @@ const ServiceSheet = ({ return } + triggerImpact('light') serviceNav.replace('AccountsService') bottomSheetRef.current?.expand() - }, [currentService, serviceNav, bottomSheetRef, bottomSheetOpen]) + }, [ + currentService, + serviceNav, + bottomSheetRef, + bottomSheetOpen, + triggerImpact, + ]) const onCloseSheet = useCallback(() => { // if (currentService === '') return diff --git a/src/assets/svgs/bluetoothOnboard.svg b/src/assets/svgs/bluetoothOnboard.svg new file mode 100644 index 000000000..8df0cf50b --- /dev/null +++ b/src/assets/svgs/bluetoothOnboard.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/svgs/hntIconNew.svg b/src/assets/svgs/hntIconNew.svg new file mode 100644 index 000000000..3ef57e6bb --- /dev/null +++ b/src/assets/svgs/hntIconNew.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/BalanceText.tsx b/src/components/BalanceText.tsx index 018ad72c0..905d5bb59 100644 --- a/src/components/BalanceText.tsx +++ b/src/components/BalanceText.tsx @@ -12,22 +12,17 @@ const BalanceText = ({ }) => { const integral = useMemo(() => Math.floor(amount || 0), [amount]) - const firstFractional = useMemo(() => { + const fractional = useMemo(() => { if (amount === undefined) return 0 const decimal = amount - integral - const fraction = decimal.toString().split('.')[1] - // Fraction with max length of decimals - const fractionWithMaxDecimals = fraction?.slice(0, 1) - return fraction ? Number(fractionWithMaxDecimals) : 0 - }, [amount, integral]) - - const secondFractional = useMemo(() => { - if (amount === undefined) return 0 - const decimal = amount - integral - const fraction = decimal.toString().split('.')[1] - // Fraction with max length of decimals - const fractionWithMaxDecimals = fraction?.slice(1, 2) - return fraction ? Number(fractionWithMaxDecimals) : 0 + const decimalFixed = decimal.toFixed(9) + const fraction = decimalFixed.toString().split('.')[1] + const decimalWithoutTrailingZeroes = decimalFixed.replace(/0+$/, '') + const decimalsLength = decimalWithoutTrailingZeroes + .toString() + .split('.')[1].length + const fractionWithMaxDecimals = fraction?.slice(1, decimalsLength) + return fraction ? fractionWithMaxDecimals : 0 }, [amount, integral]) return ( @@ -37,7 +32,7 @@ const BalanceText = ({ {`${integral.toLocaleString()}`} - {`.${firstFractional}${secondFractional}`} + {`.${fractional}`} diff --git a/src/components/SegmentedControl.tsx b/src/components/SegmentedControl.tsx index 4fdd8bb04..c3cb7b3f0 100644 --- a/src/components/SegmentedControl.tsx +++ b/src/components/SegmentedControl.tsx @@ -13,6 +13,7 @@ import { GestureResponderEvent, LayoutChangeEvent } from 'react-native' import { SvgProps } from 'react-native-svg' import { useColors } from '@config/theme/themeHooks' import { useAnimatedStyle, withTiming } from 'react-native-reanimated' +import useHaptic from '@hooks/useHaptic' import { Theme } from '../config/theme/theme' import { Box, ReAnimatedBox, Text } from '.' import TouchableOpacityBox from './TouchableOpacityBox' @@ -119,6 +120,7 @@ const SegmentedControl = forwardRef( ) => { const [selectedIndex, setSelectedIndex] = useState(0) const [hasTouched, setHasTouched] = useState(false) + const { triggerImpact } = useHaptic() useImperativeHandle(ref, () => ({ selectedIndex })) @@ -133,11 +135,12 @@ const SegmentedControl = forwardRef( const handleItemSelected = useCallback( (index: number) => () => { + triggerImpact('light') setHasTouched(true) setSelectedIndex(index) onItemSelected(index) }, - [onItemSelected], + [onItemSelected, triggerImpact], ) const leftPosition = useMemo(() => { diff --git a/src/components/ServiceNavBar.tsx b/src/components/ServiceNavBar.tsx index 57d050411..f73caae8c 100644 --- a/src/components/ServiceNavBar.tsx +++ b/src/components/ServiceNavBar.tsx @@ -14,6 +14,7 @@ import Animated, { } from 'react-native-reanimated' import { SvgProps } from 'react-native-svg' import { useColors, useVerticalHitSlop } from '@config/theme/themeHooks' +import useHaptic from '@hooks/useHaptic' import Box from './Box' import TouchableOpacityBox, { TouchableOpacityBoxProps, @@ -118,6 +119,7 @@ const NavServiceNavBar = ({ }: NavServiceBarProps) => { const hitSlop = useVerticalHitSlop('6') const [itemRects, setItemRects] = useState>() + const { triggerImpact } = useHaptic() const offset = useSharedValue(null) @@ -132,9 +134,10 @@ const NavServiceNavBar = ({ const handlePress = useCallback( (value: string) => () => { + triggerImpact('light') onItemSelected(value) }, - [onItemSelected], + [onItemSelected, triggerImpact], ) const handleLongPress = useCallback( diff --git a/src/components/SideDrawer.tsx b/src/components/SideDrawer.tsx index 7001b817c..e92e14304 100644 --- a/src/components/SideDrawer.tsx +++ b/src/components/SideDrawer.tsx @@ -6,6 +6,7 @@ import { withTiming, } from 'react-native-reanimated' import { ww } from '@utils/layout' +import useHaptic from '@hooks/useHaptic' import TouchableOpacityBox from './TouchableOpacityBox' import { Box, ReAnimatedBox, SafeAreaBox, Text } from '.' import MenuButton from './MenuButton' @@ -18,6 +19,7 @@ type SideDrawerProps = { const SideDrawer = ({ isExpanded, onRoute, onClose }: SideDrawerProps) => { const { t } = useTranslation() + const { triggerImpact } = useHaptic() const routes: { title: string; value: string }[] = useMemo( () => @@ -42,9 +44,10 @@ const SideDrawer = ({ isExpanded, onRoute, onClose }: SideDrawerProps) => { const onRoutePressed = useCallback( (route: string) => () => { + triggerImpact('light') onRoute(route) }, - [onRoute], + [onRoute, triggerImpact], ) return ( diff --git a/src/config/locales/en.ts b/src/config/locales/en.ts index a3f330f32..635ae0f13 100644 --- a/src/config/locales/en.ts +++ b/src/config/locales/en.ts @@ -1753,4 +1753,7 @@ export default { subtitle: 'There was an error with the app attempting to deep link. Please contact the app provider.', }, + UnclaimedRewardsBanner: { + title: 'You have rewards to claim.', + }, } diff --git a/src/config/storage/AppStorageProvider.tsx b/src/config/storage/AppStorageProvider.tsx index 01eec2160..fb9933554 100644 --- a/src/config/storage/AppStorageProvider.tsx +++ b/src/config/storage/AppStorageProvider.tsx @@ -33,9 +33,7 @@ const useAppStorageHook = () => { ) const [currency, setCurrency] = useState('USD') const [explorer, setExplorer] = useState(undefined) - const [enableHaptic, setEnableHaptic] = useState( - undefined, - ) + const [enableHaptic, setEnableHaptic] = useState(true) const [locked, setLocked] = useState() const [convertToCurrency, setConvertToCurrency] = useState(false) const [enableTestnet, setEnableTestnet] = useState(false) diff --git a/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx b/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx index 93d57a848..74400ea87 100644 --- a/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx +++ b/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx @@ -6,7 +6,7 @@ import { useHotspotOnboarding } from '@features/hotspot-onboarding/OnboardingShe import React, { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import RightArrow from '@assets/svgs/rightArrow.svg' -import BluetoothIcon from '@assets/svgs/bluetooth.svg' +import BluetoothIcon from '@assets/svgs/bluetoothOnboard.svg' import { useColors, useSpacing } from '@config/theme/themeHooks' import { FadeIn, FadeOut } from 'react-native-reanimated' import { ReAnimatedBox } from '@components/AnimatedBox' @@ -38,7 +38,7 @@ const ConnectViaBluetoothScreen = () => { } > - + { setNetworks(available) }) + useFocusEffect( + useCallback(() => { + handleRefresh() + }, [handleRefresh]), + ) + // Refresh on network change or on load useEffect(() => { handleRefresh() @@ -97,10 +104,11 @@ const WifiSettings = () => { [carouselRef, setOnboardDetails, getOnboardingAddress], ) - const data = useMemo( - () => [...(configuredNetworks || []), ...(networks || [])], - [configuredNetworks, networks], - ) + const data = useMemo(() => { + const nks = [...(configuredNetworks || []), ...(networks || [])] + // remove duplicates + return nks.filter((network, index, self) => self.indexOf(network) === index) + }, [configuredNetworks, networks]) const renderItem = useCallback( ({ diff --git a/src/features/hotspots/HotspotDetails.tsx b/src/features/hotspots/HotspotDetails.tsx index b8585175e..530b9e700 100644 --- a/src/features/hotspots/HotspotDetails.tsx +++ b/src/features/hotspots/HotspotDetails.tsx @@ -68,6 +68,7 @@ const HotspotDetails = () => { }, [hotspot]) const { result: hotspotAddress } = useAsync(async () => { + if (!iotInfoAcc && !mobileInfoAcc) return undefined let address: | { city: string | undefined @@ -91,7 +92,7 @@ const HotspotDetails = () => { if (!address) return undefined return `${address.street}, ${address.city}, ${address.state}` - }, [hotspot, subDao]) + }, [iotInfoAcc?.info.location, mobileInfoAcc?.info.location]) const onConfig = useCallback(() => { if (!hotspotAddress) return diff --git a/src/features/hotspots/HotspotPage.tsx b/src/features/hotspots/HotspotPage.tsx index bd8894a90..61ccf6f69 100644 --- a/src/features/hotspots/HotspotPage.tsx +++ b/src/features/hotspots/HotspotPage.tsx @@ -16,7 +16,7 @@ import { Location, MarkerView } from '@rnmapbox/maps' import ImageBox from '@components/ImageBox' import CarotRight from '@assets/svgs/carot-right.svg' import { getDistance } from 'geolib' -import { HNT_MINT, MOBILE_MINT, toNumber as heliumToNumber } from '@helium/spl-utils' +import { HNT_MINT, toNumber as heliumToNumber } from '@helium/spl-utils' import { BN } from '@coral-xyz/anchor' import { toNumber } from 'lodash' import MiniMap from '@components/MiniMap' diff --git a/src/features/wallet/TokensScreen.tsx b/src/features/wallet/TokensScreen.tsx index e47cabc63..676fd9511 100644 --- a/src/features/wallet/TokensScreen.tsx +++ b/src/features/wallet/TokensScreen.tsx @@ -41,6 +41,7 @@ import { ServiceSheetNavigationProp } from 'src/app/services/serviceSheetTypes' import { useSolana } from '@features/solana/SolanaProvider' import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' import { useBottomSpacing } from '@hooks/useBottomSpacing' +import UnclaimedRewardsBanner from './components/UnclaimedRewardsBanner' const TokensScreen = () => { const widgetGroup = 'group.com.helium.mobile.wallet.widget' @@ -203,6 +204,9 @@ const TokensScreen = () => { + + + ) }, []) diff --git a/src/features/wallet/components/UnclaimedRewardsBanner.tsx b/src/features/wallet/components/UnclaimedRewardsBanner.tsx new file mode 100644 index 000000000..3ca7e629a --- /dev/null +++ b/src/features/wallet/components/UnclaimedRewardsBanner.tsx @@ -0,0 +1,128 @@ +import Box from '@components/Box' +import Text from '@components/Text' +import TouchableContainer from '@components/TouchableContainer' +import React, { useCallback, useEffect, useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import HntIcon from '@assets/svgs/hntIconNew.svg' +import IotIcon from '@assets/svgs/iotIconNew.svg' +import MobileIcon from '@assets/svgs/mobileIconNew.svg' +import BalanceText from '@components/BalanceText' +import { toNumber } from '@helium/spl-utils' +import useHotspots from '@hooks/useHotspots' +import { useNavigation } from '@react-navigation/native' +import { ServiceSheetNavigationProp } from '@services/serviceSheetTypes' + +const UnclaimedRewardsBanner = () => { + const { t } = useTranslation() + const navigation = useNavigation() + const { + pendingIotRewards, + pendingHntRewards, + pendingMobileRewards, + refresh, + } = useHotspots() + + useEffect(() => { + refresh() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + const totalPendingIot = useMemo(() => { + if (!pendingIotRewards) return 0 + return toNumber(pendingIotRewards, 6) + }, [pendingIotRewards]) + + const totalPendingHnt = useMemo(() => { + if (!pendingHntRewards) return 0 + return toNumber(pendingHntRewards, 8) + }, [pendingHntRewards]) + + const totalPendingMobile = useMemo(() => { + if (!pendingMobileRewards) return 0 + return toNumber(pendingMobileRewards, 6) + }, [pendingMobileRewards]) + + const goToClaimRewards = useCallback(() => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(navigation as any).navigate('HotspotService', { + screen: 'ClaimTokens', + }) + }, [navigation]) + + if ( + totalPendingHnt === 0 && + totalPendingIot === 0 && + totalPendingMobile === 0 + ) + return null + + return ( + + {t('UnclaimedRewardsBanner.title')} + + {totalPendingHnt > 0 && ( + + )} + {totalPendingMobile > 0 && ( + + )} + {totalPendingIot > 0 && ( + + )} + + + ) +} + +const RewardPill = ({ + amount, + ticker, +}: { + amount: number + ticker: 'HNT' | 'IOT' | 'MOBILE' +}) => { + const pillBackgroundColor = useMemo(() => { + if (ticker === 'HNT') return 'purple.100' + if (ticker === 'IOT') return 'bg.success-primary' + if (ticker === 'MOBILE') return 'bg.brand-secondary' + }, [ticker]) + + const tickerColor = useMemo(() => { + if (ticker === 'HNT') return 'purple.600' + if (ticker === 'IOT') return 'green.600' + if (ticker === 'MOBILE') return 'blue.600' + }, [ticker]) + + const TokenIcon = useCallback(() => { + if (ticker === 'HNT') return + if (ticker === 'IOT') return + if (ticker === 'MOBILE') return + }, [ticker]) + + return ( + + + + + + {ticker} + + + + ) +} + +export default UnclaimedRewardsBanner diff --git a/src/hooks/useSwipe.ts b/src/hooks/useSwipe.ts index 7edfc3f7c..da092f11d 100644 --- a/src/hooks/useSwipe.ts +++ b/src/hooks/useSwipe.ts @@ -1,4 +1,5 @@ import { Dimensions, GestureResponderEvent } from 'react-native' +import useHaptic from './useHaptic' const windowWidth = Dimensions.get('window').width @@ -7,6 +8,7 @@ export function useSwipe( onSwipeRight?: ((event: GestureResponderEvent) => void) | undefined, rangeOffset = 4, ) { + const { triggerImpact } = useHaptic() let firstTouch = 0 // set user touch start position @@ -19,14 +21,21 @@ export function useSwipe( // get touch position and screen size const positionX = e.nativeEvent.pageX const range = windowWidth / rangeOffset - // check if position is growing positively and has reached specified range - if (positionX - firstTouch > range) { - if (onSwipeRight) onSwipeRight(e) + const swipeRightRange = positionX - firstTouch + if (swipeRightRange > range) { + if (onSwipeRight) { + triggerImpact('medium') + onSwipeRight(e) + } } // check if position is growing negatively and has reached specified range - else if (firstTouch - positionX > range) { - if (onSwipeLeft) onSwipeLeft(e) + const swipeLeftRange = firstTouch - positionX + if (swipeLeftRange > range) { + if (onSwipeLeft) { + triggerImpact('medium') + onSwipeLeft(e) + } } } diff --git a/src/utils/solanaUtils.ts b/src/utils/solanaUtils.ts index 2d8733bbd..9c82f12e3 100644 --- a/src/utils/solanaUtils.ts +++ b/src/utils/solanaUtils.ts @@ -127,7 +127,13 @@ import { } from '../types/solana' import { WrappedConnection } from './WrappedConnection' import { solAddressIsValid } from './accountUtils' -import { DAO_KEY, HNT_LAZY_KEY, IOT_LAZY_KEY, MOBILE_LAZY_KEY, Mints } from './constants' +import { + DAO_KEY, + HNT_LAZY_KEY, + IOT_LAZY_KEY, + MOBILE_LAZY_KEY, + Mints, +} from './constants' import { decimalSeparator, groupSeparator } from './i18n' import * as Logger from './logger' import sleep from './sleep' @@ -1050,16 +1056,20 @@ export const getHotspotPendingRewards = async ( 'b58', true, ) - const hntRewards = await getPendingRewards( - program, - HNT_LAZY_KEY, - dao, - entityKeys, - 'b58', - true, - ) + let hntRewards: Record = {} - return hotspots.map((hotspot, index) => { + try { + hntRewards = await getPendingRewards( + program, + HNT_LAZY_KEY, + dao, + entityKeys, + 'b58', + true, + ) + } catch {} + + const hots = hotspots.map((hotspot, index) => { const entityKey = entityKeys[index] return { @@ -1071,6 +1081,8 @@ export const getHotspotPendingRewards = async ( }, } }) + + return hots } export const getHotspotRecipients = async ( @@ -1323,14 +1335,18 @@ export async function annotateWithPendingRewards( true, ) - const hntRewards = await getPendingRewards( - program, - HNT_LAZY_KEY, - dao, - entityKeys, - 'b58', - true, - ) + let hntRewards: Record = {} + + try { + hntRewards = await getPendingRewards( + program, + HNT_LAZY_KEY, + dao, + entityKeys, + 'b58', + true, + ) + } catch {} const rewardRecipients = await getHotspotRecipients(provider, hotspots) const rewardRecipientsById: { @@ -1342,9 +1358,7 @@ export async function annotateWithPendingRewards( }), {}, ) - console.log('hntRewards', hntRewards) - - return hotspots.map((hotspot, index) => { + const hots = hotspots.map((hotspot, index) => { const entityKey = entityKeys[index] return { @@ -1357,6 +1371,8 @@ export async function annotateWithPendingRewards( rewardRecipients: rewardRecipientsById[hotspot.id] || {}, } as HotspotWithPendingRewards }) + + return hots } /**