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

Asset finance repay redesign #2282

Merged
merged 110 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
1b0e774
Move transfer debt form so it's showed after the user chooses a source
sophialittlejohn Jul 11, 2024
593b391
Add SourceSelect to repay forms
sophialittlejohn Jul 11, 2024
e76d001
Fix decimals
sophialittlejohn Jul 12, 2024
d844635
Add fee charging to finance forms (WIP)
sophialittlejohn Jul 12, 2024
fef1b07
Add remark txs
sophialittlejohn Jul 12, 2024
3c36d86
Update Repay forms and add fees to repay
sophialittlejohn Jul 15, 2024
096af14
Fix usabilty of fee select
sophialittlejohn Jul 15, 2024
62b8e6b
Fix tx execution
sophialittlejohn Jul 16, 2024
cdb7b5f
Update charge fee UI
sophialittlejohn Jul 17, 2024
83d1109
Limit fee charging to borrower (fee must be added with borrower as de…
sophialittlejohn Jul 17, 2024
df34f85
Add comment about fees
sophialittlejohn Jul 17, 2024
454c08c
Split up finance and repay drawers & UI improvements
sophialittlejohn Jul 18, 2024
e20e04d
Move available financing to loan page
sophialittlejohn Jul 18, 2024
8d3e6be
Add total amount and rename amount to principal in forms
sophialittlejohn Jul 18, 2024
7923fc9
Deploy PR preview to demo
sophialittlejohn Jul 18, 2024
91e1e5f
Purchase/Finance vs Sell/Repay and add totals
sophialittlejohn Jul 19, 2024
88e2b9c
Pass fee tx to remark tx to be executed there
sophialittlejohn Jul 19, 2024
1e53c75
Implement transfer debt directly in finance form
sophialittlejohn Jul 19, 2024
e012a3e
Allow multiple fees and check validity of inputs
sophialittlejohn Jul 22, 2024
0a642e6
Disable buttons while form is incomplete
sophialittlejohn Jul 22, 2024
dace43f
Better form validation for external assets
sophialittlejohn Jul 22, 2024
fed8491
Finish adding transfer debt to all finance/repay forms
sophialittlejohn Jul 22, 2024
b11e694
Fix mac price variants from failing on non oracle assets
sophialittlejohn Jul 22, 2024
afc110b
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Jul 22, 2024
6b2fd62
Fix inconsistencies
sophialittlejohn Jul 22, 2024
ceed6ec
Transfer debt source/desitnation only show cash assets
sophialittlejohn Jul 23, 2024
4e8369e
UI changes proposed by Jeroen
sophialittlejohn Jul 23, 2024
52bde42
Unify finance/repay and transfer debt forms
sophialittlejohn Jul 23, 2024
2833e73
Fix default behavior of add fee
sophialittlejohn Jul 23, 2024
5373183
Add text blurbs
sophialittlejohn Jul 23, 2024
64cba91
Add charge fee summary
sophialittlejohn Jul 23, 2024
0b7abb4
Remove padding on add fees button
sophialittlejohn Jul 23, 2024
585fc87
Handle input/erros in repay form
sophialittlejohn Jul 24, 2024
dfb33a1
Update info texts in all forms
sophialittlejohn Jul 24, 2024
c648cab
Add error handling and better form control
sophialittlejohn Jul 24, 2024
28d27af
Fix bug in available external finance form
sophialittlejohn Jul 24, 2024
0b26f90
Updates to inline feedback component
sophialittlejohn Jul 25, 2024
6e18da1
Fix fee tx submission
sophialittlejohn Jul 25, 2024
28a61fb
Validate upper limits in repay forms and fix required vs non required…
sophialittlejohn Jul 25, 2024
ffb9953
Rename
sophialittlejohn Jul 26, 2024
ff02385
Fix bugs in internal finance form
sophialittlejohn Jul 30, 2024
6528b7f
Check charged fees against max charageable
sophialittlejohn Jul 30, 2024
8dfaa11
Remove indiv error messages in favor of general ones on repay form
sophialittlejohn Jul 30, 2024
95333c6
Improve error handling in repay form
sophialittlejohn Jul 30, 2024
6ca0139
Fix wording
sophialittlejohn Jul 30, 2024
3091535
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Jul 30, 2024
5735a24
Fix warning
hieronx Jul 30, 2024
a42f18c
Remove repay all and allow repayments of just interest
sophialittlejohn Jul 31, 2024
66c3de7
Merge branch 'asset-finance-repay-redesign' of github.com:centrifuge/…
sophialittlejohn Jul 31, 2024
3aac9d1
Fix type error
sophialittlejohn Jul 31, 2024
c13b845
Rename external repay form to sell and use source loan max interest
sophialittlejohn Jul 31, 2024
f7a6b57
Rename external finance form to purchase
sophialittlejohn Jul 31, 2024
a54cf2b
Prep for cash finance/repayments
sophialittlejohn Jul 31, 2024
316e414
Add support for cash assets
sophialittlejohn Jul 31, 2024
40ac92a
Add cash asset suuport to repay
sophialittlejohn Jul 31, 2024
3ce899a
Clean up and fix form submissions
sophialittlejohn Jul 31, 2024
8fc9755
Fix template rendering
sophialittlejohn Jul 31, 2024
c1f3204
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Jul 31, 2024
0f951ef
Fix decimal point error and TransferDebtAmountMismatched error
sophialittlejohn Aug 1, 2024
07a6676
Allow fees to be charged by non AO proxy destinations
sophialittlejohn Aug 1, 2024
7ac2eeb
Cash: rename principal to amount and include withdrawal addresses
sophialittlejohn Aug 1, 2024
32f296d
Fix fee submission
sophialittlejohn Aug 1, 2024
f6569d7
Revert charging without AO and remove uncharge fees
sophialittlejohn Aug 1, 2024
f33889c
Attempt to fix proxy call on repay
sophialittlejohn Aug 1, 2024
511db30
Fix tx pushed mistake
sophialittlejohn Aug 1, 2024
db5e696
Wrap proxy calls and move remarks to module
sophialittlejohn Aug 1, 2024
c35aa69
Remove fee percentage from dropdown
sophialittlejohn Aug 2, 2024
e6a04bd
Fix showing finance form
sophialittlejohn Aug 2, 2024
8b80f27
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Aug 2, 2024
0b6d944
Always show repay forms so that money can be transfer even without ou…
sophialittlejohn Aug 2, 2024
654b9e0
Fix bug where initial input is missing in fee category
sophialittlejohn Aug 2, 2024
292c31b
Charge fee difference instead of uncharging/recharging
sophialittlejohn Aug 2, 2024
3fea8c4
Fix available in repay forms
sophialittlejohn Aug 5, 2024
fc5b2dd
Remove close all transaction
sophialittlejohn Aug 5, 2024
141d169
Use USD for all virtual accounting processes
sophialittlejohn Aug 5, 2024
9ba1db1
Fix null in extension period
sophialittlejohn Aug 5, 2024
8004bb8
Consitently use two commas in error messages
sophialittlejohn Aug 5, 2024
442f04e
Price and quantity updates (max, secondary labels), show buttons appr…
sophialittlejohn Aug 5, 2024
610e1cc
Add custom padding to drawer
sophialittlejohn Aug 5, 2024
6d253d7
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Aug 5, 2024
e99d59e
Remove maturity date in loan list
sophialittlejohn Aug 6, 2024
2482926
Remove decimals from quantity
sophialittlejohn Aug 6, 2024
9ca1adb
Reorder category options in repay
sophialittlejohn Aug 6, 2024
2ae2241
Remove financing date for cash assets
sophialittlejohn Aug 6, 2024
4dc136b
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Aug 6, 2024
58f6909
Merge branch 'main' into asset-finance-repay-redesign
hieronx Aug 7, 2024
9db66b8
Remove low wallet balance warning
sophialittlejohn Aug 7, 2024
d214fa7
Add interest rate in pricing values
sophialittlejohn Aug 7, 2024
39ba815
Add tooltip for additional amount input
sophialittlejohn Aug 7, 2024
eec0710
Better error messages
sophialittlejohn Aug 7, 2024
52c813f
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Aug 7, 2024
3acd30f
Merge branch 'asset-finance-repay-redesign' of github.com:centrifuge/…
sophialittlejohn Aug 7, 2024
b1dd5b2
Improve error messages and remove additional amount from max calcs
sophialittlejohn Aug 7, 2024
17fbc70
Fix repay forms and add errors for balance checking
sophialittlejohn Aug 7, 2024
00dc506
Merge branch 'main' of https://github.com/centrifuge/apps into asset-…
hieronx Aug 8, 2024
763a60c
Asset redesign fixes (#2353)
hieronx Aug 8, 2024
2708d04
Add changes for Jay and add disabled input for principal on external …
sophialittlejohn Aug 8, 2024
c9d9a7f
Add tooltips, improve spacing in summary and attempt to charge margin…
sophialittlejohn Aug 8, 2024
f3e02eb
Correct interest margin calc
sophialittlejohn Aug 9, 2024
12fb134
Merge branch 'main' of github.com:centrifuge/apps into asset-finance-…
sophialittlejohn Aug 9, 2024
368da6c
Use textencoder instead of Buffer, fix spacing in finance form summar…
sophialittlejohn Aug 9, 2024
b42647c
Fix margin buffer and when to use it
sophialittlejohn Aug 9, 2024
32f1b55
convert 5 minute buffer to seconds
sophialittlejohn Aug 9, 2024
499a414
Add reserve info box to finance forms
sophialittlejohn Aug 9, 2024
aab291d
Fix layout of external repay
sophialittlejohn Aug 9, 2024
3c41178
Add component for ErrorMessage
sophialittlejohn Aug 9, 2024
525332f
Add principal calc to external finance form
sophialittlejohn Aug 9, 2024
d4f6286
Add missing gap
sophialittlejohn Aug 9, 2024
bed9658
Merge branch 'main' into asset-finance-repay-redesign
hieronx Aug 12, 2024
ec4306a
Merge branch 'main' into asset-finance-repay-redesign
sophialittlejohn Aug 12, 2024
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
26 changes: 13 additions & 13 deletions centrifuge-app/.env-config/.env.development
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
REACT_APP_COLLATOR_WSS_URL=wss://fullnode.development.cntrfg.com
REACT_APP_DEFAULT_UNLIST_POOLS=false
REACT_APP_FAUCET_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/faucet-api-dev
REACT_APP_COLLATOR_WSS_URL=wss://fullnode-apps.demo.k-f.dev
REACT_APP_DEFAULT_UNLIST_POOLS=true
REACT_APP_FAUCET_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/faucet-api-demo
REACT_APP_IPFS_GATEWAY=https://centrifuge.mypinata.cloud/
REACT_APP_IS_DEMO=false
REACT_APP_NETWORK=centrifuge
REACT_APP_ONBOARDING_API_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/onboarding-api-dev
REACT_APP_PINNING_API_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/pinning-api-dev
REACT_APP_IS_DEMO=true
REACT_APP_ONBOARDING_API_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/onboarding-api-demo
REACT_APP_PINNING_API_URL=https://europe-central2-peak-vista-185616.cloudfunctions.net/pinning-api-demo
REACT_APP_POOL_CREATION_TYPE=immediate
REACT_APP_RELAY_WSS_URL=wss://fullnode-relay.development.cntrfg.com
REACT_APP_SUBQUERY_URL=https://api.subquery.network/sq/centrifuge/pools-development
REACT_APP_SUBSCAN_URL=https://centrifuge.subscan.io
REACT_APP_RELAY_WSS_URL=wss://frag-moonbase-relay-rpc-ws.g.moonbase.moonbeam.network
REACT_APP_SUBQUERY_URL=https://api.subquery.network/sq/centrifuge/pools-demo-multichain
REACT_APP_SUBSCAN_URL=
REACT_APP_TINLAKE_NETWORK=goerli
REACT_APP_INFURA_KEY=8cd8e043ee8d4001b97a1c37e08fd9dd
REACT_APP_ONFINALITY_KEY=0e1c049f-d876-4e77-a45f-b5afdf5739b2
REACT_APP_WHITELISTED_ACCOUNTS=
REACT_APP_TINLAKE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_clhi43ef5g4rw49zwftsvd2ks/subgraphs/main/prod/gn
REACT_APP_NETWORK=centrifuge
REACT_APP_REWARDS_TREE_URL=https://storage.googleapis.com/rad-rewards-trees-kovan-staging/latest.json
REACT_APP_MEMBERLIST_ADMIN_PURE_PROXY=kALwmJutBq95s41U9fWnoApCUgvPqPGTh1GSmFnQh5f9fWo93
REACT_APP_WALLETCONNECT_ID=c32fa79350803519804a67fcab0b742a
REACT_APP_MEMBERLIST_ADMIN_PURE_PROXY=kAJ27w29x7gHM75xajP2yXVLjVBaKmmUTxHwgRuCoAcWaoEiz
REACT_APP_TREASURY=kAJkmGxAd6iqX9JjWTdhXgCf2PL1TAphTRYrmEqzBrYhwbXAn
REACT_APP_TINLAKE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_clhi43ef5g4rw49zwftsvd2ks/subgraphs/main/prod/gn
REACT_APP_TREASURY=kAJkmGxAd6iqX9JjWTdhXgCf2PL1TAphTRYrmEqzBrYhwbXAn
10 changes: 8 additions & 2 deletions centrifuge-app/src/components/LoanList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ export function LoanList({ loans }: Props) {
header: <SortableTableHeader label="Financing date" />,
cell: (l: Row) => {
// @ts-expect-error value only exists on Tinlake loans and on active Centrifuge loans
return l.originationDate && (l.poolId.startsWith('0x') || l.status === 'Active')
return l.originationDate &&
(l.poolId.startsWith('0x') || l.status === 'Active') &&
'valuationMethod' in l.pricing &&
l.pricing.valuationMethod !== 'cash'
? // @ts-expect-error
formatDate(l.originationDate)
: '-'
Expand All @@ -132,7 +135,10 @@ export function LoanList({ loans }: Props) {
{
align: 'left',
header: <SortableTableHeader label="Maturity date" />,
cell: (l: Row) => (l?.maturityDate ? formatDate(l.maturityDate) : '-'),
cell: (l: Row) =>
l?.maturityDate && 'valuationMethod' in l.pricing && l.pricing.valuationMethod !== 'cash'
? formatDate(l.maturityDate)
: '-',
sortKey: 'maturityDate',
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const ChargeFeesDrawer = ({ onClose, isOpen }: ChargeFeesProps) => {
const feeIndex = params.get('charge')
const feeMetadata = feeIndex ? poolMetadata?.pool?.poolFees?.find((f) => f.id.toString() === feeIndex) : undefined
const feeChainData = feeIndex ? poolFees?.find((f) => f.id.toString() === feeIndex) : undefined
const maxCharge = feeChainData?.amounts.percentOfNav.toDecimal().mul(pool.nav.aum.toDecimal()).div(100)
const maxCharge = feeChainData?.amounts.percentOfNav.toDecimal().mul(pool.nav.aum.toDecimal())
const [updateCharge, setUpdateCharge] = React.useState(false)
const address = useAddress()
const isAllowedToCharge = feeChainData?.destination && addressToHex(feeChainData.destination) === address
Expand Down
1 change: 1 addition & 0 deletions centrifuge-app/src/components/PoolFees/EditFeesDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ export const EditFeesDrawer = ({ onClose, isOpen }: ChargeFeesProps) => {
receivingAddress: '',
feeId: undefined,
type: 'chargedUpTo',
category: feeCategories[0],
})
}
>
Expand Down
11 changes: 8 additions & 3 deletions centrifuge-app/src/components/Report/AssetList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Text } from '@centrifuge/fabric'
import { useContext, useEffect, useMemo } from 'react'
import { useBasePath } from '../../../src/utils/useBasePath'
import { formatDate } from '../../utils/date'
import { formatBalance } from '../../utils/formatting'
import { formatBalance, formatPercentage } from '../../utils/formatting'
import { getCSVDownloadUrl } from '../../utils/getCSVDownloadUrl'
import { useAllPoolAssetSnapshots, usePoolMetadata } from '../../utils/usePools'
import { DataTable, SortableTableHeader } from '../DataTable'
Expand Down Expand Up @@ -82,12 +82,17 @@ function getColumnConfig(isPrivate: boolean, symbol: string) {
formatter: (v: any) => (v ? formatDate(v) : 'Open-end'),
sortKey: 'maturity-date',
},
{ header: 'Valuation method', align: 'left', csvOnly: false, formatter: noop },
{
header: 'Valuation method',
align: 'left',
csvOnly: false,
formatter: (v: any) => (v === 'OutstandingDebt' ? 'At par' : v),
},
{
header: 'Advance rate',
align: 'left',
csvOnly: false,
formatter: (v: any) => (v ? formatBalance(v, symbol, 2) : '-'),
formatter: (v: any) => (v ? formatPercentage(v, true, {}, 2) : '-'),
},
{
header: 'Collateral value',
Expand Down
12 changes: 12 additions & 0 deletions centrifuge-app/src/components/Tooltips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,18 @@ export const tooltipText = {
label: 'Token price',
body: 'The token price is equal to the NAV divided by the outstanding supply of tokens.',
},
additionalAmountInput: {
label: 'Additional amount',
body: 'This can be used to repay an additional amount beyond the outstanding principal and interest of the asset. This will lead to an increase in the NAV of the pool.',
},
repayFormAvailableBalance: {
label: 'Available balance',
body: 'Balance of the asset originator account on Centrifuge.',
},
repayFormAvailableBalanceUnlimited: {
label: 'Available balance',
body: 'Unlimited because this is a virtual accounting process.',
},
}

export type TooltipsProps = {
Expand Down
1 change: 1 addition & 0 deletions centrifuge-app/src/pages/IssuerCreatePool/PoolFeeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export function PoolFeeSection() {
percentOfNav: '',
walletAddress: '',
feePosition: 'Top of waterfall',
category: feeCategories[0],
})
}}
small
Expand Down
183 changes: 183 additions & 0 deletions centrifuge-app/src/pages/Loan/ChargeFeesFields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { CurrencyBalance, Pool, addressToHex } from '@centrifuge/centrifuge-js'
import {
CombinedSubstrateAccount,
formatBalance,
useCentrifuge,
useCentrifugeApi,
wrapProxyCallsForAccount,
} from '@centrifuge/centrifuge-react'
import { Box, CurrencyInput, IconMinusCircle, IconPlusCircle, Select, Shelf, Stack, Text } from '@centrifuge/fabric'
import { Field, FieldArray, FieldProps, useFormikContext } from 'formik'
import React from 'react'
import { combineLatest, map, of } from 'rxjs'
import { Dec } from '../../utils/Decimal'
import { useBorrower } from '../../utils/usePermissions'
import { usePool, usePoolFees, usePoolMetadata } from '../../utils/usePools'
import { FinanceValues } from './ExternalFinanceForm'
import { RepayValues } from './RepayForm'

export const ChargeFeesFields = ({
pool,
borrower,
}: {
pool: Pool
borrower: CombinedSubstrateAccount | undefined
}) => {
const form = useFormikContext<FinanceValues>()
const { data: poolMetadata } = usePoolMetadata(pool)
const poolFees = usePoolFees(pool.id)
// fees can only be charged by the destination address
// fees destination must be set to the AO Proxy address
const chargableFees = React.useMemo(
() =>
poolFees?.filter(
(fee) => fee.type !== 'fixed' && borrower && addressToHex(fee.destination) === borrower.actingAddress
),
[poolFees, borrower]
)

const getOptions = React.useCallback(() => {
const chargableOptions = (chargableFees || []).map((f) => {
const feeName = poolMetadata?.pool?.poolFees?.find((feeMeta) => feeMeta.id === f.id)?.name || 'Unknown Fee'
return {
label: `${feeName}`,
value: f.id.toString(),
}
})
return chargableFees && chargableFees.length > 1
? [{ label: 'Select fee', value: '' }, ...chargableOptions]
: chargableOptions
}, [chargableFees, poolMetadata])

return (
<Stack gap={2}>
<FieldArray name="fees">
{({ remove, push }) => {
return (
<>
<Stack gap={2}>
<Stack gap={2}>
{form.values.fees.map((fee, index) => {
return (
<Shelf key={`${fee.id}-${index}`} gap={1} alignItems="flex-start">
<Box flex={1}>
<Select
options={getOptions()}
label="Fee"
onChange={(e) => {
form.setFieldValue(`fees.${index}.id`, e.target.value)
}}
value={form.values.fees[index].id}
/>
</Box>
<Box flex={1}>
<Field
key={`fees.${index}.amount`}
name={`fees.${index}.amount`}
validate={(value: number) => {
let error
if (!value) {
error = 'Enter an amount or remove the fee'
}
return error
}}
>
{({ field, meta }: FieldProps) => {
return (
<CurrencyInput
{...field}
label="Amount"
errorMessage={meta.touched ? meta.error : undefined}
currency={pool.currency.symbol}
placeholder="0"
onChange={(value) => form.setFieldValue(`fees.${index}.amount`, value)}
/>
)
}}
</Field>
</Box>
<Box
alignSelf="flex-start"
background="none"
border="none"
as="button"
mt={4}
style={{ cursor: 'pointer' }}
onClick={() => remove(index)}
>
<IconMinusCircle size="20px" />
</Box>
</Shelf>
)
})}
</Stack>
{chargableFees?.length ? (
<Shelf
gap={1}
alignItems="center"
as="button"
style={{ cursor: 'pointer', background: 'none', border: 'none' }}
onClick={(e) => {
e.preventDefault()
if (chargableFees.length === 1) {
return push({ id: chargableFees[0].id.toString(), amount: '' })
}
return push({ id: '', amount: '' })
}}
>
<IconPlusCircle size="20px" color="textButtonTertiary" />
<Text variant="label1" color="textButtonTertiary">
Add fee
</Text>
</Shelf>
) : null}
</Stack>
</>
)
}}
</FieldArray>
</Stack>
)
}

function ChargePoolFeeSummary({ poolId }: { poolId: string }) {
const form = useFormikContext<FinanceValues | RepayValues>()
const pool = usePool(poolId)
const totalFees = form.values.fees.reduce((acc, fee) => acc.add(Dec(fee.amount || 0)), Dec(0))

return form.values.fees.length > 0 ? (
<Stack gap={1}>
<Shelf justifyContent="space-between">
<Text variant="label2">Fees</Text>
<Text variant="label2">{formatBalance(Dec(totalFees), pool.currency.symbol, 2)}</Text>
</Shelf>
</Stack>
) : null
}

export function useChargePoolFees(poolId: string, loanId: string) {
const pool = usePool(poolId)
const borrower = useBorrower(poolId, loanId)
const api = useCentrifugeApi()
const cent = useCentrifuge()
return {
render: () => <ChargeFeesFields pool={pool as Pool} borrower={borrower} />,
renderSummary: () => <ChargePoolFeeSummary poolId={poolId} />,
isValid: ({ values }: { values: Pick<FinanceValues | RepayValues, 'fees'> }) => {
return values.fees.every((fee) => !!fee.id && !!fee.amount)
},
getBatch: ({ values }: { values: Pick<FinanceValues | RepayValues, 'fees'> }) => {
if (!values.fees.length) return of([])
const fees = values.fees.flatMap((fee) => {
if (!fee.amount) throw new Error('Charge amount not provided')
if (!borrower) throw new Error('No borrower')
const feeAmount = CurrencyBalance.fromFloat(fee.amount, pool.currency.decimals)
let feeTx = api.tx.poolFees.chargeFee(fee.id, feeAmount.toString())
return cent.remark
.remark([[{ Loan: [poolId, loanId] }], feeTx], { batch: true })
.pipe(map((tx) => wrapProxyCallsForAccount(api, tx, borrower, 'Borrow')))
})
return combineLatest(fees)
},
}
}
28 changes: 28 additions & 0 deletions centrifuge-app/src/pages/Loan/ErrorMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Box, InlineFeedback, Text } from '@centrifuge/fabric'

type Props = {
children: React.ReactNode
type: 'default' | 'critical'
condition: boolean
}

const styles: Record<Props['type'], { bg: string; color: string }> = {
default: {
bg: 'statusDefaultBg',
color: 'statusDefault',
},
critical: {
bg: 'statusCriticalBg',
color: 'statusCritical',
},
}

export function ErrorMessage({ children, condition, type }: Props) {
return condition ? (
<Box bg={styles[type].bg} p={1}>
<InlineFeedback status={type}>
<Text color={styles[type].color}>{children}</Text>
</InlineFeedback>
</Box>
) : null
}
Loading
Loading