Skip to content

Commit

Permalink
Merge pull request #923 from SudiptaPaul-31/fix-wallet-amount
Browse files Browse the repository at this point in the history
Fix: Add wallet amount in $
  • Loading branch information
Marchand-Nicolas authored Nov 3, 2024
2 parents d2ac97d + d1972da commit 4e0edee
Show file tree
Hide file tree
Showing 6 changed files with 592 additions and 440 deletions.
210 changes: 152 additions & 58 deletions app/[addressOrDomain]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ import ProfileCardSkeleton from "@components/skeletons/profileCardSkeleton";
import { getDataFromId } from "@services/starknetIdService";
import { usePathname, useRouter } from "next/navigation";
import ErrorScreen from "@components/UI/screens/errorScreen";
import { ArgentDappMap, ArgentTokenMap, ArgentUserDapp, ArgentUserToken, CompletedQuests } from "../../types/backTypes";
import {
ArgentDappMap,
ArgentTokenMap,
ArgentUserDapp,
ArgentUserToken,
CompletedQuests,
} from "../../types/backTypes";
import QuestSkeleton from "@components/skeletons/questsSkeleton";
import QuestCardCustomised from "@components/dashboard/CustomisedQuestCard";
import QuestStyles from "@styles/Home.module.css";
Expand All @@ -33,7 +39,13 @@ import { CustomTabPanel } from "@components/UI/tabs/customTab";
import SuggestedQuests from "@components/dashboard/SuggestedQuests";
import PortfolioSummary from "@components/dashboard/PortfolioSummary";
import { useNotification } from "@context/NotificationProvider";
import { calculateTokenPrice, fetchDapps, fetchTokens, fetchUserDapps, fetchUserTokens } from "@services/argentPortfolioService";
import {
calculateTokenPrice,
fetchDapps,
fetchTokens,
fetchUserDapps,
fetchUserTokens,
} from "@services/argentPortfolioService";
import PortfolioSummarySkeleton from "@components/skeletons/portfolioSummarySkeleton";

