@huma-finance/widgets 0.0.31 → 0.0.33
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/.env.example +2 -2
- package/.eslintignore +2 -2
- package/.eslintrc.js +64 -64
- package/.prettierignore +4 -4
- package/.prettierrc.js +16 -16
- package/API.md +332 -332
- package/LICENSE +660 -660
- package/README.md +48 -48
- package/babel.config.js +15 -15
- package/config-overrides.js +9 -9
- package/cosmos.config.json +7 -7
- package/cypress/e2e/01-invoice-factoring-borrow.test.ts +62 -62
- package/cypress/support/e2e.ts +76 -76
- package/cypress/support/ethereum.ts +142 -142
- package/cypress/tsconfig.json +9 -9
- package/cypress/utils/index.ts +54 -54
- package/cypress.config.ts +20 -20
- package/dist/cjs/index.cjs +1026 -296
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.d.ts +193 -193
- package/dist/index.js +1028 -299
- package/dist/index.js.map +1 -1
- package/jsdoc2md.json +20 -20
- package/package.json +4 -4
- package/public/index.html +40 -40
- package/public/manifest.json +25 -25
- package/public/robots.txt +3 -3
- package/rollup.config.js +81 -81
- package/src/components/Activity.tsx +132 -132
- package/src/components/ApolloWrapper.tsx +15 -15
- package/src/components/ApproveAllowanceModal.tsx +121 -121
- package/src/components/BottomButton.tsx +33 -33
- package/src/components/ChainNotSupportedModal.tsx +33 -33
- package/src/components/ChooseAmountModal.tsx +322 -322
- package/src/components/ConfirmTransferModal.tsx +153 -153
- package/src/components/CreditLine/borrow/1-Evaluation.tsx +157 -157
- package/src/components/CreditLine/borrow/2-ChooseAmount.tsx +68 -68
- package/src/components/CreditLine/borrow/3-Transfer.tsx +44 -44
- package/src/components/CreditLine/borrow/4-ApproveAllowance.tsx +29 -29
- package/src/components/CreditLine/borrow/5-Success.tsx +38 -30
- package/src/components/CreditLine/borrow/6-Notifications.tsx +10 -0
- package/src/components/CreditLine/borrow/index.tsx +136 -117
- package/src/components/CreditLine/payment/1-ChooseAmount.tsx +67 -67
- package/src/components/CreditLine/payment/2-ApproveAllowance.tsx +23 -23
- package/src/components/CreditLine/payment/3-Transfer.tsx +34 -34
- package/src/components/CreditLine/payment/4-Success.tsx +39 -39
- package/src/components/CreditLine/payment/index.tsx +94 -94
- package/src/components/ErrorModal.tsx +132 -132
- package/src/components/Factoring/FactoredList.tsx +143 -143
- package/src/components/Factoring/UpcomingList.tsx +90 -90
- package/src/components/Factoring/index.ts +2 -2
- package/src/components/HumaLoading.tsx +68 -68
- package/src/components/HumaSnackBar.tsx +60 -0
- package/src/components/HumaTable.tsx +158 -158
- package/src/components/InvoiceFactoring/borrow/1-Evaluation.tsx +49 -49
- package/src/components/InvoiceFactoring/borrow/2-ChooseAmount.tsx +88 -88
- package/src/components/InvoiceFactoring/borrow/3-ConfirmTransfer.tsx +37 -37
- package/src/components/InvoiceFactoring/borrow/4-ApproveNFT.tsx +55 -55
- package/src/components/InvoiceFactoring/borrow/5-Transfer.tsx +34 -34
- package/src/components/InvoiceFactoring/borrow/6-Success.tsx +20 -20
- package/src/components/InvoiceFactoring/borrow/index.tsx +94 -94
- package/src/components/InvoiceFactoring/payment/1-ChooseAmount.tsx +67 -67
- package/src/components/InvoiceFactoring/payment/2-ApproveAllowance.tsx +23 -23
- package/src/components/InvoiceFactoring/payment/3-Transfer.tsx +34 -34
- package/src/components/InvoiceFactoring/payment/4-Success.tsx +23 -23
- package/src/components/InvoiceFactoring/payment/index.tsx +86 -86
- package/src/components/Lend/supply/1-Evaluation/EvaluationEA.tsx +86 -0
- package/src/components/Lend/supply/1-Evaluation/EvaluationKYC.tsx +287 -0
- package/src/components/Lend/supply/1-Evaluation/index.tsx +31 -0
- package/src/components/Lend/supply/2-ChooseAmount.tsx +69 -70
- package/src/components/Lend/supply/3-ApproveAllowance.tsx +25 -25
- package/src/components/Lend/supply/{6-Transfer.tsx → 4-Transfer.tsx} +32 -32
- package/src/components/Lend/supply/{7-Success.tsx → 5-Success.tsx} +60 -49
- package/src/components/Lend/supply/6-Notifications.tsx +10 -0
- package/src/components/Lend/supply/index.tsx +167 -144
- package/src/components/Lend/withdraw/1-CheckWithdrawble.tsx +73 -73
- package/src/components/Lend/withdraw/2-ChooseAmount.tsx +50 -50
- package/src/components/Lend/withdraw/3-Transfer.tsx +32 -32
- package/src/components/Lend/withdraw/4-Success.tsx +49 -49
- package/src/components/Lend/withdraw/index.tsx +101 -101
- package/src/components/LoadingModal.tsx +49 -49
- package/src/components/Notifi/NotifiSubscriptionModal.tsx +264 -0
- package/src/components/StreamFactoring/borrow/1-Evaluation.tsx +55 -55
- package/src/components/StreamFactoring/borrow/2-ChooseAmount.tsx +127 -127
- package/src/components/StreamFactoring/borrow/3-ConfirmTransfer.tsx +42 -42
- package/src/components/StreamFactoring/borrow/4-ApproveAllowance.tsx +33 -33
- package/src/components/StreamFactoring/borrow/5-Permit.tsx +144 -144
- package/src/components/StreamFactoring/borrow/6-Transfer.tsx +37 -37
- package/src/components/StreamFactoring/borrow/7-Success.tsx +20 -20
- package/src/components/StreamFactoring/borrow/index.tsx +94 -94
- package/src/components/StreamFactoring/payment/ChooseAmount.tsx +54 -54
- package/src/components/StreamFactoring/payment/Success.tsx +23 -23
- package/src/components/StreamFactoring/payment/Transfer.tsx +34 -34
- package/src/components/StreamFactoring/payment/index.tsx +66 -66
- package/src/components/SuperfluidFactoring/SuperfluidFactoredList.tsx +70 -70
- package/src/components/SuperfluidFactoring/SuperfluidUpcomingList.tsx +167 -167
- package/src/components/SuperfluidFactoring/index.tsx +85 -85
- package/src/components/TxDoneModal.tsx +85 -83
- package/src/components/TxSendModal.tsx +59 -59
- package/src/components/ViewOnExplorer.tsx +26 -26
- package/src/components/WidgetWrapper.tsx +74 -74
- package/src/components/WrapperModal.tsx +54 -54
- package/src/components/buttons/TableActionButton.tsx +36 -36
- package/src/components/buttons/index.ts +1 -1
- package/src/components/humaModal/HumaModal.tsx +68 -68
- package/src/components/humaModal/HumaModalHeader.tsx +70 -70
- package/src/components/humaModal/index.tsx +2 -2
- package/src/components/icons/approve-lender.svg +30 -30
- package/src/components/icons/auto-payback.svg +40 -40
- package/src/components/icons/check-circle.svg +3 -3
- package/src/components/icons/check-green.svg +3 -3
- package/src/components/icons/check.svg +10 -10
- package/src/components/icons/donut.svg +904 -904
- package/src/components/icons/ellipse.svg +3 -3
- package/src/components/icons/huma-full.svg +22 -22
- package/src/components/icons/huma.svg +15 -15
- package/src/components/icons/index.tsx +93 -93
- package/src/components/icons/loader.svg +229 -229
- package/src/components/icons/metamask.svg +31 -31
- package/src/components/icons/polygon.svg +16 -16
- package/src/components/icons/receipt.svg +3 -3
- package/src/components/icons/separator.svg +3 -3
- package/src/components/icons/sorry.svg +31 -31
- package/src/components/icons/usdc.svg +5 -5
- package/src/components/icons/wallet-connect.svg +11 -11
- package/src/cosmos/CreditLineBorrow.fixture.tsx +86 -86
- package/src/cosmos/CreditLinePayment.fixture.tsx +50 -50
- package/src/cosmos/InvoiceFactoringBorrow.fixture.tsx +111 -111
- package/src/cosmos/InvoiceFactoringPayment.fixture.tsx +67 -67
- package/src/cosmos/LendSupply.fixture.tsx +75 -75
- package/src/cosmos/LendWithdraw.fixture.tsx +43 -43
- package/src/cosmos/SDKTesting.fixture.tsx +616 -616
- package/src/cosmos/SuperfluidFactoringBorrow.fixture.tsx +15 -15
- package/src/cosmos/WalletWrapper.tsx +52 -52
- package/src/cosmos/abis/InvoiceNFT.json +644 -644
- package/src/cosmos/abis/ReceivableFactoringPool.json +1529 -1529
- package/src/cosmos/utils/env.ts +6 -6
- package/src/cosmos/utils/index.ts +169 -169
- package/src/fonts/Recoleta/Recoleta-Black.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-Bold.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-Light.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-Medium.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-Regular.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-RegularDEMO.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-SemiBold.otf +0 -0
- package/src/fonts/Recoleta/Recoleta-Thin.otf +0 -0
- package/src/hooks/useEA.ts +53 -53
- package/src/hooks/useNotifi.ts +71 -0
- package/src/hooks/useRedux.ts +6 -6
- package/src/index.css +61 -61
- package/src/index.tsx +301 -301
- package/src/react-app-env.d.ts +1 -1
- package/src/reportWebVitals.ts +15 -15
- package/src/setupTests.ts +6 -6
- package/src/store/index.ts +27 -27
- package/src/store/widgets.reducers.ts +120 -120
- package/src/store/widgets.selectors.ts +3 -3
- package/src/store/widgets.store.ts +55 -54
- package/src/theme/breakpoints.ts +10 -10
- package/src/theme/components.ts +70 -70
- package/src/theme/coreThemeConstants.ts +29 -29
- package/src/theme/cssMixins.ts +92 -92
- package/src/theme/hooks/useGetSizes.ts +31 -31
- package/src/theme/index.ts +24 -24
- package/src/theme/palette.ts +150 -150
- package/src/theme/shape.ts +7 -7
- package/src/theme/theme.types.ts +80 -80
- package/src/theme/typography.ts +117 -117
- package/src/utilTypes.d.ts +31 -31
- package/src/utils/env.ts +10 -10
- package/tsconfig.build.json +7 -7
- package/tsconfig.json +32 -32
- package/webpack.cosmos.js +54 -54
- package/src/components/Lend/supply/1-Evaluation.tsx +0 -175
- package/src/components/Lend/supply/4-ConfirmTransfer.tsx +0 -104
- package/src/components/NotifiSubscriptionModal.tsx +0 -84
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { useWeb3React } from '@web3-react/core'
|
|
2
|
-
import {
|
|
3
|
-
decodeLogs,
|
|
4
|
-
downScale,
|
|
5
|
-
formatMoney,
|
|
6
|
-
PoolInfoType,
|
|
7
|
-
sendTxAtom,
|
|
8
|
-
} from '@huma-finance/shared'
|
|
9
|
-
import transferAbi from '@huma-finance/shared/dist/abis/Transfer.json'
|
|
10
|
-
import { useAtom } from 'jotai'
|
|
11
|
-
import React, { useEffect, useState } from 'react'
|
|
12
|
-
|
|
13
|
-
import { TxDoneModal } from '../../TxDoneModal'
|
|
14
|
-
|
|
15
|
-
type Props = {
|
|
16
|
-
poolInfo: PoolInfoType
|
|
17
|
-
handleAction: () => void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function Success({ poolInfo, handleAction }: Props): React.ReactElement {
|
|
21
|
-
const { account } = useWeb3React()
|
|
22
|
-
const { poolUnderlyingToken } = poolInfo
|
|
23
|
-
const [{ txReceipt }] = useAtom(sendTxAtom)
|
|
24
|
-
const { symbol, decimals, address } = poolUnderlyingToken
|
|
25
|
-
const [withdrawAmount, setWithdrawAmount] = useState<string | undefined>()
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
if (txReceipt) {
|
|
29
|
-
const events = decodeLogs(txReceipt.logs, transferAbi)
|
|
30
|
-
if (events) {
|
|
31
|
-
events.forEach((event) => {
|
|
32
|
-
const { from, to, value } = event.args
|
|
33
|
-
if (
|
|
34
|
-
from.toLowerCase() === poolInfo.pool.toLowerCase() &&
|
|
35
|
-
to.toLowerCase() === account?.toLowerCase()
|
|
36
|
-
) {
|
|
37
|
-
setWithdrawAmount(downScale(value.toString(), decimals))
|
|
38
|
-
}
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}, [account, address, decimals, poolInfo.pool, txReceipt])
|
|
43
|
-
|
|
44
|
-
const content = [
|
|
45
|
-
`You successfully withdrawn ${formatMoney(withdrawAmount)} ${symbol}.`,
|
|
46
|
-
]
|
|
47
|
-
|
|
48
|
-
return <TxDoneModal handleAction={handleAction} content={content} />
|
|
49
|
-
}
|
|
1
|
+
import { useWeb3React } from '@web3-react/core'
|
|
2
|
+
import {
|
|
3
|
+
decodeLogs,
|
|
4
|
+
downScale,
|
|
5
|
+
formatMoney,
|
|
6
|
+
PoolInfoType,
|
|
7
|
+
sendTxAtom,
|
|
8
|
+
} from '@huma-finance/shared'
|
|
9
|
+
import transferAbi from '@huma-finance/shared/dist/abis/Transfer.json'
|
|
10
|
+
import { useAtom } from 'jotai'
|
|
11
|
+
import React, { useEffect, useState } from 'react'
|
|
12
|
+
|
|
13
|
+
import { TxDoneModal } from '../../TxDoneModal'
|
|
14
|
+
|
|
15
|
+
type Props = {
|
|
16
|
+
poolInfo: PoolInfoType
|
|
17
|
+
handleAction: () => void
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function Success({ poolInfo, handleAction }: Props): React.ReactElement {
|
|
21
|
+
const { account } = useWeb3React()
|
|
22
|
+
const { poolUnderlyingToken } = poolInfo
|
|
23
|
+
const [{ txReceipt }] = useAtom(sendTxAtom)
|
|
24
|
+
const { symbol, decimals, address } = poolUnderlyingToken
|
|
25
|
+
const [withdrawAmount, setWithdrawAmount] = useState<string | undefined>()
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (txReceipt) {
|
|
29
|
+
const events = decodeLogs(txReceipt.logs, transferAbi)
|
|
30
|
+
if (events) {
|
|
31
|
+
events.forEach((event) => {
|
|
32
|
+
const { from, to, value } = event.args
|
|
33
|
+
if (
|
|
34
|
+
from.toLowerCase() === poolInfo.pool.toLowerCase() &&
|
|
35
|
+
to.toLowerCase() === account?.toLowerCase()
|
|
36
|
+
) {
|
|
37
|
+
setWithdrawAmount(downScale(value.toString(), decimals))
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}, [account, address, decimals, poolInfo.pool, txReceipt])
|
|
43
|
+
|
|
44
|
+
const content = [
|
|
45
|
+
`You successfully withdrawn ${formatMoney(withdrawAmount)} ${symbol}.`,
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
return <TxDoneModal handleAction={handleAction} content={content} />
|
|
49
|
+
}
|
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
import { useWeb3React } from '@web3-react/core'
|
|
2
|
-
import {
|
|
3
|
-
POOL_NAME,
|
|
4
|
-
POOL_TYPE,
|
|
5
|
-
useLenderPosition,
|
|
6
|
-
usePoolInfo,
|
|
7
|
-
} from '@huma-finance/shared'
|
|
8
|
-
import React, { useCallback, useEffect } from 'react'
|
|
9
|
-
import { useDispatch } from 'react-redux'
|
|
10
|
-
|
|
11
|
-
import { useAppSelector } from '../../../hooks/useRedux'
|
|
12
|
-
import { setStep } from '../../../store/widgets.reducers'
|
|
13
|
-
import { selectWidgetState } from '../../../store/widgets.selectors'
|
|
14
|
-
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
15
|
-
import { ErrorModal } from '../../ErrorModal'
|
|
16
|
-
import { WidgetWrapper } from '../../WidgetWrapper'
|
|
17
|
-
import { CheckWithdrawable } from './1-CheckWithdrawble'
|
|
18
|
-
import { ChooseAmount } from './2-ChooseAmount'
|
|
19
|
-
import { Transfer } from './3-Transfer'
|
|
20
|
-
import { Success } from './4-Success'
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Lend pool withdraw props
|
|
24
|
-
* @typedef {Object} LendWithdrawProps
|
|
25
|
-
* @property {POOL_NAME} poolName The name of the pool.
|
|
26
|
-
* @property {POOL_TYPE} poolType The type of the pool.
|
|
27
|
-
* @property {function():void} handleClose Function to notify to close the widget modal when user clicks the 'x' close button.
|
|
28
|
-
* @property {function((number|undefined)):void|undefined} handleSuccess Optional function to notify that the lending pool withdraw action is successful.
|
|
29
|
-
*/
|
|
30
|
-
export type LendWithdrawProps = {
|
|
31
|
-
poolName: keyof typeof POOL_NAME
|
|
32
|
-
poolType: keyof typeof POOL_TYPE
|
|
33
|
-
handleClose: () => void
|
|
34
|
-
handleSuccess?: (blockNumber?: number) => void
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function LendWithdraw({
|
|
38
|
-
poolName: poolNameStr,
|
|
39
|
-
poolType: poolTypeStr,
|
|
40
|
-
handleClose,
|
|
41
|
-
handleSuccess,
|
|
42
|
-
}: LendWithdrawProps): React.ReactElement | null {
|
|
43
|
-
const dispatch = useDispatch()
|
|
44
|
-
const { account } = useWeb3React()
|
|
45
|
-
const poolName = POOL_NAME[poolNameStr]
|
|
46
|
-
const poolType = POOL_TYPE[poolTypeStr]
|
|
47
|
-
const poolInfo = usePoolInfo(poolName, poolType)
|
|
48
|
-
const { step, errorMessage } = useAppSelector(selectWidgetState)
|
|
49
|
-
const [lenderPosition, refreshLenderPosition] = useLenderPosition(
|
|
50
|
-
poolName,
|
|
51
|
-
poolType,
|
|
52
|
-
account,
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
if (!step && lenderPosition) {
|
|
57
|
-
dispatch(setStep(WIDGET_STEP.CheckWithdrawable))
|
|
58
|
-
}
|
|
59
|
-
}, [dispatch, lenderPosition, step])
|
|
60
|
-
|
|
61
|
-
const handleWithdrawSuccess = useCallback(
|
|
62
|
-
(blockNumber: number) => {
|
|
63
|
-
refreshLenderPosition()
|
|
64
|
-
if (handleSuccess) {
|
|
65
|
-
handleSuccess(blockNumber)
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
[handleSuccess, refreshLenderPosition],
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
if (!poolInfo) {
|
|
72
|
-
return null
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return (
|
|
76
|
-
<WidgetWrapper
|
|
77
|
-
isOpen
|
|
78
|
-
handleClose={handleClose}
|
|
79
|
-
handleSuccess={handleWithdrawSuccess}
|
|
80
|
-
>
|
|
81
|
-
{(!step || step === WIDGET_STEP.CheckWithdrawable) && (
|
|
82
|
-
<CheckWithdrawable poolInfo={poolInfo} handleClose={handleClose} />
|
|
83
|
-
)}
|
|
84
|
-
{step === WIDGET_STEP.ChooseAmount && (
|
|
85
|
-
<ChooseAmount poolInfo={poolInfo} lenderPosition={lenderPosition!} />
|
|
86
|
-
)}
|
|
87
|
-
{step === WIDGET_STEP.Transfer && <Transfer poolInfo={poolInfo} />}
|
|
88
|
-
{step === WIDGET_STEP.Done && (
|
|
89
|
-
<Success poolInfo={poolInfo} handleAction={handleClose} />
|
|
90
|
-
)}
|
|
91
|
-
{step === WIDGET_STEP.Error && (
|
|
92
|
-
<ErrorModal
|
|
93
|
-
title='Withdraw'
|
|
94
|
-
errorReason='Sorry there was an error'
|
|
95
|
-
errorMessage={errorMessage}
|
|
96
|
-
handleOk={handleClose}
|
|
97
|
-
/>
|
|
98
|
-
)}
|
|
99
|
-
</WidgetWrapper>
|
|
100
|
-
)
|
|
101
|
-
}
|
|
1
|
+
import { useWeb3React } from '@web3-react/core'
|
|
2
|
+
import {
|
|
3
|
+
POOL_NAME,
|
|
4
|
+
POOL_TYPE,
|
|
5
|
+
useLenderPosition,
|
|
6
|
+
usePoolInfo,
|
|
7
|
+
} from '@huma-finance/shared'
|
|
8
|
+
import React, { useCallback, useEffect } from 'react'
|
|
9
|
+
import { useDispatch } from 'react-redux'
|
|
10
|
+
|
|
11
|
+
import { useAppSelector } from '../../../hooks/useRedux'
|
|
12
|
+
import { setStep } from '../../../store/widgets.reducers'
|
|
13
|
+
import { selectWidgetState } from '../../../store/widgets.selectors'
|
|
14
|
+
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
15
|
+
import { ErrorModal } from '../../ErrorModal'
|
|
16
|
+
import { WidgetWrapper } from '../../WidgetWrapper'
|
|
17
|
+
import { CheckWithdrawable } from './1-CheckWithdrawble'
|
|
18
|
+
import { ChooseAmount } from './2-ChooseAmount'
|
|
19
|
+
import { Transfer } from './3-Transfer'
|
|
20
|
+
import { Success } from './4-Success'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Lend pool withdraw props
|
|
24
|
+
* @typedef {Object} LendWithdrawProps
|
|
25
|
+
* @property {POOL_NAME} poolName The name of the pool.
|
|
26
|
+
* @property {POOL_TYPE} poolType The type of the pool.
|
|
27
|
+
* @property {function():void} handleClose Function to notify to close the widget modal when user clicks the 'x' close button.
|
|
28
|
+
* @property {function((number|undefined)):void|undefined} handleSuccess Optional function to notify that the lending pool withdraw action is successful.
|
|
29
|
+
*/
|
|
30
|
+
export type LendWithdrawProps = {
|
|
31
|
+
poolName: keyof typeof POOL_NAME
|
|
32
|
+
poolType: keyof typeof POOL_TYPE
|
|
33
|
+
handleClose: () => void
|
|
34
|
+
handleSuccess?: (blockNumber?: number) => void
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function LendWithdraw({
|
|
38
|
+
poolName: poolNameStr,
|
|
39
|
+
poolType: poolTypeStr,
|
|
40
|
+
handleClose,
|
|
41
|
+
handleSuccess,
|
|
42
|
+
}: LendWithdrawProps): React.ReactElement | null {
|
|
43
|
+
const dispatch = useDispatch()
|
|
44
|
+
const { account } = useWeb3React()
|
|
45
|
+
const poolName = POOL_NAME[poolNameStr]
|
|
46
|
+
const poolType = POOL_TYPE[poolTypeStr]
|
|
47
|
+
const poolInfo = usePoolInfo(poolName, poolType)
|
|
48
|
+
const { step, errorMessage } = useAppSelector(selectWidgetState)
|
|
49
|
+
const [lenderPosition, refreshLenderPosition] = useLenderPosition(
|
|
50
|
+
poolName,
|
|
51
|
+
poolType,
|
|
52
|
+
account,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (!step && lenderPosition) {
|
|
57
|
+
dispatch(setStep(WIDGET_STEP.CheckWithdrawable))
|
|
58
|
+
}
|
|
59
|
+
}, [dispatch, lenderPosition, step])
|
|
60
|
+
|
|
61
|
+
const handleWithdrawSuccess = useCallback(
|
|
62
|
+
(blockNumber: number) => {
|
|
63
|
+
refreshLenderPosition()
|
|
64
|
+
if (handleSuccess) {
|
|
65
|
+
handleSuccess(blockNumber)
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
[handleSuccess, refreshLenderPosition],
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if (!poolInfo) {
|
|
72
|
+
return null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<WidgetWrapper
|
|
77
|
+
isOpen
|
|
78
|
+
handleClose={handleClose}
|
|
79
|
+
handleSuccess={handleWithdrawSuccess}
|
|
80
|
+
>
|
|
81
|
+
{(!step || step === WIDGET_STEP.CheckWithdrawable) && (
|
|
82
|
+
<CheckWithdrawable poolInfo={poolInfo} handleClose={handleClose} />
|
|
83
|
+
)}
|
|
84
|
+
{step === WIDGET_STEP.ChooseAmount && (
|
|
85
|
+
<ChooseAmount poolInfo={poolInfo} lenderPosition={lenderPosition!} />
|
|
86
|
+
)}
|
|
87
|
+
{step === WIDGET_STEP.Transfer && <Transfer poolInfo={poolInfo} />}
|
|
88
|
+
{step === WIDGET_STEP.Done && (
|
|
89
|
+
<Success poolInfo={poolInfo} handleAction={handleClose} />
|
|
90
|
+
)}
|
|
91
|
+
{step === WIDGET_STEP.Error && (
|
|
92
|
+
<ErrorModal
|
|
93
|
+
title='Withdraw'
|
|
94
|
+
errorReason='Sorry there was an error'
|
|
95
|
+
errorMessage={errorMessage}
|
|
96
|
+
handleOk={handleClose}
|
|
97
|
+
/>
|
|
98
|
+
)}
|
|
99
|
+
</WidgetWrapper>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { Box, css, useTheme } from '@mui/material'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { HumaLoading } from './HumaLoading'
|
|
4
|
-
|
|
5
|
-
import { WrapperModal } from './WrapperModal'
|
|
6
|
-
|
|
7
|
-
type Props = {
|
|
8
|
-
title: string
|
|
9
|
-
description?: string
|
|
10
|
-
hideLoader?: boolean
|
|
11
|
-
children?: React.ReactNode
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function LoadingModal({
|
|
15
|
-
title,
|
|
16
|
-
description,
|
|
17
|
-
hideLoader = false,
|
|
18
|
-
children,
|
|
19
|
-
}: Props): React.ReactElement {
|
|
20
|
-
const theme = useTheme()
|
|
21
|
-
|
|
22
|
-
const styles = {
|
|
23
|
-
loader: css`
|
|
24
|
-
width: 100%;
|
|
25
|
-
${theme.cssMixins.rowHCentered};
|
|
26
|
-
position: absolute;
|
|
27
|
-
top: 50%;
|
|
28
|
-
transform: translateY(-50%);
|
|
29
|
-
`,
|
|
30
|
-
bottom: css`
|
|
31
|
-
& .MuiButtonBase-root {
|
|
32
|
-
width: 100%;
|
|
33
|
-
position: absolute;
|
|
34
|
-
bottom: 0;
|
|
35
|
-
}
|
|
36
|
-
`,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return (
|
|
40
|
-
<WrapperModal title={title} subTitle={description}>
|
|
41
|
-
{!hideLoader && (
|
|
42
|
-
<Box css={styles.loader}>
|
|
43
|
-
<HumaLoading />
|
|
44
|
-
</Box>
|
|
45
|
-
)}
|
|
46
|
-
<Box css={styles.bottom}>{children}</Box>
|
|
47
|
-
</WrapperModal>
|
|
48
|
-
)
|
|
49
|
-
}
|
|
1
|
+
import { Box, css, useTheme } from '@mui/material'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { HumaLoading } from './HumaLoading'
|
|
4
|
+
|
|
5
|
+
import { WrapperModal } from './WrapperModal'
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
title: string
|
|
9
|
+
description?: string
|
|
10
|
+
hideLoader?: boolean
|
|
11
|
+
children?: React.ReactNode
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function LoadingModal({
|
|
15
|
+
title,
|
|
16
|
+
description,
|
|
17
|
+
hideLoader = false,
|
|
18
|
+
children,
|
|
19
|
+
}: Props): React.ReactElement {
|
|
20
|
+
const theme = useTheme()
|
|
21
|
+
|
|
22
|
+
const styles = {
|
|
23
|
+
loader: css`
|
|
24
|
+
width: 100%;
|
|
25
|
+
${theme.cssMixins.rowHCentered};
|
|
26
|
+
position: absolute;
|
|
27
|
+
top: 50%;
|
|
28
|
+
transform: translateY(-50%);
|
|
29
|
+
`,
|
|
30
|
+
bottom: css`
|
|
31
|
+
& .MuiButtonBase-root {
|
|
32
|
+
width: 100%;
|
|
33
|
+
position: absolute;
|
|
34
|
+
bottom: 0;
|
|
35
|
+
}
|
|
36
|
+
`,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<WrapperModal title={title} subTitle={description}>
|
|
41
|
+
{!hideLoader && (
|
|
42
|
+
<Box css={styles.loader}>
|
|
43
|
+
<HumaLoading />
|
|
44
|
+
</Box>
|
|
45
|
+
)}
|
|
46
|
+
<Box css={styles.bottom}>{children}</Box>
|
|
47
|
+
</WrapperModal>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react'
|
|
2
|
+
import { useWeb3React } from '@web3-react/core'
|
|
3
|
+
import {
|
|
4
|
+
NotifiFrontendClient,
|
|
5
|
+
newFrontendClient,
|
|
6
|
+
Uint8SignMessageFunction,
|
|
7
|
+
SignMessageParams,
|
|
8
|
+
CardConfigItemV1,
|
|
9
|
+
DirectPushEventTypeItem,
|
|
10
|
+
EventTypeItem,
|
|
11
|
+
BroadcastEventTypeItem,
|
|
12
|
+
} from '@notifi-network/notifi-frontend-client'
|
|
13
|
+
import { getBlockchainConfigFromChain, txAtom } from '@huma-finance/shared'
|
|
14
|
+
import { ethers } from 'ethers'
|
|
15
|
+
import {
|
|
16
|
+
Box,
|
|
17
|
+
Input,
|
|
18
|
+
InputAdornment,
|
|
19
|
+
Typography,
|
|
20
|
+
css,
|
|
21
|
+
useTheme,
|
|
22
|
+
} from '@mui/material'
|
|
23
|
+
import Email from '@mui/icons-material/Email'
|
|
24
|
+
import { useResetAtom } from 'jotai/utils'
|
|
25
|
+
|
|
26
|
+
import { WrapperModal } from '../WrapperModal'
|
|
27
|
+
import { envUtil } from '../../utils/env'
|
|
28
|
+
import { BottomButton } from '../BottomButton'
|
|
29
|
+
import { LoadingModal } from '../LoadingModal'
|
|
30
|
+
import { CheckIcon } from '../icons'
|
|
31
|
+
import { resetState } from '../../store/widgets.reducers'
|
|
32
|
+
import { useAppDispatch } from '../../hooks/useRedux'
|
|
33
|
+
|
|
34
|
+
type Props = {
|
|
35
|
+
handleSuccess: () => void
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getIdFromEventType(eventType: EventTypeItem): string {
|
|
39
|
+
if (eventType.type === 'directPush') {
|
|
40
|
+
const directPushEventType = eventType as DirectPushEventTypeItem
|
|
41
|
+
return (
|
|
42
|
+
directPushEventType.directPushId as {
|
|
43
|
+
value: string
|
|
44
|
+
}
|
|
45
|
+
).value
|
|
46
|
+
}
|
|
47
|
+
if (eventType.type === 'broadcast') {
|
|
48
|
+
const broadcastEventType = eventType as BroadcastEventTypeItem
|
|
49
|
+
return (
|
|
50
|
+
broadcastEventType.broadcastId as {
|
|
51
|
+
value: string
|
|
52
|
+
}
|
|
53
|
+
).value
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return ''
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function fetchEventTypes(
|
|
60
|
+
notifiClient: NotifiFrontendClient,
|
|
61
|
+
): Promise<(EventTypeItem & { enabled: boolean })[]> {
|
|
62
|
+
const subscribedAlerts = await notifiClient.getAlerts()
|
|
63
|
+
|
|
64
|
+
const subscriptionConfig = (await notifiClient.fetchSubscriptionCard({
|
|
65
|
+
id: process.env.REACT_APP_NOTIFI_CONFIG_ID ?? '',
|
|
66
|
+
type: 'SUBSCRIPTION_CARD',
|
|
67
|
+
})) as CardConfigItemV1
|
|
68
|
+
|
|
69
|
+
const eventTypes = subscriptionConfig?.eventTypes?.map(
|
|
70
|
+
(eventType): EventTypeItem & { enabled: boolean } => {
|
|
71
|
+
const eventTypeId = getIdFromEventType(eventType)
|
|
72
|
+
let enabled = false
|
|
73
|
+
// Check whether the user is subscribed to the event
|
|
74
|
+
const subscribedAlert = subscribedAlerts?.find(
|
|
75
|
+
(alert) => alert.filterOptions.indexOf(eventTypeId) >= 0,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if (subscribedAlert) {
|
|
79
|
+
enabled = true
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
...eventType,
|
|
84
|
+
enabled,
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
return eventTypes
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function NotifiSubscriptionModal({
|
|
93
|
+
handleSuccess,
|
|
94
|
+
}: Props): React.ReactElement {
|
|
95
|
+
const theme = useTheme()
|
|
96
|
+
const reset = useResetAtom(txAtom)
|
|
97
|
+
const dispatch = useAppDispatch()
|
|
98
|
+
const { account, chainId, provider } = useWeb3React()
|
|
99
|
+
const [notifiClient, setNotifiClient] = useState<NotifiFrontendClient>()
|
|
100
|
+
const [showSuccessScreen, setShowSuccessScreen] = useState<boolean>(false)
|
|
101
|
+
const [isLoading, setIsLoading] = useState<boolean>(false)
|
|
102
|
+
const [emailAddress, setEmailAddress] = useState<string>()
|
|
103
|
+
const [emailValid, setEmailValid] = useState<boolean>()
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
const initializeClient = async () => {
|
|
107
|
+
if (account != null && chainId != null) {
|
|
108
|
+
const client = newFrontendClient({
|
|
109
|
+
account: { publicKey: account },
|
|
110
|
+
tenantId: 'humadapp',
|
|
111
|
+
env: envUtil.checkIsDev() ? 'Development' : 'Production',
|
|
112
|
+
walletBlockchain: getBlockchainConfigFromChain(chainId),
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
await client.initialize()
|
|
116
|
+
|
|
117
|
+
setNotifiClient(client)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
initializeClient()
|
|
122
|
+
}, [account, chainId])
|
|
123
|
+
|
|
124
|
+
const signMessage: Uint8SignMessageFunction = async (
|
|
125
|
+
message: Uint8Array,
|
|
126
|
+
): Promise<Uint8Array> => {
|
|
127
|
+
const signer = provider!.getSigner()
|
|
128
|
+
const signature = await signer.signMessage(Buffer.from(message))
|
|
129
|
+
return ethers.utils.arrayify(signature)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const handleEmailAddressChange = (
|
|
133
|
+
event: React.ChangeEvent<HTMLInputElement>,
|
|
134
|
+
) => {
|
|
135
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
136
|
+
setEmailValid(emailRegex.test(event.target.value ?? ''))
|
|
137
|
+
setEmailAddress(event.target.value)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const logInAndSubscribe = async (): Promise<void> => {
|
|
141
|
+
if (notifiClient != null && chainId != null) {
|
|
142
|
+
setIsLoading(true)
|
|
143
|
+
|
|
144
|
+
// Ask user to sign a message to authenticate
|
|
145
|
+
try {
|
|
146
|
+
await notifiClient.logIn({
|
|
147
|
+
walletBlockchain: getBlockchainConfigFromChain(chainId),
|
|
148
|
+
signMessage,
|
|
149
|
+
} as SignMessageParams)
|
|
150
|
+
} catch (e) {
|
|
151
|
+
setIsLoading(false)
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Fetch all event types
|
|
156
|
+
const fetchedEventTypes = await fetchEventTypes(notifiClient)
|
|
157
|
+
|
|
158
|
+
// Authorize this email address for this wallet
|
|
159
|
+
await notifiClient.ensureTargetGroup({
|
|
160
|
+
name: 'Default',
|
|
161
|
+
emailAddress: emailAddress!,
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// Intentionally running this in serial because the Notifi ensureAlert can't handle
|
|
165
|
+
// multiple calls. Notified their team to fix this.
|
|
166
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
167
|
+
for (const eventType of fetchedEventTypes) {
|
|
168
|
+
// eslint-disable-next-line no-await-in-loop
|
|
169
|
+
await notifiClient.ensureAlert({
|
|
170
|
+
eventType,
|
|
171
|
+
inputs: {},
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
setShowSuccessScreen(true)
|
|
176
|
+
setIsLoading(false)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const handleCloseModal = useCallback(() => {
|
|
181
|
+
reset()
|
|
182
|
+
dispatch(resetState())
|
|
183
|
+
handleSuccess()
|
|
184
|
+
}, [dispatch, handleSuccess, reset])
|
|
185
|
+
|
|
186
|
+
const styles = {
|
|
187
|
+
disclaimer: css`
|
|
188
|
+
${theme.cssMixins.rowCentered};
|
|
189
|
+
font-family: 'Uni-Neue-Regular';
|
|
190
|
+
font-size: 16px;
|
|
191
|
+
color: #a8a1b2;
|
|
192
|
+
margin-top: 48px;
|
|
193
|
+
`,
|
|
194
|
+
inputField: css`
|
|
195
|
+
width: 90%;
|
|
196
|
+
font-size: 16px;
|
|
197
|
+
`,
|
|
198
|
+
inputWrapper: css`
|
|
199
|
+
width: 100%;
|
|
200
|
+
`,
|
|
201
|
+
header: css`
|
|
202
|
+
${theme.cssMixins.rowHCentered};
|
|
203
|
+
margin-top: -5px;
|
|
204
|
+
`,
|
|
205
|
+
check: css`
|
|
206
|
+
width: 100%;
|
|
207
|
+
${theme.cssMixins.rowHCentered};
|
|
208
|
+
margin-top: 82px;
|
|
209
|
+
`,
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (isLoading) {
|
|
213
|
+
return <LoadingModal title='Notifications' />
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (showSuccessScreen) {
|
|
217
|
+
return (
|
|
218
|
+
<WrapperModal
|
|
219
|
+
title='Success'
|
|
220
|
+
subTitle='You successfully connected your email'
|
|
221
|
+
>
|
|
222
|
+
<Box css={styles.check}>
|
|
223
|
+
<CheckIcon />
|
|
224
|
+
</Box>
|
|
225
|
+
<BottomButton variant='contained' onClick={handleCloseModal}>
|
|
226
|
+
DONE
|
|
227
|
+
</BottomButton>
|
|
228
|
+
</WrapperModal>
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return (
|
|
233
|
+
<WrapperModal title='Connect Your Email'>
|
|
234
|
+
<Typography variant='body2' margin='12px 0'>
|
|
235
|
+
Connect your wallet to receive important emails about your account
|
|
236
|
+
</Typography>
|
|
237
|
+
<Box css={styles.inputWrapper}>
|
|
238
|
+
<Input
|
|
239
|
+
css={styles.inputField}
|
|
240
|
+
type='email'
|
|
241
|
+
value={emailAddress}
|
|
242
|
+
onChange={handleEmailAddressChange}
|
|
243
|
+
placeholder='youremail@example.com'
|
|
244
|
+
startAdornment={
|
|
245
|
+
<InputAdornment position='start'>
|
|
246
|
+
<Email />
|
|
247
|
+
</InputAdornment>
|
|
248
|
+
}
|
|
249
|
+
/>
|
|
250
|
+
</Box>
|
|
251
|
+
<Box css={styles.disclaimer}>
|
|
252
|
+
You can adjust these settings at any time by clicking the alert icon in
|
|
253
|
+
the header
|
|
254
|
+
</Box>
|
|
255
|
+
<BottomButton
|
|
256
|
+
variant='contained'
|
|
257
|
+
onClick={logInAndSubscribe}
|
|
258
|
+
disabled={!emailValid || isLoading}
|
|
259
|
+
>
|
|
260
|
+
CONNECT WALLET
|
|
261
|
+
</BottomButton>
|
|
262
|
+
</WrapperModal>
|
|
263
|
+
)
|
|
264
|
+
}
|