@huma-finance/widgets 0.0.51-beta.227 → 0.0.51-beta.347

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 (96) hide show
  1. package/API.md +454 -0
  2. package/dist/cjs/index.cjs +6097 -3790
  3. package/dist/cjs/index.cjs.map +1 -1
  4. package/dist/index.d.ts +280 -2
  5. package/dist/index.js +6089 -3792
  6. package/dist/index.js.map +1 -1
  7. package/package.json +5 -4
  8. package/src/components/ApproveAllowanceModal.tsx +3 -1
  9. package/src/components/ApproveAllowanceModalV2.tsx +141 -0
  10. package/src/components/CreditLine/approve/index.tsx +9 -3
  11. package/src/components/CreditLine/autoPaybackV2/1-ApproveAllowance.tsx +33 -0
  12. package/src/components/CreditLine/autoPaybackV2/2-Success.tsx +13 -0
  13. package/src/components/CreditLine/autoPaybackV2/index.tsx +87 -0
  14. package/src/components/CreditLine/borrow/2-ChooseAmount.tsx +12 -3
  15. package/src/components/CreditLine/borrow/5-Success.tsx +7 -2
  16. package/src/components/CreditLine/borrow/index.tsx +4 -2
  17. package/src/components/CreditLine/borrowV2/1-ChooseAmount.tsx +81 -0
  18. package/src/components/CreditLine/borrowV2/2-ApproveAllowance.tsx +33 -0
  19. package/src/components/CreditLine/borrowV2/3-Transfer.tsx +50 -0
  20. package/src/components/CreditLine/borrowV2/4-Success.tsx +42 -0
  21. package/src/components/CreditLine/borrowV2/5-Notifications.tsx +10 -0
  22. package/src/components/CreditLine/borrowV2/index.tsx +140 -0
  23. package/src/components/CreditLine/payment/1-ChooseAmount.tsx +9 -5
  24. package/src/components/CreditLine/payment/3-Transfer.tsx +1 -5
  25. package/src/components/CreditLine/payment/4-Success.tsx +2 -2
  26. package/src/components/CreditLine/payment/index.tsx +4 -2
  27. package/src/components/CreditLine/paymentV2/1-ChooseAmount.tsx +96 -0
  28. package/src/components/CreditLine/paymentV2/2-ApproveAllowance.tsx +33 -0
  29. package/src/components/CreditLine/paymentV2/3-Transfer.tsx +55 -0
  30. package/src/components/CreditLine/paymentV2/4-Success.tsx +42 -0
  31. package/src/components/CreditLine/paymentV2/index.tsx +111 -0
  32. package/src/components/CreditLine/supplyFLC/1-ApproveAllowance.tsx +40 -0
  33. package/src/components/CreditLine/supplyFLC/2-Transfer.tsx +53 -0
  34. package/src/components/CreditLine/supplyFLC/3-Success.tsx +26 -0
  35. package/src/components/CreditLine/supplyFLC/index.tsx +121 -0
  36. package/src/components/Factoring/FactoredList.tsx +2 -1
  37. package/src/components/InputAmountModal.tsx +156 -0
  38. package/src/components/InvoiceFactoring/borrow/2-ChooseAmount.tsx +8 -1
  39. package/src/components/InvoiceFactoring/borrow/4-ApproveNFT.tsx +6 -2
  40. package/src/components/InvoiceFactoring/borrow/6-Success.tsx +5 -1
  41. package/src/components/InvoiceFactoring/borrow/index.tsx +9 -3
  42. package/src/components/InvoiceFactoring/payment/1-ChooseAmount.tsx +7 -2
  43. package/src/components/InvoiceFactoring/payment/index.tsx +9 -3
  44. package/src/components/Lend/addRedemptionV2/1-ChooseTranche.tsx +114 -0
  45. package/src/components/Lend/addRedemptionV2/2-ChooseAmount.tsx +114 -0
  46. package/src/components/Lend/addRedemptionV2/3-Transfer.tsx +56 -0
  47. package/src/components/Lend/addRedemptionV2/4-Done.tsx +20 -0
  48. package/src/components/Lend/addRedemptionV2/index.tsx +173 -0
  49. package/src/components/Lend/cancelRedemptionV2 /1-Transfer.tsx +51 -0
  50. package/src/components/Lend/cancelRedemptionV2 /2-Done.tsx +29 -0
  51. package/src/components/Lend/cancelRedemptionV2 /index.tsx +120 -0
  52. package/src/components/Lend/supply/1-Evaluation/EvaluationKYC.tsx +19 -2
  53. package/src/components/Lend/supply/2-ChooseAmount.tsx +1 -0
  54. package/src/components/Lend/supply/index.tsx +17 -3
  55. package/src/components/Lend/supplyV2/1-ChooseTranche.tsx +116 -0
  56. package/src/components/Lend/supplyV2/2-Evaluation.tsx +345 -0
  57. package/src/components/Lend/supplyV2/3-ChooseAmount.tsx +87 -0
  58. package/src/components/Lend/supplyV2/4-ApproveAllowance.tsx +33 -0
  59. package/src/components/Lend/supplyV2/5-Transfer.tsx +59 -0
  60. package/src/components/Lend/supplyV2/6-Success.tsx +79 -0
  61. package/src/components/Lend/supplyV2/7-Notifications.tsx +10 -0
  62. package/src/components/Lend/supplyV2/index.tsx +175 -0
  63. package/src/components/Lend/withdraw/1-CheckWithdrawble.tsx +5 -1
  64. package/src/components/Lend/withdraw/index.tsx +10 -3
  65. package/src/components/Lend/withdrawV2/1-ConfirmTransfer.tsx +135 -0
  66. package/src/components/Lend/withdrawV2/2-Transfer.tsx +50 -0
  67. package/src/components/Lend/withdrawV2/3-Done.tsx +31 -0
  68. package/src/components/Lend/withdrawV2/index.tsx +177 -0
  69. package/src/components/Notifi/NotifiSubscriptionModal.tsx +26 -38
  70. package/src/components/NumericFormatCustom.tsx +33 -0
  71. package/src/components/ReceivableBackedCreditLine/borrow/1-ChooseAmount.tsx +101 -0
  72. package/src/components/ReceivableBackedCreditLine/borrow/2-ApproveAllowance.tsx +33 -0
  73. package/src/components/ReceivableBackedCreditLine/borrow/3-ApproveReceivable.tsx +64 -0
  74. package/src/components/ReceivableBackedCreditLine/borrow/4-Transfer.tsx +61 -0
  75. package/src/components/ReceivableBackedCreditLine/borrow/5-Success.tsx +42 -0
  76. package/src/components/ReceivableBackedCreditLine/borrow/6-Notifications.tsx +10 -0
  77. package/src/components/ReceivableBackedCreditLine/borrow/index.tsx +148 -0
  78. package/src/components/ReceivableBackedCreditLine/payment/1-ChoosePaymentType.tsx +115 -0
  79. package/src/components/ReceivableBackedCreditLine/payment/2-ChooseAmount.tsx +84 -0
  80. package/src/components/ReceivableBackedCreditLine/payment/3-ApproveAllowance.tsx +41 -0
  81. package/src/components/ReceivableBackedCreditLine/payment/4-CreateReceivable.tsx +107 -0
  82. package/src/components/ReceivableBackedCreditLine/payment/5-ApproveReceivable.tsx +64 -0
  83. package/src/components/ReceivableBackedCreditLine/payment/6-Transfer.tsx +107 -0
  84. package/src/components/ReceivableBackedCreditLine/payment/7-Success.tsx +49 -0
  85. package/src/components/ReceivableBackedCreditLine/payment/index.tsx +159 -0
  86. package/src/components/StreamFactoring/borrow/2-ChooseAmount.tsx +8 -1
  87. package/src/components/StreamFactoring/borrow/6-Transfer.tsx +3 -1
  88. package/src/components/StreamFactoring/borrow/7-Success.tsx +3 -1
  89. package/src/components/StreamFactoring/borrow/index.tsx +2 -2
  90. package/src/components/TxDoneModal.tsx +1 -1
  91. package/src/components/TxSendModal.tsx +8 -2
  92. package/src/components/TxSendModalV2.tsx +51 -0
  93. package/src/hooks/useNotifi.ts +4 -6
  94. package/src/index.tsx +268 -1
  95. package/src/store/widgets.reducers.ts +15 -0
  96. package/src/store/widgets.store.ts +6 -0
