@huma-finance/widgets 0.0.62-beta.630 → 0.0.62-beta.633

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/API.md +0 -194
  2. package/dist/cjs/index.cjs +258 -1866
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/index.d.ts +2 -136
  5. package/dist/index.js +261 -1864
  6. package/dist/index.js.map +1 -1
  7. package/package.json +7 -17
  8. package/src/components/CreditLine/paymentV2/1-ChooseAmount.tsx +0 -1
  9. package/src/components/InputAmountModal.tsx +2 -13
  10. package/src/components/Lend/supplyV2/6-Success.tsx +3 -3
  11. package/src/components/WidgetWrapper.tsx +4 -6
  12. package/src/index.tsx +0 -139
  13. package/src/store/widgets.reducers.ts +0 -5
  14. package/src/store/widgets.store.ts +0 -1
  15. package/src/components/CreditLine/solanaBorrow/1-ChooseAmount.tsx +0 -67
  16. package/src/components/CreditLine/solanaBorrow/2-Transfer.tsx +0 -159
  17. package/src/components/CreditLine/solanaBorrow/3-Done.tsx +0 -38
  18. package/src/components/CreditLine/solanaBorrow/index.tsx +0 -90
  19. package/src/components/CreditLine/solanaPayment/1-ChooseAmount.tsx +0 -75
  20. package/src/components/CreditLine/solanaPayment/2-Transfer.tsx +0 -92
  21. package/src/components/CreditLine/solanaPayment/3-Done.tsx +0 -59
  22. package/src/components/CreditLine/solanaPayment/index.tsx +0 -83
  23. package/src/components/Lend/solanaAddRedemption/1-ChooseTranche.tsx +0 -114
  24. package/src/components/Lend/solanaAddRedemption/2-ChooseAmount.tsx +0 -183
  25. package/src/components/Lend/solanaAddRedemption/3-Transfer.tsx +0 -102
  26. package/src/components/Lend/solanaAddRedemption/4-Done.tsx +0 -29
  27. package/src/components/Lend/solanaAddRedemption/index.tsx +0 -155
  28. package/src/components/Lend/solanaCancelRedemption/1-ChooseTranche.tsx +0 -114
  29. package/src/components/Lend/solanaCancelRedemption/2-Transfer.tsx +0 -99
  30. package/src/components/Lend/solanaCancelRedemption/3-Done.tsx +0 -55
  31. package/src/components/Lend/solanaCancelRedemption/index.tsx +0 -162
  32. package/src/components/Lend/solanaSupply/1-Evaluation.tsx +0 -106
  33. package/src/components/Lend/solanaSupply/2-ChooseTranche.tsx +0 -116
  34. package/src/components/Lend/solanaSupply/3-ChooseAmount.tsx +0 -131
  35. package/src/components/Lend/solanaSupply/4-Transfer.tsx +0 -137
  36. package/src/components/Lend/solanaSupply/5-Success.tsx +0 -52
  37. package/src/components/Lend/solanaSupply/index.tsx +0 -155
  38. package/src/components/SolanaTxDoneModal.tsx +0 -119
  39. package/src/components/SolanaTxSendModal.tsx +0 -61
  40. package/src/components/SolanaViewOnExplorer.tsx +0 -29
