@huma-finance/widgets 0.0.62-beta.597 → 0.0.62-beta.611

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 (33) hide show
  1. package/API.md +185 -0
  2. package/dist/cjs/index.cjs +1490 -268
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/index.d.ts +117 -2
  5. package/dist/index.js +1489 -271
  6. package/dist/index.js.map +1 -1
  7. package/package.json +11 -6
  8. package/src/components/CreditLine/solanaBorrow/1-ChooseAmount.tsx +86 -0
  9. package/src/components/CreditLine/solanaBorrow/2-ApproveAllowance.tsx +87 -0
  10. package/src/components/CreditLine/solanaBorrow/index.tsx +96 -0
  11. package/src/components/InputAmountModal.tsx +12 -2
  12. package/src/components/Lend/solanaAddRedemption/1-ChooseTranche.tsx +114 -0
  13. package/src/components/Lend/solanaAddRedemption/2-ChooseAmount.tsx +183 -0
  14. package/src/components/Lend/solanaAddRedemption/3-Transfer.tsx +102 -0
  15. package/src/components/Lend/solanaAddRedemption/4-Done.tsx +29 -0
  16. package/src/components/Lend/solanaAddRedemption/index.tsx +140 -0
  17. package/src/components/Lend/solanaCancelRedemption/1-ChooseTranche.tsx +114 -0
  18. package/src/components/Lend/solanaCancelRedemption/2-Transfer.tsx +99 -0
  19. package/src/components/Lend/solanaCancelRedemption/3-Done.tsx +55 -0
  20. package/src/components/Lend/solanaCancelRedemption/index.tsx +152 -0
  21. package/src/components/Lend/solanaSupply/1-ChooseTranche.tsx +116 -0
  22. package/src/components/Lend/solanaSupply/2-Evaluation.tsx +0 -0
  23. package/src/components/Lend/solanaSupply/3-ChooseAmount.tsx +130 -0
  24. package/src/components/Lend/solanaSupply/4-Transfer.tsx +89 -0
  25. package/src/components/Lend/solanaSupply/5-Success.tsx +50 -0
  26. package/src/components/Lend/solanaSupply/index.tsx +143 -0
  27. package/src/components/SolanaTxDoneModal.tsx +115 -0
  28. package/src/components/SolanaTxSendModal.tsx +61 -0
  29. package/src/components/SolanaViewOnExplorer.tsx +29 -0
  30. package/src/components/WidgetWrapper.tsx +6 -4
  31. package/src/index.tsx +124 -0
  32. package/src/store/widgets.reducers.ts +5 -0
  33. package/src/store/widgets.store.ts +1 -0
