@huma-finance/widgets 0.0.61-beta.550 → 0.0.61-beta.552

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@huma-finance/widgets",
3
- "version": "0.0.61-beta.550+850a9ff",
3
+ "version": "0.0.61-beta.552+89568b3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -195,5 +195,5 @@
195
195
  "optionalDependencies": {
196
196
  "encoding": "^0.1.13"
197
197
  },
198
- "gitHead": "850a9ff5aaa00b13b9fcb2de3c546c2b51b290f1"
198
+ "gitHead": "89568b3b32040fb6bcbaac6f238577ae720c109c"
199
199
  }
@@ -73,7 +73,7 @@ export function ChooseAmount({
73
73
  currentAmount={currentAmount}
74
74
  handleChangeAmount={handleChangeAmount}
75
75
  maxAmount={creditAvailableFormatted}
76
- info={`${formatNumber(creditAvailableFormatted)} Available`}
76
+ infos={[`${formatNumber(creditAvailableFormatted)} Available`]}
77
77
  handleAction={handleAction}
78
78
  actionText='BORROW'
79
79
  />
@@ -83,7 +83,7 @@ export function ChooseAmount({
83
83
  handleChangeAmount={handleChangeAmount}
84
84
  maxAmount={payoffAmount}
85
85
  maxAmountText='Pay Off'
86
- info={`${formatNumber(totalDueAmount.toFixed(0))} Due`}
86
+ infos={[`${formatNumber(totalDueAmount.toFixed(0))} Due`]}
87
87
  handleAction={handleAction}
88
88
  actionText='PAY'
89
89
  />
@@ -1,4 +1,12 @@
1
- import { Box, Button, css, TextField, useTheme } from '@mui/material'
1
+ import { isEmpty } from '@huma-finance/shared'
2
+ import {
3
+ Box,
4
+ Button,
5
+ css,
6
+ TextField,
7
+ Typography,
8
+ useTheme,
9
+ } from '@mui/material'
2
10
  import React, { useState } from 'react'
3
11
  import { NumericFormat } from 'react-number-format'
4
12
 
@@ -15,7 +23,7 @@ type Props = {
15
23
  maxAmount: number | string
16
24
  maxAmountText?: string
17
25
  maxAmountTitle?: string
18
- info?: string
26
+ infos?: string[]
19
27
  handleChangeAmount: (amount: number) => void
20
28
  handleAction: () => void
21
29
  }
@@ -30,7 +38,7 @@ export function InputAmountModal({
30
38
  maxAmount,
31
39
  maxAmountText = 'MAX',
32
40
  maxAmountTitle,
33
- info,
41
+ infos,
34
42
  handleChangeAmount,
35
43
  handleAction,
36
44
  }: Props): React.ReactElement | null {
@@ -85,12 +93,16 @@ export function InputAmountModal({
85
93
  letter-spacing: 0.46px;
86
94
  `,
87
95
  info: css`
88
- color: ${theme.palette.text.primary};
96
+ color: ${theme.palette.text.secondary};
89
97
  font-weight: 400;
90
98
  font-size: 16px;
91
99
  line-height: 160%;
92
100
  letter-spacing: 0.15px;
93
101
  `,
102
+ subInfo: css`
103
+ position: absolute;
104
+ bottom: ${theme.spacing(6)};
105
+ `,
94
106
  }
95
107
 
96
108
  const onChange = (
@@ -106,6 +118,25 @@ export function InputAmountModal({
106
118
  handleChangeAmount(Number(maxAmount))
107
119
  }
108
120
 
121
+ const getDisabled = () => {
122
+ if (Number(currentAmount) <= 0) {
123
+ return true
124
+ }
125
+ if (!isEmpty(maxAmount) && Number(currentAmount) > Number(maxAmount)) {
126
+ return true
127
+ }
128
+ return false
129
+ }
130
+
131
+ const getEndAdornment = () => (
132
+ <Box css={styles.maxWrapper}>
133
+ {maxAmountTitle && <Box css={styles.maxTitle}>{maxAmountTitle}</Box>}
134
+ <Button variant='contained' css={styles.max} onClick={setMaxAmount}>
135
+ {maxAmountText}
136
+ </Button>
137
+ </Box>
138
+ )
139
+
109
140
  return (
110
141
  <WrapperModal title={title} subTitle={subTitle}>
111
142
  <Box css={styles.inputAmountWrapper}>
@@ -122,34 +153,25 @@ export function InputAmountModal({
122
153
  customInput={TextField}
123
154
  placeholder={`0${suffix}`}
124
155
  variant='standard'
125
- InputProps={{
126
- endAdornment: maxAmountTitle ? (
127
- <Box css={styles.maxWrapper}>
128
- <Box css={styles.maxTitle}>{maxAmountTitle}</Box>
129
- <Button css={styles.max} onClick={setMaxAmount}>
130
- {maxAmountText}
131
- </Button>
132
- </Box>
133
- ) : (
134
- <Button
135
- variant='contained'
136
- css={styles.max}
137
- onClick={setMaxAmount}
138
- >
139
- {maxAmountText}
140
- </Button>
141
- ),
142
- }}
156
+ InputProps={{ endAdornment: getEndAdornment() }}
143
157
  />
144
158
  </Box>
145
159
  </Box>
146
160
 
147
- {info && <Box css={styles.info}>{info}</Box>}
161
+ {infos && (
162
+ <Box>
163
+ {infos.map((info) => (
164
+ <Typography css={styles.info} key={info}>
165
+ {info}
166
+ </Typography>
167
+ ))}
168
+ </Box>
169
+ )}
148
170
 
149
171
  <BottomButton
150
172
  variant='contained'
151
173
  onClick={handleAction}
152
- disabled={Number(currentAmount) <= 0}
174
+ disabled={getDisabled()}
153
175
  >
154
176
  {actionText}
155
177
  </BottomButton>
@@ -106,7 +106,7 @@ export function ChooseAmount({
106
106
  currentAmount={currentShares}
107
107
  handleChangeAmount={handleChangeShares}
108
108
  maxAmount={maxSharesFormatted}
109
- info={`${String(formatNumber(currentAmount))} ${symbol}`}
109
+ infos={[`${String(formatNumber(currentAmount))} ${symbol}`]}
110
110
  maxAmountTitle={`${formatNumber(maxSharesFormatted)} Shares`}
111
111
  suffix='Shares'
112
112
  handleAction={handleAction}
@@ -1,21 +1,13 @@
1
+ import { formatNumber, PoolInfoV2, TrancheType } from '@huma-finance/shared'
2
+ import { LPConfigStructOutput } from '@huma-finance/shared/src/v2/abis/types/PoolConfig'
1
3
  import {
2
- CampaignService,
3
- checkIsDev,
4
- formatNumber,
5
- PoolInfoV2,
6
- TrancheType,
7
- UnderlyingTokenInfo,
8
- } from '@huma-finance/shared'
9
- import {
10
- useDebouncedValue,
11
4
  usePoolSafeAllowanceV2,
12
5
  usePoolUnderlyingTokenBalanceV2,
13
6
  } from '@huma-finance/web-shared'
14
7
  import { useWeb3React } from '@web3-react/core'
15
8
  import { BigNumber, ethers } from 'ethers'
16
- import React, { useEffect, useState } from 'react'
9
+ import React, { useMemo, useState } from 'react'
17
10
 
18
- import { Campaign } from '.'
19
11
  import { useAppDispatch } from '../../../hooks/useRedux'
20
12
  import { setStep, setSupplyAmount } from '../../../store/widgets.reducers'
21
13
  import { WIDGET_STEP } from '../../../store/widgets.store'
@@ -23,29 +15,25 @@ import { InputAmountModal } from '../../InputAmountModal'
23
15
 
24
16
  type Props = {
25
17
  poolInfo: PoolInfoV2
26
- poolUnderlyingToken: UnderlyingTokenInfo
18
+ lpConfig: LPConfigStructOutput
19
+ juniorAssets: BigNumber
20
+ seniorAssets: BigNumber
27
21
  selectedTranche: TrancheType | undefined
28
22
  isUniTranche: boolean
29
- pointsTestnetExperience: boolean
30
- campaign?: Campaign
31
23
  }
32
24
 
33
25
  export function ChooseAmount({
34
26
  poolInfo,
35
- poolUnderlyingToken,
27
+ lpConfig,
28
+ juniorAssets: juniorAssetsBN,
29
+ seniorAssets: seniorAssetsBN,
36
30
  selectedTranche,
37
31
  isUniTranche,
38
- pointsTestnetExperience,
39
- campaign,
40
32
  }: Props): React.ReactElement | null {
41
- const isDev = checkIsDev()
42
33
  const dispatch = useAppDispatch()
43
34
  const { account, provider } = useWeb3React()
44
- const { symbol, decimals } = poolUnderlyingToken
35
+ const { symbol, decimals } = poolInfo.poolUnderlyingToken
45
36
  const [currentAmount, setCurrentAmount] = useState<number | string>(0)
46
- const debouncedValue = useDebouncedValue(currentAmount)
47
- const [campaignPoints, setCampaignPoints] = useState<number>(0)
48
- const [lockupPeriodMonths, setLockupPeriodMonths] = useState<number>(0)
49
37
  const { allowance = BigNumber.from(0) } = usePoolSafeAllowanceV2(
50
38
  poolInfo.poolName,
51
39
  account,
@@ -56,46 +44,22 @@ export function ChooseAmount({
56
44
  account,
57
45
  provider,
58
46
  )
59
- const maxAmountFormatted = ethers.utils.formatUnits(
60
- balance,
61
- poolUnderlyingToken.decimals,
62
- )
63
47
 
64
- useEffect(() => {
65
- const getBasePoints = async () => {
66
- if (campaign && selectedTranche && Number(debouncedValue) > 0) {
67
- const estimatedPoints = await CampaignService.getEstimatedPoints(
68
- campaign.campaignGroupId,
69
- ethers.utils
70
- .parseUnits(
71
- String(debouncedValue),
72
- poolInfo.poolUnderlyingToken.decimals,
73
- )
74
- .toString(),
75
- isDev,
76
- pointsTestnetExperience,
77
- )
78
- const campaignPoints = estimatedPoints.find(
79
- (item) => item.campaignId === campaign.id,
80
- )
81
- if (campaignPoints) {
82
- setCampaignPoints(campaignPoints[`${selectedTranche}TranchePoints`])
83
- setLockupPeriodMonths(campaignPoints.lockupPeriodMonths)
84
- }
85
- } else {
86
- setCampaignPoints(0)
87
- }
48
+ const { juniorAvailableCapBN, seniorAvailableCapBN } = useMemo(() => {
49
+ const { maxSeniorJuniorRatio, liquidityCap: liquidityCapBN } = lpConfig
50
+ const totalDeployedBN = seniorAssetsBN.add(juniorAssetsBN)
51
+ const totalAvailableCapBN = liquidityCapBN.sub(totalDeployedBN)
52
+ const maxSeniorAssetsBN = juniorAssetsBN.mul(maxSeniorJuniorRatio)
53
+ let seniorAvailableCapBN = maxSeniorAssetsBN.sub(seniorAssetsBN)
54
+ seniorAvailableCapBN = seniorAvailableCapBN.gt(totalAvailableCapBN)
55
+ ? totalAvailableCapBN
56
+ : seniorAvailableCapBN
57
+
58
+ return {
59
+ juniorAvailableCapBN: totalAvailableCapBN.sub(seniorAvailableCapBN),
60
+ seniorAvailableCapBN,
88
61
  }
89
- getBasePoints()
90
- }, [
91
- campaign,
92
- debouncedValue,
93
- decimals,
94
- isDev,
95
- pointsTestnetExperience,
96
- poolInfo.poolUnderlyingToken.decimals,
97
- selectedTranche,
98
- ])
62
+ }, [juniorAssetsBN, lpConfig, seniorAssetsBN])
99
63
 
100
64
  const handleChangeAmount = (newAmount: number) => {
101
65
  setCurrentAmount(newAmount)
@@ -113,24 +77,50 @@ export function ChooseAmount({
113
77
  dispatch(setStep(step))
114
78
  }
115
79
 
116
- let info = `${formatNumber(maxAmountFormatted)} Available`
117
- if (campaign && campaignPoints > 0) {
118
- info = `You will earn ${formatNumber(
119
- campaignPoints,
120
- )} Huma points for the entire ${lockupPeriodMonths} months.`
80
+ const getTrancheCap = () => {
81
+ if (selectedTranche === 'junior') {
82
+ return juniorAvailableCapBN
83
+ }
84
+ return seniorAvailableCapBN
85
+ }
86
+
87
+ const getMaxAmount = () => {
88
+ const trancheCap = getTrancheCap()
89
+ return balance.gt(trancheCap) ? trancheCap : balance
90
+ }
91
+
92
+ const getInfos = () => {
93
+ const trancheCap = getTrancheCap()
94
+ const currentAmountBN = ethers.utils.parseUnits(
95
+ String(currentAmount),
96
+ decimals,
97
+ )
98
+ const remainingCap = trancheCap.sub(currentAmountBN)
99
+
100
+ if (remainingCap.lt(0)) {
101
+ return ['0 remaining capacity']
102
+ }
103
+ return [
104
+ `${formatNumber(
105
+ ethers.utils.formatUnits(remainingCap, decimals),
106
+ )} remaining capacity`,
107
+ ]
121
108
  }
122
109
 
123
110
  return (
124
111
  <InputAmountModal
125
112
  title='Enter Amount'
126
- subTitle={`Supplying ${symbol} with ${
113
+ subTitle={`Depositing to ${
127
114
  isUniTranche ? 'uni tranche' : selectedTranche
128
- }`}
115
+ } tranche`}
129
116
  tokenSymbol={symbol}
130
117
  currentAmount={currentAmount}
131
118
  handleChangeAmount={handleChangeAmount}
132
- maxAmount={maxAmountFormatted}
133
- info={info}
119
+ maxAmount={Number(ethers.utils.formatUnits(getMaxAmount(), decimals))}
120
+ maxAmountTitle={`${formatNumber(
121
+ ethers.utils.formatUnits(balance, decimals),
122
+ )} balance`}
123
+ infos={getInfos()}
134
124
  handleAction={handleAction}
135
125
  actionText='SUPPLY'
136
126
  />
@@ -1,4 +1,4 @@
1
- import { PoolInfoV2, UnderlyingTokenInfo } from '@huma-finance/shared'
1
+ import { PoolInfoV2 } from '@huma-finance/shared'
2
2
  import React, { useCallback } from 'react'
3
3
 
4
4
  import { useAppDispatch } from '../../../hooks/useRedux'
@@ -8,12 +8,10 @@ import { ApproveAllowanceModalV2 } from '../../ApproveAllowanceModalV2'
8
8
 
9
9
  type Props = {
10
10
  poolInfo: PoolInfoV2
11
- poolUnderlyingToken: UnderlyingTokenInfo
12
11
  }
13
12
 
14
13
  export function ApproveAllowance({
15
14
  poolInfo,
16
- poolUnderlyingToken,
17
15
  }: Props): React.ReactElement | null {
18
16
  const dispatch = useAppDispatch()
19
17
  const spender = poolInfo.poolSafe
@@ -25,7 +23,7 @@ export function ApproveAllowance({
25
23
  return (
26
24
  <ApproveAllowanceModalV2
27
25
  poolInfo={poolInfo}
28
- poolUnderlyingToken={poolUnderlyingToken}
26
+ poolUnderlyingToken={poolInfo.poolUnderlyingToken}
29
27
  spender={spender}
30
28
  handleSuccess={handleSuccess}
31
29
  />
@@ -1,8 +1,4 @@
1
- import {
2
- PoolInfoV2,
3
- TrancheType,
4
- UnderlyingTokenInfo,
5
- } from '@huma-finance/shared'
1
+ import { PoolInfoV2, TrancheType } from '@huma-finance/shared'
6
2
  import { useTrancheVaultContractV2 } from '@huma-finance/web-shared'
7
3
  import { useWeb3React } from '@web3-react/core'
8
4
  import { ethers } from 'ethers'
@@ -16,19 +12,17 @@ import { TxSendModalV2 } from '../../TxSendModalV2'
16
12
 
17
13
  type Props = {
18
14
  poolInfo: PoolInfoV2
19
- poolUnderlyingToken: UnderlyingTokenInfo
20
15
  trancheType: TrancheType
21
16
  }
22
17
 
23
18
  export function Transfer({
24
19
  poolInfo,
25
- poolUnderlyingToken,
26
20
  trancheType,
27
21
  }: Props): React.ReactElement | null {
28
22
  const dispatch = useAppDispatch()
29
23
  const { account, provider } = useWeb3React()
30
24
  const { supplyAmount } = useAppSelector(selectWidgetState)
31
- const { decimals } = poolUnderlyingToken
25
+ const { decimals } = poolInfo.poolUnderlyingToken
32
26
  const supplyBigNumber = ethers.utils.parseUnits(
33
27
  String(supplyAmount),
34
28
  decimals,
@@ -5,7 +5,6 @@ import {
5
5
  PoolInfoV2,
6
6
  timeUtil,
7
7
  TRANSFER_ABI,
8
- UnderlyingTokenInfo,
9
8
  } from '@huma-finance/shared'
10
9
  import { sendTxAtom } from '@huma-finance/web-shared'
11
10
  import { useWeb3React } from '@web3-react/core'
@@ -25,7 +24,6 @@ import { TxDoneModal } from '../../TxDoneModal'
25
24
 
26
25
  type Props = {
27
26
  poolInfo: PoolInfoV2
28
- poolUnderlyingToken: UnderlyingTokenInfo
29
27
  lpConfig: { withdrawalLockoutPeriodInDays: number }
30
28
  campaign?: Campaign
31
29
  updateTransactionHash: (hash: string) => void
@@ -34,7 +32,6 @@ type Props = {
34
32
 
35
33
  export function Success({
36
34
  poolInfo,
37
- poolUnderlyingToken,
38
35
  lpConfig,
39
36
  campaign,
40
37
  updateTransactionHash,
@@ -43,7 +40,7 @@ export function Success({
43
40
  const dispatch = useDispatch()
44
41
  const { account, chainId } = useWeb3React()
45
42
  const [{ txReceipt, txHash }] = useAtom(sendTxAtom)
46
- const { symbol, decimals, address } = poolUnderlyingToken
43
+ const { symbol, decimals, address } = poolInfo.poolUnderlyingToken
47
44
  const [supplyAmount, setSupplyAmount] = useState<string | undefined>()
48
45
  const { isFirstTimeNotifiUser } = useIsFirstTimeNotifiUser(account, chainId)
49
46
  const { notifiChainSupported } = useDoesChainSupportNotifi(chainId)
@@ -8,7 +8,7 @@ import {
8
8
  useLenderApprovedV2,
9
9
  useLPConfigV2,
10
10
  usePoolInfoV2,
11
- usePoolUnderlyingTokenInfoV2,
11
+ useTrancheVaultAssetsV2,
12
12
  } from '@huma-finance/web-shared'
13
13
  import { useWeb3React } from '@web3-react/core'
14
14
  import React, { useEffect, useState } from 'react'
@@ -62,10 +62,10 @@ export function LendSupplyV2({
62
62
  const poolName = POOL_NAME[poolNameStr]
63
63
  const { chainId, provider, account } = useWeb3React()
64
64
  const poolInfo = usePoolInfoV2(poolName, chainId)
65
+ const { poolUnderlyingToken } = poolInfo || {}
65
66
  const { step, errorMessage } = useAppSelector(selectWidgetState)
66
67
  const [selectedTranche, setSelectedTranche] = useState<TrancheType>()
67
68
  const [transactionHash, setTransactionHash] = useState<string | undefined>()
68
- const poolUnderlyingToken = usePoolUnderlyingTokenInfoV2(poolName, provider)
69
69
  const lpConfig = useLPConfigV2(poolName, provider)
70
70
  const isUniTranche = lpConfig?.maxSeniorJuniorRatio === 0
71
71
  const [lenderApprovedSenior] = useLenderApprovedV2(
@@ -80,6 +80,8 @@ export function LendSupplyV2({
80
80
  account,
81
81
  provider,
82
82
  )
83
+ const [juniorAssets] = useTrancheVaultAssetsV2(poolName, 'junior', provider)
84
+ const [seniorAssets] = useTrancheVaultAssetsV2(poolName, 'senior', provider)
83
85
 
84
86
  const lenderApproveStatusFetched =
85
87
  lenderApprovedSenior !== undefined && lenderApprovedJunior !== undefined
@@ -144,7 +146,9 @@ export function LendSupplyV2({
144
146
  !poolInfo ||
145
147
  !poolUnderlyingToken ||
146
148
  !lenderApproveStatusFetched ||
147
- !lpConfig
149
+ !lpConfig ||
150
+ !juniorAssets ||
151
+ !seniorAssets
148
152
  ) {
149
153
  return (
150
154
  <WidgetWrapper
@@ -184,30 +188,22 @@ export function LendSupplyV2({
184
188
  {step === WIDGET_STEP.ChooseAmount && (
185
189
  <ChooseAmount
186
190
  poolInfo={poolInfo}
187
- poolUnderlyingToken={poolUnderlyingToken}
191
+ lpConfig={lpConfig}
192
+ juniorAssets={juniorAssets}
193
+ seniorAssets={seniorAssets}
188
194
  selectedTranche={selectedTranche}
189
195
  isUniTranche={isUniTranche}
190
- pointsTestnetExperience={pointsTestnetExperience}
191
- campaign={campaign}
192
196
  />
193
197
  )}
194
198
  {step === WIDGET_STEP.ApproveAllowance && (
195
- <ApproveAllowance
196
- poolInfo={poolInfo}
197
- poolUnderlyingToken={poolUnderlyingToken}
198
- />
199
+ <ApproveAllowance poolInfo={poolInfo} />
199
200
  )}
200
201
  {step === WIDGET_STEP.Transfer && selectedTranche && (
201
- <Transfer
202
- poolInfo={poolInfo}
203
- poolUnderlyingToken={poolUnderlyingToken}
204
- trancheType={selectedTranche}
205
- />
202
+ <Transfer poolInfo={poolInfo} trancheType={selectedTranche} />
206
203
  )}
207
204
  {step === WIDGET_STEP.Done && (
208
205
  <Success
209
206
  poolInfo={poolInfo}
210
- poolUnderlyingToken={poolUnderlyingToken}
211
207
  lpConfig={lpConfig}
212
208
  campaign={campaign}
213
209
  updateTransactionHash={setTransactionHash}