@huma-finance/widgets 0.0.36 → 0.0.37
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 +134 -134
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.d.ts +223 -223
- package/dist/index.js +134 -134
- 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 +128 -128
- package/src/components/ApolloWrapper.tsx +15 -15
- package/src/components/ApproveAllowanceModal.tsx +138 -138
- 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/approve/1-ApproveAllowance.tsx +34 -34
- package/src/components/CreditLine/approve/2-Success.tsx +43 -43
- package/src/components/CreditLine/approve/index.tsx +85 -85
- package/src/components/CreditLine/borrow/1-Evaluation.tsx +157 -157
- package/src/components/CreditLine/borrow/2-ChooseAmount.tsx +74 -74
- package/src/components/CreditLine/borrow/3-ApproveAllowance.tsx +29 -29
- package/src/components/CreditLine/borrow/4-Transfer.tsx +34 -34
- package/src/components/CreditLine/borrow/5-Success.tsx +38 -38
- package/src/components/CreditLine/borrow/6-Notifications.tsx +10 -10
- package/src/components/CreditLine/borrow/index.tsx +136 -136
- 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 +136 -136
- 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 -60
- package/src/components/HumaTable.tsx +203 -203
- 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 +90 -90
- package/src/components/Lend/supply/1-Evaluation/EvaluationKYC.tsx +319 -319
- package/src/components/Lend/supply/1-Evaluation/index.tsx +31 -31
- package/src/components/Lend/supply/2-ChooseAmount.tsx +69 -69
- package/src/components/Lend/supply/3-ApproveAllowance.tsx +25 -25
- package/src/components/Lend/supply/4-Transfer.tsx +32 -32
- package/src/components/Lend/supply/5-Success.tsx +60 -60
- package/src/components/Lend/supply/6-Notifications.tsx +10 -10
- package/src/components/Lend/supply/index.tsx +167 -167
- 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 +268 -268
- 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 +69 -69
- package/src/components/SuperfluidFactoring/SuperfluidUpcomingList.tsx +166 -166
- package/src/components/SuperfluidFactoring/index.tsx +85 -85
- package/src/components/TxDoneModal.tsx +85 -85
- package/src/components/TxSendModal.tsx +59 -59
- package/src/components/ViewOnExplorer.tsx +23 -23
- 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 +58 -58
- package/src/components/icons/auto-payback.svg +139 -139
- 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 +17 -17
- package/src/components/icons/usdc.svg +5 -5
- package/src/components/icons/wallet-connect.svg +11 -11
- package/src/components/images/index.ts +3 -3
- 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/useElementDimensions.ts +30 -30
- package/src/hooks/useNotifi.ts +71 -71
- package/src/hooks/useRedux.ts +6 -6
- package/src/index.css +61 -61
- package/src/index.tsx +283 -283
- 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 -55
- 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 +30 -30
- package/src/utils/env.ts +10 -10
- package/tsconfig.build.json +7 -7
- package/tsconfig.json +32 -32
- package/webpack.cosmos.js +54 -54
|
@@ -1,268 +1,268 @@
|
|
|
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 {
|
|
14
|
-
getBlockchainConfigFromChain,
|
|
15
|
-
txAtom,
|
|
16
|
-
getNotifiDappId,
|
|
17
|
-
} from '@huma-finance/shared'
|
|
18
|
-
import { ethers } from 'ethers'
|
|
19
|
-
import {
|
|
20
|
-
Box,
|
|
21
|
-
Input,
|
|
22
|
-
InputAdornment,
|
|
23
|
-
Typography,
|
|
24
|
-
css,
|
|
25
|
-
useTheme,
|
|
26
|
-
} from '@mui/material'
|
|
27
|
-
import Email from '@mui/icons-material/Email'
|
|
28
|
-
import { useResetAtom } from 'jotai/utils'
|
|
29
|
-
|
|
30
|
-
import { WrapperModal } from '../WrapperModal'
|
|
31
|
-
import { envUtil } from '../../utils/env'
|
|
32
|
-
import { BottomButton } from '../BottomButton'
|
|
33
|
-
import { LoadingModal } from '../LoadingModal'
|
|
34
|
-
import { CheckIcon } from '../icons'
|
|
35
|
-
import { resetState } from '../../store/widgets.reducers'
|
|
36
|
-
import { useAppDispatch } from '../../hooks/useRedux'
|
|
37
|
-
|
|
38
|
-
type Props = {
|
|
39
|
-
handleSuccess: () => void
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function getIdFromEventType(eventType: EventTypeItem): string {
|
|
43
|
-
if (eventType.type === 'directPush') {
|
|
44
|
-
const directPushEventType = eventType as DirectPushEventTypeItem
|
|
45
|
-
return (
|
|
46
|
-
directPushEventType.directPushId as {
|
|
47
|
-
value: string
|
|
48
|
-
}
|
|
49
|
-
).value
|
|
50
|
-
}
|
|
51
|
-
if (eventType.type === 'broadcast') {
|
|
52
|
-
const broadcastEventType = eventType as BroadcastEventTypeItem
|
|
53
|
-
return (
|
|
54
|
-
broadcastEventType.broadcastId as {
|
|
55
|
-
value: string
|
|
56
|
-
}
|
|
57
|
-
).value
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return ''
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function fetchEventTypes(
|
|
64
|
-
notifiClient: NotifiFrontendClient,
|
|
65
|
-
): Promise<(EventTypeItem & { enabled: boolean })[]> {
|
|
66
|
-
const subscribedAlerts = await notifiClient.getAlerts()
|
|
67
|
-
|
|
68
|
-
const subscriptionConfig = (await notifiClient.fetchSubscriptionCard({
|
|
69
|
-
id: process.env.REACT_APP_NOTIFI_CONFIG_ID ?? '',
|
|
70
|
-
type: 'SUBSCRIPTION_CARD',
|
|
71
|
-
})) as CardConfigItemV1
|
|
72
|
-
|
|
73
|
-
const eventTypes = subscriptionConfig?.eventTypes?.map(
|
|
74
|
-
(eventType): EventTypeItem & { enabled: boolean } => {
|
|
75
|
-
const eventTypeId = getIdFromEventType(eventType)
|
|
76
|
-
let enabled = false
|
|
77
|
-
// Check whether the user is subscribed to the event
|
|
78
|
-
const subscribedAlert = subscribedAlerts?.find(
|
|
79
|
-
(alert) => alert.filterOptions.indexOf(eventTypeId) >= 0,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
if (subscribedAlert) {
|
|
83
|
-
enabled = true
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
...eventType,
|
|
88
|
-
enabled,
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
return eventTypes
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export function NotifiSubscriptionModal({
|
|
97
|
-
handleSuccess,
|
|
98
|
-
}: Props): React.ReactElement {
|
|
99
|
-
const theme = useTheme()
|
|
100
|
-
const reset = useResetAtom(txAtom)
|
|
101
|
-
const dispatch = useAppDispatch()
|
|
102
|
-
const { account, chainId, provider } = useWeb3React()
|
|
103
|
-
const [notifiClient, setNotifiClient] = useState<NotifiFrontendClient>()
|
|
104
|
-
const [showSuccessScreen, setShowSuccessScreen] = useState<boolean>(false)
|
|
105
|
-
const [isLoading, setIsLoading] = useState<boolean>(false)
|
|
106
|
-
const [emailAddress, setEmailAddress] = useState<string>('')
|
|
107
|
-
const [emailValid, setEmailValid] = useState<boolean>()
|
|
108
|
-
|
|
109
|
-
useEffect(() => {
|
|
110
|
-
const initializeClient = async () => {
|
|
111
|
-
if (account != null && chainId != null) {
|
|
112
|
-
const client = newFrontendClient({
|
|
113
|
-
account: { publicKey: account },
|
|
114
|
-
tenantId: getNotifiDappId(envUtil.checkIsDev()),
|
|
115
|
-
env: envUtil.checkIsDev() ? 'Development' : 'Production',
|
|
116
|
-
walletBlockchain: getBlockchainConfigFromChain(chainId),
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
await client.initialize()
|
|
120
|
-
|
|
121
|
-
setNotifiClient(client)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
initializeClient()
|
|
126
|
-
}, [account, chainId])
|
|
127
|
-
|
|
128
|
-
const signMessage: Uint8SignMessageFunction = async (
|
|
129
|
-
message: Uint8Array,
|
|
130
|
-
): Promise<Uint8Array> => {
|
|
131
|
-
const signer = provider!.getSigner()
|
|
132
|
-
const signature = await signer.signMessage(Buffer.from(message))
|
|
133
|
-
return ethers.utils.arrayify(signature)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const handleEmailAddressChange = (
|
|
137
|
-
event: React.ChangeEvent<HTMLInputElement>,
|
|
138
|
-
) => {
|
|
139
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
140
|
-
setEmailValid(emailRegex.test(event.target.value ?? ''))
|
|
141
|
-
setEmailAddress(event.target.value)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const logInAndSubscribe = async (): Promise<void> => {
|
|
145
|
-
if (notifiClient != null && chainId != null) {
|
|
146
|
-
setIsLoading(true)
|
|
147
|
-
|
|
148
|
-
// Ask user to sign a message to authenticate
|
|
149
|
-
try {
|
|
150
|
-
await notifiClient.logIn({
|
|
151
|
-
walletBlockchain: getBlockchainConfigFromChain(chainId),
|
|
152
|
-
signMessage,
|
|
153
|
-
} as SignMessageParams)
|
|
154
|
-
} catch (e) {
|
|
155
|
-
setIsLoading(false)
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Fetch all event types
|
|
160
|
-
const fetchedEventTypes = await fetchEventTypes(notifiClient)
|
|
161
|
-
|
|
162
|
-
// Authorize this email address for this wallet
|
|
163
|
-
await notifiClient.ensureTargetGroup({
|
|
164
|
-
name: 'Default',
|
|
165
|
-
emailAddress: emailAddress!,
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
// Intentionally running this in serial because the Notifi ensureAlert can't handle
|
|
169
|
-
// multiple calls. Notified their team to fix this.
|
|
170
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
171
|
-
for (const eventType of fetchedEventTypes) {
|
|
172
|
-
// eslint-disable-next-line no-await-in-loop
|
|
173
|
-
await notifiClient.ensureAlert({
|
|
174
|
-
eventType,
|
|
175
|
-
inputs: {},
|
|
176
|
-
})
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
setShowSuccessScreen(true)
|
|
180
|
-
setIsLoading(false)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const handleCloseModal = useCallback(() => {
|
|
185
|
-
reset()
|
|
186
|
-
dispatch(resetState())
|
|
187
|
-
handleSuccess()
|
|
188
|
-
}, [dispatch, handleSuccess, reset])
|
|
189
|
-
|
|
190
|
-
const styles = {
|
|
191
|
-
disclaimer: css`
|
|
192
|
-
${theme.cssMixins.rowCentered};
|
|
193
|
-
font-family: 'Uni-Neue-Regular';
|
|
194
|
-
font-size: 16px;
|
|
195
|
-
color: #a8a1b2;
|
|
196
|
-
margin-top: 48px;
|
|
197
|
-
`,
|
|
198
|
-
inputField: css`
|
|
199
|
-
width: 90%;
|
|
200
|
-
font-size: 16px;
|
|
201
|
-
`,
|
|
202
|
-
inputWrapper: css`
|
|
203
|
-
width: 100%;
|
|
204
|
-
`,
|
|
205
|
-
header: css`
|
|
206
|
-
${theme.cssMixins.rowHCentered};
|
|
207
|
-
margin-top: -5px;
|
|
208
|
-
`,
|
|
209
|
-
check: css`
|
|
210
|
-
width: 100%;
|
|
211
|
-
${theme.cssMixins.rowHCentered};
|
|
212
|
-
margin-top: 82px;
|
|
213
|
-
`,
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (isLoading) {
|
|
217
|
-
return <LoadingModal title='Notifications' />
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (showSuccessScreen) {
|
|
221
|
-
return (
|
|
222
|
-
<WrapperModal
|
|
223
|
-
title='Success'
|
|
224
|
-
subTitle='You successfully connected your email'
|
|
225
|
-
>
|
|
226
|
-
<Box css={styles.check}>
|
|
227
|
-
<CheckIcon />
|
|
228
|
-
</Box>
|
|
229
|
-
<BottomButton variant='contained' onClick={handleCloseModal}>
|
|
230
|
-
DONE
|
|
231
|
-
</BottomButton>
|
|
232
|
-
</WrapperModal>
|
|
233
|
-
)
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return (
|
|
237
|
-
<WrapperModal title='Connect Your Email'>
|
|
238
|
-
<Typography variant='body2' margin='12px 0'>
|
|
239
|
-
Connect your wallet to receive important emails about your account
|
|
240
|
-
</Typography>
|
|
241
|
-
<Box css={styles.inputWrapper}>
|
|
242
|
-
<Input
|
|
243
|
-
css={styles.inputField}
|
|
244
|
-
type='email'
|
|
245
|
-
value={emailAddress}
|
|
246
|
-
onChange={handleEmailAddressChange}
|
|
247
|
-
placeholder='youremail@example.com'
|
|
248
|
-
startAdornment={
|
|
249
|
-
<InputAdornment position='start'>
|
|
250
|
-
<Email />
|
|
251
|
-
</InputAdornment>
|
|
252
|
-
}
|
|
253
|
-
/>
|
|
254
|
-
</Box>
|
|
255
|
-
<Box css={styles.disclaimer}>
|
|
256
|
-
You can adjust these settings at any time by clicking the alert icon in
|
|
257
|
-
the header
|
|
258
|
-
</Box>
|
|
259
|
-
<BottomButton
|
|
260
|
-
variant='contained'
|
|
261
|
-
onClick={logInAndSubscribe}
|
|
262
|
-
disabled={!emailValid || isLoading}
|
|
263
|
-
>
|
|
264
|
-
CONNECT WALLET
|
|
265
|
-
</BottomButton>
|
|
266
|
-
</WrapperModal>
|
|
267
|
-
)
|
|
268
|
-
}
|
|
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 {
|
|
14
|
+
getBlockchainConfigFromChain,
|
|
15
|
+
txAtom,
|
|
16
|
+
getNotifiDappId,
|
|
17
|
+
} from '@huma-finance/shared'
|
|
18
|
+
import { ethers } from 'ethers'
|
|
19
|
+
import {
|
|
20
|
+
Box,
|
|
21
|
+
Input,
|
|
22
|
+
InputAdornment,
|
|
23
|
+
Typography,
|
|
24
|
+
css,
|
|
25
|
+
useTheme,
|
|
26
|
+
} from '@mui/material'
|
|
27
|
+
import Email from '@mui/icons-material/Email'
|
|
28
|
+
import { useResetAtom } from 'jotai/utils'
|
|
29
|
+
|
|
30
|
+
import { WrapperModal } from '../WrapperModal'
|
|
31
|
+
import { envUtil } from '../../utils/env'
|
|
32
|
+
import { BottomButton } from '../BottomButton'
|
|
33
|
+
import { LoadingModal } from '../LoadingModal'
|
|
34
|
+
import { CheckIcon } from '../icons'
|
|
35
|
+
import { resetState } from '../../store/widgets.reducers'
|
|
36
|
+
import { useAppDispatch } from '../../hooks/useRedux'
|
|
37
|
+
|
|
38
|
+
type Props = {
|
|
39
|
+
handleSuccess: () => void
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getIdFromEventType(eventType: EventTypeItem): string {
|
|
43
|
+
if (eventType.type === 'directPush') {
|
|
44
|
+
const directPushEventType = eventType as DirectPushEventTypeItem
|
|
45
|
+
return (
|
|
46
|
+
directPushEventType.directPushId as {
|
|
47
|
+
value: string
|
|
48
|
+
}
|
|
49
|
+
).value
|
|
50
|
+
}
|
|
51
|
+
if (eventType.type === 'broadcast') {
|
|
52
|
+
const broadcastEventType = eventType as BroadcastEventTypeItem
|
|
53
|
+
return (
|
|
54
|
+
broadcastEventType.broadcastId as {
|
|
55
|
+
value: string
|
|
56
|
+
}
|
|
57
|
+
).value
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return ''
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function fetchEventTypes(
|
|
64
|
+
notifiClient: NotifiFrontendClient,
|
|
65
|
+
): Promise<(EventTypeItem & { enabled: boolean })[]> {
|
|
66
|
+
const subscribedAlerts = await notifiClient.getAlerts()
|
|
67
|
+
|
|
68
|
+
const subscriptionConfig = (await notifiClient.fetchSubscriptionCard({
|
|
69
|
+
id: process.env.REACT_APP_NOTIFI_CONFIG_ID ?? '',
|
|
70
|
+
type: 'SUBSCRIPTION_CARD',
|
|
71
|
+
})) as CardConfigItemV1
|
|
72
|
+
|
|
73
|
+
const eventTypes = subscriptionConfig?.eventTypes?.map(
|
|
74
|
+
(eventType): EventTypeItem & { enabled: boolean } => {
|
|
75
|
+
const eventTypeId = getIdFromEventType(eventType)
|
|
76
|
+
let enabled = false
|
|
77
|
+
// Check whether the user is subscribed to the event
|
|
78
|
+
const subscribedAlert = subscribedAlerts?.find(
|
|
79
|
+
(alert) => alert.filterOptions.indexOf(eventTypeId) >= 0,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
if (subscribedAlert) {
|
|
83
|
+
enabled = true
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
...eventType,
|
|
88
|
+
enabled,
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
return eventTypes
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function NotifiSubscriptionModal({
|
|
97
|
+
handleSuccess,
|
|
98
|
+
}: Props): React.ReactElement {
|
|
99
|
+
const theme = useTheme()
|
|
100
|
+
const reset = useResetAtom(txAtom)
|
|
101
|
+
const dispatch = useAppDispatch()
|
|
102
|
+
const { account, chainId, provider } = useWeb3React()
|
|
103
|
+
const [notifiClient, setNotifiClient] = useState<NotifiFrontendClient>()
|
|
104
|
+
const [showSuccessScreen, setShowSuccessScreen] = useState<boolean>(false)
|
|
105
|
+
const [isLoading, setIsLoading] = useState<boolean>(false)
|
|
106
|
+
const [emailAddress, setEmailAddress] = useState<string>('')
|
|
107
|
+
const [emailValid, setEmailValid] = useState<boolean>()
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
const initializeClient = async () => {
|
|
111
|
+
if (account != null && chainId != null) {
|
|
112
|
+
const client = newFrontendClient({
|
|
113
|
+
account: { publicKey: account },
|
|
114
|
+
tenantId: getNotifiDappId(envUtil.checkIsDev()),
|
|
115
|
+
env: envUtil.checkIsDev() ? 'Development' : 'Production',
|
|
116
|
+
walletBlockchain: getBlockchainConfigFromChain(chainId),
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
await client.initialize()
|
|
120
|
+
|
|
121
|
+
setNotifiClient(client)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
initializeClient()
|
|
126
|
+
}, [account, chainId])
|
|
127
|
+
|
|
128
|
+
const signMessage: Uint8SignMessageFunction = async (
|
|
129
|
+
message: Uint8Array,
|
|
130
|
+
): Promise<Uint8Array> => {
|
|
131
|
+
const signer = provider!.getSigner()
|
|
132
|
+
const signature = await signer.signMessage(Buffer.from(message))
|
|
133
|
+
return ethers.utils.arrayify(signature)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const handleEmailAddressChange = (
|
|
137
|
+
event: React.ChangeEvent<HTMLInputElement>,
|
|
138
|
+
) => {
|
|
139
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
140
|
+
setEmailValid(emailRegex.test(event.target.value ?? ''))
|
|
141
|
+
setEmailAddress(event.target.value)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const logInAndSubscribe = async (): Promise<void> => {
|
|
145
|
+
if (notifiClient != null && chainId != null) {
|
|
146
|
+
setIsLoading(true)
|
|
147
|
+
|
|
148
|
+
// Ask user to sign a message to authenticate
|
|
149
|
+
try {
|
|
150
|
+
await notifiClient.logIn({
|
|
151
|
+
walletBlockchain: getBlockchainConfigFromChain(chainId),
|
|
152
|
+
signMessage,
|
|
153
|
+
} as SignMessageParams)
|
|
154
|
+
} catch (e) {
|
|
155
|
+
setIsLoading(false)
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Fetch all event types
|
|
160
|
+
const fetchedEventTypes = await fetchEventTypes(notifiClient)
|
|
161
|
+
|
|
162
|
+
// Authorize this email address for this wallet
|
|
163
|
+
await notifiClient.ensureTargetGroup({
|
|
164
|
+
name: 'Default',
|
|
165
|
+
emailAddress: emailAddress!,
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
// Intentionally running this in serial because the Notifi ensureAlert can't handle
|
|
169
|
+
// multiple calls. Notified their team to fix this.
|
|
170
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
171
|
+
for (const eventType of fetchedEventTypes) {
|
|
172
|
+
// eslint-disable-next-line no-await-in-loop
|
|
173
|
+
await notifiClient.ensureAlert({
|
|
174
|
+
eventType,
|
|
175
|
+
inputs: {},
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
setShowSuccessScreen(true)
|
|
180
|
+
setIsLoading(false)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const handleCloseModal = useCallback(() => {
|
|
185
|
+
reset()
|
|
186
|
+
dispatch(resetState())
|
|
187
|
+
handleSuccess()
|
|
188
|
+
}, [dispatch, handleSuccess, reset])
|
|
189
|
+
|
|
190
|
+
const styles = {
|
|
191
|
+
disclaimer: css`
|
|
192
|
+
${theme.cssMixins.rowCentered};
|
|
193
|
+
font-family: 'Uni-Neue-Regular';
|
|
194
|
+
font-size: 16px;
|
|
195
|
+
color: #a8a1b2;
|
|
196
|
+
margin-top: 48px;
|
|
197
|
+
`,
|
|
198
|
+
inputField: css`
|
|
199
|
+
width: 90%;
|
|
200
|
+
font-size: 16px;
|
|
201
|
+
`,
|
|
202
|
+
inputWrapper: css`
|
|
203
|
+
width: 100%;
|
|
204
|
+
`,
|
|
205
|
+
header: css`
|
|
206
|
+
${theme.cssMixins.rowHCentered};
|
|
207
|
+
margin-top: -5px;
|
|
208
|
+
`,
|
|
209
|
+
check: css`
|
|
210
|
+
width: 100%;
|
|
211
|
+
${theme.cssMixins.rowHCentered};
|
|
212
|
+
margin-top: 82px;
|
|
213
|
+
`,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (isLoading) {
|
|
217
|
+
return <LoadingModal title='Notifications' />
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (showSuccessScreen) {
|
|
221
|
+
return (
|
|
222
|
+
<WrapperModal
|
|
223
|
+
title='Success'
|
|
224
|
+
subTitle='You successfully connected your email'
|
|
225
|
+
>
|
|
226
|
+
<Box css={styles.check}>
|
|
227
|
+
<CheckIcon />
|
|
228
|
+
</Box>
|
|
229
|
+
<BottomButton variant='contained' onClick={handleCloseModal}>
|
|
230
|
+
DONE
|
|
231
|
+
</BottomButton>
|
|
232
|
+
</WrapperModal>
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<WrapperModal title='Connect Your Email'>
|
|
238
|
+
<Typography variant='body2' margin='12px 0'>
|
|
239
|
+
Connect your wallet to receive important emails about your account
|
|
240
|
+
</Typography>
|
|
241
|
+
<Box css={styles.inputWrapper}>
|
|
242
|
+
<Input
|
|
243
|
+
css={styles.inputField}
|
|
244
|
+
type='email'
|
|
245
|
+
value={emailAddress}
|
|
246
|
+
onChange={handleEmailAddressChange}
|
|
247
|
+
placeholder='youremail@example.com'
|
|
248
|
+
startAdornment={
|
|
249
|
+
<InputAdornment position='start'>
|
|
250
|
+
<Email />
|
|
251
|
+
</InputAdornment>
|
|
252
|
+
}
|
|
253
|
+
/>
|
|
254
|
+
</Box>
|
|
255
|
+
<Box css={styles.disclaimer}>
|
|
256
|
+
You can adjust these settings at any time by clicking the alert icon in
|
|
257
|
+
the header
|
|
258
|
+
</Box>
|
|
259
|
+
<BottomButton
|
|
260
|
+
variant='contained'
|
|
261
|
+
onClick={logInAndSubscribe}
|
|
262
|
+
disabled={!emailValid || isLoading}
|
|
263
|
+
>
|
|
264
|
+
CONNECT WALLET
|
|
265
|
+
</BottomButton>
|
|
266
|
+
</WrapperModal>
|
|
267
|
+
)
|
|
268
|
+
}
|
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { useWeb3React } from '@web3-react/core'
|
|
2
|
-
import { PoolInfoType } from '@huma-finance/shared'
|
|
3
|
-
import React, { useEffect } from 'react'
|
|
4
|
-
|
|
5
|
-
import useEA from '../../../hooks/useEA'
|
|
6
|
-
import { LoadingModal } from '../../LoadingModal'
|
|
7
|
-
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
8
|
-
|
|
9
|
-
type Props = {
|
|
10
|
-
poolInfo: PoolInfoType
|
|
11
|
-
payerAddress: string
|
|
12
|
-
superToken: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function Evaluation({
|
|
16
|
-
poolInfo,
|
|
17
|
-
payerAddress,
|
|
18
|
-
superToken,
|
|
19
|
-
}: Props): React.ReactElement {
|
|
20
|
-
const { account } = useWeb3React()
|
|
21
|
-
const { checkingEA } = useEA()
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (account) {
|
|
25
|
-
checkingEA(
|
|
26
|
-
{
|
|
27
|
-
poolAddress: poolInfo.pool,
|
|
28
|
-
borrowerWalletAddress: account,
|
|
29
|
-
context: {
|
|
30
|
-
receivable: {
|
|
31
|
-
address: poolInfo.assetAddress!,
|
|
32
|
-
},
|
|
33
|
-
payerWalletAddress: payerAddress,
|
|
34
|
-
superToken,
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
WIDGET_STEP.ChooseAmount,
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
}, [
|
|
41
|
-
account,
|
|
42
|
-
checkingEA,
|
|
43
|
-
payerAddress,
|
|
44
|
-
poolInfo.assetAddress,
|
|
45
|
-
poolInfo.pool,
|
|
46
|
-
superToken,
|
|
47
|
-
])
|
|
48
|
-
|
|
49
|
-
return (
|
|
50
|
-
<LoadingModal
|
|
51
|
-
title='Checking Stream'
|
|
52
|
-
description='Checking if the stream qualifies for factoring...'
|
|
53
|
-
/>
|
|
54
|
-
)
|
|
55
|
-
}
|
|
1
|
+
import { useWeb3React } from '@web3-react/core'
|
|
2
|
+
import { PoolInfoType } from '@huma-finance/shared'
|
|
3
|
+
import React, { useEffect } from 'react'
|
|
4
|
+
|
|
5
|
+
import useEA from '../../../hooks/useEA'
|
|
6
|
+
import { LoadingModal } from '../../LoadingModal'
|
|
7
|
+
import { WIDGET_STEP } from '../../../store/widgets.store'
|
|
8
|
+
|
|
9
|
+
type Props = {
|
|
10
|
+
poolInfo: PoolInfoType
|
|
11
|
+
payerAddress: string
|
|
12
|
+
superToken: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function Evaluation({
|
|
16
|
+
poolInfo,
|
|
17
|
+
payerAddress,
|
|
18
|
+
superToken,
|
|
19
|
+
}: Props): React.ReactElement {
|
|
20
|
+
const { account } = useWeb3React()
|
|
21
|
+
const { checkingEA } = useEA()
|
|
22
|
+
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (account) {
|
|
25
|
+
checkingEA(
|
|
26
|
+
{
|
|
27
|
+
poolAddress: poolInfo.pool,
|
|
28
|
+
borrowerWalletAddress: account,
|
|
29
|
+
context: {
|
|
30
|
+
receivable: {
|
|
31
|
+
address: poolInfo.assetAddress!,
|
|
32
|
+
},
|
|
33
|
+
payerWalletAddress: payerAddress,
|
|
34
|
+
superToken,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
WIDGET_STEP.ChooseAmount,
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
}, [
|
|
41
|
+
account,
|
|
42
|
+
checkingEA,
|
|
43
|
+
payerAddress,
|
|
44
|
+
poolInfo.assetAddress,
|
|
45
|
+
poolInfo.pool,
|
|
46
|
+
superToken,
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<LoadingModal
|
|
51
|
+
title='Checking Stream'
|
|
52
|
+
description='Checking if the stream qualifies for factoring...'
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|