@coin-voyage/paykit 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useIsClient } from "@coin-voyage/shared/hooks";
3
3
  import { useQuery } from "@tanstack/react-query";
4
4
  import { AnimatePresence } from "framer-motion";
5
- import { useCallback, useEffect, useRef } from "react";
5
+ import { useCallback, useEffect, useMemo, useRef } from "react";
6
6
  import { usePaymentLifecycle } from "../../hooks/usePaymentLifecycle";
7
7
  import { ResetContainer } from "../../styles";
8
8
  import usePayContext from "../contexts/pay";
@@ -22,12 +22,13 @@ function PayButtonCustom(props) {
22
22
  const { paymentState, showModal, setOpen, setOnOpen, setOnClose } = usePayContext();
23
23
  const { onPaymentStarted, onPaymentCompleted, onPaymentBounced } = props;
24
24
  const { payOrder: order, setPayId } = paymentState;
25
- // Determine payment mode: either depositParams or payId (but not both)
25
+ const { children, closeOnSuccess, resetOnSuccess } = props;
26
26
  const hasDepositParams = "toAddress" in props;
27
27
  const hasPayId = "payId" in props;
28
- // Pre-compute values for hooks (must be unconditional)
29
- const depositParams = hasDepositParams
30
- ? {
28
+ const depositParams = useMemo(() => {
29
+ if (!hasDepositParams)
30
+ return null;
31
+ return {
31
32
  intent: {
32
33
  asset: {
33
34
  address: props.toToken,
@@ -39,19 +40,29 @@ function PayButtonCustom(props) {
39
40
  },
40
41
  },
41
42
  metadata: props.metadata,
42
- }
43
- : null;
43
+ };
44
+ }, [props]);
44
45
  const payId = hasPayId ? props.payId : null;
45
- // Validation: must have exactly one of payId or depositParams
46
- if ((!hasDepositParams && !hasPayId) || (hasDepositParams && hasPayId)) {
47
- throw new Error("PayButton requires either payId or deposit parameters (toChain, toAddress, toAmount), but not both");
48
- }
49
- usePaymentLifecycle(order, { onPaymentStarted, onPaymentCompleted, onPaymentBounced });
50
- // Pre-load payment info in background when using depositParams
46
+ usePaymentLifecycle(order, {
47
+ onPaymentStarted,
48
+ onPaymentCompleted,
49
+ onPaymentBounced,
50
+ });
51
+ const metadataKey = useMemo(() => JSON.stringify(depositParams?.metadata ?? {}), [depositParams?.metadata]);
52
+ // Preload payOrder
51
53
  useQuery({
52
- queryKey: ["payOrder", JSON.stringify({ depositParams })],
54
+ queryKey: [
55
+ "payOrder",
56
+ depositParams?.intent.asset?.address,
57
+ depositParams?.intent.asset?.chain_id,
58
+ depositParams?.intent.receiving_address,
59
+ depositParams?.intent.amount.token_amount,
60
+ metadataKey,
61
+ ],
62
+ enabled: hasDepositParams,
63
+ staleTime: Infinity,
53
64
  queryFn: async () => {
54
- if (depositParams == null || !depositParams.intent.receiving_address || !depositParams.intent.asset)
65
+ if (!depositParams)
55
66
  return null;
56
67
  await paymentState.createDepositPayOrder(depositParams, (msg) => props.onPaymentCreationError?.({
57
68
  type: "payorder_creation_error",
@@ -59,7 +70,6 @@ function PayButtonCustom(props) {
59
70
  }));
60
71
  return null;
61
72
  },
62
- enabled: depositParams != null,
63
73
  });
64
74
  // Load payment by ID when using payId
65
75
  useEffect(() => {
@@ -67,32 +77,34 @@ function PayButtonCustom(props) {
67
77
  return;
68
78
  setPayId(payId);
69
79
  }, [payId, setPayId]);
70
- // Set the onOpen and onClose callbacks
80
+ // Register open/close handlers
71
81
  useEffect(() => {
72
82
  setOnOpen(props.onOpen);
73
- return () => setOnOpen(undefined);
74
- }, [props.onOpen, setOnOpen]);
75
- useEffect(() => {
76
83
  setOnClose(props.onClose);
77
- return () => setOnClose(undefined);
78
- }, [props.onClose, setOnClose]);
79
- const { children, closeOnSuccess, resetOnSuccess } = props;
84
+ return () => {
85
+ setOnOpen(undefined);
86
+ setOnClose(undefined);
87
+ };
88
+ }, [props.onOpen, props.onClose, setOnOpen, setOnClose]);
80
89
  const show = useCallback(() => {
81
- if (order == null)
90
+ if (!order)
82
91
  return;
83
- const modalOptions = {
92
+ showModal({
84
93
  closeOnSuccess,
85
94
  resetOnSuccess,
86
- };
87
- showModal(modalOptions);
95
+ });
88
96
  }, [order, closeOnSuccess, resetOnSuccess, showModal]);
89
- const hide = useCallback(() => setOpen(false), [setOpen]);
90
- // Open the modal by default if the defaultOpen prop is true
97
+ const hide = useCallback(() => {
98
+ setOpen(false);
99
+ }, [setOpen]);
100
+ // Auto-open modal
91
101
  const hasAutoOpened = useRef(false);
92
102
  useEffect(() => {
93
- if (!props.defaultOpen || hasAutoOpened.current)
103
+ if (!props.defaultOpen)
104
+ return;
105
+ if (hasAutoOpened.current)
94
106
  return;
95
- if (order == null)
107
+ if (!order)
96
108
  return;
97
109
  show();
98
110
  hasAutoOpened.current = true;
@@ -11,6 +11,7 @@ export function useDepositAddressQuery({ enabled }) {
11
11
  queryKey: ["paymentDetails", orderId, chainId, tokenAddress],
12
12
  enabled: isEnabled,
13
13
  retry: false,
14
+ refetchOnWindowFocus: false,
14
15
  queryFn: async () => {
15
16
  if (!orderId || !chainId || !currency) {
16
17
  throw new Error("Missing required deposit parameters");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coin-voyage/paykit",
3
3
  "description": "Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.",
4
- "version": "2.3.0",
4
+ "version": "2.3.2",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "author": "Lars <lars@coinvoyage.io>",
@@ -61,8 +61,8 @@
61
61
  "react-use-measure": "^2.1.1",
62
62
  "styled-components": "^5.3.11",
63
63
  "uuid": "13.0.0",
64
- "@coin-voyage/crypto": "2.2.3",
65
- "@coin-voyage/shared": "2.2.5"
64
+ "@coin-voyage/crypto": "2.3.0",
65
+ "@coin-voyage/shared": "2.3.1"
66
66
  },
67
67
  "devDependencies": {
68
68
  "@types/qrcode": "1.5.5",