Skip to content

Commit

Permalink
Investment position table changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kattylucy committed Jan 10, 2025
1 parent de85de2 commit 55d3be6
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 81 deletions.
64 changes: 58 additions & 6 deletions centrifuge-app/src/components/Portfolio/Holdings.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Token, evmToSubstrateAddress } from '@centrifuge/centrifuge-js'
import { formatBalance, useBalances, useCentrifuge, useWallet } from '@centrifuge/centrifuge-react'
import { CurrencyBalance, Token, evmToSubstrateAddress } from '@centrifuge/centrifuge-js'
import { NetworkIcon, formatBalance, useBalances, useCentrifuge, useWallet } from '@centrifuge/centrifuge-react'
import { Box, Grid, IconDownload, IconMinus, IconPlus, IconSend, Shelf, Text, Thumbnail } from '@centrifuge/fabric'
import Decimal from 'decimal.js-light'
import { useMatch, useNavigate } from 'react-router'
import { useLocation } from 'react-router-dom'
import { useTheme } from 'styled-components'
import { evmChains } from '../../../src/config'
import daiLogo from '../../assets/images/dai-logo.svg'
import ethLogo from '../../assets/images/ethereum.svg'
import centLogo from '../../assets/images/logoCentrifuge.svg'
Expand All @@ -22,7 +23,6 @@ import { Column, DataTable, SortableTableHeader } from '../DataTable'
import { Eththumbnail } from '../EthThumbnail'
import { InvestRedeemDrawer } from '../InvestRedeem/InvestRedeemDrawer'
import { RouterLinkButton } from '../RouterLinkButton'
import { Tooltips } from '../Tooltips'
import { TransferTokensDrawer } from './TransferTokensDrawer'
import { usePortfolioTokens } from './usePortfolio'

Expand All @@ -35,7 +35,9 @@ export type Holding = {
tokenPrice: Decimal
showActions?: boolean
address?: string
connectedNetwork?: string | null
connectedNetwork?: any
realizedProfit?: CurrencyBalance
unrealizedProfit?: CurrencyBalance
}

