@huma-finance/widgets 0.0.30 → 0.0.32

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 (27) hide show
  1. package/dist/cjs/index.cjs +911 -179
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/index.js +913 -182
  4. package/dist/index.js.map +1 -1
  5. package/package.json +5 -4
  6. package/src/components/ChooseAmountModal.tsx +322 -322
  7. package/src/components/CreditLine/borrow/5-Success.tsx +9 -1
  8. package/src/components/CreditLine/borrow/6-Notifications.tsx +10 -0
  9. package/src/components/CreditLine/borrow/index.tsx +21 -2
  10. package/src/components/Factoring/UpcomingList.tsx +1 -1
  11. package/src/components/HumaSnackBar.tsx +60 -0
  12. package/src/components/Lend/supply/1-Evaluation/EvaluationEA.tsx +86 -0
  13. package/src/components/Lend/supply/1-Evaluation/EvaluationKYC.tsx +287 -0
  14. package/src/components/Lend/supply/1-Evaluation/index.tsx +31 -0
  15. package/src/components/Lend/supply/2-ChooseAmount.tsx +0 -1
  16. package/src/components/Lend/supply/{7-Success.tsx → 5-Success.tsx} +13 -2
  17. package/src/components/Lend/supply/6-Notifications.tsx +10 -0
  18. package/src/components/Lend/supply/index.tsx +29 -6
  19. package/src/components/Notifi/NotifiSubscriptionModal.tsx +264 -0
  20. package/src/components/SuperfluidFactoring/index.tsx +85 -85
  21. package/src/components/TxDoneModal.tsx +3 -1
  22. package/src/cosmos/SDKTesting.fixture.tsx +616 -615
  23. package/src/hooks/useNotifi.ts +71 -0
  24. package/src/store/widgets.store.ts +1 -0
  25. package/src/components/Lend/supply/1-Evaluation.tsx +0 -171
  26. package/src/components/Lend/supply/4-ConfirmTransfer.tsx +0 -104
  27. /package/src/components/Lend/supply/{6-Transfer.tsx → 4-Transfer.tsx} +0 -0
@@ -9,12 +9,14 @@ type Props = {
9
9
  poolInfo: PoolInfoType
10
10
  creditRecord: CreditRecordType
11
11
  handleAction: () => void
12
+ hasNextStep: boolean
12
13
  }
13
14
 
