@huma-finance/widgets 0.0.62-beta.612 → 0.0.62-beta.616
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +0 -185
- package/dist/cjs/index.cjs +955 -2880
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.d.ts +8 -116
- package/dist/index.js +658 -2601
- package/dist/index.js.map +1 -1
- package/package.json +9 -12
- package/src/components/InputAmountModal.tsx +2 -12
- package/src/components/Lend/addRedemptionV2/2-ChooseAmount.tsx +6 -1
- package/src/components/Lend/supplyV2/6-Success.tsx +10 -8
- package/src/components/Lend/supplyV2/7-Notifications.tsx +6 -1
- package/src/components/Notifi/NotifiContextWrapper.tsx +57 -0
- package/src/components/Notifi/NotifiSubscriptionModal.tsx +118 -113
- package/src/components/WidgetWrapper.tsx +4 -6
- package/src/hooks/useNotifi.ts +28 -17
- package/src/index.tsx +7 -124
- package/src/store/widgets.reducers.ts +0 -5
- package/src/store/widgets.store.ts +0 -1
- package/src/theme/coreThemeConstants.ts +1 -1
- package/src/components/CreditLine/solanaBorrow/1-ChooseAmount.tsx +0 -86
- package/src/components/CreditLine/solanaBorrow/2-ApproveAllowance.tsx +0 -87
- package/src/components/CreditLine/solanaBorrow/index.tsx +0 -96
- package/src/components/Lend/solanaAddRedemption/1-ChooseTranche.tsx +0 -114
- package/src/components/Lend/solanaAddRedemption/2-ChooseAmount.tsx +0 -183
- package/src/components/Lend/solanaAddRedemption/3-Transfer.tsx +0 -102
- package/src/components/Lend/solanaAddRedemption/4-Done.tsx +0 -29
- package/src/components/Lend/solanaAddRedemption/index.tsx +0 -140
- package/src/components/Lend/solanaCancelRedemption/1-ChooseTranche.tsx +0 -114
- package/src/components/Lend/solanaCancelRedemption/2-Transfer.tsx +0 -99
- package/src/components/Lend/solanaCancelRedemption/3-Done.tsx +0 -55
- package/src/components/Lend/solanaCancelRedemption/index.tsx +0 -152
- package/src/components/Lend/solanaSupply/1-ChooseTranche.tsx +0 -116
- package/src/components/Lend/solanaSupply/2-Evaluation.tsx +0 -0
- package/src/components/Lend/solanaSupply/3-ChooseAmount.tsx +0 -130
- package/src/components/Lend/solanaSupply/4-Transfer.tsx +0 -89
- package/src/components/Lend/solanaSupply/5-Success.tsx +0 -50
- package/src/components/Lend/solanaSupply/index.tsx +0 -143
- package/src/components/SolanaTxDoneModal.tsx +0 -115
- package/src/components/SolanaTxSendModal.tsx +0 -61
- package/src/components/SolanaViewOnExplorer.tsx +0 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huma-finance/widgets",
|
|
3
|
-
"version": "0.0.62-beta.
|
|
3
|
+
"version": "0.0.62-beta.616+c3a83d3",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -25,20 +25,22 @@
|
|
|
25
25
|
"@emotion/styled": "^11.3.0",
|
|
26
26
|
"@ethersproject/address": "^5.7.0",
|
|
27
27
|
"@ethersproject/bignumber": "^5.6.0",
|
|
28
|
+
"@ethersproject/bytes": "^5.7.0",
|
|
28
29
|
"@ethersproject/constants": "^5.7.0",
|
|
29
30
|
"@ethersproject/contracts": "^5.7.0",
|
|
30
31
|
"@ethersproject/experimental": "^5.7.0",
|
|
31
32
|
"@ethersproject/providers": "^5.6.0",
|
|
32
33
|
"@ethersproject/units": "^5.6.0",
|
|
33
|
-
"@huma-finance/sdk": "^0.0.62-beta.
|
|
34
|
-
"@huma-finance/shared": "^0.0.62-beta.
|
|
35
|
-
"@huma-finance/web-shared": "^0.0.
|
|
34
|
+
"@huma-finance/sdk": "^0.0.62-beta.616+c3a83d3",
|
|
35
|
+
"@huma-finance/shared": "^0.0.62-beta.616+c3a83d3",
|
|
36
|
+
"@huma-finance/web-shared": "^0.0.61",
|
|
36
37
|
"@mui/icons-material": "^5.3.0",
|
|
37
38
|
"@mui/material": "^5.0.6",
|
|
38
39
|
"@mui/styles": "^5.0.2",
|
|
39
40
|
"@mui/system": "^5.0.6",
|
|
40
41
|
"@mui/x-date-pickers": "^5.0.7",
|
|
41
|
-
"@notifi-network/notifi-frontend-client": "^
|
|
42
|
+
"@notifi-network/notifi-frontend-client": "^1.1.2",
|
|
43
|
+
"@notifi-network/notifi-react": "^1.1.2",
|
|
42
44
|
"@reduxjs/toolkit": "^1.8.6",
|
|
43
45
|
"@types/utf8": "^3.0.1",
|
|
44
46
|
"@walletconnect/ethereum-provider": "1.8.0",
|
|
@@ -76,7 +78,7 @@
|
|
|
76
78
|
"react-router-dom": "^5.3.0",
|
|
77
79
|
"react-scripts": "5.0.1",
|
|
78
80
|
"tslib": "^2.5.0",
|
|
79
|
-
"typescript": "^
|
|
81
|
+
"typescript": "^4.8.4",
|
|
80
82
|
"utf8": "^3.0.0",
|
|
81
83
|
"web-vitals": "^2.1.4",
|
|
82
84
|
"yup": "^0.32.11"
|
|
@@ -186,11 +188,6 @@
|
|
|
186
188
|
"wagmi": "^0.12.10"
|
|
187
189
|
},
|
|
188
190
|
"peerDependencies": {
|
|
189
|
-
"@coral-xyz/anchor": "^0.30.1",
|
|
190
|
-
"@solana/spl-token": "^0.4.8",
|
|
191
|
-
"@solana/wallet-adapter-base": "^0.9.23",
|
|
192
|
-
"@solana/wallet-adapter-react": "^0.15.35",
|
|
193
|
-
"@solana/web3.js": "^1.95.3",
|
|
194
191
|
"ethers": "^5.6.1",
|
|
195
192
|
"react": ">=16.8.0",
|
|
196
193
|
"react-dom": ">=16.8.0",
|
|
@@ -200,5 +197,5 @@
|
|
|
200
197
|
"optionalDependencies": {
|
|
201
198
|
"encoding": "^0.1.13"
|
|
202
199
|
},
|
|
203
|
-
"gitHead": "
|
|
200
|
+
"gitHead": "c3a83d314e09557e5d192ea8c2b4dd6c90c20609"
|
|
204
201
|
}
|
|
@@ -20,7 +20,6 @@ type Props = {
|
|
|
20
20
|
tokenSymbol: string
|
|
21
21
|
suffix?: string
|
|
22
22
|
currentAmount: number | string
|
|
23
|
-
minimumAmount?: number
|
|
24
23
|
maxAmount: number | string
|
|
25
24
|
maxAmountText?: string
|
|
26
25
|
maxAmountTitle?: string
|
|
@@ -36,7 +35,6 @@ export function InputAmountModal({
|
|
|
36
35
|
tokenSymbol,
|
|
37
36
|
suffix: defaultSuffix,
|
|
38
37
|
currentAmount,
|
|
39
|
-
minimumAmount,
|
|
40
38
|
maxAmount,
|
|
41
39
|
maxAmountText = 'MAX',
|
|
42
40
|
maxAmountTitle,
|
|
@@ -127,9 +125,6 @@ export function InputAmountModal({
|
|
|
127
125
|
if (!isEmpty(maxAmount) && Number(currentAmount) > Number(maxAmount)) {
|
|
128
126
|
return true
|
|
129
127
|
}
|
|
130
|
-
if (!isEmpty(minimumAmount) && Number(currentAmount) < minimumAmount!) {
|
|
131
|
-
return true
|
|
132
|
-
}
|
|
133
128
|
return false
|
|
134
129
|
}
|
|
135
130
|
|
|
@@ -162,6 +157,7 @@ export function InputAmountModal({
|
|
|
162
157
|
/>
|
|
163
158
|
</Box>
|
|
164
159
|
</Box>
|
|
160
|
+
|
|
165
161
|
{infos && (
|
|
166
162
|
<Box>
|
|
167
163
|
{infos.map((info) => (
|
|
@@ -171,13 +167,7 @@ export function InputAmountModal({
|
|
|
171
167
|
))}
|
|
172
168
|
</Box>
|
|
173
169
|
)}
|
|
174
|
-
|
|
175
|
-
<Box>
|
|
176
|
-
<Typography css={styles.info} key='minDeposit'>
|
|
177
|
-
Minimum deposit: {minimumAmount} {tokenSymbol}
|
|
178
|
-
</Typography>
|
|
179
|
-
</Box>
|
|
180
|
-
)}
|
|
170
|
+
|
|
181
171
|
<BottomButton
|
|
182
172
|
variant='contained'
|
|
183
173
|
onClick={handleAction}
|
|
@@ -68,13 +68,18 @@ export function ChooseAmount({
|
|
|
68
68
|
lpConfig.withdrawalLockoutPeriodInDays * SECONDS_IN_A_DAY
|
|
69
69
|
if (nextEpochStartTime < lockupEndTime) {
|
|
70
70
|
const lockupEndTimeDayjs = dayjs.unix(lockupEndTime).date(1)
|
|
71
|
+
const withdrawTime = lockupEndTimeDayjs.add(1, 'month')
|
|
71
72
|
dispatch(setStep(WIDGET_STEP.Error))
|
|
72
73
|
dispatch(
|
|
73
74
|
setError({
|
|
74
75
|
errorReason: 'Redemption too soon',
|
|
75
76
|
errorMessage: `Your last deposit was on ${timestampToLL(
|
|
76
77
|
depositRecord!.lastDepositTime.toNumber(),
|
|
77
|
-
)}. You can
|
|
78
|
+
)}. You can begin submitting redemption requests on ${timestampToLL(
|
|
79
|
+
lockupEndTimeDayjs.unix(),
|
|
80
|
+
)}, which can be redeemed starting ${timestampToLL(
|
|
81
|
+
withdrawTime.unix(),
|
|
82
|
+
)}.`,
|
|
78
83
|
}),
|
|
79
84
|
)
|
|
80
85
|
}
|
|
@@ -9,10 +9,10 @@ import {
|
|
|
9
9
|
import { sendTxAtom } from '@huma-finance/web-shared'
|
|
10
10
|
import { useWeb3React } from '@web3-react/core'
|
|
11
11
|
import { useAtom } from 'jotai'
|
|
12
|
-
import moment from 'moment'
|
|
13
12
|
import React, { useCallback, useEffect, useState } from 'react'
|
|
14
13
|
import { useDispatch } from 'react-redux'
|
|
15
14
|
|
|
15
|
+
import dayjs from 'dayjs'
|
|
16
16
|
import { Campaign } from '.'
|
|
17
17
|
import {
|
|
18
18
|
useDoesChainSupportNotifi,
|
|
@@ -90,14 +90,16 @@ export function Success({
|
|
|
90
90
|
]
|
|
91
91
|
|
|
92
92
|
const getSubContent = () => {
|
|
93
|
-
const
|
|
94
|
-
lpConfig.withdrawalLockoutPeriodInDays,
|
|
95
|
-
|
|
96
|
-
)
|
|
93
|
+
const redemptionTime = dayjs()
|
|
94
|
+
.add(lpConfig.withdrawalLockoutPeriodInDays, 'day')
|
|
95
|
+
.date(1)
|
|
96
|
+
const withdrawTime = redemptionTime.add(1, 'month')
|
|
97
97
|
return [
|
|
98
|
-
`
|
|
99
|
-
|
|
100
|
-
)}
|
|
98
|
+
`You can begin submitting redemption requests on ${timeUtil.timestampToLL(
|
|
99
|
+
redemptionTime.unix(),
|
|
100
|
+
)}, which can be redeemed starting ${timeUtil.timestampToLL(
|
|
101
|
+
withdrawTime.unix(),
|
|
102
|
+
)}.`,
|
|
101
103
|
]
|
|
102
104
|
}
|
|
103
105
|
|
|
@@ -25,5 +25,10 @@ export function Notifications({
|
|
|
25
25
|
}
|
|
26
26
|
}, [campaign, dispatch, handleAction])
|
|
27
27
|
|
|
28
|
-
return
|
|
28
|
+
return (
|
|
29
|
+
<NotifiSubscriptionModal
|
|
30
|
+
successText={campaign ? 'VIEW POINTS' : undefined}
|
|
31
|
+
handleSuccess={handleUserAction}
|
|
32
|
+
/>
|
|
33
|
+
)
|
|
29
34
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { arrayify } from '@ethersproject/bytes'
|
|
2
|
+
import { ChainEnum, getBlockchainConfigFromChain } from '@huma-finance/shared'
|
|
3
|
+
import { NotifiContextProvider } from '@notifi-network/notifi-react'
|
|
4
|
+
import { useWeb3React } from '@web3-react/core'
|
|
5
|
+
import { providers } from 'ethers'
|
|
6
|
+
import React, { useMemo } from 'react'
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
chainId: number | undefined
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
|
+
children?: any
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function NotifiContextWrapper({
|
|
15
|
+
chainId,
|
|
16
|
+
children,
|
|
17
|
+
}: Props): React.ReactElement | null {
|
|
18
|
+
const { account, provider } = useWeb3React()
|
|
19
|
+
const signer = useMemo(() => {
|
|
20
|
+
if (provider instanceof providers.JsonRpcProvider) {
|
|
21
|
+
return provider.getSigner()
|
|
22
|
+
}
|
|
23
|
+
return undefined
|
|
24
|
+
}, [provider])
|
|
25
|
+
|
|
26
|
+
if (account == null || signer == null || chainId == null) {
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let cardId = ''
|
|
31
|
+
if (chainId === ChainEnum.Celo || chainId === ChainEnum.Alfajores) {
|
|
32
|
+
cardId = process.env.REACT_APP_NOTIFI_CONFIG_ID_CELO ?? ''
|
|
33
|
+
} else if (chainId === ChainEnum.Polygon || chainId === ChainEnum.Amoy) {
|
|
34
|
+
cardId = process.env.REACT_APP_NOTIFI_CONFIG_ID_POLYGON ?? ''
|
|
35
|
+
} else if (
|
|
36
|
+
chainId === ChainEnum.Scroll ||
|
|
37
|
+
chainId === ChainEnum.ScrollSepolia
|
|
38
|
+
) {
|
|
39
|
+
cardId = process.env.REACT_APP_NOTIFI_CONFIG_ID_SCROLL ?? ''
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<NotifiContextProvider
|
|
44
|
+
tenantId='humafinanceprod'
|
|
45
|
+
env='Production'
|
|
46
|
+
signMessage={async (message: Uint8Array) => {
|
|
47
|
+
const result = await signer.signMessage(message)
|
|
48
|
+
return arrayify(result)
|
|
49
|
+
}}
|
|
50
|
+
walletPublicKey={account}
|
|
51
|
+
walletBlockchain={getBlockchainConfigFromChain(chainId)}
|
|
52
|
+
cardId={cardId}
|
|
53
|
+
>
|
|
54
|
+
{children}
|
|
55
|
+
</NotifiContextProvider>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import { getBlockchainConfigFromChain } from '@huma-finance/shared'
|
|
2
1
|
import { txAtom } from '@huma-finance/web-shared'
|
|
3
2
|
import { Box, css, TextField, Typography, useTheme } from '@mui/material'
|
|
4
|
-
import {
|
|
5
|
-
BroadcastEventTypeItem,
|
|
6
|
-
CardConfigItemV1,
|
|
7
|
-
DirectPushEventTypeItem,
|
|
8
|
-
EventTypeItem,
|
|
9
|
-
NotifiFrontendClient,
|
|
10
|
-
SignMessageParams,
|
|
11
|
-
Uint8SignMessageFunction,
|
|
12
|
-
} from '@notifi-network/notifi-frontend-client'
|
|
13
|
-
import { useWeb3React } from '@web3-react/core'
|
|
14
|
-
import { ethers } from 'ethers'
|
|
15
3
|
import { useResetAtom } from 'jotai/utils'
|
|
16
|
-
import React, { useCallback, useState } from 'react'
|
|
4
|
+
import React, { useCallback, useEffect, useState } from 'react'
|
|
17
5
|
|
|
18
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
FtuStage,
|
|
8
|
+
useNotifiFrontendClientContext,
|
|
9
|
+
useNotifiTargetContext,
|
|
10
|
+
useNotifiTenantConfigContext,
|
|
11
|
+
useNotifiTopicContext,
|
|
12
|
+
useNotifiUserSettingContext,
|
|
13
|
+
} from '@notifi-network/notifi-react'
|
|
14
|
+
import { NotifiFrontendClient } from '@notifi-network/notifi-frontend-client'
|
|
19
15
|
import { useAppDispatch } from '../../hooks/useRedux'
|
|
20
16
|
import { resetState } from '../../store/widgets.reducers'
|
|
21
17
|
import { BottomButton } from '../BottomButton'
|
|
@@ -24,83 +20,48 @@ import { LoadingModal } from '../LoadingModal'
|
|
|
24
20
|
import { WrapperModal } from '../WrapperModal'
|
|
25
21
|
|
|
26
22
|
type Props = {
|
|
23
|
+
successText?: string
|
|
27
24
|
handleSuccess: () => void
|
|
28
25
|
}
|
|
29
26
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
if (eventType.type === 'broadcast') {
|
|
40
|
-
const broadcastEventType = eventType as BroadcastEventTypeItem
|
|
41
|
-
return (
|
|
42
|
-
broadcastEventType.broadcastId as {
|
|
43
|
-
value: string
|
|
44
|
-
}
|
|
45
|
-
).value
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return ''
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function fetchEventTypes(
|
|
52
|
-
notifiClient: NotifiFrontendClient,
|
|
53
|
-
): Promise<(EventTypeItem & { enabled: boolean })[]> {
|
|
54
|
-
const subscribedAlerts = await notifiClient.getAlerts()
|
|
55
|
-
|
|
56
|
-
const subscriptionConfig = (await notifiClient.fetchSubscriptionCard({
|
|
57
|
-
id: process.env.REACT_APP_NOTIFI_CONFIG_ID ?? '',
|
|
58
|
-
type: 'SUBSCRIPTION_CARD',
|
|
59
|
-
})) as CardConfigItemV1
|
|
60
|
-
|
|
61
|
-
const eventTypes = subscriptionConfig?.eventTypes?.map(
|
|
62
|
-
(eventType): EventTypeItem & { enabled: boolean } => {
|
|
63
|
-
const eventTypeId = getIdFromEventType(eventType)
|
|
64
|
-
let enabled = false
|
|
65
|
-
// Check whether the user is subscribed to the event
|
|
66
|
-
const subscribedAlert = subscribedAlerts?.find(
|
|
67
|
-
(alert) => alert.filterOptions.indexOf(eventTypeId) >= 0,
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
if (subscribedAlert) {
|
|
71
|
-
enabled = true
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
...eventType,
|
|
76
|
-
enabled,
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
return eventTypes
|
|
27
|
+
const validateDefaultTargetGroup = async (
|
|
28
|
+
frontendClient: NotifiFrontendClient,
|
|
29
|
+
) => {
|
|
30
|
+
// NOTE: this extra request is necessary as the targetGroupId state in NotifiTargetContext will not be updated constantly right after login
|
|
31
|
+
const targetGroup = (
|
|
32
|
+
await frontendClient?.fetchFusionData()
|
|
33
|
+
)?.targetGroup?.find((group) => group?.name === 'Default')
|
|
34
|
+
return !!targetGroup
|
|
82
35
|
}
|
|
83
36
|
|
|
84
37
|
export function NotifiSubscriptionModal({
|
|
38
|
+
successText,
|
|
85
39
|
handleSuccess,
|
|
86
40
|
}: Props): React.ReactElement {
|
|
87
41
|
const theme = useTheme()
|
|
88
42
|
const reset = useResetAtom(txAtom)
|
|
89
43
|
const dispatch = useAppDispatch()
|
|
90
|
-
const { account, chainId, provider } = useWeb3React()
|
|
91
44
|
const [showSuccessScreen, setShowSuccessScreen] = useState<boolean>(false)
|
|
92
45
|
const [isLoading, setIsLoading] = useState<boolean>(false)
|
|
93
46
|
const [emailAddress, setEmailAddress] = useState<string>('')
|
|
94
47
|
const [emailValid, setEmailValid] = useState<boolean>()
|
|
95
|
-
const {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
48
|
+
const {
|
|
49
|
+
frontendClientStatus: { isInitialized, isAuthenticated, isExpired },
|
|
50
|
+
frontendClient,
|
|
51
|
+
login,
|
|
52
|
+
} = useNotifiFrontendClientContext()
|
|
53
|
+
const { fusionEventTopics } = useNotifiTenantConfigContext()
|
|
54
|
+
const { subscribeAlertsDefault } = useNotifiTopicContext()
|
|
55
|
+
const {
|
|
56
|
+
targetDocument: { targetGroupId },
|
|
57
|
+
updateTargetInputs,
|
|
58
|
+
renewTargetGroup,
|
|
59
|
+
} = useNotifiTargetContext()
|
|
60
|
+
const {
|
|
61
|
+
ftuStage,
|
|
62
|
+
isLoading: isLoadingFtuStage,
|
|
63
|
+
updateFtuStage,
|
|
64
|
+
} = useNotifiUserSettingContext()
|
|
104
65
|
|
|
105
66
|
const handleEmailAddressChange = (
|
|
106
67
|
event: React.ChangeEvent<HTMLInputElement>,
|
|
@@ -110,43 +71,89 @@ export function NotifiSubscriptionModal({
|
|
|
110
71
|
setEmailAddress(event.target.value)
|
|
111
72
|
}
|
|
112
73
|
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
async function subscribe() {
|
|
76
|
+
if (
|
|
77
|
+
!isInitialized ||
|
|
78
|
+
!isAuthenticated ||
|
|
79
|
+
!targetGroupId ||
|
|
80
|
+
isLoadingFtuStage
|
|
81
|
+
) {
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If a user is authenticated but already finished with the FTU (First Time User) setup
|
|
86
|
+
// (AKA their login expired and they logged back in), then we can skip the subscription step.
|
|
87
|
+
if (ftuStage !== FtuStage.Done) {
|
|
88
|
+
await updateTargetInputs('email', { value: emailAddress! })
|
|
89
|
+
// Authorize this email address for this wallet
|
|
90
|
+
|
|
91
|
+
if (!targetGroupId) {
|
|
92
|
+
setIsLoading(false)
|
|
93
|
+
return
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
await subscribeAlertsDefault(fusionEventTopics, targetGroupId)
|
|
97
|
+
await updateFtuStage(FtuStage.Done)
|
|
98
|
+
|
|
99
|
+
const targetGroup = (
|
|
100
|
+
await frontendClient?.fetchFusionData()
|
|
101
|
+
)?.targetGroup?.find((group) => group?.name === 'Default')
|
|
102
|
+
const emailTarget = targetGroup?.emailTargets?.[0]
|
|
103
|
+
if (emailTarget && !emailTarget.isConfirmed) {
|
|
104
|
+
await frontendClient.sendEmailTargetVerification({
|
|
105
|
+
targetId: emailTarget.id,
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
setShowSuccessScreen(true)
|
|
111
|
+
setIsLoading(false)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
subscribe()
|
|
115
|
+
}, [
|
|
116
|
+
isInitialized,
|
|
117
|
+
isAuthenticated,
|
|
118
|
+
targetGroupId,
|
|
119
|
+
updateTargetInputs,
|
|
120
|
+
emailAddress,
|
|
121
|
+
subscribeAlertsDefault,
|
|
122
|
+
fusionEventTopics,
|
|
123
|
+
updateFtuStage,
|
|
124
|
+
isLoadingFtuStage,
|
|
125
|
+
ftuStage,
|
|
126
|
+
frontendClient,
|
|
127
|
+
])
|
|
128
|
+
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
const loginIfExpired = async () => {
|
|
131
|
+
if (isExpired) {
|
|
132
|
+
await login()
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
loginIfExpired()
|
|
137
|
+
}, [isExpired, login])
|
|
138
|
+
|
|
113
139
|
const logInAndSubscribe = async (): Promise<void> => {
|
|
114
|
-
if (
|
|
140
|
+
if (!isAuthenticated) {
|
|
115
141
|
setIsLoading(true)
|
|
116
142
|
|
|
117
143
|
// Ask user to sign a message to authenticate
|
|
118
144
|
try {
|
|
119
|
-
await
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
145
|
+
await login()
|
|
146
|
+
|
|
147
|
+
const isDefaultTargetExist = await validateDefaultTargetGroup(
|
|
148
|
+
frontendClient,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
if (!isDefaultTargetExist) {
|
|
152
|
+
await renewTargetGroup()
|
|
153
|
+
}
|
|
123
154
|
} catch (e) {
|
|
124
155
|
setIsLoading(false)
|
|
125
|
-
return
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Fetch all event types
|
|
129
|
-
const fetchedEventTypes = await fetchEventTypes(notifiClient)
|
|
130
|
-
|
|
131
|
-
// Authorize this email address for this wallet
|
|
132
|
-
await notifiClient.ensureTargetGroup({
|
|
133
|
-
name: 'Default',
|
|
134
|
-
emailAddress: emailAddress!,
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
// Intentionally running this in serial because the Notifi ensureAlert can't handle
|
|
138
|
-
// multiple calls. Notified their team to fix this.
|
|
139
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
140
|
-
for (const eventType of fetchedEventTypes) {
|
|
141
|
-
// eslint-disable-next-line no-await-in-loop
|
|
142
|
-
await notifiClient.ensureAlert({
|
|
143
|
-
eventType,
|
|
144
|
-
inputs: {},
|
|
145
|
-
})
|
|
146
156
|
}
|
|
147
|
-
|
|
148
|
-
setShowSuccessScreen(true)
|
|
149
|
-
setIsLoading(false)
|
|
150
157
|
}
|
|
151
158
|
}
|
|
152
159
|
|
|
@@ -196,7 +203,7 @@ export function NotifiSubscriptionModal({
|
|
|
196
203
|
<CheckIcon />
|
|
197
204
|
</Box>
|
|
198
205
|
<BottomButton variant='contained' onClick={handleCloseModal}>
|
|
199
|
-
DONE
|
|
206
|
+
{successText ?? 'DONE'}
|
|
200
207
|
</BottomButton>
|
|
201
208
|
</WrapperModal>
|
|
202
209
|
)
|
|
@@ -204,11 +211,7 @@ export function NotifiSubscriptionModal({
|
|
|
204
211
|
|
|
205
212
|
return (
|
|
206
213
|
<WrapperModal title='Connect Your Email'>
|
|
207
|
-
<Typography
|
|
208
|
-
variant='body2'
|
|
209
|
-
textAlign='justify'
|
|
210
|
-
margin={theme.spacing(6, 0, 4, 0)}
|
|
211
|
-
>
|
|
214
|
+
<Typography variant='body2' margin={theme.spacing(6, 0, 4, 0)}>
|
|
212
215
|
Connect your emails to receive important update about your account.
|
|
213
216
|
</Typography>
|
|
214
217
|
<Box css={styles.inputWrapper}>
|
|
@@ -218,7 +221,9 @@ export function NotifiSubscriptionModal({
|
|
|
218
221
|
type='email'
|
|
219
222
|
value={emailAddress}
|
|
220
223
|
onChange={handleEmailAddressChange}
|
|
221
|
-
variant='
|
|
224
|
+
variant='outlined'
|
|
225
|
+
color='primary'
|
|
226
|
+
focused
|
|
222
227
|
/>
|
|
223
228
|
</Box>
|
|
224
229
|
<Box css={styles.disclaimer}>
|
|
@@ -228,7 +233,7 @@ export function NotifiSubscriptionModal({
|
|
|
228
233
|
<BottomButton
|
|
229
234
|
variant='contained'
|
|
230
235
|
onClick={logInAndSubscribe}
|
|
231
|
-
disabled={!emailValid || isLoading}
|
|
236
|
+
disabled={!emailValid || isLoading || !isInitialized}
|
|
232
237
|
>
|
|
233
238
|
CONNECT EMAIL
|
|
234
239
|
</BottomButton>
|
|
@@ -31,7 +31,7 @@ export function WidgetWrapper({
|
|
|
31
31
|
}: WCProps<Props>): React.ReactElement | null {
|
|
32
32
|
const theme = useTheme()
|
|
33
33
|
const dispatch = useAppDispatch()
|
|
34
|
-
const { step
|
|
34
|
+
const { step } = useAppSelector(selectWidgetState)
|
|
35
35
|
const [{ state, failReason, txReceipt }] = useAtom(sendTxAtom)
|
|
36
36
|
const reset = useResetAtom(txAtom)
|
|
37
37
|
|
|
@@ -42,14 +42,12 @@ export function WidgetWrapper({
|
|
|
42
42
|
}, [dispatch, failReason, state])
|
|
43
43
|
|
|
44
44
|
useEffect(() => {
|
|
45
|
-
if (step === WIDGET_STEP.Done &&
|
|
46
|
-
if (handleSuccess
|
|
45
|
+
if (step === WIDGET_STEP.Done && txReceipt) {
|
|
46
|
+
if (handleSuccess) {
|
|
47
47
|
handleSuccess(txReceipt.blockNumber)
|
|
48
|
-
} else if (handleSuccess && solanaSignature) {
|
|
49
|
-
handleSuccess(0) // solana tx doesn't have block number
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
|
-
}, [handleSuccess,
|
|
50
|
+
}, [handleSuccess, step, txReceipt])
|
|
53
51
|
|
|
54
52
|
const handleCloseModal = useCallback(() => {
|
|
55
53
|
reset()
|
package/src/hooks/useNotifi.ts
CHANGED
|
@@ -8,6 +8,11 @@ import {
|
|
|
8
8
|
NotifiFrontendClient,
|
|
9
9
|
newFrontendClient,
|
|
10
10
|
} from '@notifi-network/notifi-frontend-client'
|
|
11
|
+
import {
|
|
12
|
+
FtuStage,
|
|
13
|
+
useNotifiFrontendClientContext,
|
|
14
|
+
useNotifiUserSettingContext,
|
|
15
|
+
} from '@notifi-network/notifi-react'
|
|
11
16
|
|
|
12
17
|
export const useDoesChainSupportNotifi = (chainId: number | undefined) => {
|
|
13
18
|
const [notifiChainSupported, setNotifiChainSupported] = useState(false)
|
|
@@ -54,32 +59,31 @@ export const useNotifiClient = (
|
|
|
54
59
|
return { notifiClient }
|
|
55
60
|
}
|
|
56
61
|
|
|
62
|
+
// Check if user is authenticated
|
|
63
|
+
// If not authenticated or expired, have user login
|
|
64
|
+
// After login, check FTU stage
|
|
65
|
+
// If FTU stage is not Done, go to signup flow. Otherwise, skip to next step
|
|
66
|
+
|
|
57
67
|
export const useIsFirstTimeNotifiUser = (
|
|
58
68
|
account: string | undefined,
|
|
59
69
|
chainId: number | undefined,
|
|
60
70
|
) => {
|
|
61
71
|
const [isFirstTimeNotifiUser, setIsFirstTimeNotifiUser] = useState(false)
|
|
62
|
-
const {
|
|
72
|
+
const {
|
|
73
|
+
frontendClientStatus: { isInitialized, isAuthenticated, isExpired },
|
|
74
|
+
} = useNotifiFrontendClientContext()
|
|
75
|
+
const { ftuStage, isLoading: isLoadingFtu } = useNotifiUserSettingContext()
|
|
63
76
|
const { notifiChainSupported } = useDoesChainSupportNotifi(chainId)
|
|
64
77
|
|
|
65
78
|
useEffect(() => {
|
|
66
79
|
const checkIsFirstTimeNotifiUser = async () => {
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
userState == null ||
|
|
72
|
-
(userState.status !== 'authenticated' &&
|
|
73
|
-
userState.status !== 'expired')
|
|
74
|
-
) {
|
|
80
|
+
if (isInitialized && notifiChainSupported) {
|
|
81
|
+
// If the user is not authenticated or expired, they are possibly a first time user.
|
|
82
|
+
if (!isAuthenticated || isExpired) {
|
|
75
83
|
setIsFirstTimeNotifiUser(true)
|
|
76
|
-
} else if (
|
|
77
|
-
// If a user is authenticated, check if they
|
|
78
|
-
|
|
79
|
-
const targetGroups = await notifiClient.getTargetGroups()
|
|
80
|
-
const emailTargets = targetGroups[0]?.emailTargets?.[0]
|
|
81
|
-
|
|
82
|
-
if (emailTargets == null || emailTargets.emailAddress == null) {
|
|
84
|
+
} else if (isAuthenticated) {
|
|
85
|
+
// If a user is authenticated, check if they've completed all the FTU (First Time User) stages.
|
|
86
|
+
if (ftuStage !== FtuStage.Done) {
|
|
83
87
|
setIsFirstTimeNotifiUser(true)
|
|
84
88
|
}
|
|
85
89
|
}
|
|
@@ -87,7 +91,14 @@ export const useIsFirstTimeNotifiUser = (
|
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
checkIsFirstTimeNotifiUser()
|
|
90
|
-
}, [
|
|
94
|
+
}, [
|
|
95
|
+
ftuStage,
|
|
96
|
+
isAuthenticated,
|
|
97
|
+
isExpired,
|
|
98
|
+
isInitialized,
|
|
99
|
+
isLoadingFtu,
|
|
100
|
+
notifiChainSupported,
|
|
101
|
+
])
|
|
91
102
|
|
|
92
103
|
return { isFirstTimeNotifiUser }
|
|
93
104
|
}
|