const columns: Column[] = [
Expand All @@ -45,9 +47,23 @@ const columns: Column[] = [
cell: (token: Holding) => {
return <TokenWithIcon {...token} />
},
width: '300px',
},
{
header: <Tooltips type="cfgPrice" label="Token price" />,
align: 'left',
header: 'Network',
cell: ({ connectedNetwork }: Holding) => {
if (!connectedNetwork) return
return (
<Box display={'flex'}>
<NetworkIcon size="iconSmall" network={connectedNetwork || 'centrifuge'} />
<Text style={{ marginLeft: 4 }}> {(evmChains as any)[connectedNetwork]?.name || 'Centrifuge'}</Text>
</Box>
)
},
},
{
header: <SortableTableHeader label="Token price" />,
cell: ({ tokenPrice }: Holding) => {
return (
<Text textOverflow="ellipsis" variant="body3">
Expand Down Expand Up @@ -81,6 +97,30 @@ const columns: Column[] = [
sortKey: 'marketValue',
align: 'left',
},
{
header: <SortableTableHeader label="Realized P&L" />,
cell: ({ realizedProfit }: Holding) => {
return (
<Text textOverflow="ellipsis" variant="body3">
{formatBalance(realizedProfit || 0, 'USD', 2)}
</Text>
)
},
sortKey: 'realizedProfit',
align: 'left',
},
{
header: <SortableTableHeader label="Unrealized P&L" />,
cell: ({ unrealizedProfit }: Holding) => {
return (
<Text textOverflow="ellipsis" variant="body3">
{formatBalance(unrealizedProfit || 0, 'USD', 2)}
</Text>
)
},
sortKey: 'unrealizedProfit',
align: 'left',
},
{
align: 'right',
header: '', // invest redeem buttons
Expand Down Expand Up @@ -139,6 +179,7 @@ export function useHoldings(address?: string, chainId?: number, showActions = tr
...token,
tokenPrice: token.tokenPrice.toDecimal() || Dec(0),
showActions,
connectedNetwork: wallet.connectedNetwork,
})),
...(tinlakeBalances?.tranches.filter((tranche) => !tranche.balancePending.isZero()) || []).map((balance) => {
const pool = tinlakePools.data?.pools?.find((pool) => pool.id === balance.poolId)
Expand Down Expand Up @@ -223,6 +264,7 @@ export function Holdings({
address?: string
chainId?: number
}) {
const theme = useTheme()
const { search, pathname } = useLocation()
const navigate = useNavigate()
const params = new URLSearchParams(search)
Expand Down Expand Up @@ -251,7 +293,17 @@ export function Holdings({
isOpen={!!(openSendDrawer || openReceiveDrawer)}
onClose={() => navigate(pathname, { replace: true })}
/>
<DataTable columns={columns} data={tokens} defaultSortKey="position" />
<DataTable
headerStyles={{
backgroundColor: 'white',
border: 'transparent',
borderBottom: `1px solid ${theme.colors.backgroundInverted}`,
}}
columns={columns}
data={tokens}
defaultSortKey="position"
hideBorder
/>
</>
) : (
<Shelf borderRadius="4px" backgroundColor="backgroundSecondary" justifyContent="center" p="10px">
Expand Down
110 changes: 37 additions & 73 deletions centrifuge-app/src/components/Portfolio/usePortfolio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,6 @@ const getPriceAtDate = (
}

export function usePortfolio(substrateAddress?: string) {
// const [result] = useCentrifugeQuery(['accountPortfolio', substrateAddress], (cent) => cent.pools.getPortfolio([substrateAddress!]), {
// enabled: !!substrateAddress,
// })
// return result

const pools = usePools()
const { data: subData } = useSubquery(
`query ($account: String!) {
Expand Down Expand Up @@ -174,6 +169,12 @@ export function usePortfolio(substrateAddress?: string) {
purchasePrice
timestamp
trancheId
tranche {
pool {
sumUnrealizedProfitAtMarketPrice
sumRealizedProfitFifoByPeriod
}
}
}
}
}
Expand All @@ -187,7 +188,15 @@ export function usePortfolio(substrateAddress?: string) {
)

const data = useMemo(() => {
const trancheBalances: Record<string, { totalTrancheTokens: TokenBalance; tokenPrice: Price }> = {}
const trancheBalances: Record<
string,
{
totalTrancheTokens: TokenBalance
tokenPrice: Price
unrealizedProfit: CurrencyBalance
realizedProfit: CurrencyBalance
}
> = {}

subData?.account?.investorPositions.nodes.forEach((position: any) => {
const pool = pools?.find((p) => p.id === position.poolId)
Expand All @@ -199,72 +208,14 @@ export function usePortfolio(substrateAddress?: string) {
if (existing) {
existing.totalTrancheTokens.iadd(balance)
} else {
trancheBalances[trancheId] = { totalTrancheTokens: balance, tokenPrice }
trancheBalances[trancheId] = {
totalTrancheTokens: balance,
tokenPrice,
realizedProfit: new CurrencyBalance(position.tranche.pool.sumRealizedProfitFifoByPeriod, decimals),
unrealizedProfit: new CurrencyBalance(position.tranche.pool.sumUnrealizedProfitAtMarketPrice, decimals),
}
}
})
// return (
// (subData?.account as undefined | {}) &&
// (Object.fromEntries(
// subData.account.trancheBalances.nodes.map((tranche: any) => {
// const decimals = tranche.pool.currency.decimals
// const tokenPrice = new Price(tranche.tranche.tokenPrice)
// let freeTrancheTokens = new CurrencyBalance(0, decimals)

// const claimableCurrency = new CurrencyBalance(tranche.claimableCurrency, decimals)
// const claimableTrancheTokens = new TokenBalance(tranche.claimableTrancheTokens, decimals)
// const pendingInvestCurrency = new CurrencyBalance(tranche.pendingInvestCurrency, decimals)
// const pendingRedeemTrancheTokens = new TokenBalance(tranche.pendingRedeemTrancheTokens, decimals)
// const sumClaimedCurrency = new CurrencyBalance(tranche.sumClaimedCurrency, decimals)
// const sumClaimedTrancheTokens = new TokenBalance(tranche.sumClaimedTrancheTokens, decimals)

// const currencyAmounts = subData.account.currencyBalances.nodes.filter(
// (b: any) => b.currency.trancheId && b.currency.trancheId === tranche.trancheId
// )
// if (currencyAmounts.length) {
// freeTrancheTokens = new CurrencyBalance(
// currencyAmounts.reduce((acc: BN, cur: any) => acc.add(new BN(cur.amount)), new BN(0)),
// decimals
// )
// }

// const totalTrancheTokens = new CurrencyBalance(
// new BN(tranche.claimableTrancheTokens)
// .add(new BN(tranche.pendingRedeemTrancheTokens))
// .add(freeTrancheTokens),
// decimals
// )

// return [
// tranche.trancheId.split('-')[1],
// {
// claimableCurrency,
// claimableTrancheTokens,
// pendingInvestCurrency,
// pendingRedeemTrancheTokens,
// sumClaimedCurrency,
// sumClaimedTrancheTokens,
// totalTrancheTokens,
// freeTrancheTokens,
// tokenPrice,
// },
// ]
// })
// ) satisfies Record<
// string,
// {
// claimableCurrency: CurrencyBalance
// claimableTrancheTokens: TokenBalance
// pendingInvestCurrency: CurrencyBalance
// pendingRedeemTrancheTokens: TokenBalance
// sumClaimedCurrency: CurrencyBalance
// sumClaimedTrancheTokens: TokenBalance
// totalTrancheTokens: TokenBalance
// freeTrancheTokens: TokenBalance
// tokenPrice: Price
// // TODO: add reservedTrancheTokens
// }
// >)
// )
return trancheBalances
}, [subData, pools])

Expand All @@ -278,25 +229,36 @@ type PortfolioToken = {
trancheId: string
poolId: string
currency: Token['currency']
realizedProfit: CurrencyBalance
unrealizedProfit: CurrencyBalance
}

export function usePortfolioTokens(address?: string) {
const pools = usePools()
const portfolioData = usePortfolio(address)

console.log(pools)

const trancheTokenPrices = pools?.reduce(
(tranches, pool) =>
pool.tranches.reduce((tranches, tranche) => {
tranches[tranche.id] = {
currency: tranche.currency,
tokenPrice: tranche.tokenPrice,
poolId: tranche.poolId,
realizedProfit: portfolioData[tranche.id]?.realizedProfit,
unrealizedProfit: portfolioData[tranche.id]?.unrealizedProfit,
}
return tranches
}, tranches),
{} as Record<string, { tokenPrice: Price | null; poolId: string; currency: CurrencyMetadata }>
{} as Record<
string,
{
tokenPrice: Price | null
poolId: string
currency: CurrencyMetadata
realizedProfit: CurrencyBalance
unrealizedProfit: CurrencyBalance
}
>
)

if (portfolioData && trancheTokenPrices) {
Expand All @@ -312,6 +274,8 @@ export function usePortfolioTokens(address?: string) {
trancheId: trancheId,
poolId: trancheTokenPrices[trancheId].poolId,
currency: trancheTokenPrices[trancheId].currency,
realizedProfit: trancheTokenPrices[trancheId].realizedProfit,
unrealizedProfit: trancheTokenPrices[trancheId].unrealizedProfit,
}
}, [] as PortfolioToken[])
}
Expand Down
3 changes: 2 additions & 1 deletion centrifuge-app/src/pages/Prime/Detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ const PrimeDetail = () => {
<CardPortfolioValue address={centAddress} />
</Box>

<LayoutSection title="Holdings" pt={12} pb={12}>
<LayoutSection mt={3} pt={0}>
<Text variant="heading4">Investment positions</Text>
<Holdings address={centAddress} showActions={false} />
</LayoutSection>
{/* <LayoutSection title="Transaction history" pt={12} pb={12}>
Expand Down
2 changes: 1 addition & 1 deletion centrifuge-app/src/pages/Prime/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function Prime() {
return (
<>
<LayoutSection alignItems="flex-start" pt={3} pb={3}>
<Box display="flex" alignItems="center">
<Box display="flex" alignItems="center" ml={2}>
<Box
backgroundColor="backgroundSecondary"
borderRadius={28}
Expand Down

0 comments on commit 55d3be6

Please sign in to comment.