Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions paybutton/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3655,6 +3655,11 @@ react-jss@10.10.0:
theming "^3.3.0"
tiny-warning "^1.0.2"

react-number-format@^5.4.4:
version "5.4.4"
resolved "https://registry.yarnpkg.com/react-number-format/-/react-number-format-5.4.4.tgz#d31f0e260609431500c8d3f81bbd3ae1fb7cacad"
integrity sha512-wOmoNZoOpvMminhifQYiYSTCLUDOiUbBunrMrMjA+dV52sY+vck1S4UhR6PkgnoCquvvMSeJjErXZ4qSaWCliA==

react-transition-group@^4.4.5:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
Expand Down
122 changes: 109 additions & 13 deletions react/lib/components/PayButton/PayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
isValidCashAddress,
isValidXecAddress,
CurrencyObject,
generatePaymentId,
getCurrencyObject,
isPropsTrue,
setupAltpaymentSocket,
Expand All @@ -22,6 +21,7 @@ import {
ButtonSize,
DEFAULT_DONATION_RATE
} from '../../util';
import { createPayment } from '../../util/api-client';
import { PaymentDialog } from '../PaymentDialog';
import { AltpaymentCoin, AltpaymentError, AltpaymentPair, AltpaymentShift } from '../../altpayment';
export interface PayButtonProps extends ButtonProps {
Expand Down Expand Up @@ -110,17 +110,20 @@ export const PayButton = ({

const [currencyObj, setCurrencyObj] = useState<CurrencyObject | undefined>();
const [cryptoAmount, setCryptoAmount] = useState<string>();
const [convertedCurrencyObj, setConvertedCurrencyObj] = useState<CurrencyObject | undefined>();

const [price, setPrice] = useState(0);
const [newTxs, setNewTxs] = useState<Transaction[] | undefined>();
const priceRef = useRef<number>(price);
const cryptoAmountRef = useRef<string | undefined>(cryptoAmount);


const [paymentId] = useState(!disablePaymentId ? generatePaymentId(8) : undefined);
const [paymentId, setPaymentId] = useState<string | undefined>(undefined);
const [addressType, setAddressType] = useState<CryptoCurrency>(
getCurrencyTypeFromAddress(to),
);



useEffect(() => {
priceRef.current = price;
}, [price]);
Expand All @@ -137,16 +140,96 @@ export const PayButton = ({
}
}, 300);
};


const getPaymentId = useCallback(async (
currency: Currency,
to: string | undefined,
amount?: number,
): Promise<string | undefined> => {
if (disablePaymentId || !to) return undefined

try {
const convertedBaseAmount = convertedCurrencyObj?.float

const amountToUse =
(isFiat(currency) || randomSatoshis) && convertedBaseAmount !== undefined
? convertedBaseAmount
: amount

const responsePaymentId = await createPayment(amountToUse, to, apiBaseUrl)

setPaymentId(responsePaymentId)
return responsePaymentId
} catch (err) {
console.error('Error creating payment ID:', err)
return undefined
}
},
[disablePaymentId, apiBaseUrl, randomSatoshis, convertedCurrencyObj]
)

const lastPaymentAmount = useRef<number | null | undefined>(undefined)
useEffect(() => {

if (
!dialogOpen ||
disablePaymentId ||
!to
) {
return;
}

let effectiveAmount: number | null
if (isFiat(currency)) {
if (!convertedCurrencyObj) {
// Conversion not ready yet – wait for convertedCurrencyObj update
return;
}
effectiveAmount = convertedCurrencyObj.float;
} else if (amount === undefined) {
effectiveAmount = null
} else {
const amountNumber = Number(amount);
if (Number.isNaN(amountNumber)) {
return;
}
effectiveAmount = amountNumber;
}
if (lastPaymentAmount.current === effectiveAmount) {
return;
}

lastPaymentAmount.current = effectiveAmount;

void getPaymentId(
currency,
to,
effectiveAmount ?? undefined,
);
}, [amount, currency, to, dialogOpen, disablePaymentId, paymentId, getPaymentId, convertedCurrencyObj]);


const handleButtonClick = useCallback(async (): Promise<void> => {
if (onOpen !== undefined) {

if (onOpen) {
if (isFiat(currency)) {
void waitPrice(() => { onOpen(cryptoAmountRef.current, to, paymentId) })
void waitPrice(() => onOpen(cryptoAmountRef.current, to, paymentId))
} else {
onOpen(amount, to, paymentId)
}
}
setDialogOpen(true);
}, [cryptoAmount, to, paymentId, price])

setDialogOpen(true)
}, [
onOpen,
currency,
amount,
to,
paymentId,
disablePaymentId,
getPaymentId,
])

const handleCloseDialog = (success?: boolean, paymentId?: string): void => {
if (onClose !== undefined) onClose(success, paymentId);
Expand Down Expand Up @@ -260,22 +343,33 @@ export const PayButton = ({

useEffect(() => {
(async () => {
if (isFiat(currency) && price === 0) {
await getPrice();
}
if (isFiat(currency) && price === 0) {
await getPrice();
}
})()
}, [currency, getPrice, to, price]);

useEffect(() => {
if (currencyObj && isFiat(currency) && price) {
const addressType: Currency = getCurrencyTypeFromAddress(to);
if (!convertedCurrencyObj) {
const addressType: Currency = getCurrencyTypeFromAddress(to);
const convertedObj = getCurrencyObject(
currencyObj.float / price,
addressType,
randomSatoshis,
);
setCryptoAmount(convertedObj.string);
setConvertedCurrencyObj(convertedObj);
}
} else if (!isFiat(currency) && randomSatoshis && !convertedCurrencyObj) {
const convertedObj = getCurrencyObject(
currencyObj.float / price,
amount as number,
addressType,
randomSatoshis,
);
setCryptoAmount(convertedObj.string);
} else if (!isFiat(currency)) {
setConvertedCurrencyObj(convertedObj);
} else if (!isFiat(currency) && !randomSatoshis) {
setCryptoAmount(amount?.toString());
}
}, [price, currencyObj, amount, currency, randomSatoshis, to]);
Expand Down Expand Up @@ -354,6 +448,8 @@ export const PayButton = ({
transactionText={transactionText}
donationAddress={donationAddress}
donationRate={donationRate}
convertedCurrencyObj={convertedCurrencyObj}
setConvertedCurrencyObj={setConvertedCurrencyObj}
/>
{errorMsg && (
<p
Expand Down
8 changes: 7 additions & 1 deletion react/lib/components/PaymentDialog/PaymentDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ export interface PaymentDialogProps extends ButtonProps {
newTxs?: Transaction[],
autoClose?: boolean | number | string;
disableSound?: boolean;
transactionText?: string;
donationAddress?: string;
donationRate?: number;
transactionText?: string
convertedCurrencyObj?: CurrencyObject;
setConvertedCurrencyObj?: Function;
}

export const PaymentDialog = ({
Expand Down Expand Up @@ -123,6 +125,8 @@ export const PaymentDialog = ({
disableSound,
transactionText,
disabled,
convertedCurrencyObj,
setConvertedCurrencyObj,
theme: themeProp,
donationAddress,
donationRate
Expand Down Expand Up @@ -253,6 +257,8 @@ export const PaymentDialog = ({
transactionText={transactionText}
donationAddress={donationAddress}
donationRate={donationRate}
convertedCurrencyObj={convertedCurrencyObj}
setConvertedCurrencyObj={setConvertedCurrencyObj}
foot={success && (
<ButtonComponent
onClick={handleWidgetClose}
Expand Down
Loading