type AddressOrDomainProps = {
Expand All @@ -43,15 +55,15 @@ type AddressOrDomainProps = {
};

type ChartItemMap = {
[dappId: string]: ChartItem
[dappId: string]: ChartItem;
};

type DebtStatus = {
hasDebt: boolean;
tokens: {
dappId: string,
tokenAddress: string,
tokenBalance: number
tokens: {
dappId: string;
tokenAddress: string;
tokenBalance: number;
}[];
};

Expand Down Expand Up @@ -190,63 +202,111 @@ export default function Page({ params }: AddressOrDomainProps) {
}, []);

const fetchPortfolioAssets = useCallback(async (addr: string) => {

// TODO: Implement fetch from Argent API
const assets = [
{ color: "#1E2097", itemLabel: "USDC", itemValue: "46.68", itemValueSymbol: "%" },
{ color: "#637DEB", itemLabel: "USDT", itemValue: "27.94", itemValueSymbol: "%" },
{ color: "#2775CA", itemLabel: "STRK", itemValue: "22.78", itemValueSymbol: "%" },
{ color: "#5CE3FE", itemLabel: "ETH", itemValue: "0.36", itemValueSymbol: "%" },
{ color: "#F4FAFF", itemLabel: "Others", itemValue: "2.36", itemValueSymbol: "%" },
{
color: "#1E2097",
itemLabel: "USDC",
itemValue: "46.68",
itemValueSymbol: "%",
},
{
color: "#637DEB",
itemLabel: "USDT",
itemValue: "27.94",
itemValueSymbol: "%",
},
{
color: "#2775CA",
itemLabel: "STRK",
itemValue: "22.78",
itemValueSymbol: "%",
},
{
color: "#5CE3FE",
itemLabel: "ETH",
itemValue: "0.36",
itemValueSymbol: "%",
},
{
color: "#F4FAFF",
itemLabel: "Others",
itemValue: "2.36",
itemValueSymbol: "%",
},
];
setPortfolioAssets(assets);

}, []);

const userHasDebt = (userDapps: ArgentUserDapp[]) => {
let debt: DebtStatus = { hasDebt: false, tokens: [] };

for (const dapp of userDapps) {
if (!dapp.products[0]) { continue; }
if (!dapp.products[0]) {
continue;
}
for (const position of dapp.products[0].positions) {
for (const tokenAddress of Object.keys(position.totalBalances)) {
const tokenBalance = Number(position.totalBalances[tokenAddress]);
if (tokenBalance < 0) {
debt.hasDebt = true;
debt.tokens.push({dappId: dapp.dappId, tokenAddress, tokenBalance});
debt.tokens.push({
dappId: dapp.dappId,
tokenAddress,
tokenBalance,
});
}
}
}
}
return debt;
};

const handleDebt = async (protocolsMap: ChartItemMap, userDapps: ArgentUserDapp[], tokens: ArgentTokenMap) => {
const handleDebt = async (
protocolsMap: ChartItemMap,
userDapps: ArgentUserDapp[],
tokens: ArgentTokenMap
) => {
const debtStatus = userHasDebt(userDapps);
if (!debtStatus || !debtStatus.hasDebt) { return; }
if (!debtStatus || !debtStatus.hasDebt) {
return;
}

for await (const debt of debtStatus.tokens) {
let value = Number(protocolsMap[debt.dappId].itemValue);
value += await calculateTokenPrice(
debt.tokenAddress,
tokenToDecimal(debt.tokenBalance.toString(),
tokens[debt.tokenAddress].decimals),
tokenToDecimal(
debt.tokenBalance.toString(),
tokens[debt.tokenAddress].decimals
),
"USD"
);

protocolsMap[debt.dappId].itemValue = value.toFixed(2);
}
};

const getProtocolsFromTokens = async (protocolsMap: ChartItemMap, userTokens: ArgentUserToken[], tokens: ArgentTokenMap, dapps: ArgentDappMap) => {
const getProtocolsFromTokens = async (
protocolsMap: ChartItemMap,
userTokens: ArgentUserToken[],
tokens: ArgentTokenMap,
dapps: ArgentDappMap
) => {
for await (const token of userTokens) {
const tokenInfo = tokens[token.tokenAddress];
if (tokenInfo.dappId && token.tokenBalance != "0") {
let itemValue = 0;
const currentTokenBalance = await calculateTokenPrice(token.tokenAddress, tokenToDecimal(token.tokenBalance, tokenInfo.decimals), "USD");

const currentTokenBalance = await calculateTokenPrice(
token.tokenAddress,
tokenToDecimal(token.tokenBalance, tokenInfo.decimals),
"USD"
);

if (protocolsMap[tokenInfo.dappId]?.itemValue) {
itemValue = Number(protocolsMap[tokenInfo.dappId].itemValue) + currentTokenBalance;
itemValue =
Number(protocolsMap[tokenInfo.dappId].itemValue) +
currentTokenBalance;
} else {
itemValue = currentTokenBalance;
}
Expand All @@ -255,23 +315,35 @@ export default function Page({ params }: AddressOrDomainProps) {
color: "",
itemLabel: dapps[tokenInfo.dappId].name,
itemValueSymbol: "$",
itemValue: itemValue.toFixed(2)
}
itemValue: itemValue.toFixed(2),
};
}
}
}
};

const getProtocolsFromDapps = async (protocolsMap: ChartItemMap, userDapps: ArgentUserDapp[], tokens: ArgentTokenMap, dapps: ArgentDappMap) => {
const getProtocolsFromDapps = async (
protocolsMap: ChartItemMap,
userDapps: ArgentUserDapp[],
tokens: ArgentTokenMap,
dapps: ArgentDappMap
) => {
for await (const userDapp of userDapps) {
if (protocolsMap[userDapp.dappId]) { continue; } // Ignore entry if already present in the map
if (protocolsMap[userDapp.dappId]) {
continue;
} // Ignore entry if already present in the map

let protocolBalance = 0;
if (!userDapp.products[0]) { return; }
if (!userDapp.products[0]) {
return;
}
for await (const position of userDapp.products[0].positions) {
for await (const tokenAddress of Object.keys(position.totalBalances)) {
protocolBalance += await calculateTokenPrice(
tokenAddress,
tokenToDecimal(position.totalBalances[tokenAddress], tokens[tokenAddress].decimals),
tokenAddress,
tokenToDecimal(
position.totalBalances[tokenAddress],
tokens[tokenAddress].decimals
),
"USD"
);
}
Expand All @@ -281,38 +353,48 @@ export default function Page({ params }: AddressOrDomainProps) {
color: "",
itemLabel: dapps[userDapp.dappId].name,
itemValueSymbol: "$",
itemValue: protocolBalance.toFixed(2)
}
itemValue: protocolBalance.toFixed(2),
};
}
}
};

const sortProtocols = (protocolsMap: ChartItemMap) => {
return Object.values(protocolsMap).sort((a, b) => parseFloat(b.itemValue) - parseFloat(a.itemValue));
}
return Object.values(protocolsMap).sort(
(a, b) => parseFloat(b.itemValue) - parseFloat(a.itemValue)
);
};

