diff --git a/src/buy/components/BuyAmountInput.tsx b/src/buy/components/BuyAmountInput.tsx
index 528534c745..4453ebab0f 100644
--- a/src/buy/components/BuyAmountInput.tsx
+++ b/src/buy/components/BuyAmountInput.tsx
@@ -1,6 +1,6 @@
import { isValidAmount } from '../../core/utils/isValidAmount';
import { TextInput } from '../../internal/components/TextInput';
-import { background, cn, color } from '../../styles/theme';
+import { background, border, cn, color } from '../../styles/theme';
import { formatAmount } from '../../swap/utils/formatAmount';
import { TokenChip } from '../../token';
import { useBuyContext } from './BuyProvider';
@@ -15,8 +15,9 @@ export function BuyAmountInput() {
return (
Buy with
diff --git a/src/buy/components/BuyMessage.tsx b/src/buy/components/BuyMessage.tsx
index 5bd7afefc5..6de618ca9d 100644
--- a/src/buy/components/BuyMessage.tsx
+++ b/src/buy/components/BuyMessage.tsx
@@ -1,4 +1,4 @@
-import { cn, color } from '../../styles/theme';
+import { cn, color, text } from '../../styles/theme';
import { isSwapError } from '../../swap/utils/isSwapError';
import { useBuyContext } from './BuyProvider';
@@ -16,7 +16,7 @@ export function BuyMessage() {
? color.foregroundMuted
: color.error;
- return {message}
;
+ return {message}
;
}
return null;
diff --git a/src/buy/components/BuyOnrampItem.tsx b/src/buy/components/BuyOnrampItem.tsx
index c4c263adb6..cc83d4a2c2 100644
--- a/src/buy/components/BuyOnrampItem.tsx
+++ b/src/buy/components/BuyOnrampItem.tsx
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
import { appleSvg } from '../../internal/svg/appleSvg';
import { cardSvg } from '../../internal/svg/cardSvg';
import { coinbaseLogoSvg } from '../../internal/svg/coinbaseLogoSvg';
-import { cn, color } from '../../styles/theme';
+import { cn, color, text } from '../../styles/theme';
import { useBuyContext } from './BuyProvider';
type OnrampItemReact = {
@@ -37,6 +37,7 @@ export function BuyOnrampItem({
className={cn(
'flex items-center gap-2 rounded-lg p-2',
'hover:bg-[var(--ock-bg-inverse)]',
+ text.label2,
)}
onClick={handleClick}
type="button"
diff --git a/src/buy/components/BuyProvider.tsx b/src/buy/components/BuyProvider.tsx
index 0f4d0b7adf..bd5a0afaa9 100644
--- a/src/buy/components/BuyProvider.tsx
+++ b/src/buy/components/BuyProvider.tsx
@@ -99,6 +99,7 @@ export function BuyProvider({
const { onPopupClose } = useOnrampEventListeners({
updateLifecycleStatus,
maxSlippage: config.maxSlippage,
+ lifecycleStatus,
});
// used to detect when the popup is closed in order to stop loading state
diff --git a/src/buy/components/BuyTokenItem.tsx b/src/buy/components/BuyTokenItem.tsx
index 71fabe8241..c4d5cdd554 100644
--- a/src/buy/components/BuyTokenItem.tsx
+++ b/src/buy/components/BuyTokenItem.tsx
@@ -1,6 +1,6 @@
import { useCallback, useMemo } from 'react';
import { getRoundedAmount } from '../../core/utils/getRoundedAmount';
-import { cn, color, pressable } from '../../styles/theme';
+import { cn, color, pressable, text } from '../../styles/theme';
import type { SwapUnit } from '../../swap/types';
import { TokenImage } from '../../token';
import { useBuyContext } from './BuyProvider';
@@ -37,6 +37,7 @@ export function BuyTokenItem({ swapUnit }: { swapUnit?: SwapUnit }) {
className={cn(
'flex items-center gap-2 rounded-lg p-2',
!hasInsufficientBalance && pressable.default,
+ text.label2,
)}
onClick={handleClick}
type="button"
diff --git a/src/buy/hooks/useOnrampEventListeners.test.ts b/src/buy/hooks/useOnrampEventListeners.test.ts
index 3a890b83dc..57e0881360 100644
--- a/src/buy/hooks/useOnrampEventListeners.test.ts
+++ b/src/buy/hooks/useOnrampEventListeners.test.ts
@@ -21,6 +21,13 @@ describe('useOnrampEventListeners', () => {
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
+ lifecycleStatus: {
+ statusName: 'init',
+ statusData: {
+ isMissingRequiredField: false,
+ maxSlippage: 0.5,
+ },
+ },
}),
);
@@ -38,6 +45,13 @@ describe('useOnrampEventListeners', () => {
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
+ lifecycleStatus: {
+ statusName: 'init',
+ statusData: {
+ isMissingRequiredField: false,
+ maxSlippage: 0.5,
+ },
+ },
}),
);
@@ -61,11 +75,53 @@ describe('useOnrampEventListeners', () => {
});
});
+ it('should not handle transition_view event if lifecycleStatus is transactionPending', () => {
+ renderHook(() =>
+ useOnrampEventListeners({
+ updateLifecycleStatus: mockUpdateLifecycleStatus,
+ maxSlippage: 0.5,
+ lifecycleStatus: {
+ statusName: 'transactionPending',
+ statusData: {
+ isMissingRequiredField: false,
+ maxSlippage: 0.5,
+ },
+ },
+ }),
+ );
+
+ const mockedSetupOnrampEventListeners =
+ setupOnrampEventListeners as unknown as Mock;
+ const onEventCallback =
+ mockedSetupOnrampEventListeners.mock.calls[0][0].onEvent;
+
+ act(() => {
+ onEventCallback({
+ eventName: 'transition_view',
+ });
+ });
+
+ expect(mockUpdateLifecycleStatus).not.toHaveBeenCalledWith({
+ statusName: 'transactionPending',
+ statusData: {
+ isMissingRequiredField: false,
+ maxSlippage: 0.5,
+ },
+ });
+ });
+
it('should handle onramp success', () => {
renderHook(() =>
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
+ lifecycleStatus: {
+ statusName: 'init',
+ statusData: {
+ isMissingRequiredField: false,
+ maxSlippage: 0.5,
+ },
+ },
}),
);
@@ -93,6 +149,13 @@ describe('useOnrampEventListeners', () => {
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
+ lifecycleStatus: {
+ statusName: 'init',
+ statusData: {
+ isMissingRequiredField: false,
+ maxSlippage: 0.5,
+ },
+ },
}),
);
diff --git a/src/buy/hooks/useOnrampEventListeners.ts b/src/buy/hooks/useOnrampEventListeners.ts
index 5f01541779..4a41dcf41e 100644
--- a/src/buy/hooks/useOnrampEventListeners.ts
+++ b/src/buy/hooks/useOnrampEventListeners.ts
@@ -7,15 +7,22 @@ import { setupOnrampEventListeners } from '../../fund/utils/setupOnrampEventList
type UseOnrampLifecycleParams = {
updateLifecycleStatus: (status: LifecycleStatus) => void;
maxSlippage: number;
+ lifecycleStatus: LifecycleStatus;
};
export const useOnrampEventListeners = ({
updateLifecycleStatus,
maxSlippage,
+ lifecycleStatus,
}: UseOnrampLifecycleParams) => {
const handleOnrampEvent = useCallback(
(data: EventMetadata) => {
- if (data.eventName === 'transition_view') {
+ // Only update the lifecycle status if the current status is not 'transactionPending'
+ // Onramp emits a 'transition_view' event multiple times
+ if (
+ data.eventName === 'transition_view' &&
+ lifecycleStatus?.statusName !== 'transactionPending'
+ ) {
updateLifecycleStatus({
statusName: 'transactionPending',
statusData: {
@@ -25,7 +32,7 @@ export const useOnrampEventListeners = ({
});
}
},
- [maxSlippage, updateLifecycleStatus],
+ [maxSlippage, updateLifecycleStatus, lifecycleStatus?.statusName],
);
const handleOnrampSuccess = useCallback(() => {