Files
com.blitzwallet/app/hooks/usePaymentMethodSelection.js
T

172 lines
4.7 KiB
JavaScript

import { useMemo } from 'react';
export default function usePaymentMethodSelection({
// Payment info
paymentInfo = {},
convertedSendAmount = 0,
paymentFee = 0,
// Balances
sparkBalance = 0,
bitcoinBalance = 0,
dollarBalanceSat = 0,
dollarBalanceToken = 0,
// Swap limits
min_usd_swap_amount = 0,
swapLimits = { bitcoin: 0 },
// Token info
isUsingLRC20 = false,
useFullTokensDisplay = false,
// Pre-selected method (from navigation params)
selectedPaymentMethod = '',
didSelectPaymentMethod = false,
// for swap validation
sparkInformation,
}) {
const isBitcoinPayment = paymentInfo?.paymentNetwork === 'Bitcoin';
const isSparkPayment = paymentInfo?.paymentNetwork === 'spark';
const hasBothUSDAndBitcoinBalance =
Number(dollarBalanceToken) > 0.01 && !!bitcoinBalance;
const determinePaymentMethod = useMemo(() => {
// If using LRC20, payment method is not relevant
if (isUsingLRC20) return 'BTC';
// Bitcoin payments can only use BTC
if (isBitcoinPayment) return 'BTC';
// If user already selected a method, use it
if (selectedPaymentMethod) return selectedPaymentMethod;
// Check user balances
const hasBTCBalance = sparkBalance >= convertedSendAmount + paymentFee;
const hasUSDBalance = dollarBalanceSat >= convertedSendAmount + paymentFee;
// Check swap limits
const meetsUSDMinimum = convertedSendAmount >= min_usd_swap_amount;
const meetsBTCMinimum = convertedSendAmount >= swapLimits.bitcoin;
if (!Object.keys(paymentInfo).length) return undefined;
// If payment is Spark
if (isSparkPayment) {
// If using full token display (multiple tokens), always use BTC
if (useFullTokensDisplay) return 'BTC';
// Receiver expects BTC
if (paymentInfo.data?.expectedReceive === 'sats') {
// BTC → BTC Spark (no swap needed)
const canPayBTCtoBTC = hasBTCBalance;
// USD → BTC Spark (requires swap, check minimums)
const canPayUSDtoBTC = hasUSDBalance && meetsUSDMinimum;
if (
canPayBTCtoBTC &&
canPayUSDtoBTC &&
sparkInformation?.didConnectToFlashnet
) {
return 'user-choice';
}
return canPayBTCtoBTC ? 'BTC' : canPayUSDtoBTC ? 'USD' : 'BTC';
}
// Receiver expects USD
else {
// USD → USD Spark (no swap needed)
const canPayUSDtoUSD = hasUSDBalance;
// BTC → USD Spark (requires swap, check minimums)
const canPayBTCtoUSD = hasBTCBalance && meetsBTCMinimum;
if (
canPayUSDtoUSD &&
canPayBTCtoUSD &&
sparkInformation?.didConnectToFlashnet
) {
return 'user-choice';
}
return canPayUSDtoUSD ? 'USD' : canPayBTCtoUSD ? 'BTC' : 'USD';
}
}
// Lightning payments (always receive as BTC)
// BTC → BTC (no swap)
const canPayBTCtoBTC = hasBTCBalance;
// USD → BTC (requires swap, check minimums)
const canPayUSDtoBTC = hasUSDBalance && meetsUSDMinimum;
if (
canPayBTCtoBTC &&
canPayUSDtoBTC &&
sparkInformation?.didConnectToFlashnet
) {
return 'user-choice';
}
if (!hasBothUSDAndBitcoinBalance) {
return Number(dollarBalanceToken) > 0.01 ? 'USD' : 'BTC';
}
return canPayBTCtoBTC ? 'BTC' : canPayUSDtoBTC ? 'USD' : 'BTC';
}, [
isUsingLRC20,
isBitcoinPayment,
selectedPaymentMethod,
paymentInfo,
sparkBalance,
dollarBalanceSat,
dollarBalanceToken,
convertedSendAmount,
paymentFee,
min_usd_swap_amount,
swapLimits,
useFullTokensDisplay,
hasBothUSDAndBitcoinBalance,
isSparkPayment,
sparkInformation?.didConnectToFlashnet,
]);
/**
* Determines if user needs to make a payment method choice
*/
const needsToChoosePaymentMethod = useMemo(() => {
return (
determinePaymentMethod === 'user-choice' &&
!selectedPaymentMethod &&
!useFullTokensDisplay &&
!isUsingLRC20 &&
hasBothUSDAndBitcoinBalance &&
!didSelectPaymentMethod
);
}, [
determinePaymentMethod,
selectedPaymentMethod,
useFullTokensDisplay,
isUsingLRC20,
hasBothUSDAndBitcoinBalance,
didSelectPaymentMethod,
]);
/**
* Get the final payment method to use (resolves 'user-choice' to actual method)
*/
const finalPaymentMethod = useMemo(() => {
if (selectedPaymentMethod) return selectedPaymentMethod;
if (determinePaymentMethod === 'user-choice') return undefined;
return determinePaymentMethod;
}, [determinePaymentMethod, selectedPaymentMethod]);
return {
determinePaymentMethod,
needsToChoosePaymentMethod,
finalPaymentMethod,
hasBothUSDAndBitcoinBalance,
};
}