const handleExtraProtocols = (sortedProtocols: ChartItem[]) => {
let otherProtocols = sortedProtocols.length > 5 ? sortedProtocols.splice(4) : [];
if (otherProtocols.length === 0) { return;}
let otherProtocols =
sortedProtocols.length > 5 ? sortedProtocols.splice(4) : [];
if (otherProtocols.length === 0) {
return;
}
sortedProtocols.push({
itemLabel: "Others",
itemValue: otherProtocols.reduce((valueSum, protocol) => valueSum + Number(protocol.itemValue), 0).toFixed(2),
itemValue: otherProtocols
.reduce(
(valueSum, protocol) => valueSum + Number(protocol.itemValue),
0
)
.toFixed(2),
itemValueSymbol: "$",
color: ""
color: "",
});
}
};

const assignProtocolColors = (sortedProtocols: ChartItem[]) => {
const portfolioProtocolColors = [
"#278015",
"#23F51F",
"#DEFE5C",
"#9EFABB",
"#F4FAFF"
"#F4FAFF",
];
sortedProtocols.forEach((protocol, index) => {
protocol.color = portfolioProtocolColors[index];
});
}
};

const fetchPortfolioProtocols = useCallback(async (addr: string) => {
let dapps: ArgentDappMap = {};
Expand All @@ -326,7 +408,7 @@ export default function Page({ params }: AddressOrDomainProps) {
fetchDapps(),
fetchTokens(),
fetchUserTokens(addr),
fetchUserDapps(addr)
fetchUserDapps(addr),
]);
} catch (error) {
showNotification("Error while fetching address portfolio", "error");
Expand All @@ -344,10 +426,13 @@ export default function Page({ params }: AddressOrDomainProps) {
let sortedProtocols = sortProtocols(protocolsMap);
handleExtraProtocols(sortedProtocols);
assignProtocolColors(sortedProtocols);

setPortfolioProtocols(sortedProtocols);
} catch (error) {
showNotification("Error while calculating address portfolio stats", "error");
showNotification(
"Error while calculating address portfolio stats",
"error"
);
console.log("Error while calculating address portfolio stats", error);
}

Expand Down Expand Up @@ -503,7 +588,6 @@ export default function Page({ params }: AddressOrDomainProps) {
{initProfile && identity ? (
<ProfileCard
identity={identity}
addressOrDomain={addressOrDomain}
rankingData={userRanking}
leaderboardData={leaderboardData}
isOwner={isOwner}
Expand All @@ -518,20 +602,26 @@ export default function Page({ params }: AddressOrDomainProps) {
{loadingProtocols ? ( // Change for corresponding state
<PortfolioSummarySkeleton />
) : (
<PortfolioSummary
title="Portfolio by assets type"
<PortfolioSummary
title="Portfolio by assets type"
data={portfolioAssets}
totalBalance={portfolioAssets.reduce((sum, item) => sum + Number(item.itemValue), 0)}
totalBalance={portfolioAssets.reduce(
(sum, item) => sum + Number(item.itemValue),
0
)}
isProtocol={false}
/>
)}
{loadingProtocols ? (
<PortfolioSummarySkeleton />
) : (
<PortfolioSummary
title="Portfolio by protocol usage"
data={portfolioProtocols}
totalBalance={portfolioProtocols.reduce((sum, item) => sum + Number(item.itemValue), 0)}
<PortfolioSummary
title="Portfolio by protocol usage"
data={portfolioProtocols}
totalBalance={portfolioProtocols.reduce(
(sum, item) => sum + Number(item.itemValue),
0
)}
isProtocol={true}
/>
)}
Expand Down Expand Up @@ -587,9 +677,13 @@ export default function Page({ params }: AddressOrDomainProps) {
{questsLoading ? (
<QuestSkeleton />
) : completedQuests?.length === 0 ? (
isOwner
? <SuggestedQuests />
: <Typography type={TEXT_TYPE.H2} className={styles.noBoosts}>User has not completed any quests at the moment</Typography>
isOwner ? (
<SuggestedQuests />
) : (
<Typography type={TEXT_TYPE.H2} className={styles.noBoosts}>
User has not completed any quests at the moment
</Typography>
)
) : (
<section className={QuestStyles.section}>
<div className={QuestStyles.questContainer}>
Expand Down
Loading

0 comments on commit 4e0edee

Please sign in to comment.