@@ -1,38 +1,26 @@
1
- import React, { useCallback, useState } from 'react'
2
- import { useWeb3React } from '@web3-react/core'
1
+ import { getBlockchainConfigFromChain, txAtom } from '@huma-finance/shared'
2
+ import { Box, css, TextField, Typography, useTheme } from '@mui/material'
3
3
  import {
4
- NotifiFrontendClient,
5
- Uint8SignMessageFunction,
6
- SignMessageParams,
4
+ BroadcastEventTypeItem,
7
5
  CardConfigItemV1,
8
6
  DirectPushEventTypeItem,
9
7
  EventTypeItem,
10
- BroadcastEventTypeItem,
8
+ NotifiFrontendClient,
9
+ SignMessageParams,
10
+ Uint8SignMessageFunction,
11
11
  } from '@notifi-network/notifi-frontend-client'
12
- import {
13
- checkIsDev,
14
- getBlockchainConfigFromChain,
15
- txAtom,
16
- } from '@huma-finance/shared'
12
+ import { useWeb3React } from '@web3-react/core'
17
13
  import { ethers } from 'ethers'
18
- import {
19
- Box,
20
- Input,
21
- InputAdornment,
22
- Typography,
23
- css,
24
- useTheme,
25
- } from '@mui/material'
26
- import Email from '@mui/icons-material/Email'
27
14
  import { useResetAtom } from 'jotai/utils'
