Skip to content

Commit

Permalink
fix(transfer): prevent buying channel when node capacity is reached
Browse files Browse the repository at this point in the history
  • Loading branch information
pwltr committed Mar 26, 2024
1 parent 60c85b1 commit 3349da8
Show file tree
Hide file tree
Showing 11 changed files with 222 additions and 216 deletions.
12 changes: 4 additions & 8 deletions src/screens/Lightning/CustomConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { showToast } from '../../utils/notifications';
import { DEFAULT_CHANNEL_DURATION } from '../../utils/wallet/constants';
import {
selectedNetworkSelector,
selectedWalletSelector,
transactionFeeSelector,
} from '../../store/reselect/wallet';

Expand All @@ -43,7 +42,6 @@ const CustomConfirm = ({
const [orderId, setOrderId] = useState(route.params.orderId);
const [showNumberPad, setShowNumberPad] = useState(false);
const transactionFee = useAppSelector(transactionFeeSelector);
const selectedWallet = useAppSelector(selectedWalletSelector);
const selectedNetwork = useAppSelector(selectedNetworkSelector);
const blocktankInfo = useAppSelector(blocktankInfoSelector);
const order = useAppSelector((state) => {
Expand Down Expand Up @@ -76,12 +74,10 @@ const CustomConfirm = ({
const updateOrderExpiration = async (): Promise<void> => {
const { max0ConfClientBalanceSat, minExpiryWeeks } = blocktankInfo.options;
const purchaseResponse = await startChannelPurchase({
remoteBalance: order.clientBalanceSat,
localBalance: order.lspBalanceSat,
channelExpiry: Math.max(weeks, minExpiryWeeks),
clientBalance: order.clientBalanceSat,
lspBalance: order.lspBalanceSat,
channelExpiryWeeks: Math.max(weeks, minExpiryWeeks),
zeroConfPayment: order.clientBalanceSat <= max0ConfClientBalanceSat,
selectedWallet,
selectedNetwork,
});
if (purchaseResponse.isErr()) {
showToast({
Expand All @@ -91,7 +87,7 @@ const CustomConfirm = ({
});
return;
}
setOrderId(purchaseResponse.value.order.id);
setOrderId(purchaseResponse.value.id);
};

return (
Expand Down
68 changes: 37 additions & 31 deletions src/screens/Lightning/CustomSetup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,11 @@ import {
denominationSelector,
} from '../../store/reselect/settings';
import { blocktankInfoSelector } from '../../store/reselect/blocktank';
import {
selectedNetworkSelector,
selectedWalletSelector,
} from '../../store/reselect/wallet';
import NumberPadTextField from '../../components/NumberPadTextField';
import { getNumberPadText } from '../../utils/numberpad';
import { SPENDING_LIMIT_RATIO } from '../../utils/wallet/constants';
import { MAX_SPENDING_PERCENTAGE } from '../../utils/wallet/constants';
import { refreshBlocktankInfo } from '../../store/utils/blocktank';
import { lnSetupSelector } from '../../store/reselect/aggregations';
import { useDisplayValues } from '../../hooks/displayValues';

export type TPackage = {
Expand Down Expand Up @@ -110,11 +107,13 @@ const CustomSetup = ({
const nextUnit = useAppSelector(nextUnitSelector);
const conversionUnit = useAppSelector(conversionUnitSelector);
const denomination = useAppSelector(denominationSelector);
const selectedWallet = useAppSelector(selectedWalletSelector);
const selectedNetwork = useAppSelector(selectedNetworkSelector);
const selectedCurrency = useAppSelector(selectedCurrencySelector);
const blocktankInfo = useAppSelector(blocktankInfoSelector);

const { limits } = useAppSelector((state) => {
return lnSetupSelector(state, spendingAmount);
});

const [textFieldValue, setTextFieldValue] = useState('');
const [channelOpenFee, setChannelOpenFee] = useState<{
[key: string]: string;
Expand Down Expand Up @@ -148,15 +147,15 @@ const CustomSetup = ({
);

useEffect(() => {
const spendableBalance = Math.round(
onchainFiatBalance * SPENDING_LIMIT_RATIO,
const spendableBalanceFiat = Math.round(
onchainFiatBalance * MAX_SPENDING_PERCENTAGE,
);

let reachedSpendingCap = false;
const availSpendingPackages: TPackage[] = [];
PACKAGES_SPENDING.every((p, i) => {
// This ensures we have enough money to actually pay for the channel.
if (spendableBalance > p.fiatAmount) {
if (spendableBalanceFiat > p.fiatAmount) {
const convertedAmount = convertCurrency({
amount: p.fiatAmount,
from: 'USD',
Expand All @@ -172,7 +171,7 @@ const CustomSetup = ({
satoshis,
});
} else {
const satoshis = convertToSats(spendableBalance, EConversionUnit.fiat);
// if we can't afford a package, add a package with the maximum amount we can afford.
const convertedAmount = convertCurrency({
amount: PACKAGES_SPENDING[i].fiatAmount,
from: 'USD',
Expand All @@ -181,7 +180,7 @@ const CustomSetup = ({
availSpendingPackages.push({
...PACKAGES_SPENDING[i],
fiatAmount: convertedAmount.fiatValue,
satoshis,
satoshis: limits.local,
});
reachedSpendingCap = true;
}
Expand Down Expand Up @@ -222,7 +221,13 @@ const CustomSetup = ({
});
availReceivingPackages.sort((a, b) => a.satoshis - b.satoshis);
setReceivingPackages(availReceivingPackages);
}, [maxChannelSizeSat, onchainFiatBalance, selectedCurrency, spendingAmount]);
}, [
maxChannelSizeSat,
onchainFiatBalance,
selectedCurrency,
spendingAmount,
limits.local,
]);

// set initial spending/receiving amount
useEffect(() => {
Expand Down Expand Up @@ -273,8 +278,8 @@ const CustomSetup = ({
}, [textFieldValue, conversionUnit]);

const maxAmount = useMemo((): number => {
return spending ? onchainBalance : maxChannelSizeSat;
}, [spending, onchainBalance, maxChannelSizeSat]);
return spending ? limits.local : maxChannelSizeSat;
}, [spending, limits.local, maxChannelSizeSat]);

// fetch approximate channel open cost on ReceiveAmount screen
useEffect(() => {
Expand All @@ -292,7 +297,7 @@ const CustomSetup = ({
return;
}
const res = await estimateOrderFee({
lspBalanceSat: amount,
lspBalance: amount,
options: {
clientBalanceSat: spendingAmount,
lspNodeId: blocktankInfo.nodes[0].pubkey,
Expand Down Expand Up @@ -322,8 +327,6 @@ const CustomSetup = ({
spending,
channelOpenFee,
spendingAmount,
selectedWallet,
selectedNetwork,
blocktankInfo.nodes,
blocktankInfo.options.max0ConfClientBalanceSat,
]);
Expand Down Expand Up @@ -398,6 +401,11 @@ const CustomSetup = ({
}
}, [spending, spendingPackages, receivingPackages, denomination, unit]);

const onCustomAmount = (): void => {
setShowNumberPad(true);
setTextFieldValue('0');
};

const onDone = useCallback(() => {
setShowNumberPad(false);
}, []);
Expand All @@ -416,12 +424,10 @@ const CustomSetup = ({
setLoading(true);

const purchaseResponse = await startChannelPurchase({
remoteBalance: spendingAmount!,
localBalance: amount,
clientBalance: spendingAmount!,
lspBalance: amount,
zeroConfPayment:
spendingAmount! <= blocktankInfo.options.max0ConfClientBalanceSat,
selectedWallet,
selectedNetwork,
});

setLoading(false);
Expand All @@ -442,16 +448,14 @@ const CustomSetup = ({
navigation.navigate('CustomConfirm', {
spendingAmount: spendingAmount!,
receivingAmount: amount,
orderId: purchaseResponse.value.order.id,
orderId: purchaseResponse.value.id,
});
}
}, [
t,
spending,
spendingAmount,
amount,
selectedWallet,
selectedNetwork,
navigation,
maxChannelSizeSat,
blocktankInfo.options.max0ConfClientBalanceSat,
Expand Down Expand Up @@ -503,12 +507,14 @@ const CustomSetup = ({
{!showNumberPad && (
<AnimatedView color="transparent" entering={FadeIn} exiting={FadeOut}>
<View style={styles.barrels}>{getBarrels()}</View>
<Button
style={styles.buttonCustom}
text={t('enter_custom_amount')}
testID="CustomSetupCustomAmount"
onPress={(): void => setShowNumberPad((k) => !k)}
/>
{spending && (
<Button
style={styles.buttonCustom}
text={t('enter_custom_amount')}
testID="CustomSetupCustomAmount"
onPress={onCustomAmount}
/>
)}
</AnimatedView>
)}

Expand Down
Loading

0 comments on commit 3349da8

Please sign in to comment.