@huma-finance/widgets 0.0.62-beta.716 → 0.0.62-beta.719
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.
- package/API.md +38 -0
- package/dist/cjs/index.cjs +442 -186
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +444 -189
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/Lend/solanaEnableAutoRedemption/1-ApproveAllowance.tsx +63 -0
- package/src/components/Lend/solanaEnableAutoRedemption/2-Transfer.tsx +167 -0
- package/src/components/Lend/solanaEnableAutoRedemption/3-Success.tsx +45 -0
- package/src/components/Lend/solanaEnableAutoRedemption/index.tsx +76 -0
- package/src/components/Lend/solanaSupply/3-ChooseAmount.tsx +2 -2
- package/src/components/Lend/solanaSupply/4-ApproveAllowance.tsx +59 -0
- package/src/components/Lend/solanaSupply/4-Transfer.tsx +29 -7
- package/src/components/Lend/solanaSupply/index.tsx +4 -0
- package/src/index.tsx +26 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huma-finance/widgets",
|
|
3
|
-
"version": "0.0.62-beta.
|
|
3
|
+
"version": "0.0.62-beta.719+d4756b7",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"@ethersproject/units": "^5.6.0",
|
|
32
32
|
"@huma-finance/sdk": "^0.0.61",
|
|
33
33
|
"@huma-finance/shared": "^0.0.61",
|
|
34
|
-
"@huma-finance/web-shared": "^0.0.
|
|
34
|
+
"@huma-finance/web-shared": "^0.0.62-beta.719+d4756b7",
|
|
35
35
|
"@mui/icons-material": "^5.3.0",
|
|
36
36
|
"@mui/material": "^5.0.6",
|
|
37
37
|
"@mui/styles": "^5.0.2",
|
|
@@ -203,5 +203,5 @@
|
|
|
203
203
|
"optionalDependencies": {
|
|
204
204
|
"encoding": "^0.1.13"
|
|
205
205
|
},
|
|
206
|
-
"gitHead": "
|
|
206
|
+
"gitHead": "d4756b72702a52dc37fde2cc07b421755f63eb84"
|
|
207
207
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { timeUtil } from '@huma-finance/shared'
|
|
2
|
+
import { SolanaPoolState } from '@huma-finance/web-shared'
|
|
3
|
+
import dayjs from 'dayjs'
|
|
4
|
+
import React, { useCallback } from 'react'
|
|
5
|
+
import { Box, css, useTheme } from '@mui/material'
|
|
6
|
+
import { useAppDispatch } from '../../../hooks/useRedux'
|
|
7
|
+
import { WrapperModal } from '../../WrapperModal'
|
|
8
|
+
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
9
|
+
import { setStep } from '../../../store/widgets.reducers'
|
|
10
|
+
import { BottomButton } from '../../BottomButton'
|
|
11
|
+
import { AutoPaybackImg } from '../../images'
|
|
12
|
+
|
|
13
|
+
type Props = {
|
|
14
|
+
poolState: SolanaPoolState
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function ApproveAllowance({ poolState }: Props): React.ReactElement {
|
|
18
|
+
const theme = useTheme()
|
|
19
|
+
const dispatch = useAppDispatch()
|
|
20
|
+
const handleNext = useCallback(() => {
|
|
21
|
+
dispatch(setStep(WIDGET_STEP.Transfer))
|
|
22
|
+
}, [dispatch])
|
|
23
|
+
|
|
24
|
+
const styles = {
|
|
25
|
+
iconWrapper: css`
|
|
26
|
+
${theme.cssMixins.rowCentered};
|
|
27
|
+
margin-top: ${theme.spacing(6)};
|
|
28
|
+
& > img {
|
|
29
|
+
width: 220px;
|
|
30
|
+
}
|
|
31
|
+
`,
|
|
32
|
+
description: css`
|
|
33
|
+
margin-top: ${theme.spacing(4)};
|
|
34
|
+
font-weight: 400;
|
|
35
|
+
font-size: 16px;
|
|
36
|
+
color: ${theme.palette.text.secondary};
|
|
37
|
+
padding: ${theme.spacing(0, 1)};
|
|
38
|
+
`,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const lockupEndTime = dayjs()
|
|
42
|
+
.add(poolState.withdrawalLockupPeriodDays ?? 0, 'day')
|
|
43
|
+
.date(1)
|
|
44
|
+
const withdrawTime = lockupEndTime.add(1, 'month')
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<WrapperModal title='Auto-Redemption'>
|
|
48
|
+
<Box css={styles.iconWrapper}>
|
|
49
|
+
<img src={AutoPaybackImg} alt='auto-payback' />
|
|
50
|
+
</Box>
|
|
51
|
+
<Box css={styles.description}>
|
|
52
|
+
This allowance transaction will enable auto-redemption for your existing
|
|
53
|
+
tranche shares. Redemption requests will be automatically submitted on{' '}
|
|
54
|
+
{timeUtil.timestampToLL(lockupEndTime.unix())}. Your deposit can be
|
|
55
|
+
redeemed and yield rewards will stop on{' '}
|
|
56
|
+
{timeUtil.timestampToLL(withdrawTime.unix())}.
|
|
57
|
+
</Box>
|
|
58
|
+
<BottomButton variant='contained' onClick={handleNext}>
|
|
59
|
+
APPROVE ALLOWANCE
|
|
60
|
+
</BottomButton>
|
|
61
|
+
</WrapperModal>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getSentinelAddress,
|
|
3
|
+
getTokenAccounts,
|
|
4
|
+
SolanaPoolInfo,
|
|
5
|
+
} from '@huma-finance/shared'
|
|
6
|
+
import React, { useCallback, useEffect, useState } from 'react'
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
notEnabledAutoRedeem,
|
|
10
|
+
SolanaPoolState,
|
|
11
|
+
useHumaProgram,
|
|
12
|
+
useLenderAccounts,
|
|
13
|
+
useTrancheTokenAccounts,
|
|
14
|
+
} from '@huma-finance/web-shared'
|
|
15
|
+
import {
|
|
16
|
+
createApproveCheckedInstruction,
|
|
17
|
+
TOKEN_2022_PROGRAM_ID,
|
|
18
|
+
} from '@solana/spl-token'
|
|
19
|
+
import { useWallet } from '@solana/wallet-adapter-react'
|
|
20
|
+
import { PublicKey, Transaction } from '@solana/web3.js'
|
|
21
|
+
import { useAppDispatch } from '../../../hooks/useRedux'
|
|
22
|
+
import { setError, setStep } from '../../../store/widgets.reducers'
|
|
23
|
+
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
24
|
+
import { LoadingModal } from '../../LoadingModal'
|
|
25
|
+
import { SolanaTxSendModal } from '../../SolanaTxSendModal'
|
|
26
|
+
|
|
27
|
+
type Props = {
|
|
28
|
+
poolInfo: SolanaPoolInfo
|
|
29
|
+
poolState: SolanaPoolState
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function Transfer({
|
|
33
|
+
poolInfo,
|
|
34
|
+
poolState,
|
|
35
|
+
}: Props): React.ReactElement | null {
|
|
36
|
+
const dispatch = useAppDispatch()
|
|
37
|
+
const { publicKey } = useWallet()
|
|
38
|
+
const sentinel = getSentinelAddress(poolInfo.chainId)
|
|
39
|
+
const [transaction, setTransaction] = useState<Transaction>()
|
|
40
|
+
const {
|
|
41
|
+
juniorLenderApprovedAccountPDA,
|
|
42
|
+
seniorLenderApprovedAccountPDA,
|
|
43
|
+
seniorLenderStateAccount,
|
|
44
|
+
juniorLenderStateAccount,
|
|
45
|
+
seniorTrancheMintSupply,
|
|
46
|
+
juniorTrancheMintSupply,
|
|
47
|
+
loading: isLoadingLenderAccounts,
|
|
48
|
+
} = useLenderAccounts(poolInfo.chainId, poolInfo.poolName)
|
|
49
|
+
const {
|
|
50
|
+
seniorTokenAccount,
|
|
51
|
+
juniorTokenAccount,
|
|
52
|
+
loading: isLoadingTrancheTokenAccounts,
|
|
53
|
+
} = useTrancheTokenAccounts(poolInfo)
|
|
54
|
+
const program = useHumaProgram(poolInfo.chainId)
|
|
55
|
+
|
|
56
|
+
const handleSuccess = useCallback(() => {
|
|
57
|
+
dispatch(setStep(WIDGET_STEP.Done))
|
|
58
|
+
}, [dispatch])
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
async function getTx() {
|
|
62
|
+
if (
|
|
63
|
+
!publicKey ||
|
|
64
|
+
transaction ||
|
|
65
|
+
isLoadingLenderAccounts ||
|
|
66
|
+
isLoadingTrancheTokenAccounts
|
|
67
|
+
) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const tx = new Transaction()
|
|
72
|
+
|
|
73
|
+
const { seniorTrancheATA, juniorTrancheATA } = getTokenAccounts(
|
|
74
|
+
poolInfo,
|
|
75
|
+
publicKey,
|
|
76
|
+
)
|
|
77
|
+
const poolAuthorityPubkey = new PublicKey(poolInfo.poolAuthority)
|
|
78
|
+
|
|
79
|
+
if (!seniorTokenAccount?.amount && !juniorTokenAccount?.amount) {
|
|
80
|
+
dispatch(
|
|
81
|
+
setError({ errorMessage: 'Error reading tranche token balance' }),
|
|
82
|
+
)
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
if (
|
|
86
|
+
notEnabledAutoRedeem(
|
|
87
|
+
seniorTokenAccount,
|
|
88
|
+
poolAuthorityPubkey,
|
|
89
|
+
seniorTokenAccount?.amount,
|
|
90
|
+
)
|
|
91
|
+
) {
|
|
92
|
+
tx.add(
|
|
93
|
+
createApproveCheckedInstruction(
|
|
94
|
+
seniorTrancheATA,
|
|
95
|
+
new PublicKey(poolInfo.seniorTrancheMint),
|
|
96
|
+
poolAuthorityPubkey, // delegate
|
|
97
|
+
publicKey, // owner of the wallet
|
|
98
|
+
BigInt(seniorTokenAccount?.amount.toString() ?? 0), // amount
|
|
99
|
+
poolInfo.trancheDecimals,
|
|
100
|
+
undefined, // multiSigners
|
|
101
|
+
TOKEN_2022_PROGRAM_ID,
|
|
102
|
+
),
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
if (
|
|
106
|
+
notEnabledAutoRedeem(
|
|
107
|
+
juniorTokenAccount,
|
|
108
|
+
poolAuthorityPubkey,
|
|
109
|
+
juniorTokenAccount?.amount,
|
|
110
|
+
)
|
|
111
|
+
) {
|
|
112
|
+
tx.add(
|
|
113
|
+
createApproveCheckedInstruction(
|
|
114
|
+
juniorTrancheATA,
|
|
115
|
+
new PublicKey(poolInfo.juniorTrancheMint),
|
|
116
|
+
poolAuthorityPubkey, // delegate
|
|
117
|
+
publicKey, // owner of the wallet
|
|
118
|
+
BigInt(juniorTokenAccount?.amount.toString() ?? 0), // amount
|
|
119
|
+
poolInfo.trancheDecimals,
|
|
120
|
+
undefined, // multiSigners
|
|
121
|
+
TOKEN_2022_PROGRAM_ID,
|
|
122
|
+
),
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
if (!tx.instructions.length) {
|
|
126
|
+
dispatch(
|
|
127
|
+
setError({ errorMessage: 'No tranches require Auto-Redemption' }),
|
|
128
|
+
)
|
|
129
|
+
return
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
setTransaction(tx)
|
|
133
|
+
}
|
|
134
|
+
getTx()
|
|
135
|
+
}, [
|
|
136
|
+
dispatch,
|
|
137
|
+
isLoadingLenderAccounts,
|
|
138
|
+
isLoadingTrancheTokenAccounts,
|
|
139
|
+
juniorLenderApprovedAccountPDA,
|
|
140
|
+
juniorLenderStateAccount,
|
|
141
|
+
juniorTokenAccount,
|
|
142
|
+
juniorTrancheMintSupply,
|
|
143
|
+
poolInfo,
|
|
144
|
+
poolState.juniorTrancheAssets,
|
|
145
|
+
poolState.seniorTrancheAssets,
|
|
146
|
+
program.methods,
|
|
147
|
+
publicKey,
|
|
148
|
+
seniorLenderApprovedAccountPDA,
|
|
149
|
+
seniorLenderStateAccount,
|
|
150
|
+
seniorTokenAccount,
|
|
151
|
+
seniorTrancheMintSupply,
|
|
152
|
+
sentinel,
|
|
153
|
+
transaction,
|
|
154
|
+
])
|
|
155
|
+
|
|
156
|
+
if (isLoadingLenderAccounts || isLoadingTrancheTokenAccounts) {
|
|
157
|
+
return <LoadingModal title='Auto-Redeem' />
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<SolanaTxSendModal
|
|
162
|
+
tx={transaction}
|
|
163
|
+
chainId={poolInfo.chainId}
|
|
164
|
+
handleSuccess={handleSuccess}
|
|
165
|
+
/>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CloseModalOptions,
|
|
3
|
+
SolanaPoolInfo,
|
|
4
|
+
timeUtil,
|
|
5
|
+
} from '@huma-finance/shared'
|
|
6
|
+
import { getLenderLockupDates, SolanaPoolState } from '@huma-finance/web-shared'
|
|
7
|
+
import React from 'react'
|
|
8
|
+
import { useAppSelector } from '../../../hooks/useRedux'
|
|
9
|
+
import { selectWidgetState } from '../../../store/widgets.selectors'
|
|
10
|
+
import { SolanaTxDoneModal } from '../../SolanaTxDoneModal'
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
poolInfo: SolanaPoolInfo
|
|
14
|
+
poolState: SolanaPoolState
|
|
15
|
+
handleAction: (options?: CloseModalOptions) => void
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function Success({
|
|
19
|
+
poolInfo,
|
|
20
|
+
poolState,
|
|
21
|
+
handleAction,
|
|
22
|
+
}: Props): React.ReactElement {
|
|
23
|
+
const { solanaSignature } = useAppSelector(selectWidgetState)
|
|
24
|
+
|
|
25
|
+
const { lockupEndTimeUnix, withdrawTimeUnix } = getLenderLockupDates(
|
|
26
|
+
poolState.withdrawalLockupPeriodDays ?? 0,
|
|
27
|
+
)
|
|
28
|
+
const content = [
|
|
29
|
+
`Redemption request will be automatically submitted on ${timeUtil.timestampToLL(
|
|
30
|
+
lockupEndTimeUnix,
|
|
31
|
+
)}. Your deposit can be redeemed and yield rewards will stop on ${timeUtil.timestampToLL(
|
|
32
|
+
withdrawTimeUnix,
|
|
33
|
+
)}.`,
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<SolanaTxDoneModal
|
|
38
|
+
handleAction={handleAction}
|
|
39
|
+
content={content}
|
|
40
|
+
chainId={poolInfo.chainId}
|
|
41
|
+
solanaSignature={solanaSignature}
|
|
42
|
+
buttonText='DONE'
|
|
43
|
+
/>
|
|
44
|
+
)
|
|
45
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { CloseModalOptions, SolanaPoolInfo } from '@huma-finance/shared'
|
|
2
|
+
import { SolanaPoolState } 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 { setStep } from '../../../store/widgets.reducers'
|
|
8
|
+
import { selectWidgetState } from '../../../store/widgets.selectors'
|
|
9
|
+
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
10
|
+
import { ErrorModal } from '../../ErrorModal'
|
|
11
|
+
import { WidgetWrapper } from '../../WidgetWrapper'
|
|
12
|
+
import { Transfer } from './2-Transfer'
|
|
13
|
+
import { Success } from './3-Success'
|
|
14
|
+
import { ApproveAllowance } from './1-ApproveAllowance'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Lend pool supply props
|
|
18
|
+
* @typedef {Object} SolanaEnableAutoRedemptionProps
|
|
19
|
+
* @property {SolanaPoolInfo} poolInfo The metadata of the pool.
|
|
20
|
+
* @property {SolanaPoolState} poolState The current state config of the pool.
|
|
21
|
+
* @property {function((CloseModalOptions|undefined)):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 SolanaEnableAutoRedemptionProps {
|
|
25
|
+
poolInfo: SolanaPoolInfo
|
|
26
|
+
poolState: SolanaPoolState
|
|
27
|
+
handleClose: (options?: CloseModalOptions) => void
|
|
28
|
+
handleSuccess?: () => void
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function SolanaEnableAutoRedemption({
|
|
32
|
+
poolInfo,
|
|
33
|
+
poolState,
|
|
34
|
+
handleClose,
|
|
35
|
+
handleSuccess,
|
|
36
|
+
}: SolanaEnableAutoRedemptionProps): React.ReactElement | null {
|
|
37
|
+
const dispatch = useDispatch()
|
|
38
|
+
const { step, errorMessage } = useAppSelector(selectWidgetState)
|
|
39
|
+
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (!step) {
|
|
42
|
+
dispatch(setStep(WIDGET_STEP.ApproveAllowance))
|
|
43
|
+
}
|
|
44
|
+
}, [dispatch, step])
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<WidgetWrapper
|
|
48
|
+
isOpen
|
|
49
|
+
loadingTitle='Auto-Redemption'
|
|
50
|
+
handleClose={handleClose}
|
|
51
|
+
handleSuccess={handleSuccess}
|
|
52
|
+
>
|
|
53
|
+
{step === WIDGET_STEP.ApproveAllowance && (
|
|
54
|
+
<ApproveAllowance poolState={poolState} />
|
|
55
|
+
)}
|
|
56
|
+
{step === WIDGET_STEP.Transfer && (
|
|
57
|
+
<Transfer poolInfo={poolInfo} poolState={poolState} />
|
|
58
|
+
)}
|
|
59
|
+
{step === WIDGET_STEP.Done && (
|
|
60
|
+
<Success
|
|
61
|
+
poolInfo={poolInfo}
|
|
62
|
+
poolState={poolState}
|
|
63
|
+
handleAction={handleClose}
|
|
64
|
+
/>
|
|
65
|
+
)}
|
|
66
|
+
{step === WIDGET_STEP.Error && (
|
|
67
|
+
<ErrorModal
|
|
68
|
+
title='Auto-Redemption'
|
|
69
|
+
errorReason='Sorry there was an error'
|
|
70
|
+
errorMessage={errorMessage}
|
|
71
|
+
handleOk={handleClose}
|
|
72
|
+
/>
|
|
73
|
+
)}
|
|
74
|
+
</WidgetWrapper>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
@@ -66,7 +66,7 @@ export function ChooseAmount({
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
const handleAction = () => {
|
|
69
|
-
dispatch(setStep(WIDGET_STEP.
|
|
69
|
+
dispatch(setStep(WIDGET_STEP.ApproveAllowance))
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
const getTrancheCap = () => {
|
|
@@ -125,7 +125,7 @@ export function ChooseAmount({
|
|
|
125
125
|
)} balance`}
|
|
126
126
|
infos={getInfos()}
|
|
127
127
|
handleAction={handleAction}
|
|
128
|
-
actionText='
|
|
128
|
+
actionText='NEXT'
|
|
129
129
|
/>
|
|
130
130
|
)
|
|
131
131
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useCallback } from 'react'
|
|
2
|
+
import { Box, css, useTheme } from '@mui/material'
|
|
3
|
+
import { getLenderLockupDates, SolanaPoolState } from '@huma-finance/web-shared'
|
|
4
|
+
import { timeUtil } from '@huma-finance/shared'
|
|
5
|
+
import { useAppDispatch } from '../../../hooks/useRedux'
|
|
6
|
+
import { WrapperModal } from '../../WrapperModal'
|
|
7
|
+
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
8
|
+
import { setStep } from '../../../store/widgets.reducers'
|
|
9
|
+
import { BottomButton } from '../../BottomButton'
|
|
10
|
+
import { AutoPaybackImg } from '../../images'
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
poolState: SolanaPoolState
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function ApproveAllowance({ poolState }: Props): React.ReactElement {
|
|
17
|
+
const theme = useTheme()
|
|
18
|
+
const dispatch = useAppDispatch()
|
|
19
|
+
const handleNext = useCallback(() => {
|
|
20
|
+
dispatch(setStep(WIDGET_STEP.Transfer))
|
|
21
|
+
}, [dispatch])
|
|
22
|
+
|
|
23
|
+
const styles = {
|
|
24
|
+
iconWrapper: css`
|
|
25
|
+
${theme.cssMixins.rowCentered};
|
|
26
|
+
margin-top: ${theme.spacing(6)};
|
|
27
|
+
& > img {
|
|
28
|
+
width: 220px;
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
description: css`
|
|
32
|
+
margin-top: ${theme.spacing(4)};
|
|
33
|
+
font-weight: 400;
|
|
34
|
+
font-size: 16px;
|
|
35
|
+
color: ${theme.palette.text.secondary};
|
|
36
|
+
padding: ${theme.spacing(0, 1)};
|
|
37
|
+
`,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const { lockupEndTimeUnix } = getLenderLockupDates(
|
|
41
|
+
poolState.withdrawalLockupPeriodDays ?? 0,
|
|
42
|
+
)
|
|
43
|
+
return (
|
|
44
|
+
<WrapperModal title='Auto-Redemption'>
|
|
45
|
+
<Box css={styles.iconWrapper}>
|
|
46
|
+
<img src={AutoPaybackImg} alt='auto-payback' />
|
|
47
|
+
</Box>
|
|
48
|
+
<Box css={styles.description}>
|
|
49
|
+
This transaction will also enable auto-redemption for your tranche
|
|
50
|
+
shares by approving our automation account as a delegate. Redemption
|
|
51
|
+
requests will be automatically submitted on{' '}
|
|
52
|
+
{timeUtil.timestampToLL(lockupEndTimeUnix)}.
|
|
53
|
+
</Box>
|
|
54
|
+
<BottomButton variant='contained' onClick={handleNext}>
|
|
55
|
+
SUPPLY
|
|
56
|
+
</BottomButton>
|
|
57
|
+
</WrapperModal>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
CampaignService,
|
|
3
3
|
checkIsDev,
|
|
4
4
|
convertToShares,
|
|
5
|
-
getSentinelAddress,
|
|
6
5
|
getTokenAccounts,
|
|
7
6
|
SolanaPoolInfo,
|
|
8
7
|
SolanaTokenUtils,
|
|
@@ -14,6 +13,7 @@ import {
|
|
|
14
13
|
SolanaPoolState,
|
|
15
14
|
useHumaProgram,
|
|
16
15
|
useLenderAccounts,
|
|
16
|
+
useTrancheTokenAccounts,
|
|
17
17
|
} from '@huma-finance/web-shared'
|
|
18
18
|
import {
|
|
19
19
|
createApproveCheckedInstruction,
|
|
@@ -46,7 +46,6 @@ export function Transfer({
|
|
|
46
46
|
const isDev = checkIsDev()
|
|
47
47
|
const dispatch = useAppDispatch()
|
|
48
48
|
const { publicKey } = useWallet()
|
|
49
|
-
const sentinel = getSentinelAddress(poolInfo.chainId)
|
|
50
49
|
const { supplyAmount } = useAppSelector(selectWidgetState)
|
|
51
50
|
const { decimals } = poolInfo.underlyingMint
|
|
52
51
|
const supplyBigNumber = SolanaTokenUtils.parseUnits(
|
|
@@ -63,6 +62,11 @@ export function Transfer({
|
|
|
63
62
|
juniorTrancheMintSupply,
|
|
64
63
|
loading: isLoadingLenderAccounts,
|
|
65
64
|
} = useLenderAccounts(poolInfo.chainId, poolInfo.poolName)
|
|
65
|
+
const {
|
|
66
|
+
seniorTokenAccount,
|
|
67
|
+
juniorTokenAccount,
|
|
68
|
+
loading: isLoadingTrancheTokenAccounts,
|
|
69
|
+
} = useTrancheTokenAccounts(poolInfo)
|
|
66
70
|
const program = useHumaProgram(poolInfo.chainId)
|
|
67
71
|
|
|
68
72
|
const handleSuccess = useCallback(
|
|
@@ -95,7 +99,12 @@ export function Transfer({
|
|
|
95
99
|
|
|
96
100
|
useEffect(() => {
|
|
97
101
|
async function getTx() {
|
|
98
|
-
if (
|
|
102
|
+
if (
|
|
103
|
+
!publicKey ||
|
|
104
|
+
transaction ||
|
|
105
|
+
isLoadingLenderAccounts ||
|
|
106
|
+
isLoadingTrancheTokenAccounts
|
|
107
|
+
) {
|
|
99
108
|
return
|
|
100
109
|
}
|
|
101
110
|
|
|
@@ -165,6 +174,17 @@ export function Transfer({
|
|
|
165
174
|
: juniorTrancheMintSupply ?? new BN(0),
|
|
166
175
|
supplyBigNumber,
|
|
167
176
|
)
|
|
177
|
+
const existingShares = convertToShares(
|
|
178
|
+
selectedTranche === 'senior'
|
|
179
|
+
? new BN(poolState.seniorTrancheAssets ?? 0)
|
|
180
|
+
: new BN(poolState.juniorTrancheAssets ?? 0),
|
|
181
|
+
selectedTranche === 'senior'
|
|
182
|
+
? seniorTrancheMintSupply ?? new BN(0)
|
|
183
|
+
: juniorTrancheMintSupply ?? new BN(0),
|
|
184
|
+
selectedTranche === 'senior'
|
|
185
|
+
? new BN(seniorTokenAccount?.amount.toString() ?? '0')
|
|
186
|
+
: new BN(juniorTokenAccount?.amount.toString() ?? '0'),
|
|
187
|
+
)
|
|
168
188
|
tx.add(
|
|
169
189
|
createApproveCheckedInstruction(
|
|
170
190
|
selectedTranche === 'senior' ? seniorTrancheATA : juniorTrancheATA,
|
|
@@ -173,9 +193,9 @@ export function Transfer({
|
|
|
173
193
|
? poolInfo.seniorTrancheMint
|
|
174
194
|
: poolInfo.juniorTrancheMint,
|
|
175
195
|
),
|
|
176
|
-
new PublicKey(
|
|
196
|
+
new PublicKey(poolInfo.poolAuthority), // delegate
|
|
177
197
|
publicKey, // owner of the wallet
|
|
178
|
-
BigInt(sharesAmount.muln(1.1).toString()), // amount
|
|
198
|
+
BigInt(sharesAmount.muln(1.1).add(existingShares).toString()), // amount
|
|
179
199
|
poolInfo.trancheDecimals,
|
|
180
200
|
undefined, // multiSigners
|
|
181
201
|
TOKEN_2022_PROGRAM_ID,
|
|
@@ -187,8 +207,10 @@ export function Transfer({
|
|
|
187
207
|
getTx()
|
|
188
208
|
}, [
|
|
189
209
|
isLoadingLenderAccounts,
|
|
210
|
+
isLoadingTrancheTokenAccounts,
|
|
190
211
|
juniorLenderApprovedAccountPDA,
|
|
191
212
|
juniorLenderStateAccount,
|
|
213
|
+
juniorTokenAccount?.amount,
|
|
192
214
|
juniorTrancheMintSupply,
|
|
193
215
|
poolInfo,
|
|
194
216
|
poolState.juniorTrancheAssets,
|
|
@@ -198,13 +220,13 @@ export function Transfer({
|
|
|
198
220
|
selectedTranche,
|
|
199
221
|
seniorLenderApprovedAccountPDA,
|
|
200
222
|
seniorLenderStateAccount,
|
|
223
|
+
seniorTokenAccount?.amount,
|
|
201
224
|
seniorTrancheMintSupply,
|
|
202
|
-
sentinel,
|
|
203
225
|
supplyBigNumber,
|
|
204
226
|
transaction,
|
|
205
227
|
])
|
|
206
228
|
|
|
207
|
-
if (isLoadingLenderAccounts) {
|
|
229
|
+
if (isLoadingLenderAccounts || isLoadingTrancheTokenAccounts) {
|
|
208
230
|
return <LoadingModal title='Supply' />
|
|
209
231
|
}
|
|
210
232
|
|
|
@@ -23,6 +23,7 @@ import { ChooseTranche } from './2-ChooseTranche'
|
|
|
23
23
|
import { ChooseAmount } from './3-ChooseAmount'
|
|
24
24
|
import { Transfer } from './4-Transfer'
|
|
25
25
|
import { Success } from './5-Success'
|
|
26
|
+
import { ApproveAllowance } from './4-ApproveAllowance'
|
|
26
27
|
|
|
27
28
|
export interface Campaign {
|
|
28
29
|
id: string
|
|
@@ -143,6 +144,9 @@ export function SolanaLendSupply({
|
|
|
143
144
|
isUniTranche={isUniTranche}
|
|
144
145
|
/>
|
|
145
146
|
)}
|
|
147
|
+
{step === WIDGET_STEP.ApproveAllowance && (
|
|
148
|
+
<ApproveAllowance poolState={poolState} />
|
|
149
|
+
)}
|
|
146
150
|
{step === WIDGET_STEP.Transfer && selectedTranche && (
|
|
147
151
|
<Transfer
|
|
148
152
|
poolInfo={poolInfo}
|
package/src/index.tsx
CHANGED
|
@@ -90,6 +90,10 @@ import {
|
|
|
90
90
|
SolanaPaymentProps,
|
|
91
91
|
} from './components/CreditLine/solanaPayment'
|
|
92
92
|
import { NotifiContextWrapper } from './components/Notifi/NotifiContextWrapper'
|
|
93
|
+
import {
|
|
94
|
+
SolanaEnableAutoRedemption,
|
|
95
|
+
SolanaEnableAutoRedemptionProps,
|
|
96
|
+
} from './components/Lend/solanaEnableAutoRedemption'
|
|
93
97
|
|
|
94
98
|
/**
|
|
95
99
|
* Mapping of your JSON-RPC connections indexed by chainId
|
|
@@ -667,4 +671,26 @@ export function SolanaPaymentWidget(props: SolanaPaymentWidgetProps) {
|
|
|
667
671
|
)
|
|
668
672
|
}
|
|
669
673
|
|
|
674
|
+
/**
|
|
675
|
+
* Lend pool supply widget props for Solana pools
|
|
676
|
+
* @typedef {Object} SolanaEnableAutoRedemptionWidgetProps
|
|
677
|
+
*/
|
|
678
|
+
type SolanaEnableAutoRedemptionWidgetProps = SolanaEnableAutoRedemptionProps &
|
|
679
|
+
SolanaWidgetProps
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* Lend pool supply widget for Solana pools
|
|
683
|
+
*
|
|
684
|
+
* @param {SolanaEnableAutoRedemptionWidgetProps} props - Widget props
|
|
685
|
+
*/
|
|
686
|
+
export function SolanaEnableAutoRedemptionWidget(
|
|
687
|
+
props: SolanaEnableAutoRedemptionWidgetProps,
|
|
688
|
+
) {
|
|
689
|
+
return (
|
|
690
|
+
<SolanaWidget {...props}>
|
|
691
|
+
<SolanaEnableAutoRedemption {...props} />
|
|
692
|
+
</SolanaWidget>
|
|
693
|
+
)
|
|
694
|
+
}
|
|
695
|
+
|
|
670
696
|
export * from './components/Notifi/NotifiContextWrapper'
|