172 lines
4.7 KiB
JavaScript
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,
|
|
};
|
|
}
|