diff --git a/src/components/Earn.tsx b/src/components/Earn.tsx index c934b69d..1c0dab1f 100644 --- a/src/components/Earn.tsx +++ b/src/components/Earn.tsx @@ -6,8 +6,14 @@ import { TFunction } from 'i18next' import { useSettings } from '../context/SettingsContext' import { CurrentWallet, useCurrentWalletInfo, useReloadCurrentWalletInfo, WalletInfo } from '../context/WalletContext' import { useServiceInfo, useReloadServiceInfo, Offer } from '../context/ServiceInfoContext' -import { factorToPercentage, isAbsoluteOffer, isRelativeOffer, isValidNumber, percentageToFactor } from '../utils' -import { JM_DUST_THRESHOLD } from '../constants/jm' +import { + calcOfferMinsizeMax, + factorToPercentage, + isAbsoluteOffer, + isRelativeOffer, + isValidNumber, + percentageToFactor, +} from '../utils' import { OFFER_FEE_ABS_MIN, OFFER_FEE_REL_MAX, @@ -220,20 +226,9 @@ const EarnForm = ({ }: EarnFormProps) => { const { t } = useTranslation() - const maxAvailableBalanceInJar = useMemo(() => { - return Math.max( - 0, - Math.max( - ...Object.values(walletInfo?.balanceSummary.accountBalances || []).map( - (it) => it.calculatedAvailableBalanceInSats, - ), - ), - ) - }, [walletInfo]) - const offerMinsizeMax = useMemo(() => { - return Math.max(0, maxAvailableBalanceInJar - JM_DUST_THRESHOLD) - }, [maxAvailableBalanceInJar]) + return walletInfo === undefined ? 0 : calcOfferMinsizeMax(walletInfo.balanceSummary.accountBalances) + }, [walletInfo]) const validate = (values: EarnFormValues) => { const errors = {} as FormikErrors @@ -277,15 +272,7 @@ const EarnForm = ({ } return ( - + {(props) => { const { handleSubmit, setFieldValue, handleBlur, values, touched, errors, isSubmitting } = props const minsizeField = props.getFieldProps('minsize') diff --git a/src/utils.test.ts b/src/utils.test.ts index 937199ed..6662127d 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -7,6 +7,7 @@ import { formatSats, formatBtc, formatBtcDisplayValue, + calcOfferMinsizeMax, } from './utils' describe('shortenStringMiddle', () => { @@ -180,3 +181,41 @@ describe('formatBtcDisplayValue', () => { expect(formatBtcDisplayValue(123456789, { withSymbol: true })).toBe('₿ 1.23 456 789') }) }) + +describe('calcOfferMinsizeMax', () => { + it('should calc offer minsize based on wallet balance', () => { + expect(calcOfferMinsizeMax({})).toBe(0) + expect( + calcOfferMinsizeMax( + { + '0': { + accountIndex: 0, + calculatedTotalBalanceInSats: 21, + calculatedAvailableBalanceInSats: 21, + calculatedFrozenOrLockedBalanceInSats: 0, + }, + }, + 0, + ), + ).toBe(21) + expect( + calcOfferMinsizeMax( + { + '0': { + accountIndex: 0, + calculatedTotalBalanceInSats: 42, + calculatedAvailableBalanceInSats: 41, + calculatedFrozenOrLockedBalanceInSats: 1, + }, + '1': { + accountIndex: 1, + calculatedTotalBalanceInSats: 42_000, + calculatedAvailableBalanceInSats: 1, + calculatedFrozenOrLockedBalanceInSats: 41_999, + }, + }, + 21, + ), + ).toBe(20) + }) +}) diff --git a/src/utils.ts b/src/utils.ts index 9a2db657..526c6c41 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,6 @@ -import { AmountSats, OfferType, WalletFileName } from './libs/JmWalletApi' +import { JM_DUST_THRESHOLD } from './constants/jm' +import type { AccountBalances } from './context/BalanceSummary' +import type { AmountSats, OfferType, WalletFileName } from './libs/JmWalletApi' const BTC_FORMATTER = new Intl.NumberFormat('en-US', { minimumIntegerDigits: 1, @@ -135,3 +137,15 @@ export const setIntervalDebounced = ( ) })() } + +const calcMaxAvailableBalanceInJar = (accountBalances: AccountBalances) => { + return Math.max(0, Math.max(...Object.values(accountBalances || []).map((it) => it.calculatedAvailableBalanceInSats))) +} + +export const calcOfferMinsizeMax = ( + accountBalances: AccountBalances, + minBufferAmount: AmountSats = JM_DUST_THRESHOLD, +) => { + const maxAvailableBalanceInJar = calcMaxAvailableBalanceInJar(accountBalances) + return Math.max(0, maxAvailableBalanceInJar - minBufferAmount) +}