diff --git a/centrifuge-app/.env-config/.env.production b/centrifuge-app/.env-config/.env.production index 3151c4aa12..3c6cdaafb0 100644 --- a/centrifuge-app/.env-config/.env.production +++ b/centrifuge-app/.env-config/.env.production @@ -9,7 +9,7 @@ REACT_APP_ONBOARDING_API_URL=https://europe-central2-centrifuge-production-x.clo REACT_APP_PINNING_API_URL=https://europe-central2-centrifuge-production-x.cloudfunctions.net/pinning-api-production REACT_APP_POOL_CREATION_TYPE=propose REACT_APP_RELAY_WSS_URL=wss://rpc.polkadot.io -REACT_APP_SUBQUERY_URL=https://api.subquery.network/sq/centrifuge/pools-centrifuge +REACT_APP_SUBQUERY_URL=https://api.subquery.network/sq/centrifuge/pools REACT_APP_SUBSCAN_URL=https://centrifuge.subscan.io REACT_APP_TINLAKE_NETWORK=mainnet REACT_APP_INFURA_KEY=bf808e7d3d924fbeb74672d9341d0550 diff --git a/centrifuge-app/src/assets/images/currency-dollar.svg b/centrifuge-app/src/assets/images/currency-dollar.svg new file mode 100644 index 0000000000..cbee5b983c --- /dev/null +++ b/centrifuge-app/src/assets/images/currency-dollar.svg @@ -0,0 +1,3 @@ + + + diff --git a/centrifuge-app/src/components/DataTable.tsx b/centrifuge-app/src/components/DataTable.tsx index 622a60e341..e3a91d63cd 100644 --- a/centrifuge-app/src/components/DataTable.tsx +++ b/centrifuge-app/src/components/DataTable.tsx @@ -30,12 +30,19 @@ type GroupedProps = { export type DataTableProps = { data: Array + /** + * pinnedData is not included in sorting and will be pinned to the top of the table in the order provided + * */ + pinnedData?: Array columns: Column[] keyField?: string onRowClicked?: (row: T) => string | LinkProps['to'] defaultSortKey?: string defaultSortOrder?: OrderBy hoverable?: boolean + /** + * summary row is not included in sorting + */ summary?: T pageSize?: number page?: number @@ -88,6 +95,7 @@ const sorter = >(data: Array, order: OrderBy, s export const DataTable = >({ data, + pinnedData, columns, keyField, onRowClicked, @@ -140,6 +148,21 @@ export const DataTable = >({ ))} )} + {pinnedData?.map((row, i) => ( + onRowClicked(row))} + key={keyField ? row[keyField] : i} + tabIndex={onRowClicked ? 0 : undefined} + > + {columns.map((col, index) => ( + + {col.cell(row, i)} + + ))} + + ))} {sortedAndPaginatedData?.map((row, i) => ( = ({ loan }) => { : null const isExternalAssetRepaid = currentFace?.isZero() && loan.status === 'Active' + const isCashAsset = 'valuationMethod' in loan.pricing && loan.pricing?.valuationMethod === 'cash' const [status, text] = getLoanLabelStatus(loan, isExternalAssetRepaid) + if (!status || isCashAsset) return null return {text} } diff --git a/centrifuge-app/src/components/LoanList.tsx b/centrifuge-app/src/components/LoanList.tsx index b20fd7ed64..2f34b4e80f 100644 --- a/centrifuge-app/src/components/LoanList.tsx +++ b/centrifuge-app/src/components/LoanList.tsx @@ -1,4 +1,4 @@ -import { Loan, TinlakeLoan } from '@centrifuge/centrifuge-js' +import { CurrencyBalance, Loan, Rate, TinlakeLoan } from '@centrifuge/centrifuge-js' import { Box, IconChevronRight, @@ -11,8 +11,11 @@ import { Thumbnail, usePagination, } from '@centrifuge/fabric' +import get from 'lodash/get' import * as React from 'react' import { useParams, useRouteMatch } from 'react-router' +import currencyDollar from '../assets/images/currency-dollar.svg' +import usdcLogo from '../assets/images/usdc-logo.svg' import { formatNftAttribute } from '../pages/Loan/utils' import { nftMetadataSchema } from '../schemas' import { LoanTemplate, LoanTemplateAttribute } from '../types' @@ -27,10 +30,13 @@ import { Column, DataTable, FilterableTableHeader, SortableTableHeader } from '. import { LoadBoundary } from './LoadBoundary' import LoanLabel, { getLoanLabelStatus } from './LoanLabel' import { prefetchRoute } from './Root' +import { Tooltips } from './Tooltips' type Row = (Loan | TinlakeLoan) & { idSortKey: number originationDateSortKey: string + maturityDate: string | null + status: 'Created' | 'Active' | 'Closed' | '' } type Props = { @@ -64,10 +70,25 @@ export function LoanList({ loans }: Props) { const templateIds = poolMetadata?.loanTemplates?.map((s) => s.id) ?? [] const templateId = templateIds.at(-1) const { data: templateMetadata } = useMetadata(templateId) - const loansWithLabelStatus = loans.map((loan) => ({ - ...loan, - labelStatus: getLoanStatus(loan), - })) + const loansWithLabelStatus = React.useMemo(() => { + return loans + .map((loan) => ({ + ...loan, + labelStatus: getLoanStatus(loan), + })) + .sort((a, b) => { + const aValuation = get(a, 'pricing.valuationMethod') + const bValuation = get(b, 'pricing.valuationMethod') + const aId = get(a, 'id') as string + const bId = get(b, 'id') as string + + if (aValuation === 'cash' && bValuation !== 'cash') return -1 + if (aValuation !== 'cash' && bValuation === 'cash') return 1 + if (aValuation === 'cash' && bValuation === 'cash') return aId.localeCompare(bId) + + return aId.localeCompare(bId) + }) + }, [loans]) const filters = useFilters({ data: loansWithLabelStatus, }) @@ -113,7 +134,7 @@ export function LoanList({ loans }: Props) { return l.originationDate && (l.poolId.startsWith('0x') || l.status === 'Active') ? // @ts-expect-error formatDate(l.originationDate) - : '' + : '-' }, sortKey: 'originationDateSortKey', }, @@ -121,7 +142,7 @@ export function LoanList({ loans }: Props) { { align: 'left', header: , - cell: (l: Row) => (l.pricing.maturityDate ? formatDate(l.pricing.maturityDate) : ''), + cell: (l: Row) => (l?.maturityDate ? formatDate(l.maturityDate) : '-'), sortKey: 'maturityDate', }, { @@ -144,7 +165,7 @@ export function LoanList({ loans }: Props) { }, { header: '', - cell: () => , + cell: (l: Row) => (l.status ? : ''), width: '52px', }, ].filter(Boolean) as Column[] @@ -161,10 +182,33 @@ export function LoanList({ loans }: Props) { !loan?.totalBorrowed?.isZero() ? loan.originationDate : '', - maturityDate: loan.pricing.maturityDate, + maturityDate: + 'valuationMethod' in loan.pricing && loan.pricing.valuationMethod === 'cash' ? null : loan.pricing.maturityDate, ...loan, })) + const pinnedData: Row[] = [ + { + id: 'reserve', + // @ts-expect-error + status: '', + poolId: pool.id, + pricing: { + valuationMethod: 'discountedCashFlow', + maxBorrowAmount: 'upToTotalBorrowed', + value: CurrencyBalance.fromFloat(0, 18), + maturityDate: '', + maturityExtensionDays: 0, + advanceRate: Rate.fromFloat(0), + interestRate: Rate.fromFloat(0), + }, + asset: { collectionId: '', nftId: '' }, + totalBorrowed: CurrencyBalance.fromFloat(0, 18), + totalRepaid: CurrencyBalance.fromFloat(0, 18), + outstandingDebt: CurrencyBalance.fromFloat(0, 18), + }, + ] + const pagination = usePagination({ data: rows, pageSize: 20 }) return ( @@ -175,9 +219,11 @@ export function LoanList({ loans }: Props) { `${basePath}/${poolId}/assets/${row.id}`} + onRowClicked={(row) => + row.status ? `${basePath}/${poolId}/assets/${row.id}` : `${basePath}/${poolId}/assets` + } pageSize={20} page={pagination.page} /> @@ -216,14 +262,49 @@ export function AssetName({ loan }: { loan: Pick const isTinlakePool = loan.poolId.startsWith('0x') const nft = useCentNFT(loan.asset.collectionId, loan.asset.nftId, false, isTinlakePool) const { data: metadata, isLoading } = useMetadata(nft?.metadataUri, nftMetadataSchema) + if (loan.id === 'reserve') { + return ( + + + + + + Onchain reserve} /> + + + ) + } + + if (loan.status === 'Active' && 'valuationMethod' in loan.pricing && loan.pricing.valuationMethod === 'cash') { + return ( + + + + + + Bank account} /> + + + ) + } + return ( - + {metadata?.name} @@ -261,6 +342,10 @@ function Amount({ loan }: { loan: Row }) { return formatBalance(l.outstandingDebt, pool?.currency.symbol) + // @ts-expect-error + case '': + return formatBalance(pool.reserve.total, pool?.currency.symbol) + default: return '' } diff --git a/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx b/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx index ad57d28fcc..b44e886c39 100644 --- a/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx +++ b/centrifuge-app/src/components/Portfolio/TransactionTypeChip.tsx @@ -1,10 +1,10 @@ -import { BorrowerTransactionType, InvestorTransactionType } from '@centrifuge/centrifuge-js' +import { AssetTransactionType, InvestorTransactionType } from '@centrifuge/centrifuge-js' import { StatusChip } from '@centrifuge/fabric' import * as React from 'react' import { formatTransactionsType } from '../Report/utils' type TransactionTypeProps = { - type: InvestorTransactionType | BorrowerTransactionType + type: InvestorTransactionType | AssetTransactionType trancheTokenSymbol: string poolCurrencySymbol: string currencyAmount: number | null diff --git a/centrifuge-app/src/components/Portfolio/Transactions.tsx b/centrifuge-app/src/components/Portfolio/Transactions.tsx index cb790ba3ef..e5dc3170be 100644 --- a/centrifuge-app/src/components/Portfolio/Transactions.tsx +++ b/centrifuge-app/src/components/Portfolio/Transactions.tsx @@ -1,4 +1,4 @@ -import { BorrowerTransactionType, InvestorTransactionType, Pool, Token, TokenBalance } from '@centrifuge/centrifuge-js' +import { AssetTransactionType, InvestorTransactionType, Pool, Token, TokenBalance } from '@centrifuge/centrifuge-js' import { formatBalance } from '@centrifuge/centrifuge-react' import { AnchorButton, @@ -30,7 +30,7 @@ type TransactionsProps = { } type Row = { - action: InvestorTransactionType | BorrowerTransactionType + action: InvestorTransactionType | AssetTransactionType date: number tranche?: Token tranchePrice: string diff --git a/centrifuge-app/src/components/Report/AssetTransactions.tsx b/centrifuge-app/src/components/Report/AssetTransactions.tsx index 8f1c9565fc..83cc9a11e9 100644 --- a/centrifuge-app/src/components/Report/AssetTransactions.tsx +++ b/centrifuge-app/src/components/Report/AssetTransactions.tsx @@ -26,7 +26,7 @@ export function AssetTransactions({ pool }: { pool: Pool }) { return transactions?.map((tx) => ({ name: '', value: [ - tx.loanId.split('-').at(-1)!, + tx.assetId.split('-').at(-1)!, tx.epochId.split('-').at(-1)!, formatDate(tx.timestamp.toString()), formatAssetTransactionType(tx.type), diff --git a/centrifuge-app/src/components/Report/utils.tsx b/centrifuge-app/src/components/Report/utils.tsx index 8ccefab7ff..637bf067e7 100644 --- a/centrifuge-app/src/components/Report/utils.tsx +++ b/centrifuge-app/src/components/Report/utils.tsx @@ -1,4 +1,4 @@ -import { BorrowerTransactionType, InvestorTransactionType } from '@centrifuge/centrifuge-js/dist/types/subquery' +import { AssetTransactionType, InvestorTransactionType } from '@centrifuge/centrifuge-js/dist/types/subquery' import { Text } from '@centrifuge/fabric' import { copyToClipboard } from '../../utils/copyToClipboard' import { truncate } from '../../utils/web3' @@ -48,7 +48,7 @@ export function formatInvestorTransactionsType({ } const assetTransactionTypes: { - [key in BorrowerTransactionType]: string + [key in AssetTransactionType]: string } = { CREATED: 'Created', PRICED: 'Priced', @@ -57,9 +57,9 @@ const assetTransactionTypes: { CLOSED: 'Closed', } -export function formatAssetTransactionType(type: BorrowerTransactionType) { +export function formatAssetTransactionType(type: AssetTransactionType) { if (!assetTransactionTypes[type]) { - console.warn(`Type '${type}' is not assignable to type 'BorrowerTransactionType'`) + console.warn(`Type '${type}' is not assignable to type 'AssetTransactionType'`) return type } @@ -72,7 +72,7 @@ export function formatTransactionsType({ poolCurrencySymbol, currencyAmount, }: { - type: InvestorTransactionType | BorrowerTransactionType + type: InvestorTransactionType | AssetTransactionType trancheTokenSymbol: string poolCurrencySymbol: string currencyAmount: number | null @@ -89,7 +89,7 @@ export function formatTransactionsType({ }) } -function isAssetType(type: InvestorTransactionType | BorrowerTransactionType): type is BorrowerTransactionType { +function isAssetType(type: InvestorTransactionType | AssetTransactionType): type is AssetTransactionType { return ['CREATED', 'PRICED', 'BORROWED', 'REPAID', 'CLOSED'].includes(type) } diff --git a/centrifuge-app/src/components/Tooltips.tsx b/centrifuge-app/src/components/Tooltips.tsx index 85ad95729e..654eb2593a 100644 --- a/centrifuge-app/src/components/Tooltips.tsx +++ b/centrifuge-app/src/components/Tooltips.tsx @@ -262,6 +262,18 @@ export const tooltipText = { label: 'Pool type', body: 'An open pool can have multiple unrelated token holders and can onboard third party investors. A closed pool has very limited distributions and is not available for investment on the app.', }, + totalNav: { + label: "Total NAV", + body: "The total Net Asset Value (NAV) reflects the combined present value of assets, cash held in the onchain reserve of the pool, and cash in the bank account designated as offchain cash." + } , + onchainReserve: { + label: "Onchain reserve", + body: "The onchain reserve represents the amount of available liquidity in the pool available for asset originations and redemptions." + }, + offchainCash: { + label: "Offchain cash", + body: "Offchain cash represents funds held in a traditional bank account or custody account." + } } export type TooltipsProps = { diff --git a/centrifuge-app/src/pages/Loan/HoldingsValues.tsx b/centrifuge-app/src/pages/Loan/HoldingsValues.tsx index 2c46e9680b..3b1234e80b 100644 --- a/centrifuge-app/src/pages/Loan/HoldingsValues.tsx +++ b/centrifuge-app/src/pages/Loan/HoldingsValues.tsx @@ -1,4 +1,4 @@ -import { BorrowerTransaction, CurrencyBalance, ExternalPricingInfo, Pool } from '@centrifuge/centrifuge-js' +import { AssetTransaction, CurrencyBalance, ExternalPricingInfo, Pool } from '@centrifuge/centrifuge-js' import Decimal from 'decimal.js-light' import { LabelValueStack } from '../../components/LabelValueStack' import { Dec } from '../../utils/Decimal' @@ -6,7 +6,7 @@ import { formatBalance } from '../../utils/formatting' type Props = { pool: Pool - transactions?: BorrowerTransaction[] | null + transactions?: AssetTransaction[] | null currentFace: Decimal | null pricing: ExternalPricingInfo } diff --git a/centrifuge-app/src/pages/Loan/PricingValues.tsx b/centrifuge-app/src/pages/Loan/PricingValues.tsx index 003545f37e..2f6ad66c56 100644 --- a/centrifuge-app/src/pages/Loan/PricingValues.tsx +++ b/centrifuge-app/src/pages/Loan/PricingValues.tsx @@ -33,7 +33,7 @@ export function PricingValues({ loan, pool }: Props) { const days = getAge(new Date(latestOraclePrice.timestamp).toISOString()) const borrowerAssetTransactions = assetTransactions?.filter( - (borrowerTransaction) => borrowerTransaction.loanId === `${loan.poolId}-${loan.id}` + (assetTransaction) => assetTransaction.loanId === `${loan.poolId}-${loan.id}` ) const latestPrice = getLatestPrice(latestOraclePrice.value, borrowerAssetTransactions, pool.currency.decimals) diff --git a/centrifuge-app/src/pages/Loan/TransactionTable.tsx b/centrifuge-app/src/pages/Loan/TransactionTable.tsx index a3a7e59d4f..0c6f7c0aa1 100644 --- a/centrifuge-app/src/pages/Loan/TransactionTable.tsx +++ b/centrifuge-app/src/pages/Loan/TransactionTable.tsx @@ -1,5 +1,5 @@ -import { BorrowerTransaction, CurrencyBalance, ExternalPricingInfo, PricingInfo } from '@centrifuge/centrifuge-js' -import { BorrowerTransactionType } from '@centrifuge/centrifuge-js/dist/types/subquery' +import { AssetTransaction, CurrencyBalance, ExternalPricingInfo, PricingInfo } from '@centrifuge/centrifuge-js' +import { AssetTransactionType } from '@centrifuge/centrifuge-js/dist/types/subquery' import { StatusChip, Tooltip } from '@centrifuge/fabric' import BN from 'bn.js' import { useMemo } from 'react' @@ -9,7 +9,7 @@ import { Dec } from '../../utils/Decimal' import { formatBalance } from '../../utils/formatting' type Props = { - transactions: BorrowerTransaction[] + transactions: AssetTransaction[] currency: string decimals: number loanType: 'external' | 'internal' @@ -76,13 +76,13 @@ export const TransactionTable = ({ transactions, currency, loanType, decimals, p })) }, [transactions, decimals, pricing]) - const getStatusChipType = (type: BorrowerTransactionType) => { + const getStatusChipType = (type: AssetTransactionType) => { if (type === 'BORROWED' || type === 'CREATED' || type === 'PRICED') return 'info' if (type === 'REPAID') return 'ok' return 'default' } - const getStatusText = (type: BorrowerTransactionType) => { + const getStatusText = (type: AssetTransactionType) => { if (loanType === 'external' && type === 'BORROWED') return 'Purchase' if (loanType === 'external' && type === 'REPAID') return 'Sale' @@ -99,7 +99,7 @@ export const TransactionTable = ({ transactions, currency, loanType, decimals, p { align: 'left', header: 'Type', - cell: (row: { type: BorrowerTransactionType }) => ( + cell: (row: { type: AssetTransactionType }) => ( {getStatusText(row.type)} ), }, diff --git a/centrifuge-app/src/pages/Loan/index.tsx b/centrifuge-app/src/pages/Loan/index.tsx index e92fc4adcc..fafe42b2a7 100644 --- a/centrifuge-app/src/pages/Loan/index.tsx +++ b/centrifuge-app/src/pages/Loan/index.tsx @@ -173,7 +173,9 @@ function Loan() { : nftMetadata?.properties[key], })) || [] : []), - ...(loan.pricing.maturityDate + ...(loan.pricing.maturityDate && + 'valuationMethod' in loan.pricing && + loan.pricing.valuationMethod !== 'cash' ? [ { label: 'Maturity date', diff --git a/centrifuge-app/src/pages/Pool/Assets/index.tsx b/centrifuge-app/src/pages/Pool/Assets/index.tsx index 3892d71cb3..5133cee25c 100644 --- a/centrifuge-app/src/pages/Pool/Assets/index.tsx +++ b/centrifuge-app/src/pages/Pool/Assets/index.tsx @@ -1,7 +1,9 @@ -import { ActiveLoan } from '@centrifuge/centrifuge-js' +import { ActiveLoan, Loan } from '@centrifuge/centrifuge-js' import { Box, Shelf, Text } from '@centrifuge/fabric' import * as React from 'react' import { useParams } from 'react-router' +import currencyDollar from '../../../assets/images/currency-dollar.svg' +import usdcLogo from '../../../assets/images/usdc-logo.svg' import { LayoutBase } from '../../../components/LayoutBase' import { LoadBoundary } from '../../../components/LoadBoundary' import { LoanList } from '../../../components/LoanList' @@ -13,7 +15,7 @@ import { Dec } from '../../../utils/Decimal' import { formatBalance } from '../../../utils/formatting' import { useLoans } from '../../../utils/useLoans' import { useSuitableAccounts } from '../../../utils/usePermissions' -import { useAverageAmount, usePool } from '../../../utils/usePools' +import { usePool } from '../../../utils/usePools' import { PoolDetailHeader } from '../Header' export function PoolDetailAssetsTab() { @@ -31,7 +33,7 @@ export function PoolDetailAssets() { const { pid: poolId } = useParams<{ pid: string }>() const pool = usePool(poolId) const loans = useLoans(poolId) - const averageAmount = useAverageAmount(poolId) + const isTinlakePool = poolId.startsWith('0x') if (!pool) return null @@ -47,26 +49,52 @@ export function PoolDetailAssets() { const ongoingAssets = (loans && [...loans].filter((loan) => loan.status === 'Active' && !loan.outstandingDebt.isZero())) as ActiveLoan[] - const isExternal = 'valuationMethod' in loans[0].pricing && loans[0].pricing.valuationMethod === 'oracle' - - const avgAmount = isExternal - ? averageAmount - : ongoingAssets - .reduce((curr, prev) => curr.add(prev.outstandingDebt.toDecimal() || Dec(0)), Dec(0)) - .dividedBy(ongoingAssets.length) - .toDecimalPlaces(2) + const offchainAssets = !isTinlakePool + ? loans.filter((loan) => (loan as Loan).pricing.valuationMethod === 'cash') + : null + const offchainReserve = offchainAssets?.reduce( + (curr, prev) => curr.add(prev.status === 'Active' ? prev.outstandingDebt.toDecimal() : Dec(0)), + Dec(0) + ) - const assetValue = formatBalance(pool.nav.latest.toDecimal().toNumber(), pool.currency.symbol) + const overdueAssets = loans.filter( + (loan) => + loan.status === 'Active' && + loan.outstandingDebt.gtn(0) && + new Date(loan.pricing.maturityDate).getTime() < Date.now() + ) const pageSummaryData: { label: React.ReactNode; value: React.ReactNode }[] = [ { - label: , - value: assetValue, + label: , + value: formatBalance(pool.nav.latest.toDecimal(), pool.currency.symbol), + }, + { + label: ( + + + + + ), + value: formatBalance(pool.reserve.total || 0, pool.currency.symbol), + }, + { + label: ( + + + + + ), + value: formatBalance(offchainReserve, 'USD'), + }, + { + label: 'Total assets', + value: loans.length, }, { label: , value: ongoingAssets.length || 0 }, { - label: , - value: formatBalance(avgAmount, pool.currency.symbol), + label: 'Overdue assets', + value: 0 ? 'statusCritical' : 'inherit'}>{overdueAssets.length}, }, ] diff --git a/centrifuge-app/src/utils/getLatestPrice.ts b/centrifuge-app/src/utils/getLatestPrice.ts index 8fc2aa54cf..dbb102c8f1 100644 --- a/centrifuge-app/src/utils/getLatestPrice.ts +++ b/centrifuge-app/src/utils/getLatestPrice.ts @@ -1,8 +1,8 @@ -import { BorrowerTransaction, CurrencyBalance } from '@centrifuge/centrifuge-js' +import { AssetTransaction, CurrencyBalance } from '@centrifuge/centrifuge-js' export const getLatestPrice = ( oracleValue: CurrencyBalance, - borrowerAssetTransactions: BorrowerTransaction[] | undefined, + borrowerAssetTransactions: AssetTransaction[] | undefined, decimals: number ) => { if (!borrowerAssetTransactions) return null diff --git a/centrifuge-app/src/utils/usePools.ts b/centrifuge-app/src/utils/usePools.ts index 433ea1a856..bf3ac7e756 100644 --- a/centrifuge-app/src/utils/usePools.ts +++ b/centrifuge-app/src/utils/usePools.ts @@ -1,4 +1,4 @@ -import Centrifuge, { addressToHex, BorrowerTransaction, Loan, Pool, PoolMetadata } from '@centrifuge/centrifuge-js' +import Centrifuge, { addressToHex, AssetTransaction, Loan, Pool, PoolMetadata } from '@centrifuge/centrifuge-js' import { useCentrifugeApi, useCentrifugeConsts, useCentrifugeQuery, useWallet } from '@centrifuge/centrifuge-react' import BN from 'bn.js' import { useEffect, useMemo } from 'react' @@ -83,7 +83,7 @@ export function useInvestorTransactions(poolId: string, trancheId?: string, from export function useAssetTransactions(poolId: string, from?: Date, to?: Date) { const [result] = useCentrifugeQuery( ['assetTransactions', poolId, from, to], - (cent) => cent.pools.getBorrowerTransactions([poolId, from, to]), + (cent) => cent.pools.getAssetTransactions([poolId, from, to]), { enabled: !poolId.startsWith('0x'), } @@ -113,11 +113,11 @@ export function useBorrowerAssetTransactions(poolId: string, assetId: string, fr const [result] = useCentrifugeQuery( ['borrowerAssetTransactions', poolId, assetId, from, to], (cent) => { - const borrowerTransactions = cent.pools.getBorrowerTransactions([poolId, from, to]) + const assetTransactions = cent.pools.getAssetTransactions([poolId, from, to]) - return borrowerTransactions.pipe( - map((transactions: BorrowerTransaction[]) => - transactions.filter((transaction) => transaction.loanId.split('-')[1] === assetId) + return assetTransactions.pipe( + map((transactions: AssetTransaction[]) => + transactions.filter((transaction) => transaction.assetId.split('-')[1] === assetId) ) ) }, diff --git a/centrifuge-js/src/modules/pools.ts b/centrifuge-js/src/modules/pools.ts index 670804e728..438f09da05 100644 --- a/centrifuge-js/src/modules/pools.ts +++ b/centrifuge-js/src/modules/pools.ts @@ -10,14 +10,14 @@ import { SolverResult, calculateOptimalSolution } from '..' import { Centrifuge } from '../Centrifuge' import { Account, TransactionOptions } from '../types' import { - BorrowerTransactionType, - InvestorTransactionType, - SubqueryBorrowerTransaction, - SubqueryCurrencyBalances, - SubqueryInvestorTransaction, - SubqueryPoolSnapshot, - SubqueryTrancheBalances, - SubqueryTrancheSnapshot, + AssetTransactionType, + InvestorTransactionType, + SubqueryAssetTransaction, + SubqueryCurrencyBalances, + SubqueryInvestorTransaction, + SubqueryPoolSnapshot, + SubqueryTrancheBalances, + SubqueryTrancheSnapshot, } from '../types/subquery' import { addressToHex, @@ -743,14 +743,14 @@ type InvestorTransaction = { evmAddress?: string } -export type BorrowerTransaction = { +export type AssetTransaction = { id: string timestamp: string poolId: string accountId: string epochId: string loanId: string - type: BorrowerTransactionType + type: AssetTransactionType amount: CurrencyBalance | undefined settlementPrice: string | null quantity: string | null @@ -2663,21 +2663,21 @@ export function getPoolsModule(inst: Centrifuge) { ) } - function getBorrowerTransactions(args: [poolId: string, from?: Date, to?: Date]) { + function getAssetTransactions(args: [poolId: string, from?: Date, to?: Date]) { const [poolId, from, to] = args const $query = inst.getSubqueryObservable<{ - borrowerTransactions: { nodes: SubqueryBorrowerTransaction[] } + assetTransactions: { nodes: SubqueryAssetTransaction[] } }>( `query($poolId: String!, $from: Datetime!, $to: Datetime!) { - borrowerTransactions( + assetTransactions( orderBy: TIMESTAMP_ASC, filter: { poolId: { equalTo: $poolId }, timestamp: { greaterThan: $from, lessThan: $to }, }) { nodes { - loanId + assetId epochId type timestamp @@ -2699,11 +2699,11 @@ export function getPoolsModule(inst: Centrifuge) { return $query.pipe( switchMap(() => combineLatest([$query, getPoolCurrency([poolId])])), map(([data, currency]) => { - return data!.borrowerTransactions.nodes.map((tx) => ({ + return data!.assetTransactions.nodes.map((tx) => ({ ...tx, amount: tx.amount ? new CurrencyBalance(tx.amount, currency.decimals) : undefined, timestamp: new Date(`${tx.timestamp}+00:00`), - })) as unknown as BorrowerTransaction[] + })) as unknown as AssetTransaction[] }) ) } @@ -3720,7 +3720,7 @@ export function getPoolsModule(inst: Centrifuge) { getDailyPoolStates, getMonthlyPoolStates, getInvestorTransactions, - getBorrowerTransactions, + getAssetTransactions, getNativeCurrency, getCurrencies, getDailyTrancheStates, diff --git a/centrifuge-js/src/types/subquery.ts b/centrifuge-js/src/types/subquery.ts index 9bdb29437e..4cc7707737 100644 --- a/centrifuge-js/src/types/subquery.ts +++ b/centrifuge-js/src/types/subquery.ts @@ -74,17 +74,17 @@ export type SubqueryInvestorTransaction = { transactionFee?: number | null } -export type BorrowerTransactionType = 'CREATED' | 'PRICED' | 'BORROWED' | 'REPAID' | 'CLOSED' +export type AssetTransactionType = 'CREATED' | 'PRICED' | 'BORROWED' | 'REPAID' | 'CLOSED' -export type SubqueryBorrowerTransaction = { - __typename?: 'BorrowerTransaction' +export type SubqueryAssetTransaction = { + __typename?: 'AssetTransaction' id: string timestamp: string poolId: string accountId: string epochId: string - loanId: string - type: BorrowerTransactionType + assetId: string + type: AssetTransactionType amount?: number | null settlementPrice: string | null quantity: string | null diff --git a/fabric/src/components/Thumbnail/index.tsx b/fabric/src/components/Thumbnail/index.tsx index eda0060078..34ebed6a8f 100644 --- a/fabric/src/components/Thumbnail/index.tsx +++ b/fabric/src/components/Thumbnail/index.tsx @@ -54,8 +54,8 @@ const StyledThumbnail = styled(Text)>` background: 'transparent', '&::before': { content: '""', - width: '80%', - height: '80%', + width: '50%', + height: '50%', position: 'absolute', left: 0, top: 0, @@ -64,9 +64,9 @@ const StyledThumbnail = styled(Text)>` margin: 'auto', zIndex: 0, transform: 'rotate(45deg)', - background: theme.colors.backgroundThumbnail, + background: theme.colors.statusInfo, color: theme.colors.textInverted, - borderRadius: '4px', + borderRadius: '2px', }, }) case 'token': diff --git a/package.json b/package.json index 518808112d..ff369b2f70 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "esbuild": "^0.16.17", "esbuild-node-externals": "^1.6.0", "husky": "^6.0.0", - "prettier": "^2.3.1", - "prettier-plugin-organize-imports": "1.1.1", + "prettier": "^2.4.1", + "prettier-plugin-organize-imports": "3.2.4", "pretty-quick": "^3.1.1", "ts-node": "9.0.0", "typescript": "~5.3.3" diff --git a/yarn.lock b/yarn.lock index c345e2b867..bc7439e0de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22489,17 +22489,24 @@ fsevents@~2.3.3: languageName: node linkType: hard -"prettier-plugin-organize-imports@npm:1.1.1": - version: 1.1.1 - resolution: "prettier-plugin-organize-imports@npm:1.1.1" +"prettier-plugin-organize-imports@npm:3.2.4": + version: 3.2.4 + resolution: "prettier-plugin-organize-imports@npm:3.2.4" peerDependencies: - prettier: ">=1.10" - typescript: ">=2.8.2" - checksum: 030b9534ad40741643ca5747ddf85290c68f67b5b96a4c389670d2ac8b39c09df24f7aa821a2f5d5c4a95a99dd699276082bae5b4aeea7817d1e3596434dad10 + "@volar/vue-language-plugin-pug": ^1.0.4 + "@volar/vue-typescript": ^1.0.4 + prettier: ">=2.0" + typescript: ">=2.9" + peerDependenciesMeta: + "@volar/vue-language-plugin-pug": + optional: true + "@volar/vue-typescript": + optional: true + checksum: 57ae97d7e403445e650ae92b7da586761d1d88a47e46b3ea274baeb96782165bebd0132db9c652081e185c41b50701ba1d30d615ad1c9000300cc0c67eb12b7a languageName: node linkType: hard -"prettier@npm:^2.1.2, prettier@npm:^2.3.1, prettier@npm:^2.4.1, prettier@npm:^2.8.0": +"prettier@npm:^2.1.2, prettier@npm:^2.4.1, prettier@npm:^2.8.0": version: 2.8.8 resolution: "prettier@npm:2.8.8" bin: @@ -23916,8 +23923,8 @@ fsevents@~2.3.3: esbuild: ^0.16.17 esbuild-node-externals: ^1.6.0 husky: ^6.0.0 - prettier: ^2.3.1 - prettier-plugin-organize-imports: 1.1.1 + prettier: ^2.4.1 + prettier-plugin-organize-imports: 3.2.4 pretty-quick: ^3.1.1 rxjs: ^7.8.0 ts-node: 9.0.0