From 9e2143da5c767154d9cf1fe7b7c1c9ce1d350228 Mon Sep 17 00:00:00 2001 From: chambaz Date: Wed, 27 Nov 2024 09:58:05 -0500 Subject: [PATCH 1/2] feat: portfolio upgrades, usd values, improved support for small numbers --- .../asset-card/portfolio-asset-card.tsx | 34 +++++++++++-------- .../common/Portfolio/lending-portfolio.tsx | 12 +++---- .../mrgn-common/src/utils/formatters.utils.ts | 10 ++++-- .../screens/lending-screen.tsx | 15 ++++++-- .../action-complete/screens/loop-screen.tsx | 4 +-- .../action-complete/screens/stake-screen.tsx | 6 ++-- .../mrgn-ui/src/components/ui/accordion.tsx | 2 +- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/apps/marginfi-v2-ui/src/components/common/Portfolio/components/asset-card/portfolio-asset-card.tsx b/apps/marginfi-v2-ui/src/components/common/Portfolio/components/asset-card/portfolio-asset-card.tsx index 3775526db2..c440e61c73 100644 --- a/apps/marginfi-v2-ui/src/components/common/Portfolio/components/asset-card/portfolio-asset-card.tsx +++ b/apps/marginfi-v2-ui/src/components/common/Portfolio/components/asset-card/portfolio-asset-card.tsx @@ -3,7 +3,12 @@ import React from "react"; import Image from "next/image"; import { IconAlertTriangle, IconFolderShare } from "@tabler/icons-react"; -import { usdFormatter, dynamicNumeralFormatter, groupedNumberFormatter } from "@mrgnlabs/mrgn-common"; +import { + usdFormatter, + dynamicNumeralFormatter, + groupedNumberFormatter, + tokenPriceFormatter, +} from "@mrgnlabs/mrgn-common"; import { ActiveBankInfo, ActionType, ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state"; import { capture } from "@mrgnlabs/mrgn-utils"; import { ActionBox } from "@mrgnlabs/mrgn-ui"; @@ -94,11 +99,16 @@ export const PortfolioAssetCard = ({ bank, isInLendingMode, isBorrower = true }: -
- {dynamicNumeralFormatter(bank.position.amount, { - tokenPrice: bank.info.oraclePrice.priceRealtime.price.toNumber(), - })} - {" " + bank.meta.tokenSymbol} +
+
+ {dynamicNumeralFormatter(bank.position.amount, { + tokenPrice: bank.info.oraclePrice.priceRealtime.price.toNumber(), + })} + {" " + bank.meta.tokenSymbol} +
+ + {usdFormatter.format(bank.position.usdValue)} +
@@ -143,15 +153,13 @@ export const PortfolioAssetCard = ({ bank, isInLendingMode, isBorrower = true }:
Value
- {bank.position.amount < 0.01 ? "< $0.01" : groupedNumberFormatter.format(bank.position.amount)} + {groupedNumberFormatter.format(bank.position.amount)} {" " + bank.meta.tokenSymbol}
USD value
-
- {bank.position.usdValue < 0.01 ? "< $0.01" : usdFormatter.format(bank.position.usdValue)} -
+
{usdFormatter.format(bank.position.usdValue)}
Current price
-
{usdFormatter.format(bank.info.state.price)}
+
{tokenPriceFormatter(bank.info.state.price)}
{bank.position.liquidationPrice && ( <>
Liquidation price
@@ -162,9 +170,7 @@ export const PortfolioAssetCard = ({ bank, isInLendingMode, isBorrower = true }: )} > {isUserPositionPoorHealth && } - {bank.position.liquidationPrice > 0.01 - ? usdFormatter.format(bank.position.liquidationPrice) - : `$${bank.position.liquidationPrice.toExponential(2)}`} + {tokenPriceFormatter(bank.position.liquidationPrice)} )} diff --git a/apps/marginfi-v2-ui/src/components/common/Portfolio/lending-portfolio.tsx b/apps/marginfi-v2-ui/src/components/common/Portfolio/lending-portfolio.tsx index b45952952b..c15ec78ef1 100644 --- a/apps/marginfi-v2-ui/src/components/common/Portfolio/lending-portfolio.tsx +++ b/apps/marginfi-v2-ui/src/components/common/Portfolio/lending-portfolio.tsx @@ -334,9 +334,9 @@ export const LendingPortfolio = () => {
-
-
Supplied
-
{accountSupplied}
+
+
Supplied
+
{accountSupplied}
{isStoreInitialized ? ( lendingBanks.length > 0 ? ( @@ -360,9 +360,9 @@ export const LendingPortfolio = () => { )}
-
-
Borrowed
-
{accountBorrowed}
+
+
Borrowed
+
{accountBorrowed}
{isStoreInitialized ? ( borrowingBanks.length > 0 ? ( diff --git a/packages/mrgn-common/src/utils/formatters.utils.ts b/packages/mrgn-common/src/utils/formatters.utils.ts index d21ef3eaf5..1bf5c92b8f 100644 --- a/packages/mrgn-common/src/utils/formatters.utils.ts +++ b/packages/mrgn-common/src/utils/formatters.utils.ts @@ -16,7 +16,7 @@ class CustomNumberFormat extends Intl.NumberFormat { const groupedNumberFormatter = new CustomNumberFormat("en-US", { useGrouping: true, - minimumFractionDigits: 2, + minimumFractionDigits: 0, maximumFractionDigits: 2, }); @@ -43,11 +43,11 @@ export const dynamicNumeralFormatter = (value: number, options: dynamicNumeralFo } if (Math.abs(value) >= 0.01) { - return numeral(value).format("0.00a"); + return numeral(value).format("0,0.[0000]a"); } if (tokenPrice) { - const minUsdDisplay = 0.01; + const minUsdDisplay = 0.00000001; const smallestUnit = minUsdDisplay / tokenPrice; const requiredDecimals = Math.max(2, Math.ceil(-Math.log10(smallestUnit)) + 1); @@ -110,6 +110,10 @@ const tokenPriceFormatter = (price: number, style: "currency" | "decimal" = "cur } const reformatNum = Number(price.toFixed(20)); + if (price === 0) { + return 0; + } + if (reformatNum < 0.00000001) { return price.toExponential(2); } diff --git a/packages/mrgn-ui/src/components/action-complete/screens/lending-screen.tsx b/packages/mrgn-ui/src/components/action-complete/screens/lending-screen.tsx index 354ae50d78..cde4af69eb 100644 --- a/packages/mrgn-ui/src/components/action-complete/screens/lending-screen.tsx +++ b/packages/mrgn-ui/src/components/action-complete/screens/lending-screen.tsx @@ -85,14 +85,23 @@ export const LendingScreen = ({ amount, bank, type, txn, txnLink, collatRepay }:

{type === ActionType.RepayCollat ? ( <> - You repaid {dynamicNumeralFormatter(amount ?? 0, { minDisplay: 0.01 })}{" "} + You repaid{" "} + {dynamicNumeralFormatter(amount, { + tokenPrice: collatRepay?.borrowBank.info.state.price, + })}{" "} {bank?.meta.tokenSymbol.toUpperCase()} with{" "} - {dynamicNumeralFormatter(collatRepay?.withdrawAmount ?? 0, { minDisplay: 0.01 })}{" "} + {dynamicNumeralFormatter(collatRepay?.withdrawAmount ?? 0, { + tokenPrice: collatRepay?.withdrawBank.info.state.price, + })}{" "} {collatRepay?.withdrawBank.meta.tokenSymbol.toUpperCase()} ) : ( <> - You {type === ActionType.Deposit ? "deposited" : "borrowed"} {amount} {bank?.meta.tokenSymbol} + You {type === ActionType.Deposit ? "deposited" : "borrowed"}{" "} + {dynamicNumeralFormatter(amount, { + tokenPrice: bank?.info.state.price, + })}{" "} + {bank?.meta.tokenSymbol} )}

diff --git a/packages/mrgn-ui/src/components/action-complete/screens/loop-screen.tsx b/packages/mrgn-ui/src/components/action-complete/screens/loop-screen.tsx index 14ec249baa..896ea5d122 100644 --- a/packages/mrgn-ui/src/components/action-complete/screens/loop-screen.tsx +++ b/packages/mrgn-ui/src/components/action-complete/screens/loop-screen.tsx @@ -76,9 +76,9 @@ export const LoopScreen = ({

- You looped {dynamicNumeralFormatter(depositAmount, { minDisplay: 0.01 })}{" "} + You looped {dynamicNumeralFormatter(depositAmount)}{" "} {depositBank.meta.tokenSymbol.toUpperCase()} with{" "} - {dynamicNumeralFormatter(borrowAmount, { minDisplay: 0.01 })} {borrowBank.meta.tokenSymbol.toUpperCase()} + {dynamicNumeralFormatter(borrowAmount)} {borrowBank.meta.tokenSymbol.toUpperCase()}

Leverage: {leverage}x

diff --git a/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx b/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx index 8a52cd6e32..30b847e56b 100644 --- a/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx +++ b/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx @@ -3,7 +3,7 @@ import Link from "next/link"; import { IconExternalLink } from "@tabler/icons-react"; import { ActionType, ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state"; -import { numeralFormatter, shortenAddress } from "@mrgnlabs/mrgn-common"; +import { dynamicNumeralFormatter, shortenAddress } from "@mrgnlabs/mrgn-common"; import { IconSol, IconLST } from "~/components/ui/icons"; @@ -24,7 +24,7 @@ export const StakingScreen = ({ amount, type, txn, originDetails, txnLink }: Pro

- {amount <= 0.01 ? "<0.01" : numeralFormatter(amount)} {type === ActionType.MintLST ? "LST" : "SOL"} + {dynamicNumeralFormatter(amount)} {type === ActionType.MintLST ? "LST" : "SOL"}

{type === ActionType.MintLST ? : }
@@ -32,7 +32,7 @@ export const StakingScreen = ({ amount, type, txn, originDetails, txnLink }: Pro
Paid
- {numeralFormatter(originDetails?.amount)} {originDetails?.bank.meta.tokenSymbol} + {dynamicNumeralFormatter(originDetails?.amount)} {originDetails?.bank.meta.tokenSymbol}
Transaction
diff --git a/packages/mrgn-ui/src/components/ui/accordion.tsx b/packages/mrgn-ui/src/components/ui/accordion.tsx index df42ea272a..769defd450 100644 --- a/packages/mrgn-ui/src/components/ui/accordion.tsx +++ b/packages/mrgn-ui/src/components/ui/accordion.tsx @@ -30,7 +30,7 @@ const AccordionTrigger = React.forwardRef< {...props} > {children} -
+
From 68ef174bbb815a815dfd8ff8f4328252bb44c328 Mon Sep 17 00:00:00 2001 From: borcherd Date: Wed, 27 Nov 2024 21:26:37 +0530 Subject: [PATCH 2/2] chore: stake-screen updates --- .../action-complete/screens/stake-screen.tsx | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx b/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx index 30b847e56b..4ffde89d71 100644 --- a/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx +++ b/packages/mrgn-ui/src/components/action-complete/screens/stake-screen.tsx @@ -1,5 +1,7 @@ import React from "react"; import Link from "next/link"; +import Image from "next/image"; + import { IconExternalLink } from "@tabler/icons-react"; import { ActionType, ExtendedBankInfo } from "@mrgnlabs/marginfi-v2-ui-state"; @@ -21,18 +23,50 @@ interface Props { export const StakingScreen = ({ amount, type, txn, originDetails, txnLink }: Props) => { return ( <> -
-
-

- {dynamicNumeralFormatter(amount)} {type === ActionType.MintLST ? "LST" : "SOL"} -

- {type === ActionType.MintLST ? : } +
+
+ {(originDetails.bank.meta.tokenLogoUri + {type === ActionType.MintLST ? ( + + ) : ( + + )}
+

+ {/* {dynamicNumeralFormatter(amount)} {type === ActionType.MintLST ? "LST" : "SOL"} */} + {type === ActionType.MintLST + ? `You staked ${dynamicNumeralFormatter(originDetails.amount, { + minDisplay: 0.01, + })} ${originDetails.bank.meta.tokenSymbol.toUpperCase()} for ${dynamicNumeralFormatter(amount, { + minDisplay: 0.01, + })} LST` + : `You swapped ${dynamicNumeralFormatter(originDetails.amount, { + minDisplay: 0.01, + })} LST for ${dynamicNumeralFormatter(amount, { + minDisplay: 0.01, + })} SOL`} +

Paid
- {dynamicNumeralFormatter(originDetails?.amount)} {originDetails?.bank.meta.tokenSymbol} + {dynamicNumeralFormatter(originDetails?.amount, { + minDisplay: 0.01, + })}{" "} + {originDetails?.bank.meta.tokenSymbol} +
+
Received
+
+ {dynamicNumeralFormatter(amount, { + minDisplay: 0.01, + })}{" "} + {type === ActionType.MintLST ? "LST" : "SOL"}
Transaction