15
+ import React, { useCallback, useState } from 'react'
28
16
 
29
- import { WrapperModal } from '../WrapperModal'
17
+ import { useNotifiClient } from '../../hooks/useNotifi'
18
+ import { useAppDispatch } from '../../hooks/useRedux'
19
+ import { resetState } from '../../store/widgets.reducers'
30
20
  import { BottomButton } from '../BottomButton'
31
- import { LoadingModal } from '../LoadingModal'
32
21
  import { CheckIcon } from '../icons'
33
- import { resetState } from '../../store/widgets.reducers'
34
- import { useAppDispatch } from '../../hooks/useRedux'
35
- import { useNotifiClient } from '../../hooks/useNotifi'
22
+ import { LoadingModal } from '../LoadingModal'
23
+ import { WrapperModal } from '../WrapperModal'
36
24
 
37
25
  type Props = {
38
26
  handleSuccess: () => void
@@ -103,7 +91,7 @@ export function NotifiSubscriptionModal({
103
91
  const [isLoading, setIsLoading] = useState<boolean>(false)
104
92
  const [emailAddress, setEmailAddress] = useState<string>('')
105
93
  const [emailValid, setEmailValid] = useState<boolean>()
106
- const { notifiClient } = useNotifiClient(account, chainId, checkIsDev())
94
+ const { notifiClient } = useNotifiClient(account, chainId)
107
95
 
108
96
  const signMessage: Uint8SignMessageFunction = async (
109
97
  message: Uint8Array,
@@ -176,7 +164,7 @@ export function NotifiSubscriptionModal({
176
164
  margin-top: ${theme.spacing(6)};
177
165
  `,
178
166
  inputField: css`
179
- width: 90%;
167
+ width: 100%;
180
168
  font-size: 16px;
181
169
  `,
182
170
  inputWrapper: css`
@@ -215,33 +203,33 @@ export function NotifiSubscriptionModal({
215
203
 
216
204
  return (
217
205
  <WrapperModal title='Connect Your Email'>
218
- <Typography variant='body2' margin={theme.spacing(1, 0)}>
219
- Connect your wallet to receive important emails about your account
206
+ <Typography
207
+ variant='body2'
208
+ textAlign='justify'
209
+ margin={theme.spacing(6, 0, 4, 0)}
210
+ >
211
+ Connect your emails to receive important update about your account.
220
212
  </Typography>
221
213
  <Box css={styles.inputWrapper}>
222
- <Input
214
+ <TextField
223
215
  css={styles.inputField}
216
+ label='Your Email'
224
217
  type='email'
225
218
  value={emailAddress}
226
219
  onChange={handleEmailAddressChange}
227
- placeholder='youremail@example.com'
228
- startAdornment={
229
- <InputAdornment position='start'>
230
- <Email />
231
- </InputAdornment>
232
- }
220
+ variant='standard'
233
221
  />
234
222
  </Box>
235
223
  <Box css={styles.disclaimer}>
236
224
  You can adjust these settings at any time by clicking the alert icon in
237
- the header
225
+ the header.
238
226
  </Box>
239
227
  <BottomButton
240
228
  variant='contained'
241
229
  onClick={logInAndSubscribe}
242
230
  disabled={!emailValid || isLoading}
243
231
  >
244
- CONNECT WALLET
232
+ CONNECT EMAIL
245
233
  </BottomButton>
246
234
  </WrapperModal>
247
235
  )
@@ -0,0 +1,33 @@
1
+ import React from 'react'
2
+ import { NumericFormat, NumericFormatProps } from 'react-number-format'
3
+
4
+ interface CustomProps {
5
+ onChange: (event: { target: { name: string; value: string } }) => void
6
+ name: string
7
+ suffix?: string
8
+ }
9
+
10
+ export const NumericFormatCustom = React.forwardRef<
11
+ NumericFormatProps,
12
+ CustomProps
13
+ >((props, ref) => {
14
+ const { onChange, suffix, ...other } = props
15
+
16
+ return (
17
+ <NumericFormat
18
+ {...other}
19
+ getInputRef={ref}
20
+ onValueChange={(values) => {
21
+ onChange({
22
+ target: {
23
+ name: props.name,
24
+ value: values.value,
25
+ },
26
+ })
27
+ }}
28
+ thousandSeparator
29
+ valueIsNumericString
30
+ suffix={suffix}
31
+ />
32
+ )
33
+ })
@@ -0,0 +1,101 @@
1
+ import {
2
+ CreditStatsV2,
3
+ PoolInfoV2,
4
+ UnderlyingTokenInfo,
5
+ usePoolSafeAllowanceV2,
6
+ useReceivableInfoV2,
7
+ } from '@huma-finance/shared'
8
+ import { useWeb3React } from '@web3-react/core'
9
+ import { BigNumber, ethers } from 'ethers'
10
+ import React, { useCallback, useEffect, useState } from 'react'
11
+
12
+ import { useAppDispatch } from '../../../hooks/useRedux'
13
+ import { setBorrowInfo } from '../../../store/widgets.reducers'
14
+ import { WIDGET_STEP } from '../../../store/widgets.store'
15
+ import { ChooseAmountModal } from '../../ChooseAmountModal'
16
+ import { LoadingModal } from '../../LoadingModal'
17
+
18
+ type Props = {
19
+ poolInfo: PoolInfoV2
20
+ poolUnderlyingToken: UnderlyingTokenInfo
21
+ accountStats: CreditStatsV2
22
+ tokenId: string
23
+ }
24
+
25
+ export function ChooseAmount({
26
+ poolInfo,
27
+ poolUnderlyingToken,
28
+ accountStats,
29
+ tokenId,
30
+ }: Props): React.ReactElement | null {
31
+ const dispatch = useAppDispatch()
32
+ const { account, provider } = useWeb3React()
33
+ const { symbol, decimals } = poolUnderlyingToken!
34
+ const [currentAmount, setCurrentAmount] = useState(0)
35
+ const { creditAvailable } = accountStats
36
+ const receivableInfo = useReceivableInfoV2(
37
+ poolInfo.poolName,
38
+ tokenId,
39
+ provider,
40
+ )
41
+ const { autopayEnabled } = usePoolSafeAllowanceV2(
42
+ poolInfo.poolName,
43
+ account,
44
+ provider,
45
+ )
46
+ const [maxAmount, setMaxAmount] = useState(0)
47
+
48
+ useEffect(() => {
49
+ if (creditAvailable) {
50
+ let maxAmountBN: BigNumber = creditAvailable
51
+
52
+ if (receivableInfo) {
53
+ const receivableAmountBN = BigNumber.from(
54
+ receivableInfo.receivableAmount,
55
+ )
56
+ maxAmountBN = receivableAmountBN.lte(creditAvailable)
57
+ ? receivableAmountBN
58
+ : creditAvailable
59
+ }
60
+ setMaxAmount(Number(ethers.utils.formatUnits(maxAmountBN, decimals)))
61
+ }
62
+ }, [creditAvailable, decimals, receivableInfo])
63
+
64
+ const handleChangeAmount = useCallback((newAmount: number) => {
65
+ setCurrentAmount(newAmount)
66
+ }, [])
67
+
68
+ const handleAction = useCallback(() => {
69
+ const nextStep = autopayEnabled
70
+ ? WIDGET_STEP.ApproveNFT
71
+ : WIDGET_STEP.ApproveAllowance
72
+
73
+ dispatch(
74
+ setBorrowInfo({
75
+ borrowAmount: currentAmount,
76
+ borrowAmountBN: ethers.utils
77
+ .parseUnits(currentAmount.toString(), decimals)
78
+ .toJSON(),
79
+ chargedFees: 0,
80
+ nextStep,
81
+ }),
82
+ )
83
+ }, [autopayEnabled, currentAmount, decimals, dispatch])
84
+
85
+ if (autopayEnabled === undefined || (tokenId && !receivableInfo)) {
86
+ return <LoadingModal title='Borrow' />
87
+ }
88
+
89
+ return (
90
+ <ChooseAmountModal
91
+ title='Borrow'
92
+ description1='Choose Amount'
93
+ sliderMax={maxAmount}
94
+ currentAmount={currentAmount}
95
+ tokenSymbol={symbol}
96
+ handleChangeAmount={handleChangeAmount}
97
+ handleAction={handleAction}
98
+ actionText='Borrow'
99
+ />
100
+ )
101
+ }
@@ -0,0 +1,33 @@
1
+ import { PoolInfoV2, UnderlyingTokenInfo } from '@huma-finance/shared'
2
+ import React, { useCallback } from 'react'
3
+
4
+ import { useAppDispatch } from '../../../hooks/useRedux'
5
+ import { setStep } from '../../../store/widgets.reducers'
6
+ import { WIDGET_STEP } from '../../../store/widgets.store'
7
+ import { ApproveAllowanceModalV2 } from '../../ApproveAllowanceModalV2'
8
+
9
+ type Props = {
10
+ poolInfo: PoolInfoV2
11
+ poolUnderlyingToken: UnderlyingTokenInfo
12
+ }
13
+
14
+ export function ApproveAllowance({
15
+ poolInfo,
16
+ poolUnderlyingToken,
17
+ }: Props): React.ReactElement | null {
18
+ const dispatch = useAppDispatch()
19
+
20
+ const handleSuccess = useCallback(() => {
21
+ dispatch(setStep(WIDGET_STEP.ApproveNFT))
22
+ }, [dispatch])
23
+
24
+ return (
25
+ <ApproveAllowanceModalV2
26
+ poolInfo={poolInfo}
27
+ spender={poolInfo.poolSafe}
28
+ poolUnderlyingToken={poolUnderlyingToken}
29
+ handleSuccess={handleSuccess}
30
+ showAutoPayback
31
+ />
32
+ )
33
+ }
@@ -0,0 +1,64 @@
1
+ import {
2
+ PoolInfoV2,
3
+ sendTxAtom,
4
+ txAtom,
5
+ TxStateType,
6
+ useReceivableContractV2,
7
+ } from '@huma-finance/shared'
8
+ import { useWeb3React } from '@web3-react/core'
9
+ import { useAtom } from 'jotai'
10
+ import { useResetAtom } from 'jotai/utils'
11
+ import React, { useEffect } 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 { LoadingModal } from '../../LoadingModal'
17
+ import { ViewOnExplorer } from '../../ViewOnExplorer'
18
+
19
+ type Props = {
20
+ poolInfo: PoolInfoV2
21
+ tokenId: string
22
+ }
23
+
24
+ export function ApproveReceivable({
25
+ poolInfo,
26
+ tokenId,
27
+ }: Props): React.ReactElement {
28
+ const dispatch = useAppDispatch()
29
+ const { provider, account } = useWeb3React()
30
+ const [{ state, txHash }, send] = useAtom(sendTxAtom)
31
+ const reset = useResetAtom(txAtom)
32
+ const receivableContract = useReceivableContractV2(
33
+ poolInfo.poolName,
34
+ provider,
35
+ account,
36
+ )
37
+
38
+ useEffect(() => {
39
+ if (state === TxStateType.Success) {
40
+ reset()
41
+ dispatch(setStep(WIDGET_STEP.Transfer))
42
+ }
43
+ }, [dispatch, reset, state])
44
+
45
+ useEffect(() => {
46
+ if (receivableContract) {
47
+ send({
48
+ contract: receivableContract,
49
+ method: 'approve',
50
+ params: [poolInfo.poolCredit, tokenId],
51
+ provider,
52
+ })
53
+ }
54
+ }, [poolInfo.poolCredit, provider, receivableContract, send, tokenId])
55
+
56
+ return (
57
+ <LoadingModal
58
+ title='Approve Receivable'
59
+ description='Waiting for approval confirmation...'
60
+ >
61
+ <ViewOnExplorer txHash={txHash} />
62
+ </LoadingModal>
63
+ )
64
+ }
@@ -0,0 +1,61 @@
1
+ import { drawdownWithReceivable } from '@huma-finance/sdk'
2
+ import { PoolInfoV2 } from '@huma-finance/shared'
3
+ import { useWeb3React } from '@web3-react/core'
4
+ import { BigNumber } from 'ethers'
5
+ import React, { useEffect, useState } from 'react'
6
+
7
+ import { useAppDispatch, useAppSelector } from '../../../hooks/useRedux'
8
+ import { setStep } from '../../../store/widgets.reducers'
9
+ import { selectWidgetState } from '../../../store/widgets.selectors'
10
+ import { WIDGET_STEP } from '../../../store/widgets.store'
11
+ import { LoadingModal } from '../../LoadingModal'
12
+ import { ViewOnExplorer } from '../../ViewOnExplorer'
13
+
14
+ type Props = {
15
+ poolInfo: PoolInfoV2
16
+ tokenId: string
17
+ }
18
+
19
+ export function Transfer({ poolInfo, tokenId }: Props): React.ReactElement {
20
+ const dispatch = useAppDispatch()
21
+ const { provider, account } = useWeb3React()
22
+ const { borrowAmountBN: borrowAmountBNJson } =
23
+ useAppSelector(selectWidgetState)
24
+ const borrowAmountBN = BigNumber.from(borrowAmountBNJson).toString()
25
+ const [txHash, setTxHash] = useState('')
26
+
27
+ useEffect(() => {
28
+ const sendTx = async () => {
29
+ if (provider) {
30
+ try {
31
+ const tx = await drawdownWithReceivable(
32
+ provider.getSigner(),
33
+ poolInfo.poolName,
34
+ tokenId,
35
+ borrowAmountBN,
36
+ )
37
+ setTxHash(tx.hash)
38
+ await tx.wait()
39
+ dispatch(setStep(WIDGET_STEP.Done))
40
+ } catch (e) {
41
+ console.error(e)
42
+ dispatch(setStep(WIDGET_STEP.Error))
43
+ }
44
+ }
45
+ }
46
+ sendTx()
47
+ }, [borrowAmountBN, dispatch, poolInfo.poolName, provider, tokenId])
48
+
49
+ if (!account || !provider) {
50
+ return <LoadingModal title='Borrow' />
51
+ }
52
+
53
+ return (
54
+ <LoadingModal
55
+ title='Transaction Pending'
56
+ description='Waiting for confirmation...'
57
+ >
58
+ <ViewOnExplorer txHash={txHash} />
59
+ </LoadingModal>
60
+ )
61
+ }
@@ -0,0 +1,42 @@
1
+ import {
2
+ CreditStatsV2,
3
+ formatNumber,
4
+ timeUtil,
5
+ UnderlyingTokenInfo,
6
+ } from '@huma-finance/shared'
7
+ import React from 'react'
8
+
9
+ import { useAppSelector } from '../../../hooks/useRedux'
10
+ import { selectWidgetState } from '../../../store/widgets.selectors'
11
+ import { TxDoneModal } from '../../TxDoneModal'
12
+
13
+ type Props = {
14
+ poolUnderlyingToken: UnderlyingTokenInfo
15
+ creditRecord: CreditStatsV2['creditRecord']
16
+ handleAction: () => void
17
+ hasNextStep: boolean
18
+ }
19
+
20
+ export function Success({
21
+ poolUnderlyingToken,
22
+ creditRecord,
23
+ handleAction,
24
+ hasNextStep,
25
+ }: Props): React.ReactElement {
26
+ const { borrowAmountNet } = useAppSelector(selectWidgetState)
27
+ const { symbol } = poolUnderlyingToken
28
+ const dueDate = timeUtil.timestampToLL(creditRecord?.nextDueDate.toNumber())
29
+
30
+ const content = [
31
+ `${formatNumber(borrowAmountNet)} ${symbol} is now in your wallet.`,
32
+ `Note: your payment will be automatically deducted on ${dueDate}.`,
33
+ ]
34
+
35
+ return (
36
+ <TxDoneModal
37
+ handleAction={handleAction}
38
+ content={content}
39
+ buttonText={hasNextStep ? "WHAT'S NEXT" : undefined}
40
+ />
41
+ )
42
+ }
@@ -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
+ }
@@ -0,0 +1,148 @@
1
+ import {
2
+ CreditStateV2,
3
+ POOL_NAME,
4
+ useCreditStatsV2,
5
+ usePoolInfoV2,
6
+ usePoolUnderlyingTokenInfoV2,
7
+ } from '@huma-finance/shared'
8
+ import { useWeb3React } from '@web3-react/core'
9
+ import React, { useCallback, useEffect } from 'react'
10
+ import { useDispatch } from 'react-redux'
11
+
12
+ import {
13
+ useDoesChainSupportNotifi,
14
+ useIsFirstTimeNotifiUser,
15
+ } from '../../../hooks/useNotifi'
16
+ import { useAppSelector } from '../../../hooks/useRedux'
17
+ import { setStep } from '../../../store/widgets.reducers'
18
+ import { selectWidgetState } from '../../../store/widgets.selectors'
19
+ import { WIDGET_STEP } from '../../../store/widgets.store'
20
+ import { ErrorModal } from '../../ErrorModal'
21
+ import { WidgetWrapper } from '../../WidgetWrapper'
22
+ import { ChooseAmount } from './1-ChooseAmount'
23
+ import { ApproveAllowance } from './2-ApproveAllowance'
24
+ import { ApproveReceivable } from './3-ApproveReceivable'
25
+ import { Transfer } from './4-Transfer'
26
+ import { Success } from './5-Success'
27
+ import { Notifications } from './6-Notifications'
28
+
29
+ /**
30
+ * Receivable backed credit line pool borrow props V2
31
+ * @typedef {Object} ReceivableBackedCreditLineBorrowPropsV2
32
+ * @property {POOL_NAME} poolName The name of the pool.
33
+ * @property {tokenId} tokenId The receivable token id.
34
+ * @property {function():void} handleClose Function to notify to close the widget modal when user clicks the 'x' close button.
35
+ * @property {function((number|undefined)):void|undefined} handleSuccess Optional function to notify that the credit line pool borrow action is successful.
36
+ */
37
+ export interface ReceivableBackedCreditLineBorrowPropsV2 {
38
+ poolName: keyof typeof POOL_NAME
39
+ tokenId: string
40
+ handleClose: () => void
41
+ handleSuccess?: (blockNumber?: number) => void
42
+ }
43
+
44
+ export function ReceivableBackedCreditLineBorrowV2({
45
+ poolName: poolNameStr,
46
+ tokenId,
47
+ handleClose,
48
+ handleSuccess,
49
+ }: ReceivableBackedCreditLineBorrowPropsV2): React.ReactElement | null {
50
+ const dispatch = useDispatch()
51
+ const poolName = POOL_NAME[poolNameStr]
52
+ const { account, chainId, provider } = useWeb3React()
53
+ const poolInfo = usePoolInfoV2(poolName, chainId)
54
+ const poolUnderlyingToken = usePoolUnderlyingTokenInfoV2(poolName, provider)
55
+ const { step, errorMessage } = useAppSelector(selectWidgetState)
56
+ const [accountStats, refreshAccountStats] = useCreditStatsV2(
57
+ poolName,
58
+ account,
59
+ provider,
60
+ )
61
+ const { isFirstTimeNotifiUser } = useIsFirstTimeNotifiUser(account, chainId)
62
+ const { notifiChainSupported } = useDoesChainSupportNotifi(account, chainId)
63
+ const { creditRecord } = accountStats
64
+ const accountState = creditRecord?.state
65
+
66
+ useEffect(() => {
67
+ if (!step && accountState !== undefined) {
68
+ if (accountState >= CreditStateV2.Approved) {
69
+ dispatch(setStep(WIDGET_STEP.ChooseAmount))
70
+ }
71
+ }
72
+ }, [accountState, dispatch, step])
73
+
74
+ const setupNotificationsOrClose = useCallback(() => {
75
+ if (isFirstTimeNotifiUser && notifiChainSupported) {
76
+ dispatch(setStep(WIDGET_STEP.Notifications))
77
+ } else {
78
+ handleClose()
79
+ }
80
+ }, [dispatch, handleClose, isFirstTimeNotifiUser, notifiChainSupported])
81
+
82
+ const handleSuccessCallback = useCallback(() => {
83
+ refreshAccountStats()
84
+ if (handleSuccess) {
85
+ handleSuccess()
86
+ }
87
+ }, [handleSuccess, refreshAccountStats])
88
+
89
+ if (!poolInfo || !poolUnderlyingToken || !creditRecord || !step) {
90
+ return (
91
+ <WidgetWrapper
92
+ isOpen
93
+ isLoading
94
+ loadingTitle='Borrow'
95
+ handleClose={handleClose}
96
+ handleSuccess={handleSuccessCallback}
97
+ />
98
+ )
99
+ }
100
+
101
+ return (
102
+ <WidgetWrapper
103
+ isOpen
104
+ loadingTitle='Borrow'
105
+ handleClose={handleClose}
106
+ handleSuccess={handleSuccessCallback}
107
+ >
108
+ {step === WIDGET_STEP.ChooseAmount && (
109
+ <ChooseAmount
110
+ poolInfo={poolInfo}
111
+ poolUnderlyingToken={poolUnderlyingToken}
112
+ accountStats={accountStats}
113
+ tokenId={tokenId}
114
+ />
115
+ )}
116
+ {step === WIDGET_STEP.ApproveAllowance && (
117
+ <ApproveAllowance
118
+ poolInfo={poolInfo}
119
+ poolUnderlyingToken={poolUnderlyingToken}
120
+ />
121
+ )}
122
+ {step === WIDGET_STEP.ApproveNFT && tokenId && (
123
+ <ApproveReceivable poolInfo={poolInfo} tokenId={tokenId} />
124
+ )}
125
+ {step === WIDGET_STEP.Transfer && tokenId && (
126
+ <Transfer poolInfo={poolInfo} tokenId={tokenId} />
127
+ )}
128
+ {step === WIDGET_STEP.Done && (
129
+ <Success
130
+ poolUnderlyingToken={poolUnderlyingToken}
131
+ handleAction={setupNotificationsOrClose}
132
+ creditRecord={accountStats.creditRecord!}
133
+ hasNextStep={isFirstTimeNotifiUser}
134
+ />
135
+ )}
136
+ {step === WIDGET_STEP.Notifications && (
137
+ <Notifications handleAction={handleClose} />
138
+ )}
139
+ {step === WIDGET_STEP.Error && (
140
+ <ErrorModal
141
+ title='Borrow'
142
+ errorMessage={errorMessage}
143
+ handleOk={handleClose}
144
+ />
145
+ )}
146
+ </WidgetWrapper>
147
+ )
148
+ }