14
15
  export function Success({
15
16
  poolInfo,
16
17
  creditRecord,
17
18
  handleAction,
19
+ hasNextStep,
18
20
  }: Props): React.ReactElement {
19
21
  const { borrowAmountNet } = useAppSelector(selectWidgetState)
20
22
  const { poolUnderlyingToken } = poolInfo
@@ -26,5 +28,11 @@ export function Success({
26
28
  `Note: your payment will be automatically deducted on ${dueDate}.`,
27
29
  ]
28
30
 
29
- return <TxDoneModal handleAction={handleAction} content={content} />
31
+ return (
32
+ <TxDoneModal
33
+ handleAction={handleAction}
34
+ content={content}
35
+ buttonText={hasNextStep ? "WHAT'S NEXT" : undefined}
36
+ />
37
+ )
30
38
  }
@@ -0,0 +1,10 @@
1
+ import React from 'react'
2
+ import { NotifiSubscriptionModal } from '../../Notifi/NotifiSubscriptionModal'
3
+
4
+ type Props = {
5
+ handleAction: () => void
6
+ }
7
+
8
+ export function Notifications({ handleAction }: Props): React.ReactElement {
9
+ return <NotifiSubscriptionModal handleSuccess={handleAction} />
10
+ }
@@ -20,6 +20,11 @@ import { ChooseAmount } from './2-ChooseAmount'
20
20
  import { ApproveAllowance } from './4-ApproveAllowance'
21
21
  import { Transfer } from './3-Transfer'
22
22
  import { Success } from './5-Success'
23
+ import { Notifications } from './6-Notifications'
24
+ import {
25
+ useDoesChainSupportNotifi,
26
+ useIsFirstTimeNotifiUser,
27
+ } from '../../../hooks/useNotifi'
23
28
 
24
29
  /**
25
30
  * Credit line pool borrow props
@@ -46,7 +51,7 @@ export function CreditLineBorrow({
46
51
  handleSuccess,
47
52
  }: CreditLineBorrowProps): React.ReactElement | null {
48
53
  const dispatch = useDispatch()
49
- const { account } = useWeb3React()
54
+ const { account, chainId } = useWeb3React()
50
55
  const poolName = POOL_NAME[poolNameStr]
51
56
  const poolType = POOL_TYPE[poolTypeStr]
52
57
  const poolInfo = usePoolInfo(poolName, poolType)
@@ -56,6 +61,8 @@ export function CreditLineBorrow({
56
61
  poolType,
57
62
  account,
58
63
  )
64
+ const { isFirstTimeNotifiUser } = useIsFirstTimeNotifiUser(account, chainId)
65
+ const { notifiChainSupported } = useDoesChainSupportNotifi(account, chainId)
59
66
  const { creditRecord } = accountStats
60
67
  const accountState = creditRecord?.state
61
68
 
@@ -76,6 +83,14 @@ export function CreditLineBorrow({
76
83
  refreshAccountStats()
77
84
  }, [handleApprove, refreshAccountStats])
78
85
 
86
+ const setupNotificationsOrClose = useCallback(() => {
87
+ if (isFirstTimeNotifiUser && notifiChainSupported) {
88
+ dispatch(setStep(WIDGET_STEP.Notifications))
89
+ } else {
90
+ handleClose()
91
+ }
92
+ }, [dispatch, handleClose, isFirstTimeNotifiUser, notifiChainSupported])
93
+
79
94
  if (!poolInfo) {
80
95
  return null
81
96
  }
@@ -101,10 +116,14 @@ export function CreditLineBorrow({
101
116
  {step === WIDGET_STEP.Done && (
102
117
  <Success
103
118
  poolInfo={poolInfo}
104
- handleAction={handleClose}
119
+ handleAction={setupNotificationsOrClose}
105
120
  creditRecord={creditRecord!}
121
+ hasNextStep={isFirstTimeNotifiUser}
106
122
  />
107
123
  )}
124
+ {step === WIDGET_STEP.Notifications && (
125
+ <Notifications handleAction={handleClose} />
126
+ )}
108
127
  {step === WIDGET_STEP.Error && (
109
128
  <ErrorModal
110
129
  title='Borrow'
@@ -69,7 +69,7 @@ export function UpcomingList<T>({
69
69
  <Box css={styles.description} marginBottom='47px'>
70
70
  {!isActive && <Box component='span'>{connectWalletDesc}</Box>}
71
71
  {isActive && !items?.length && <Box>{noItemDesc}</Box>}
72
- {isActive && items?.length && (
72
+ {isActive && !!items?.length && (
73
73
  <Box css={styles.tableWrapper}>
74
74
  {loading && (
75
75
  <Box css={styles.progress}>
@@ -0,0 +1,60 @@
1
+ import { css } from '@emotion/react'
2
+ import { Alert, Box, Snackbar } from '@mui/material'
3
+
4
+ type Props = {
5
+ open: boolean
6
+ title: string
7
+ message: string
8
+ severity: 'success' | 'info' | 'warning' | 'error'
9
+ autoHideDuration?: number
10
+ onClose: () => void
11
+ }
12
+
13
+ export function HumaSnackBar({
14
+ open,
15
+ autoHideDuration,
16
+ title,
17
+ message,
18
+ severity,
19
+ onClose,
20
+ }: Props) {
21
+ const styles = {
22
+ snackbar: css`
23
+ margin-top: 80px;
24
+ `,
25
+ alert: css`
26
+ max-width: 400px;
27
+ padding: 20px 35px 20px 20px;
28
+ border-radius: 16px;
29
+ overflow: hidden;
30
+ `,
31
+ title: css`
32
+ margin-bottom: 10px;
33
+ font-size: 16px;
34
+ font-family: 'Uni-Neue-Bold';
35
+ `,
36
+ message: css`
37
+ font-size: 15px;
38
+ font-family: 'Uni-Neue-Regular';
39
+ `,
40
+ }
41
+
42
+ return (
43
+ <Snackbar
44
+ open={open}
45
+ autoHideDuration={autoHideDuration ?? 6000}
46
+ onClose={onClose}
47
+ css={styles.snackbar}
48
+ >
49
+ <Alert
50
+ onClose={onClose}
51
+ title={title}
52
+ severity={severity}
53
+ css={styles.alert}
54
+ >
55
+ <Box css={styles.title}>{title}</Box>
56
+ <Box css={styles.message}>{message}</Box>
57
+ </Alert>
58
+ </Snackbar>
59
+ )
60
+ }
@@ -0,0 +1,86 @@
1
+ import { Box, css, useTheme } from '@mui/material'
2
+ import { useWeb3React } from '@web3-react/core'
3
+ import { EAService, PoolInfoType } from '@huma-finance/shared'
4
+ import React, { useState } from 'react'
5
+
6
+ import { useAppDispatch } from '../../../../hooks/useRedux'
7
+ import { setError, setStep } from '../../../../store/widgets.reducers'
8
+ import { WIDGET_STEP } from '../../../../store/widgets.store'
9
+ import { CustomError } from '../../../../utilTypes'
10
+ import { BottomButton } from '../../../BottomButton'
11
+ import { ApproveLenderIcon } from '../../../icons'
12
+ import { LoadingModal } from '../../../LoadingModal'
13
+ import { WrapperModal } from '../../../WrapperModal'
14
+
15
+ type Props = {
16
+ poolInfo: PoolInfoType
17
+ handleApproveSuccess: () => void
18
+ }
19
+
20
+ export function EvaluationEA({
21
+ poolInfo,
22
+ handleApproveSuccess,
23
+ }: Props): React.ReactElement | null {
24
+ const theme = useTheme()
25
+ const dispatch = useAppDispatch()
26
+ const { account, chainId } = useWeb3React()
27
+ const [loading, setLoading] = useState(false)
28
+
29
+ const styles = {
30
+ iconWrapper: css`
31
+ ${theme.cssMixins.rowCentered};
32
+ margin-top: 30px;
33
+ `,
34
+ description: css`
35
+ ${theme.cssMixins.rowCentered};
36
+ margin-top: 50px;
37
+ font-family: 'Uni-Neue-Regular';
38
+ font-size: 16px;
39
+ color: #a8a1b2;
40
+ `,
41
+ }
42
+
43
+ const approveLender = async () => {
44
+ if (account) {
45
+ try {
46
+ setLoading(true)
47
+ const payload = {
48
+ poolAddress: poolInfo.pool,
49
+ lenderWalletAddress: account,
50
+ }
51
+ await EAService.approveLender(payload, chainId!)
52
+ handleApproveSuccess()
53
+ setLoading(false)
54
+ dispatch(setStep(WIDGET_STEP.ChooseAmount))
55
+ } catch (e: unknown) {
56
+ const error = e as CustomError
57
+ setLoading(false)
58
+ dispatch(setError({ errorMessage: error.message }))
59
+ }
60
+ }
61
+ }
62
+
63
+ if (!loading) {
64
+ return (
65
+ <WrapperModal
66
+ title='Lender Approval'
67
+ subTitle='This pool requires lender approval'
68
+ >
69
+ <Box css={styles.iconWrapper}>
70
+ <ApproveLenderIcon />
71
+ </Box>
72
+ <Box css={styles.description} />
73
+ <BottomButton variant='contained' onClick={approveLender}>
74
+ GET APPROVED
75
+ </BottomButton>
76
+ </WrapperModal>
77
+ )
78
+ }
79
+
80
+ return (
81
+ <LoadingModal
82
+ title='Approval Pending'
83
+ description='Waiting for approval confirmation...'
84
+ />
85
+ )
86
+ }
@@ -0,0 +1,287 @@
1
+ import {
2
+ configUtil,
3
+ DocSignatureStatus,
4
+ IdentityService,
5
+ PoolInfoType,
6
+ timeUtil,
7
+ VerificationStatusResult,
8
+ } from '@huma-finance/shared'
9
+ import { Box, css, useTheme } from '@mui/material'
10
+ import { useWeb3React } from '@web3-react/core'
11
+ import React, { useCallback, useEffect, useMemo, useState } from 'react'
12
+
13
+ import { useAppDispatch } from '../../../../hooks/useRedux'
14
+ import { setError } from '../../../../store/widgets.reducers'
15
+ import { envUtil } from '../../../../utils/env'
16
+ import { BottomButton } from '../../../BottomButton'
17
+ import { HumaSnackBar } from '../../../HumaSnackBar'
18
+ import { ApproveLenderIcon } from '../../../icons'
19
+ import { LoadingModal } from '../../../LoadingModal'
20
+ import { WrapperModal } from '../../../WrapperModal'
21
+
22
+ const KYCProvider = 'Securitize'
23
+
24
+ const KYCCopiesByState: {
25
+ [key: string]: {
26
+ description: string
27
+ buttonText: string
28
+ }
29
+ } = {
30
+ verifyIdentity: {
31
+ description: `Link your ${KYCProvider} account or create a new one to complete identity verification.`,
32
+ buttonText: 'VERIFY MY IDENTITY',
33
+ },
34
+ emailSignatureLink: {
35
+ description: `Final step: Your digital signature on legal documents is required. Click below to email yourself the DocuSign link.`,
36
+ buttonText: 'EMAIL DOCUSIGN LINK',
37
+ },
38
+ resendSignatureLink: {
39
+ description: `DocuSign link sent successfully. Haven't received it? Check your spam folder or click below to resend it.`,
40
+ buttonText: 'RESEND DOCUSIGN LINK',
41
+ },
42
+ docUnderReview: {
43
+ description: `Documents received and under review. You'll be notified upon approval. Your patience is appreciated.`,
44
+ buttonText: 'THANK YOU',
45
+ },
46
+ }
47
+
48
+ const LoadingCopiesByType: {
49
+ [key: string]: {
50
+ description: string
51
+ }
52
+ } = {
53
+ verificationStatus: {
54
+ description: `Checking your verification status...`,
55
+ },
56
+ sendDocSignatureLink: {
57
+ description: `Sending signature link...`,
58
+ },
59
+ }
60
+
61
+ type Props = {
62
+ poolInfo: PoolInfoType
63
+ handleClose: () => void
64
+ }
65
+
66
+ export function EvaluationKYC({
67
+ poolInfo,
68
+ handleClose,
69
+ }: Props): React.ReactElement | null {
70
+ const theme = useTheme()
71
+ const dispatch = useAppDispatch()
72
+ const isDev = envUtil.checkIsDev()
73
+ const { account, chainId } = useWeb3React()
74
+ const [loadingType, setLoadingType] = useState<
75
+ 'verificationStatus' | 'sendDocSignatureLink'
76
+ >()
77
+ const [description, setDescription] = useState<string>(
78
+ KYCCopiesByState.verifyIdentity.description,
79
+ )
80
+ const [buttonText, setButtonText] = useState<string>(
81
+ KYCCopiesByState.verifyIdentity.buttonText,
82
+ )
83
+ const [KYCVerifyStatus, setKYCVerifyStatus] =
84
+ useState<VerificationStatusResult>()
85
+ const [docSignatureStatus, setDocSignatureStatus] =
86
+ useState<DocSignatureStatus['status']>()
87
+ const docSignatureCompleted = docSignatureStatus === 'completed'
88
+ const [openSnackBar, setOpenSnackBar] = useState<boolean>(false)
89
+
90
+ const styles = {
91
+ iconWrapper: css`
92
+ ${theme.cssMixins.rowCentered};
93
+ margin-top: 30px;
94
+ `,
95
+ description: css`
96
+ ${theme.cssMixins.rowCentered};
97
+ margin-top: 50px;
98
+ font-family: 'Uni-Neue-Regular';
99
+ font-size: 16px;
100
+ color: #a8a1b2;
101
+ `,
102
+ }
103
+
104
+ const { envelopeKey, envelopeLastQueryTimeKey } = useMemo(() => {
105
+ const envelopeKey = `${poolInfo.pool.toLowerCase()}-${account?.toLowerCase()}`
106
+ const envelopeLastQueryTimeKey = `${envelopeKey}-last-query-time`
107
+ return {
108
+ envelopeKey,
109
+ envelopeLastQueryTimeKey,
110
+ }
111
+ }, [account, poolInfo.pool])
112
+
113
+ // DocuSign GET requests to any specific URL can be called not more often than once every 15 minutes.
114
+ // https://developers.docusign.com/platform/api-guidelines/#:~:text=Polling,not%20once%20every%2010%20minutes
115
+ const checkGetDocSignatureStatusIsAvailable = useCallback(() => {
116
+ const lastQueryTime = localStorage.getItem(envelopeLastQueryTimeKey)
117
+ if (!lastQueryTime) {
118
+ return true
119
+ }
120
+ const lastQueryTimeNumber = Number(lastQueryTime)
121
+ const now = timeUtil.getUnixTimestamp()
122
+ const diff = now - lastQueryTimeNumber
123
+ const fifteenMinutes = 15 * 60
124
+ return diff > fifteenMinutes
125
+ }, [envelopeLastQueryTimeKey])
126
+
127
+ useEffect(() => {
128
+ const fetchData = async () => {
129
+ if (account && chainId) {
130
+ try {
131
+ setLoadingType('verificationStatus')
132
+ const verificationStatus =
133
+ await IdentityService.getVerificationStatus(
134
+ account,
135
+ poolInfo.pool,
136
+ chainId,
137
+ isDev,
138
+ )
139
+ setKYCVerifyStatus(verificationStatus)
140
+ if (verificationStatus.isVerified) {
141
+ const envelopeId = localStorage.getItem(envelopeKey)
142
+ if (!envelopeId) {
143
+ setDescription(KYCCopiesByState.emailSignatureLink.description)
144
+ setButtonText(KYCCopiesByState.emailSignatureLink.buttonText)
145
+ } else if (!checkGetDocSignatureStatusIsAvailable()) {
146
+ setDescription(KYCCopiesByState.resendSignatureLink.description)
147
+ setButtonText(KYCCopiesByState.resendSignatureLink.buttonText)
148
+ } else {
149
+ const { status } = await IdentityService.getDocSignatureStatus(
150
+ envelopeId,
151
+ chainId,
152
+ isDev,
153
+ )
154
+ localStorage.setItem(
155
+ envelopeLastQueryTimeKey,
156
+ String(timeUtil.getUnixTimestamp()),
157
+ )
158
+ setDocSignatureStatus(status)
159
+ if (status === 'completed') {
160
+ setDescription(KYCCopiesByState.docUnderReview.description)
161
+ setButtonText(KYCCopiesByState.docUnderReview.buttonText)
162
+ // For voided and declined status, we need to send a new link
163
+ } else if (['voided', 'declined'].includes(status)) {
164
+ localStorage.removeItem(envelopeKey)
165
+ localStorage.removeItem(envelopeLastQueryTimeKey)
166
+ setDescription(KYCCopiesByState.emailSignatureLink.description)
167
+ setButtonText(KYCCopiesByState.emailSignatureLink.buttonText)
168
+ } else {
169
+ setDescription(KYCCopiesByState.resendSignatureLink.description)
170
+ setButtonText(KYCCopiesByState.resendSignatureLink.buttonText)
171
+ }
172
+ }
173
+ }
174
+ } catch (e: unknown) {
175
+ console.error(e)
176
+ dispatch(
177
+ setError({
178
+ errorMessage: 'Something went wrong, please try again later.',
179
+ }),
180
+ )
181
+ } finally {
182
+ setLoadingType(undefined)
183
+ }
184
+ }
185
+ }
186
+ fetchData()
187
+ }, [
188
+ account,
189
+ chainId,
190
+ checkGetDocSignatureStatusIsAvailable,
191
+ dispatch,
192
+ envelopeKey,
193
+ envelopeLastQueryTimeKey,
194
+ isDev,
195
+ poolInfo.pool,
196
+ ])
197
+
198
+ const approveLender = async () => {
199
+ if (docSignatureCompleted) {
200
+ handleClose()
201
+ return
202
+ }
203
+
204
+ const { isNotOnboarded, isVerified } = KYCVerifyStatus || {}
205
+
206
+ if (!isVerified) {
207
+ const issuerId = '53a66b32-583e-40e7-ba90-baf516d2cadd'
208
+ const baseUrl = configUtil.getKYCProviderBaseUrl(KYCProvider, isDev)
209
+ const originUrl = window.location.href.split('?')[0]
210
+ const redirectUrl = `${originUrl}?kycProvider=${KYCProvider}&kycPool=${poolInfo.pool}`
211
+ const providerAuthorizeUrl = `${baseUrl}/#/authorize?issuerId=${issuerId}&scope=details&details=verification&redirectUrl=${redirectUrl}`
212
+ const providerUrl = isNotOnboarded ? providerAuthorizeUrl : baseUrl
213
+ window.location.href = providerUrl
214
+ } else {
215
+ const envelopeId = localStorage.getItem(envelopeKey)
216
+ try {
217
+ setLoadingType('sendDocSignatureLink')
218
+ if (!envelopeId) {
219
+ const { envelopeId } = await IdentityService.requestDocSignature(
220
+ account!,
221
+ chainId!,
222
+ isDev,
223
+ )
224
+ localStorage.setItem(envelopeKey, envelopeId)
225
+ localStorage.setItem(
226
+ envelopeLastQueryTimeKey,
227
+ String(timeUtil.getUnixTimestamp()),
228
+ )
229
+ setOpenSnackBar(true)
230
+ setDescription(KYCCopiesByState.resendSignatureLink.description)
231
+ setButtonText(KYCCopiesByState.resendSignatureLink.buttonText)
232
+ } else {
233
+ await IdentityService.resendDocSignatureLink(
234
+ envelopeId,
235
+ chainId!,
236
+ isDev,
237
+ )
238
+ setOpenSnackBar(true)
239
+ }
240
+ } catch (e: unknown) {
241
+ console.error(e)
242
+ dispatch(
243
+ setError({
244
+ errorMessage: 'Something went wrong, please try again later.',
245
+ }),
246
+ )
247
+ } finally {
248
+ setLoadingType(undefined)
249
+ }
250
+ }
251
+ }
252
+
253
+ const getEmailLinkSentSnackbar = () => (
254
+ <HumaSnackBar
255
+ open={openSnackBar}
256
+ title='Signature Link Sent'
257
+ message='The secure signature session link has been sent to your email.'
258
+ severity='success'
259
+ onClose={() => setOpenSnackBar(false)}
260
+ />
261
+ )
262
+
263
+ if (!loadingType) {
264
+ return (
265
+ <WrapperModal
266
+ title='Lender Approval'
267
+ subTitle='This pool requires lender approval'
268
+ >
269
+ <Box css={styles.iconWrapper}>
270
+ <ApproveLenderIcon />
271
+ </Box>
272
+ <Box css={styles.description}>{description}</Box>
273
+ <BottomButton variant='contained' onClick={approveLender}>
274
+ {buttonText}
275
+ </BottomButton>
276
+ {getEmailLinkSentSnackbar()}
277
+ </WrapperModal>
278
+ )
279
+ }
280
+
281
+ return (
282
+ <LoadingModal
283
+ title='Lender Approval'
284
+ description={LoadingCopiesByType[loadingType].description}
285
+ />
286
+ )
287
+ }
@@ -0,0 +1,31 @@
1
+ import { PoolInfoType } from '@huma-finance/shared'
2
+ import React from 'react'
3
+
4
+ import { EvaluationEA } from './EvaluationEA'
5
+ import { EvaluationKYC } from './EvaluationKYC'
6
+
7
+ type Props = {
8
+ poolInfo: PoolInfoType
9
+ handleClose: () => void
10
+ handleApproveSuccess: () => void
11
+ }
12
+
13
+ export function Evaluation({
14
+ poolInfo,
15
+ handleClose,
16
+ handleApproveSuccess,
17
+ }: Props): React.ReactElement | null {
18
+ const lenderApprovalProvider = poolInfo.extra?.lenderApprovalProvider
19
+ const isKYC = lenderApprovalProvider?.type === 'KYC'
20
+
21
+ if (isKYC) {
22
+ return <EvaluationKYC poolInfo={poolInfo} handleClose={handleClose} />
23
+ }
24
+
25
+ return (
26
+ <EvaluationEA
27
+ poolInfo={poolInfo}
28
+ handleApproveSuccess={handleApproveSuccess}
29
+ />
30
+ )
31
+ }
@@ -48,7 +48,6 @@ export function ChooseAmount({
48
48
  : WIDGET_STEP.Transfer
49
49
  dispatch(setStep(step))
50
50
  }, [dispatch, needApprove])
51
-
52
51
  return (
53
52
  <ChooseAmountModal
54
53
  title={`Supply ${symbol}`}
@@ -15,9 +15,14 @@ import { TxDoneModal } from '../../TxDoneModal'
15
15
  type Props = {
16
16
  poolInfo: PoolInfoType
17
17
  handleAction: () => void
18
+ hasNextStep: boolean
18
19
  }
19
20
 
20
- export function Success({ poolInfo, handleAction }: Props): React.ReactElement {
21
+ export function Success({
22
+ poolInfo,
23
+ handleAction,
24
+ hasNextStep,
25
+ }: Props): React.ReactElement {
21
26
  const { account } = useWeb3React()
22
27
  const { poolUnderlyingToken } = poolInfo
23
28
  const [{ txReceipt }] = useAtom(sendTxAtom)
@@ -45,5 +50,11 @@ export function Success({ poolInfo, handleAction }: Props): React.ReactElement {
45
50
  `You successfully supplied ${formatMoney(supplyAmount)} ${symbol}.`,
46
51
  ]
47
52
 
48
- return <TxDoneModal handleAction={handleAction} content={content} />
53
+ return (
54
+ <TxDoneModal
55
+ handleAction={handleAction}
56
+ content={content}
57
+ buttonText={hasNextStep ? "WHAT'S NEXT" : undefined}
58
+ />
59
+ )
49
60
  }
@@ -0,0 +1,10 @@
1
+ import React from 'react'
2
+ import { NotifiSubscriptionModal } from '../../Notifi/NotifiSubscriptionModal'
3
+
4
+ type Props = {
5
+ handleAction: () => void
6
+ }
7
+
8
+ export function Notifications({ handleAction }: Props): React.ReactElement {
9
+ return <NotifiSubscriptionModal handleSuccess={handleAction} />
10
+ }