Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce calls to subquery #2454

Merged
merged 2 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 19 additions & 29 deletions centrifuge-app/src/components/PoolCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { CurrencyBalance, Rate } from '@centrifuge/centrifuge-js'
import { CurrencyBalance, Rate, Token } from '@centrifuge/centrifuge-js'
import { Box, Card, Divider, Stack, Text, Thumbnail } from '@centrifuge/fabric'
import Decimal from 'decimal.js-light'
import styled from 'styled-components'
import { daysBetween } from '../../utils/date'
import { formatBalance, formatBalanceAbbreviated, formatPercentage } from '../../utils/formatting'
import { CardHeader } from '../ListItemCardStyles'
import { RouterTextLink } from '../TextLink'
import { PoolStatus, PoolStatusKey } from './PoolStatus'

type TrancheData = {
name: string
apr: string
minInvestment: string
}

export type InnerMetadata = {
minInitialInvestment?: CurrencyBalance
}
Expand All @@ -29,19 +24,6 @@ export type MetaData = {
}
}

export type Tranche = {
id: string
currency: {
name: string
decimals: number
}
interestRatePerSec: {
toAprPercent: () => Decimal
} | null
capacity?: CurrencyBalance | number
metadata?: MetaData
}

const StyledRouterTextLink = styled(RouterTextLink)`
font-size: 12px;
margin-top: 8px;
Expand Down Expand Up @@ -77,8 +59,9 @@ export type PoolCardProps = {
apr?: Rate | null | undefined
status?: PoolStatusKey
iconUri?: string
tranches?: Tranche[]
tranches?: Pick<Token, 'yield30DaysAnnualized' | 'interestRatePerSec' | 'currency' | 'id'>[]
metaData?: MetaData
createdAt?: string
}

export function PoolCard({
Expand All @@ -91,6 +74,7 @@ export function PoolCard({
iconUri,
tranches,
metaData,
createdAt,
}: PoolCardProps) {
const isOneTranche = tranches && tranches?.length === 1
const renderText = (text: string) => (
Expand All @@ -99,7 +83,7 @@ export function PoolCard({
</Text>
)

const tranchesData: TrancheData[] = tranches?.map((tranche: Tranche) => {
const tranchesData = tranches?.map((tranche) => {
const words = tranche.currency.name.trim().split(' ')
const metadata = metaData?.tranches[tranche.id] ?? null
const trancheName = words[words.length - 1]
Expand All @@ -108,18 +92,24 @@ export function PoolCard({
tranche.currency.decimals
).toDecimal()

const daysSinceCreation = createdAt ? daysBetween(createdAt, new Date()) : 0

function calculateApy() {
if (poolId === '4139607887') return formatPercentage(5, true, {}, 1)
if (poolId === '1655476167') return formatPercentage(15, true, {}, 1)
if (daysSinceCreation > 30 && tranche.yield30DaysAnnualized)
return formatPercentage(tranche.yield30DaysAnnualized, true, {}, 1)
if (tranche.interestRatePerSec) return formatPercentage(tranche.interestRatePerSec.toAprPercent(), true, {}, 1)
return '-'
}

return {
name: trancheName,
apr: tranche.interestRatePerSec
? formatPercentage(tranche.interestRatePerSec.toAprPercent(), true, {
minimumFractionDigits: 1,
maximumFractionDigits: 1,
})
: '-',
apr: calculateApy(),
minInvestment:
metadata && metadata.minInitialInvestment ? formatBalanceAbbreviated(investmentBalance, '', 0) : '-',
}
}) as TrancheData[]
})

return (
<StyledCard>
Expand Down
4 changes: 2 additions & 2 deletions centrifuge-app/src/components/PoolList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { useIsAboveBreakpoint } from '../utils/useIsAboveBreakpoint'
import { useListedPools } from '../utils/useListedPools'
import { useMetadataMulti } from '../utils/useMetadata'
import { MetaData, PoolCard, PoolCardProps, Tranche } from './PoolCard'
import { MetaData, PoolCard, PoolCardProps } from './PoolCard'
import { PoolStatusKey } from './PoolCard/PoolStatus'
import { filterPools } from './PoolFilter/utils'

Expand Down Expand Up @@ -51,7 +51,7 @@

const sortedPools = [...openInvestmentPools, ...upcomingPools, ...tinlakePools]
return [pools, search ? filterPools([...pools, ...upcomingPools], new URLSearchParams(search)) : sortedPools]
}, [listedPools, search])

Check warning on line 54 in centrifuge-app/src/components/PoolList.tsx

View workflow job for this annotation

GitHub Actions / build-app

React Hook React.useMemo has missing dependencies: 'cent' and 'centPoolsMetaDataById'. Either include them or remove the dependency array

Check warning on line 54 in centrifuge-app/src/components/PoolList.tsx

View workflow job for this annotation

GitHub Actions / ff-prod / build-app

React Hook React.useMemo has missing dependencies: 'cent' and 'centPoolsMetaDataById'. Either include them or remove the dependency array

const archivedPools = pools.filter((pool) => pool?.status?.includes('Archived'))

Expand Down Expand Up @@ -154,7 +154,7 @@
? 'Open for investments'
: ('Closed' as PoolStatusKey),
iconUri: metaData?.pool?.icon?.uri ? cent.metadata.parseMetadataUrl(metaData?.pool?.icon?.uri) : undefined,
tranches: pool.tranches as Tranche[],
tranches: pool.tranches,
metaData: metaData as MetaData,
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Perquintill } from '@centrifuge/centrifuge-js'
import { Box, Shelf, Stack, Text } from '@centrifuge/fabric'
import { InvestButton, Token } from '../../pages/Pool/Overview'
import { daysBetween } from '../../utils/date'
Expand Down Expand Up @@ -74,7 +73,7 @@ const TrancheTokenCard = ({
if (poolId === '1655476167') return formatPercentage(15)
if (isTinlakePool && trancheText === 'senior') return formatPercentage(trancheToken.apy)
if (daysSinceCreation < 30 || !trancheToken.yield30DaysAnnualized) return 'N/A'
return formatPercentage(new Perquintill(trancheToken.yield30DaysAnnualized))
return formatPercentage(trancheToken.yield30DaysAnnualized)
}

return (
Expand Down
3 changes: 1 addition & 2 deletions centrifuge-app/src/utils/tinlake/useTinlakePools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,7 @@ export function useTinlakeLoans(poolId: string) {
export type TinlakePool = Omit<Pool, 'metadata' | 'loanCollectionId' | 'tranches'> & {
metadata: PoolMetadata
tinlakeMetadata: PoolMetadataDetails
tranches: (Omit<Pool['tranches'][0], 'poolMetadata' | 'yield30DaysAnnualized'> & {
yield30DaysAnnualized?: string | null
tranches: (Omit<Pool['tranches'][0], 'poolMetadata'> & {
poolMetadata: PoolMetadata
pendingInvestments: CurrencyBalance
pendingRedemptions: TokenBalance
Expand Down
30 changes: 11 additions & 19 deletions centrifuge-js/src/modules/pools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ export type Tranche = {
minRiskBuffer: Perquintill | null
currentRiskBuffer: Perquintill
interestRatePerSec: Rate | null
yield30DaysAnnualized?: string | null
yield30DaysAnnualized: Perquintill | null
lastUpdatedInterest: string
ratio: Perquintill
}
Expand Down Expand Up @@ -2054,13 +2054,6 @@ export function getPoolsModule(inst: Centrifuge) {
})
.flat()

const $yield30DaysAnnualized = combineLatest(
keys.map((key) => {
const poolIdTrancheId = `${key[0]}-${key[1].toLowerCase()}`
return getLatestTrancheSnapshot(poolIdTrancheId).pipe(map((snapshot) => snapshot?.trancheSnapshots.nodes))
})
) as Observable<{ yield30DaysAnnualized: string | null; trancheId: string }[][]>

const trancheIdToIndex: Record<string, number> = {}
keys.forEach(([, tid], i) => {
trancheIdToIndex[tid] = i
Expand All @@ -2080,11 +2073,11 @@ export function getPoolsModule(inst: Centrifuge) {

const $block = inst.getBlocks().pipe(take(1))

return combineLatest([$issuance, $block, $prices, $navs, $yield30DaysAnnualized]).pipe(
map(([rawIssuances, { block }, rawPrices, rawNavs, [rawYield30DaysAnnualized]]) => {
return combineLatest([$issuance, $block, $prices, $navs, getLatestTrancheSnapshots()]).pipe(
map(([rawIssuances, { block }, rawPrices, rawNavs, rawYield30DaysAnnualized]) => {
const blockNumber = block.header.number.toNumber()

const yield30DaysAnnualizedByPoolIdTrancheId = rawYield30DaysAnnualized?.reduce(
const yield30DaysTrancheId = rawYield30DaysAnnualized?.trancheSnapshots.nodes.reduce(
(acc, { yield30DaysAnnualized, trancheId }) => {
acc[trancheId] = yield30DaysAnnualized
return acc
Expand Down Expand Up @@ -2168,7 +2161,9 @@ export function getPoolsModule(inst: Centrifuge) {
poolId,
poolMetadata: (metadata ?? undefined) as string | undefined,
interestRatePerSec,
yield30DaysAnnualized: yield30DaysAnnualizedByPoolIdTrancheId?.[`${poolId}-${trancheId}`],
yield30DaysAnnualized: yield30DaysTrancheId?.[`${poolId}-${trancheId}`]
? new Perquintill(yield30DaysTrancheId[`${poolId}-${trancheId}`]!)
: null,
minRiskBuffer,
currentRiskBuffer,
capacity: CurrencyBalance.fromFloat(capacity, currency.decimals),
Expand Down Expand Up @@ -2301,21 +2296,18 @@ export function getPoolsModule(inst: Centrifuge) {
)
}

function getLatestTrancheSnapshot(poolIdTrancheId: string) {
function getLatestTrancheSnapshots() {
return inst.getSubqueryObservable<{
trancheSnapshots: { nodes: { yield30DaysAnnualized: string | null; trancheId: string }[] }
}>(
`query ($poolIdTrancheId: String!) {
trancheSnapshots(filter: { trancheId: { equalTo: $poolIdTrancheId } }, last: 1) {
`{
trancheSnapshots(distinct: TRANCHE_ID, orderBy: TIMESTAMP_DESC) {
nodes {
trancheId
yield30DaysAnnualized
}
}
}`,
{
poolIdTrancheId,
}
}`
)
}
function getPoolSnapshotsWithCursor(poolId: string, endCursor: string | null, from?: Date, to?: Date) {
Expand Down
Loading