Skip to content

Commit c753916

Browse files
committed
feature: basic earnings card
1 parent ab5dfb8 commit c753916

File tree

4 files changed

+112
-1
lines changed

4 files changed

+112
-1
lines changed

src/features/rnbw-membership/screens/rnbw-membership-screen/RnbwMembershipScreen.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { useStakingPositionStore } from '@/features/rnbw-staking/stores/rnbwStak
1313
import { useAirdropBalanceStore } from '@/features/rnbw-rewards/stores/airdropBalanceStore';
1414
import { delay } from '@/utils/delay';
1515
import { time } from '@/utils/time';
16+
import { RnbwStakingEarningsCard } from './components/RnbwStakingEarningsCard';
1617

1718
export const RnbwMembershipScreen = memo(function RnbwMembershipScreen() {
1819
return (
@@ -23,6 +24,7 @@ export const RnbwMembershipScreen = memo(function RnbwMembershipScreen() {
2324
<RnbwStakingCard />
2425
<RnbwUnstakePenaltyRecoveryCard />
2526
<MembershipTierCard />
27+
<RnbwStakingEarningsCard />
2628
<RnbwRewardsClaimCard />
2729
<RnbwAirdropClaimCard />
2830
</Box>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { memo } from 'react';
2+
import { Box, Separator, Text } from '@/design-system';
3+
import { useRnbwStakingEarnings } from '@/features/rnbw-staking/stores/derived/useRnbwStakingEarnings';
4+
import { RNBW_SYMBOL } from '@/features/rnbw-rewards/constants';
5+
import rnbwCoinImage from '@/assets/rnbw.png';
6+
import { Image } from 'react-native';
7+
8+
export const RnbwStakingEarningsCard = memo(function RnbwStakingEarningsCard() {
9+
const { totalEarnings, cashbackEarnings, cashbackShare, exitRewardsEarnings, exitRewardsShare } = useRnbwStakingEarnings();
10+
11+
return (
12+
<Box background="surfacePrimary" borderRadius={32} padding="24px" shadow="18px">
13+
<Box gap={16}>
14+
<Text size="17pt" weight="bold" color="labelTertiary" align="left">
15+
{'Total Earnings'}
16+
</Text>
17+
18+
<Box flexDirection="row" alignItems="center" gap={8}>
19+
<Image source={rnbwCoinImage} style={{ width: 40, height: 40 }} />
20+
<Text size="34pt" weight="bold" color="label">
21+
{totalEarnings}
22+
</Text>
23+
</Box>
24+
25+
<Separator color="separatorTertiary" thickness={1} />
26+
27+
<Box gap={14}>
28+
<EarningsRow label="Cashback" percentage={cashbackShare} amount={cashbackEarnings} />
29+
<Separator color="separatorTertiary" thickness={1} />
30+
<EarningsRow label="Exit Rewards" percentage={exitRewardsShare} amount={exitRewardsEarnings} />
31+
</Box>
32+
</Box>
33+
</Box>
34+
);
35+
});
36+
37+
const EarningsRow = memo(function EarningsRow({ label, percentage, amount }: { label: string; percentage: string; amount: string }) {
38+
return (
39+
<Box flexDirection="row" alignItems="center" justifyContent="space-between">
40+
<Box flexDirection="row" alignItems="center" gap={6}>
41+
<Text size="17pt" weight="bold" color="label">
42+
{label}
43+
</Text>
44+
<Text size="17pt" weight="bold" color="labelQuaternary">
45+
{percentage}
46+
</Text>
47+
</Box>
48+
<Box flexDirection="row" alignItems="center" gap={2}>
49+
<Text size="17pt" weight="bold" color={'green'}>
50+
{amount}
51+
</Text>
52+
<Text size="17pt" weight="bold" color={'green'}>
53+
{RNBW_SYMBOL}
54+
</Text>
55+
</Box>
56+
</Box>
57+
);
58+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { convertRawAmountToDecimalFormat, isZero } from '@/helpers/utilities';
2+
import { createDerivedStore } from '@/state/internal/createDerivedStore';
3+
import { shallowEqual } from '@/worklets/comparisons';
4+
import { useStakingPositionStore } from '../rnbwStakingPositionStore';
5+
import { divWorklet, sumWorklet, toFixedWorklet, toPercentageWorklet } from '@/framework/core/safeMath';
6+
import { formatNumber } from '@/helpers/strings';
7+
8+
type StakingEarnings = {
9+
totalEarnings: string;
10+
cashbackEarnings: string;
11+
cashbackShare: string;
12+
exitRewardsEarnings: string;
13+
exitRewardsShare: string;
14+
};
15+
16+
const EMPTY_EARNINGS: StakingEarnings = {
17+
totalEarnings: formatNumber('0', { decimals: 4 }),
18+
cashbackEarnings: formatNumber('0'),
19+
cashbackShare: '0%',
20+
exitRewardsEarnings: formatNumber('0'),
21+
exitRewardsShare: '0%',
22+
};
23+
24+
export const useRnbwStakingEarnings = createDerivedStore<StakingEarnings>(
25+
$ => {
26+
const data = $(useStakingPositionStore, state => state.getData());
27+
28+
if (!data) return EMPTY_EARNINGS;
29+
30+
const tokenDecimals = data.decimals;
31+
const sessionPnl = data.sessionPnl;
32+
const cashbackRaw = sessionPnl.totalCashbackReceived;
33+
const exitRewardsRaw = sessionPnl.exchangeRateGain;
34+
const totalRaw = sumWorklet(cashbackRaw, exitRewardsRaw);
35+
const totalIsZero = isZero(totalRaw);
36+
const totalEarnings = convertRawAmountToDecimalFormat(totalRaw, tokenDecimals);
37+
const cashbackEarnings = convertRawAmountToDecimalFormat(cashbackRaw, tokenDecimals);
38+
const exitRewardsEarnings = convertRawAmountToDecimalFormat(exitRewardsRaw, tokenDecimals);
39+
const cashbackRatio = totalIsZero ? '0' : toFixedWorklet(divWorklet(cashbackRaw, totalRaw), 2);
40+
const exitRewardsRatio = totalIsZero ? '0' : toFixedWorklet(divWorklet(exitRewardsRaw, totalRaw), 2);
41+
42+
return {
43+
totalEarnings: formatNumber(totalEarnings, { decimals: 4 }),
44+
cashbackEarnings: formatNumber(cashbackEarnings),
45+
cashbackShare: totalIsZero ? '0%' : `${toPercentageWorklet(cashbackRatio, 0.001)}%`,
46+
exitRewardsEarnings: formatNumber(exitRewardsEarnings),
47+
exitRewardsShare: totalIsZero ? '0%' : `${toPercentageWorklet(exitRewardsRatio, 0.001)}%`,
48+
};
49+
},
50+
{ equalityFn: shallowEqual, fastMode: true }
51+
);

src/features/rnbw-staking/stores/rnbwStakingPositionStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import { type Address } from 'viem';
99
import type { Tier } from '@/features/rnbw-membership/types';
1010

1111
type StakingPnl = {
12-
exchangeRateGain: string;
1312
netProfit: string;
1413
totalCashbackReceived: string;
1514
totalExitFeePaid: string;
1615
totalRnbwStaked: string;
1716
totalRnbwUnstaked: string;
17+
exchangeRateGain: string;
1818
};
1919

2020
type StakingPositionData = {

0 commit comments

Comments
 (0)