@@ -1,90 +0,0 @@
1
- import { SolanaPoolInfo } from '@huma-finance/shared'
2
- import { SolanaPoolState, useBorrowerAccounts } from '@huma-finance/web-shared'
3
- import React, { useEffect } from 'react'
4
- import { useDispatch } from 'react-redux'
5
-
6
- import { useAppSelector } from '../../../hooks/useRedux'
7
- import { selectWidgetState } from '../../../store/widgets.selectors'
8
- import { WidgetWrapper } from '../../WidgetWrapper'
9
- import { WIDGET_STEP } from '../../../store/widgets.store'
10
- import { setStep } from '../../../store/widgets.reducers'
11
- import { ErrorModal } from '../../ErrorModal'
12
- import { ChooseAmount } from './1-ChooseAmount'
13
- import { Transfer } from './2-Transfer'
14
- import { Done } from './3-Done'
15
-
16
- /**
17
- * Lend pool supply props
18
- * @typedef {Object} SolanaBorrowProps
19
- * @property {SolanaPoolInfo} poolInfo The metadata of the pool.
20
- * @property {SolanaPoolState} poolState The current state config of the pool. * @property {function():void} handleClose Function to notify to close the widget modal when user clicks the 'x' close button.
21
- * @property {function():void|undefined} handleSuccess Optional function to notify that the lending pool supply action is successful.
22
- */
23
- export interface SolanaBorrowProps {
24
- poolInfo: SolanaPoolInfo
25
- poolState: SolanaPoolState
26
- handleClose: () => void
27
- handleSuccess?: () => void
28
- }
29
-
30
- export function SolanaBorrow({
31
- poolInfo,
32
- poolState,
33
- handleClose,
34
- handleSuccess,
35
- }: SolanaBorrowProps): React.ReactElement | null {
36
- const dispatch = useDispatch()
37
- const { creditConfigAccount, loading: isLoadingBorrowerAccounts } =
38
- useBorrowerAccounts(poolInfo.chainId, poolInfo.poolName)
39
- const { step, errorMessage } = useAppSelector(selectWidgetState)
40
- useEffect(() => {
41
- if (!step) {
42
- dispatch(setStep(WIDGET_STEP.ChooseAmount))
43
- }
44
- }, [dispatch, step])
45
-
46
- const title = 'Borrow'
47
- if (isLoadingBorrowerAccounts) {
48
- return (
49
- <WidgetWrapper
50
- isOpen
51
- isLoading
52
- loadingTitle={title}
53
- handleClose={handleClose}
54
- handleSuccess={handleSuccess}
55
- />
56
- )
57
- }
58
-
59
- return (
60
- <WidgetWrapper
61
- isOpen
62
- loadingTitle={title}
63
- handleClose={handleClose}
64
- handleSuccess={handleSuccess}
65
- >
66
- {step === WIDGET_STEP.ChooseAmount && creditConfigAccount && (
67
- <ChooseAmount
68
- poolInfo={poolInfo}
69
- creditConfigAccount={creditConfigAccount}
70
- />
71
- )}
72
- {step === WIDGET_STEP.Transfer && <Transfer poolInfo={poolInfo} />}
73
- {step === WIDGET_STEP.Done && (
74
- <Done
75
- poolInfo={poolInfo}
76
- poolState={poolState}
77
- handleAction={handleClose}
78
- />
79
- )}
80
- {step === WIDGET_STEP.Error && (
81
- <ErrorModal
82
- title={title}
83
- errorReason='Sorry there was an error'
84
- errorMessage={errorMessage}
85
- handleOk={handleClose}
86
- />
87
- )}
88
- </WidgetWrapper>
89
- )
90
- }
@@ -1,75 +0,0 @@
1
- import {
2
- formatNumber,
3
- SolanaPoolInfo,
4
- SolanaTokenUtils,
5
- } from '@huma-finance/shared'
6
- import { CreditStateAccount } from '@huma-finance/web-shared'
7
- import React, { useCallback, useEffect, useMemo, useState } from 'react'
8
-
9
- import { useAppDispatch } from '../../../hooks/useRedux'
10
- import { setPaymentAmount, setStep } from '../../../store/widgets.reducers'
11
- import { WIDGET_STEP } from '../../../store/widgets.store'
12
- import { InputAmountModal } from '../../InputAmountModal'
13
-
14
- type Props = {
15
- poolInfo: SolanaPoolInfo
16
- creditStateAccount: CreditStateAccount
17
- }
18
-
19
- export function ChooseAmount({
20
- poolInfo,
21
- creditStateAccount,
22
- }: Props): React.ReactElement {
23
- const dispatch = useAppDispatch()
24
- const { symbol, decimals } = poolInfo.underlyingMint
25
- const [currentAmount, setCurrentAmount] = useState<number>(0)
26
- const totalDueAmount = useMemo(
27
- () =>
28
- Number(
29
- SolanaTokenUtils.formatUnits(
30
- creditStateAccount.creditRecord.totalDueAmount,
31
- decimals,
32
- ),
33
- ),
34
- [creditStateAccount.creditRecord.totalDueAmount, decimals],
35
- )
36
- const payoffAmount = useMemo(
37
- () =>
38
- Number(
39
- SolanaTokenUtils.formatUnits(
40
- creditStateAccount.creditRecord.payoffAmount,
41
- decimals,
42
- ),
43
- ),
44
- [creditStateAccount.creditRecord.payoffAmount, decimals],
45
- )
46
-
47
- useEffect(() => {
48
- setCurrentAmount(totalDueAmount)
49
- dispatch(setPaymentAmount({ paymentAmount: totalDueAmount }))
50
- }, [dispatch, totalDueAmount])
51
-
52
- const handleChangeAmount = (newAmount: number) => {
53
- setCurrentAmount(newAmount)
54
- dispatch(setPaymentAmount({ paymentAmount: newAmount }))
55
- }
56
-
57
- const handleAction = useCallback(() => {
58
- dispatch(setStep(WIDGET_STEP.Transfer))
59
- }, [dispatch])
60
-
61
- return (
62
- <InputAmountModal
63
- title='Make Payment'
64
- subTitle='Choose Amount'
65
- tokenSymbol={symbol}
66
- currentAmount={currentAmount}
67
- handleChangeAmount={handleChangeAmount}
68
- maxAmount={payoffAmount}
69
- maxAmountText='Pay Off'
70
- infos={[`${formatNumber(totalDueAmount.toFixed(0))} Due`]}
71
- handleAction={handleAction}
72
- actionText='PAY'
73
- />
74
- )
75
- }
@@ -1,92 +0,0 @@
1
- import {
2
- getCreditAccounts,
3
- getTokenAccounts,
4
- SolanaPoolInfo,
5
- SolanaTokenUtils,
6
- } from '@huma-finance/shared'
7
- import React, { useCallback, useEffect, useState } from 'react'
8
-
9
- import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'
10
- import { useConnection, useWallet } from '@solana/wallet-adapter-react'
11
- import { Transaction } from '@solana/web3.js'
12
- import { useHumaProgram } from '@huma-finance/web-shared'
13
- import { useAppDispatch, useAppSelector } from '../../../hooks/useRedux'
14
- import { SolanaTxSendModal } from '../../SolanaTxSendModal'
15
- import { setStep } from '../../../store/widgets.reducers'
16
- import { WIDGET_STEP } from '../../../store/widgets.store'
17
- import { selectWidgetState } from '../../../store/widgets.selectors'
18
-
19
- type Props = {
20
- poolInfo: SolanaPoolInfo
21
- }
22
-
23
- export function Transfer({ poolInfo }: Props): React.ReactElement | null {
24
- const dispatch = useAppDispatch()
25
- const { wallet, publicKey } = useWallet()
26
- const { connection } = useConnection()
27
- const [transaction, setTransaction] = useState<Transaction>()
28
- const program = useHumaProgram(poolInfo.chainId)
29
- const { paymentAmount } = useAppSelector(selectWidgetState)
30
- const { decimals } = poolInfo.underlyingMint
31
-
32
- const handleSuccess = useCallback(() => {
33
- dispatch(setStep(WIDGET_STEP.Done))
34
- }, [dispatch])
35
-
36
- useEffect(() => {
37
- async function getTx() {
38
- if (!wallet || !publicKey || !connection || !paymentAmount) {
39
- return
40
- }
41
-
42
- const { underlyingTokenATA } = getTokenAccounts(poolInfo, publicKey)
43
-
44
- const { creditConfigAccount, creditStateAccount } = getCreditAccounts(
45
- poolInfo,
46
- publicKey,
47
- )
48
- const paymentAmountBN = SolanaTokenUtils.parseUnits(
49
- paymentAmount.toString(),
50
- decimals,
51
- )
52
- const tx = await program.methods
53
- .makePayment(paymentAmountBN)
54
- .accountsPartial({
55
- signer: publicKey,
56
- humaConfig: poolInfo.humaConfig,
57
- poolConfig: poolInfo.poolConfig,
58
- poolState: poolInfo.poolState,
59
- creditConfig: creditConfigAccount,
60
- creditState: creditStateAccount,
61
- poolAuthority: poolInfo.poolAuthority,
62
- underlyingMint: poolInfo.underlyingMint.address,
63
- poolUnderlyingToken: poolInfo.poolUnderlyingTokenAccount,
64
- borrowerUnderlyingToken: underlyingTokenATA,
65
- tokenProgram: TOKEN_2022_PROGRAM_ID,
66
- })
67
- .transaction()
68
-
69
- setTransaction(tx)
70
- }
71
- getTx()
72
- }, [
73
- connection,
74
- decimals,
75
- dispatch,
76
- paymentAmount,
77
- poolInfo,
78
- poolInfo.underlyingMint.address,
79
- poolInfo.underlyingMint.decimals,
80
- program.methods,
81
- publicKey,
82
- wallet,
83
- ])
84
-
85
- return (
86
- <SolanaTxSendModal
87
- tx={transaction}
88
- chainId={poolInfo.chainId}
89
- handleSuccess={handleSuccess}
90
- />
91
- )
92
- }
@@ -1,59 +0,0 @@
1
- import { formatNumber, SolanaPoolInfo } from '@huma-finance/shared'
2
- import React, { useEffect, useMemo, useState } from 'react'
3
-
4
- import { useConnection } from '@solana/wallet-adapter-react'
5
- import { useAppSelector } from '../../../hooks/useRedux'
6
- import { selectWidgetState } from '../../../store/widgets.selectors'
7
- import { SolanaTxDoneModal } from '../../SolanaTxDoneModal'
8
-
9
- type Props = {
10
- poolInfo: SolanaPoolInfo
11
- handleAction: () => void
12
- }
13
-
14
- export function Done({ poolInfo, handleAction }: Props): React.ReactElement {
15
- const { solanaSignature } = useAppSelector(selectWidgetState)
16
- const { symbol } = poolInfo.underlyingMint
17
- const { connection } = useConnection()
18
- const [tokensPaid, setTokensPaid] = useState<number | null>(null)
19
-
20
- useEffect(() => {
21
- const fetchTokensPaid = async () => {
22
- if (!solanaSignature) {
23
- return
24
- }
25
-
26
- const txData = await connection.getTransaction(solanaSignature, {
27
- maxSupportedTransactionVersion: 2,
28
- })
29
-
30
- const preTokenBalance =
31
- txData?.meta?.preTokenBalances?.[1]?.uiTokenAmount?.uiAmount
32
- const postTokenBalance =
33
- txData?.meta?.postTokenBalances?.[1]?.uiTokenAmount?.uiAmount
34
- if (preTokenBalance && postTokenBalance) {
35
- setTokensPaid(preTokenBalance - postTokenBalance)
36
- }
37
- }
38
-
39
- fetchTokensPaid()
40
- }, [connection, solanaSignature])
41
-
42
- const content = useMemo(() => {
43
- if (tokensPaid !== null) {
44
- return [`You successfully paid ${formatNumber(tokensPaid)} ${symbol}.`]
45
- }
46
-
47
- return ['Your payment to the pool was successful']
48
- }, [tokensPaid, symbol])
49
-
50
- return (
51
- <SolanaTxDoneModal
52
- handleAction={handleAction}
53
- content={content}
54
- chainId={poolInfo.chainId}
55
- solanaSignature={solanaSignature}
56
- buttonText='DONE'
57
- />
58
- )
59
- }
@@ -1,83 +0,0 @@
1
- import { SolanaPoolInfo } from '@huma-finance/shared'
2
- import { useBorrowerAccounts } from '@huma-finance/web-shared'
3
- import React, { useEffect } from 'react'
4
- import { useDispatch } from 'react-redux'
5
-
6
- import { useAppSelector } from '../../../hooks/useRedux'
7
- import { selectWidgetState } from '../../../store/widgets.selectors'
8
- import { WidgetWrapper } from '../../WidgetWrapper'
9
- import { WIDGET_STEP } from '../../../store/widgets.store'
10
- import { setStep } from '../../../store/widgets.reducers'
11
- import { ErrorModal } from '../../ErrorModal'
12
- import { ChooseAmount } from './1-ChooseAmount'
13
- import { Transfer } from './2-Transfer'
14
- import { Done } from './3-Done'
15
-
16
- /**
17
- * Lend pool supply props
18
- * @typedef {Object} SolanaPaymentProps
19
- * @property {SolanaPoolInfo} poolInfo The metadata of the pool.
20
- * @property {function():void|undefined} handleSuccess Optional function to notify that the lending pool supply action is successful.
21
- */
22
- export interface SolanaPaymentProps {
23
- poolInfo: SolanaPoolInfo
24
- handleClose: () => void
25
- handleSuccess?: () => void
26
- }
27
-
28
- export function SolanaPayment({
29
- poolInfo,
30
- handleClose,
31
- handleSuccess,
32
- }: SolanaPaymentProps): React.ReactElement | null {
33
- const dispatch = useDispatch()
34
- const { creditStateAccount, loading: isLoadingBorrowerAccounts } =
35
- useBorrowerAccounts(poolInfo.chainId, poolInfo.poolName)
36
- const { step, errorMessage } = useAppSelector(selectWidgetState)
37
- useEffect(() => {
38
- if (!step) {
39
- dispatch(setStep(WIDGET_STEP.ChooseAmount))
40
- }
41
- }, [dispatch, step])
42
-
43
- const title = 'Make Payment'
44
- if (isLoadingBorrowerAccounts) {
45
- return (
46
- <WidgetWrapper
47
- isOpen
48
- isLoading
49
- loadingTitle={title}
50
- handleClose={handleClose}
51
- handleSuccess={handleSuccess}
52
- />
53
- )
54
- }
55
-
56
- return (
57
- <WidgetWrapper
58
- isOpen
59
- loadingTitle={title}
60
- handleClose={handleClose}
61
- handleSuccess={handleSuccess}
62
- >
63
- {step === WIDGET_STEP.ChooseAmount && creditStateAccount && (
64
- <ChooseAmount
65
- poolInfo={poolInfo}
66
- creditStateAccount={creditStateAccount}
67
- />
68
- )}
69
- {step === WIDGET_STEP.Transfer && <Transfer poolInfo={poolInfo} />}
70
- {step === WIDGET_STEP.Done && (
71
- <Done poolInfo={poolInfo} handleAction={handleClose} />
72
- )}
73
- {step === WIDGET_STEP.Error && (
74
- <ErrorModal
75
- title={title}
76
- errorReason='Sorry there was an error'
77
- errorMessage={errorMessage}
78
- handleOk={handleClose}
79
- />
80
- )}
81
- </WidgetWrapper>
82
- )
83
- }
@@ -1,114 +0,0 @@
1
- import { TrancheType } from '@huma-finance/shared'
2
- import {
3
- css,
4
- FormControl,
5
- FormControlLabel,
6
- FormLabel,
7
- Radio,
8
- RadioGroup,
9
- useTheme,
10
- } from '@mui/material'
11
- import React from 'react'
12
-
13
- import { useAppDispatch } from '../../../hooks/useRedux'
14
- import { setStep } from '../../../store/widgets.reducers'
15
- import { WIDGET_STEP } from '../../../store/widgets.store'
16
- import { BottomButton } from '../../BottomButton'
17
- import { WrapperModal } from '../../WrapperModal'
18
-
19
- type Props = {
20
- selectedTranche: TrancheType | undefined
21
- changeTranche: (tranche: TrancheType) => void
22
- }
23
-
24
- export function ChooseTranche({
25
- selectedTranche,
26
- changeTranche,
27
- }: Props): React.ReactElement | null {
28
- const theme = useTheme()
29
- const dispatch = useAppDispatch()
30
-
31
- const styles = {
32
- subTitle: css`
33
- color: ${theme.palette.text.primary} !important;
34
- font-weight: 400;
35
- font-size: 16px;
36
- line-height: 150%;
37
- letter-spacing: 0.15px;
38
- margin-top: ${theme.spacing(5)};
39
- margin-left: ${theme.spacing(2)};
40
- `,
41
- radioGroup: css`
42
- margin-left: ${theme.spacing(3)};
43
- margin-top: ${theme.spacing(3)};
44
- `,
45
- formControl: css`
46
- margin-bottom: ${theme.spacing(1)};
47
-
48
- .MuiFormControlLabel-label {
49
- color: ${theme.palette.text.primary};
50
- font-weight: 400;
51
- font-size: 16px;
52
- line-height: 150%;
53
- letter-spacing: 0.15px;
54
- }
55
- `,
56
- }
57
-
58
- const handleNext = () => {
59
- dispatch(setStep(WIDGET_STEP.ChooseAmount))
60
- }
61
-
62
- const items: {
63
- label: string
64
- value: TrancheType
65
- }[] = [
66
- {
67
- label: 'Senior',
68
- value: 'senior',
69
- },
70
- {
71
- label: 'Junior',
72
- value: 'junior',
73
- },
74
- ]
75
-
76
- return (
77
- <WrapperModal title='Redemption'>
78
- <FormControl>
79
- <FormLabel css={styles.subTitle}>Select Tranche Type</FormLabel>
80
- <RadioGroup
81
- aria-labelledby='buttons-group-label'
82
- name='radio-buttons-group'
83
- css={styles.radioGroup}
84
- onChange={(e) => changeTranche(e.target.value as TrancheType)}
85
- >
86
- {items.map((item) => (
87
- <FormControlLabel
88
- key={item.label}
89
- value={item.value}
90
- control={
91
- <Radio
92
- sx={{
93
- '& .MuiSvgIcon-root': {
94
- fontSize: 24,
95
- },
96
- }}
97
- />
98
- }
99
- label={item.label}
100
- css={styles.formControl}
101
- />
102
- ))}
103
- </RadioGroup>
104
- </FormControl>
105
- <BottomButton
106
- variant='contained'
107
- disabled={!selectedTranche}
108
- onClick={handleNext}
109
- >
110
- NEXT
111
- </BottomButton>
112
- </WrapperModal>
113
- )
114
- }
@@ -1,183 +0,0 @@
1
- import {
2
- formatNumber,
3
- SolanaPoolInfo,
4
- SolanaTokenUtils,
5
- timestampToLL,
6
- TrancheType,
7
- } from '@huma-finance/shared'
8
- import {
9
- LenderStateAccount,
10
- SolanaPoolState,
11
- useTrancheMintAccounts,
12
- useTrancheTokenAccounts,
13
- } from '@huma-finance/web-shared'
14
- import dayjs from 'dayjs'
15
- import React, { useEffect, useMemo, useState } from 'react'
16
-
17
- import { BN } from '@coral-xyz/anchor'
18
- import { useAppDispatch } from '../../../hooks/useRedux'
19
- import {
20
- setError,
21
- setRedeemAmount,
22
- setRedeemShares,
23
- setStep,
24
- } from '../../../store/widgets.reducers'
25
- import { WIDGET_STEP } from '../../../store/widgets.store'
26
- import { InputAmountModal } from '../../InputAmountModal'
27
- import { LoadingModal } from '../../LoadingModal'
28
-
29
- type Props = {
30
- poolInfo: SolanaPoolInfo
31
- poolState: SolanaPoolState
32
- selectedTranche: TrancheType
33
- lenderState: LenderStateAccount | null | undefined
34
- }
35
-
36
- export function ChooseAmount({
37
- poolInfo,
38
- poolState,
39
- selectedTranche,
40
- lenderState,
41
- }: Props): React.ReactElement {
42
- const dispatch = useAppDispatch()
43
- const { symbol } = poolInfo.underlyingMint
44
- const [currentAmount, setCurrentAmount] = useState<number>(0)
45
- const [currentShares, setCurrentShares] = useState<number>(0)
46
- const { mintAccount, loading: isLoadingTrancheMintAccounts } =
47
- useTrancheMintAccounts(poolInfo, selectedTranche)
48
- const {
49
- seniorTokenAccount,
50
- juniorTokenAccount,
51
- loading: isLoadingTokenAccounts,
52
- } = useTrancheTokenAccounts(poolInfo)
53
-
54
- const maxSharesFormatted = useMemo(() => {
55
- if (!mintAccount?.decimals) {
56
- return 0
57
- }
58
-
59
- return SolanaTokenUtils.formatUnits(
60
- selectedTranche === 'senior'
61
- ? new BN(seniorTokenAccount?.amount?.toString() ?? 0)
62
- : new BN(juniorTokenAccount?.amount?.toString() ?? 0),
63
- mintAccount.decimals,
64
- )
65
- }, [
66
- mintAccount,
67
- juniorTokenAccount?.amount,
68
- selectedTranche,
69
- seniorTokenAccount?.amount,
70
- ])
71
-
72
- const sharePrice = useMemo(() => {
73
- if (!mintAccount?.decimals || !mintAccount?.supply) {
74
- return 0
75
- }
76
-
77
- const mintSupplyFormatted = Number(
78
- SolanaTokenUtils.formatUnits(
79
- new BN(mintAccount.supply.toString()),
80
- mintAccount.decimals,
81
- ),
82
- )
83
-
84
- if (mintSupplyFormatted === 0) {
85
- return 0
86
- }
87
-
88
- const seniorTrancheAssetsFormatted = Number(
89
- SolanaTokenUtils.formatUnits(
90
- new BN(poolState?.seniorTrancheAssets ?? 0),
91
- mintAccount.decimals,
92
- ),
93
- )
94
-
95
- if (selectedTranche === 'senior') {
96
- return seniorTrancheAssetsFormatted / mintSupplyFormatted
97
- }
98
-
99
- const juniorTrancheAssetsFormatted = Number(
100
- SolanaTokenUtils.formatUnits(
101
- new BN(poolState?.juniorTrancheAssets ?? 0),
102
- mintAccount.decimals,
103
- ),
104
- )
105
-
106
- return juniorTrancheAssetsFormatted / mintSupplyFormatted
107
- }, [
108
- mintAccount?.decimals,
109
- mintAccount?.supply,
110
- poolState?.juniorTrancheAssets,
111
- poolState?.seniorTrancheAssets,
112
- selectedTranche,
113
- ])
114
-
115
- useEffect(() => {
116
- if (
117
- poolState?.withdrawalLockupPeriodDays &&
118
- poolState?.epochEndTime &&
119
- lenderState
120
- ) {
121
- const SECONDS_IN_A_DAY = 24 * 60 * 60
122
- const lastDepositTime = Number(lenderState.depositRecord.lastDepositTime)
123
- const lockupEndTime =
124
- lastDepositTime +
125
- poolState.withdrawalLockupPeriodDays * SECONDS_IN_A_DAY
126
- if (poolState.epochEndTime < lockupEndTime) {
127
- const lockupEndTimeDayjs = dayjs.unix(lockupEndTime).date(1)
128
- dispatch(setStep(WIDGET_STEP.Error))
129
- dispatch(
130
- setError({
131
- errorReason: 'Redemption too soon',
132
- errorMessage: `Your last deposit was on ${timestampToLL(
133
- lastDepositTime,
134
- )}. You can redeem on ${timestampToLL(lockupEndTimeDayjs.unix())}.`,
135
- }),
136
- )
137
- }
138
- }
139
- }, [
140
- dispatch,
141
- lenderState,
142
- poolState.epochEndTime,
143
- poolState.withdrawalLockupPeriodDays,
144
- ])
145
-
146
- const handleChangeShares = (newShares: number) => {
147
- const amount = Number(newShares) * sharePrice
148
- setCurrentShares(Number(newShares))
149
- setCurrentAmount(amount)
150
- dispatch(setRedeemShares(Number(newShares)))
151
- dispatch(setRedeemAmount(amount))
152
- }
153
-
154
- const handleAction = () => {
155
- dispatch(setStep(WIDGET_STEP.Transfer))
156
- }
157
-
158
- if (
159
- isLoadingTokenAccounts ||
160
- isLoadingTrancheMintAccounts ||
161
- !lenderState ||
162
- poolState?.withdrawalLockupPeriodDays === undefined || // withdrawalLockupPeriodDays can be 0
163
- !poolState?.epochEndTime
164
- ) {
165
- return <LoadingModal title='Redemption' />
166
- }
167
-
168
- return (
169
- <InputAmountModal
170
- title='Redemption'
171
- subTitle={`Enter number of shares to redeem from the ${selectedTranche} tranche`}
172
- tokenSymbol={symbol}
173
- currentAmount={currentShares}
174
- handleChangeAmount={handleChangeShares}
175
- maxAmount={maxSharesFormatted}
176
- infos={[`${String(formatNumber(currentAmount))} ${symbol}`]}
177
- maxAmountTitle={`${formatNumber(maxSharesFormatted)} Shares`}
178
- suffix='Shares'
179
- handleAction={handleAction}
180
- actionText='REQUEST'
181
- />
182
- )
183
- }