@@ -0,0 +1,102 @@
1
+ import {
2
+ getTokenAccounts,
3
+ SolanaPoolInfo,
4
+ SolanaTokenUtils,
5
+ TrancheType,
6
+ } from '@huma-finance/shared'
7
+ import React, { useCallback, useEffect, useMemo, useState } from 'react'
8
+
9
+ import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'
10
+ import { useWallet } from '@solana/wallet-adapter-react'
11
+ import {
12
+ useHumaProgram,
13
+ useTrancheMintAccounts,
14
+ } from '@huma-finance/web-shared'
15
+ import { Transaction } from '@solana/web3.js'
16
+ import { useAppDispatch, useAppSelector } from '../../../hooks/useRedux'
17
+ import { setStep } from '../../../store/widgets.reducers'
18
+ import { WIDGET_STEP } from '../../../store/widgets.store'
19
+ import { selectWidgetState } from '../../../store/widgets.selectors'
20
+ import { SolanaTxSendModal } from '../../SolanaTxSendModal'
21
+
22
+ type Props = {
23
+ poolInfo: SolanaPoolInfo
24
+ selectedTranche: TrancheType
25
+ }
26
+
27
+ export function Transfer({
28
+ poolInfo,
29
+ selectedTranche,
30
+ }: Props): React.ReactElement | null {
31
+ const dispatch = useAppDispatch()
32
+ const { publicKey } = useWallet()
33
+ const { redeemShares } = useAppSelector(selectWidgetState)
34
+ const { mintAccount } = useTrancheMintAccounts(poolInfo, selectedTranche)
35
+ const [transaction, setTransaction] = useState<Transaction>()
36
+ const program = useHumaProgram(poolInfo.chainId)
37
+ const redeemBN = useMemo(() => {
38
+ if (!mintAccount) {
39
+ return null
40
+ }
41
+ return SolanaTokenUtils.parseUnits(
42
+ String(redeemShares),
43
+ mintAccount?.decimals,
44
+ )
45
+ }, [mintAccount, redeemShares])
46
+
47
+ const handleSuccess = useCallback(() => {
48
+ dispatch(setStep(WIDGET_STEP.Done))
49
+ }, [dispatch])
50
+
51
+ useEffect(() => {
52
+ async function getTx() {
53
+ if (!publicKey || !redeemBN || transaction) {
54
+ return
55
+ }
56
+
57
+ const {
58
+ seniorTrancheATA,
59
+ juniorTrancheATA,
60
+ poolSeniorTrancheATA,
61
+ poolJuniorTrancheATA,
62
+ } = getTokenAccounts(poolInfo, publicKey)
63
+ const tx = await program.methods
64
+ .addRedemptionRequest(redeemBN)
65
+ .accountsPartial({
66
+ lender: publicKey,
67
+ humaConfig: poolInfo.humaConfig,
68
+ poolConfig: poolInfo.poolConfig,
69
+ trancheMint:
70
+ selectedTranche === 'senior'
71
+ ? poolInfo.seniorTrancheMint
72
+ : poolInfo.juniorTrancheMint,
73
+ poolTrancheToken:
74
+ selectedTranche === 'senior'
75
+ ? poolSeniorTrancheATA
76
+ : poolJuniorTrancheATA,
77
+ lenderTrancheToken:
78
+ selectedTranche === 'senior' ? seniorTrancheATA : juniorTrancheATA,
79
+ tokenProgram: TOKEN_2022_PROGRAM_ID,
80
+ })
81
+ .transaction()
82
+
83
+ setTransaction(tx)
84
+ }
85
+ getTx()
86
+ }, [
87
+ poolInfo,
88
+ program.methods,
89
+ publicKey,
90
+ redeemBN,
91
+ selectedTranche,
92
+ transaction,
93
+ ])
94
+
95
+ return (
96
+ <SolanaTxSendModal
97
+ tx={transaction}
98
+ chainId={poolInfo.chainId}
99
+ handleSuccess={handleSuccess}
100
+ />
101
+ )
102
+ }
@@ -0,0 +1,29 @@
1
+ import { formatNumber, SolanaPoolInfo } from '@huma-finance/shared'
2
+ import React from 'react'
3
+
4
+ import { useAppSelector } from '../../../hooks/useRedux'
5
+ import { selectWidgetState } from '../../../store/widgets.selectors'
6
+ import { SolanaTxDoneModal } from '../../SolanaTxDoneModal'
7
+
8
+ type Props = {
9
+ poolInfo: SolanaPoolInfo
10
+ handleAction: () => void
11
+ }
12
+
13
+ export function Done({ poolInfo, handleAction }: Props): React.ReactElement {
14
+ const { redeemShares, solanaSignature } = useAppSelector(selectWidgetState)
15
+
16
+ const content = [
17
+ `${formatNumber(redeemShares)} shares requested for redemption`,
18
+ ]
19
+
20
+ return (
21
+ <SolanaTxDoneModal
22
+ handleAction={handleAction}
23
+ content={content}
24
+ chainId={poolInfo.chainId}
25
+ solanaSignature={solanaSignature}
26
+ buttonText='DONE'
27
+ />
28
+ )
29
+ }
@@ -0,0 +1,140 @@
1
+ import { SolanaPoolInfo, TrancheType } from '@huma-finance/shared'
2
+ import {
3
+ SolanaPoolState,
4
+ useLenderAccounts,
5
+ useTrancheTokenAccounts,
6
+ } from '@huma-finance/web-shared'
7
+ import React, { useEffect, useState } from 'react'
8
+ import { useDispatch } from 'react-redux'
9
+
10
+ import { BN } from '@coral-xyz/anchor'
11
+ import { useAppSelector } from '../../../hooks/useRedux'
12
+ import { selectWidgetState } from '../../../store/widgets.selectors'
13
+ import { WidgetWrapper } from '../../WidgetWrapper'
14
+ import { WIDGET_STEP } from '../../../store/widgets.store'
15
+ import { ChooseAmount } from './2-ChooseAmount'
16
+ import { setStep } from '../../../store/widgets.reducers'
17
+ import { ErrorModal } from '../../ErrorModal'
18
+ import { ChooseTranche } from './1-ChooseTranche'
19
+ import { Done } from './4-Done'
20
+ import { Transfer } from './3-Transfer'
21
+
22
+ /**
23
+ * Lend pool supply props
24
+ * @typedef {Object} SolanaLendAddRedemptionProps
25
+ * @property {SolanaPoolInfo} poolInfo The metadata of the pool.
26
+ * @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.
27
+ * @property {function():void|undefined} handleSuccess Optional function to notify that the lending pool supply action is successful.
28
+ */
29
+ export interface SolanaLendAddRedemptionProps {
30
+ poolInfo: SolanaPoolInfo
31
+ poolState: SolanaPoolState
32
+ handleClose: () => void
33
+ handleSuccess?: () => void
34
+ }
35
+
36
+ export function SolanaLendAddRedemption({
37
+ poolInfo,
38
+ poolState,
39
+ handleClose,
40
+ handleSuccess,
41
+ }: SolanaLendAddRedemptionProps): React.ReactElement | null {
42
+ const dispatch = useDispatch()
43
+ const {
44
+ seniorLenderStateAccount,
45
+ juniorLenderStateAccount,
46
+ loading: isLoadingLenderAccounts,
47
+ } = useLenderAccounts(poolInfo.chainId, poolInfo.poolName)
48
+ const {
49
+ seniorTokenAccount,
50
+ juniorTokenAccount,
51
+ loading: isLoadingTokenAccounts,
52
+ } = useTrancheTokenAccounts(poolInfo)
53
+ const { step, errorMessage } = useAppSelector(selectWidgetState)
54
+ const [selectedTranche, setSelectedTranche] = useState<TrancheType>()
55
+
56
+ useEffect(() => {
57
+ if (!step && !isLoadingLenderAccounts && !isLoadingTokenAccounts) {
58
+ const seniorTrancheShares = new BN(seniorTokenAccount?.amount)
59
+ const juniorTrancheShares = new BN(juniorTokenAccount?.amount)
60
+
61
+ if (juniorTrancheShares.gtn(0) && seniorTrancheShares.lten(0)) {
62
+ setSelectedTranche('junior')
63
+ dispatch(setStep(WIDGET_STEP.ChooseAmount))
64
+ return
65
+ }
66
+
67
+ if (seniorTrancheShares.gtn(0) && juniorTrancheShares.lten(0)) {
68
+ setSelectedTranche('senior')
69
+ dispatch(setStep(WIDGET_STEP.ChooseAmount))
70
+ return
71
+ }
72
+
73
+ if (seniorTrancheShares.gtn(0) && juniorTrancheShares.gtn(0)) {
74
+ dispatch(setStep(WIDGET_STEP.ChooseTranche))
75
+ }
76
+ }
77
+ }, [
78
+ dispatch,
79
+ step,
80
+ isLoadingLenderAccounts,
81
+ isLoadingTokenAccounts,
82
+ seniorTokenAccount?.amount,
83
+ juniorTokenAccount?.amount,
84
+ ])
85
+
86
+ const title = 'Redemption'
87
+ if (isLoadingLenderAccounts || isLoadingTokenAccounts) {
88
+ return (
89
+ <WidgetWrapper
90
+ isOpen
91
+ isLoading
92
+ loadingTitle={title}
93
+ handleClose={handleClose}
94
+ handleSuccess={handleSuccess}
95
+ />
96
+ )
97
+ }
98
+
99
+ return (
100
+ <WidgetWrapper
101
+ isOpen
102
+ loadingTitle={title}
103
+ handleClose={handleClose}
104
+ handleSuccess={handleSuccess}
105
+ >
106
+ {step === WIDGET_STEP.ChooseTranche && (
107
+ <ChooseTranche
108
+ selectedTranche={selectedTranche}
109
+ changeTranche={setSelectedTranche}
110
+ />
111
+ )}
112
+ {step === WIDGET_STEP.ChooseAmount && selectedTranche && (
113
+ <ChooseAmount
114
+ poolInfo={poolInfo}
115
+ poolState={poolState}
116
+ lenderState={
117
+ selectedTranche === 'senior'
118
+ ? seniorLenderStateAccount
119
+ : juniorLenderStateAccount
120
+ }
121
+ selectedTranche={selectedTranche}
122
+ />
123
+ )}
124
+ {step === WIDGET_STEP.Transfer && selectedTranche && (
125
+ <Transfer poolInfo={poolInfo} selectedTranche={selectedTranche} />
126
+ )}
127
+ {step === WIDGET_STEP.Done && (
128
+ <Done poolInfo={poolInfo} handleAction={handleClose} />
129
+ )}
130
+ {step === WIDGET_STEP.Error && (
131
+ <ErrorModal
132
+ title={title}
133
+ errorReason='Sorry there was an error'
134
+ errorMessage={errorMessage}
135
+ handleOk={handleClose}
136
+ />
137
+ )}
138
+ </WidgetWrapper>
139
+ )
140
+ }
@@ -0,0 +1,114 @@
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='Cancel 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
+ }
@@ -0,0 +1,99 @@
1
+ import {
2
+ getTokenAccounts,
3
+ SolanaPoolInfo,
4
+ TrancheType,
5
+ } from '@huma-finance/shared'
6
+ import React, { useCallback, useEffect, useState } from 'react'
7
+
8
+ import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'
9
+ import { useWallet } from '@solana/wallet-adapter-react'
10
+ import { LenderStateAccount, useHumaProgram } from '@huma-finance/web-shared'
11
+ import { Transaction } from '@solana/web3.js'
12
+ import { useAppDispatch } from '../../../hooks/useRedux'
13
+ import { setStep } from '../../../store/widgets.reducers'
14
+ import { WIDGET_STEP } from '../../../store/widgets.store'
15
+ import { SolanaTxSendModal } from '../../SolanaTxSendModal'
16
+
17
+ type Props = {
18
+ poolInfo: SolanaPoolInfo
19
+ lenderState: LenderStateAccount | null | undefined
20
+ lenderStatePDA: string | null | undefined
21
+ selectedTranche: TrancheType
22
+ }
23
+
24
+ export function Transfer({
25
+ poolInfo,
26
+ lenderState,
27
+ lenderStatePDA,
28
+ selectedTranche,
29
+ }: Props): React.ReactElement | null {
30
+ const dispatch = useAppDispatch()
31
+ const { publicKey } = useWallet()
32
+ const [transaction, setTransaction] = useState<Transaction>()
33
+ const program = useHumaProgram(poolInfo.chainId)
34
+
35
+ const handleSuccess = useCallback(() => {
36
+ dispatch(setStep(WIDGET_STEP.Done))
37
+ }, [dispatch])
38
+
39
+ useEffect(() => {
40
+ async function getTx() {
41
+ if (!publicKey || !lenderState || !lenderStatePDA || transaction) {
42
+ return
43
+ }
44
+
45
+ const {
46
+ seniorTrancheATA,
47
+ juniorTrancheATA,
48
+ poolSeniorTrancheATA,
49
+ poolJuniorTrancheATA,
50
+ } = getTokenAccounts(poolInfo, publicKey)
51
+ const tx = await program.methods
52
+ .cancelRedemptionRequest(
53
+ lenderState.redemptionRecord.numSharesRequested,
54
+ )
55
+ .accountsPartial({
56
+ lender: publicKey,
57
+ humaConfig: poolInfo.humaConfig,
58
+ poolConfig: poolInfo.poolConfig,
59
+ trancheMint:
60
+ selectedTranche === 'senior'
61
+ ? poolInfo.seniorTrancheMint
62
+ : poolInfo.juniorTrancheMint,
63
+ trancheState:
64
+ selectedTranche === 'senior'
65
+ ? poolInfo.seniorTrancheState
66
+ : poolInfo.juniorTrancheState,
67
+ lenderState: lenderStatePDA,
68
+ poolAuthority: poolInfo.poolAuthority,
69
+ poolTrancheToken:
70
+ selectedTranche === 'senior'
71
+ ? poolSeniorTrancheATA
72
+ : poolJuniorTrancheATA,
73
+ lenderTrancheToken:
74
+ selectedTranche === 'senior' ? seniorTrancheATA : juniorTrancheATA,
75
+ tokenProgram: TOKEN_2022_PROGRAM_ID,
76
+ })
77
+ .transaction()
78
+
79
+ setTransaction(tx)
80
+ }
81
+ getTx()
82
+ }, [
83
+ lenderState,
84
+ lenderStatePDA,
85
+ poolInfo,
86
+ program.methods,
87
+ publicKey,
88
+ selectedTranche,
89
+ transaction,
90
+ ])
91
+
92
+ return (
93
+ <SolanaTxSendModal
94
+ tx={transaction}
95
+ chainId={poolInfo.chainId}
96
+ handleSuccess={handleSuccess}
97
+ />
98
+ )
99
+ }
@@ -0,0 +1,55 @@
1
+ import {
2
+ formatNumber,
3
+ SolanaPoolInfo,
4
+ SolanaTokenUtils,
5
+ TrancheType,
6
+ } from '@huma-finance/shared'
7
+ import React from 'react'
8
+
9
+ import {
10
+ LenderStateAccount,
11
+ useTrancheMintAccounts,
12
+ } from '@huma-finance/web-shared'
13
+ import { SolanaTxDoneModal } from '../../SolanaTxDoneModal'
14
+ import { useAppSelector } from '../../../hooks/useRedux'
15
+ import { selectWidgetState } from '../../../store/widgets.selectors'
16
+
17
+ type Props = {
18
+ poolInfo: SolanaPoolInfo
19
+ lenderState: LenderStateAccount | null | undefined
20
+ selectedTranche: TrancheType
21
+ handleAction: () => void
22
+ }
23
+
24
+ export function Done({
25
+ poolInfo,
26
+ lenderState,
27
+ selectedTranche,
28
+ handleAction,
29
+ }: Props): React.ReactElement | null {
30
+ const { mintAccount, loading: isLoadingTrancheMintAccounts } =
31
+ useTrancheMintAccounts(poolInfo, selectedTranche)
32
+ const { solanaSignature } = useAppSelector(selectWidgetState)
33
+
34
+ const content =
35
+ !lenderState || isLoadingTrancheMintAccounts || !mintAccount
36
+ ? ['']
37
+ : [
38
+ `Your request to cancel the redemption of ${formatNumber(
39
+ SolanaTokenUtils.formatUnits(
40
+ lenderState.redemptionRecord.numSharesRequested,
41
+ mintAccount.decimals,
42
+ ),
43
+ )} shares has been successfully processed.`,
44
+ ]
45
+
46
+ return (
47
+ <SolanaTxDoneModal
48
+ handleAction={handleAction}
49
+ content={content}
50
+ chainId={poolInfo.chainId}
51
+ solanaSignature={solanaSignature}
52
+ buttonText='DONE'
53
+ />
54
+ )
55
+ }
@@ -0,0 +1,152 @@
1
+ import { SolanaPoolInfo, TrancheType } from '@huma-finance/shared'
2
+ import { useLenderAccounts } from '@huma-finance/web-shared'
3
+ import React, { useEffect, useState } from 'react'
4
+ import { useDispatch } from 'react-redux'
5
+
6
+ import { BN } from '@coral-xyz/anchor'
7
+ import { useAppSelector } from '../../../hooks/useRedux'
8
+ import { selectWidgetState } from '../../../store/widgets.selectors'
9
+ import { WidgetWrapper } from '../../WidgetWrapper'
10
+ import { WIDGET_STEP } from '../../../store/widgets.store'
11
+ import { setStep } from '../../../store/widgets.reducers'
12
+ import { ErrorModal } from '../../ErrorModal'
13
+ import { Transfer } from './2-Transfer'
14
+ import { ChooseTranche } from './1-ChooseTranche'
15
+ import { Done } from './3-Done'
16
+
17
+ /**
18
+ * Lend pool supply props
19
+ * @typedef {Object} SolanaLendCancelRedemptionProps
20
+ * @property {SolanaPoolInfo} poolInfo The metadata of the pool.
21
+ * @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.
22
+ * @property {function():void|undefined} handleSuccess Optional function to notify that the lending pool supply action is successful.
23
+ */
24
+ export interface SolanaLendCancelRedemptionProps {
25
+ poolInfo: SolanaPoolInfo
26
+ handleClose: () => void
27
+ handleSuccess?: () => void
28
+ }
29
+
30
+ export function SolanaLendCancelRedemption({
31
+ poolInfo,
32
+ handleClose,
33
+ handleSuccess,
34
+ }: SolanaLendCancelRedemptionProps): React.ReactElement | null {
35
+ const dispatch = useDispatch()
36
+ const {
37
+ seniorLenderStateAccount,
38
+ juniorLenderStateAccount,
39
+ juniorLenderStateAccountPDA,
40
+ seniorLenderStateAccountPDA,
41
+ loading: isLoadingLenderAccounts,
42
+ } = useLenderAccounts(poolInfo.chainId, poolInfo.poolName)
43
+ const { step, errorMessage } = useAppSelector(selectWidgetState)
44
+ const [selectedTranche, setSelectedTranche] = useState<TrancheType>()
45
+
46
+ useEffect(() => {
47
+ if (!step && !isLoadingLenderAccounts) {
48
+ const seniorTrancheSharesRequested = new BN(
49
+ seniorLenderStateAccount?.redemptionRecord.numSharesRequested,
50
+ )
51
+ const juniorTrancheSharesRequested = new BN(
52
+ juniorLenderStateAccount?.redemptionRecord.numSharesRequested,
53
+ )
54
+
55
+ if (
56
+ juniorTrancheSharesRequested.gtn(0) &&
57
+ seniorTrancheSharesRequested.lten(0)
58
+ ) {
59
+ setSelectedTranche('junior')
60
+ dispatch(setStep(WIDGET_STEP.Transfer))
61
+ return
62
+ }
63
+
64
+ if (
65
+ seniorTrancheSharesRequested.gtn(0) &&
66
+ juniorTrancheSharesRequested.lten(0)
67
+ ) {
68
+ setSelectedTranche('senior')
69
+ dispatch(setStep(WIDGET_STEP.Transfer))
70
+ return
71
+ }
72
+
73
+ if (
74
+ seniorTrancheSharesRequested.gtn(0) &&
75
+ juniorTrancheSharesRequested.gtn(0)
76
+ ) {
77
+ dispatch(setStep(WIDGET_STEP.ChooseTranche))
78
+ }
79
+ }
80
+ }, [
81
+ dispatch,
82
+ step,
83
+ isLoadingLenderAccounts,
84
+ seniorLenderStateAccount?.redemptionRecord.numSharesRequested,
85
+ juniorLenderStateAccount?.redemptionRecord.numSharesRequested,
86
+ ])
87
+
88
+ const title = 'Cancel Redemption'
89
+ if (isLoadingLenderAccounts) {
90
+ return (
91
+ <WidgetWrapper
92
+ isOpen
93
+ isLoading
94
+ loadingTitle={title}
95
+ handleClose={handleClose}
96
+ handleSuccess={handleSuccess}
97
+ />
98
+ )
99
+ }
100
+
101
+ return (
102
+ <WidgetWrapper
103
+ isOpen
104
+ loadingTitle={title}
105
+ handleClose={handleClose}
106
+ handleSuccess={handleSuccess}
107
+ >
108
+ {step === WIDGET_STEP.ChooseTranche && (
109
+ <ChooseTranche
110
+ selectedTranche={selectedTranche}
111
+ changeTranche={setSelectedTranche}
112
+ />
113
+ )}
114
+ {step === WIDGET_STEP.Transfer && selectedTranche && (
115
+ <Transfer
116
+ poolInfo={poolInfo}
117
+ lenderState={
118
+ selectedTranche === 'senior'
119
+ ? seniorLenderStateAccount
120
+ : juniorLenderStateAccount
121
+ }
122
+ lenderStatePDA={
123
+ selectedTranche === 'senior'
124
+ ? seniorLenderStateAccountPDA
125
+ : juniorLenderStateAccountPDA
126
+ }
127
+ selectedTranche={selectedTranche}
128
+ />
129
+ )}
130
+ {step === WIDGET_STEP.Done && selectedTranche && (
131
+ <Done
132
+ poolInfo={poolInfo}
133
+ lenderState={
134
+ selectedTranche === 'senior'
135
+ ? seniorLenderStateAccount
136
+ : juniorLenderStateAccount
137
+ }
138
+ selectedTranche={selectedTranche}
139
+ handleAction={handleClose}
140
+ />
141
+ )}
142
+ {step === WIDGET_STEP.Error && (
143
+ <ErrorModal
144
+ title={title}
145
+ errorReason='Sorry there was an error'
146
+ errorMessage={errorMessage}
147
+ handleOk={handleClose}
148
+ />
149
+ )}
150
+ </WidgetWrapper>
151
+ )
152
+ }