Skip to content

Commit

Permalink
chore: handle multiple onramp event emissions (#1773)
Browse files Browse the repository at this point in the history
Co-authored-by: Alissa Crane <[email protected]>
  • Loading branch information
abcrane123 and alissacrane-cb authored Dec 19, 2024
1 parent e923912 commit 1e15529
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 10 deletions.
5 changes: 3 additions & 2 deletions src/buy/components/BuyAmountInput.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -15,8 +15,9 @@ export function BuyAmountInput() {
return (
<div
className={cn(
'flex h-full items-center rounded-lg border px-2 pl-4',
'flex h-full items-center border px-2 pl-4',
background.default,
border.radius,
)}
>
<TextInput
Expand Down
5 changes: 3 additions & 2 deletions src/buy/components/BuyDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useAccount } from 'wagmi';
import { getRoundedAmount } from '../../core/utils/getRoundedAmount';
import { ONRAMP_BUY_URL } from '../../fund/constants';
import { getFundingPopupSize } from '../../fund/utils/getFundingPopupSize';
import { background, cn, color, text } from '../../styles/theme';
import { background, border, cn, color, text } from '../../styles/theme';
import { ONRAMP_PAYMENT_METHODS } from '../constants';
import { BuyOnrampItem } from './BuyOnrampItem';
import { useBuyContext } from './BuyProvider';
Expand Down Expand Up @@ -80,7 +80,8 @@ export function BuyDropdown() {
color.foreground,
background.default,
'absolute right-0 bottom-0 flex translate-y-[102%] flex-col gap-2',
'z-10 min-w-80 rounded rounded-lg border p-2',
'z-10 min-w-80 rounded border p-2',
border.radius,
)}
>
<div className="px-2 pt-2">Buy with</div>
Expand Down
4 changes: 2 additions & 2 deletions src/buy/components/BuyMessage.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -16,7 +16,7 @@ export function BuyMessage() {
? color.foregroundMuted
: color.error;

return <div className={cn(textColor, 'text-sm')}>{message}</div>;
return <div className={cn(textColor, text.label2)}>{message}</div>;
}

return null;
Expand Down
3 changes: 2 additions & 1 deletion src/buy/components/BuyOnrampItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions src/buy/components/BuyProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion src/buy/components/BuyTokenItem.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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"
Expand Down
63 changes: 63 additions & 0 deletions src/buy/hooks/useOnrampEventListeners.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ describe('useOnrampEventListeners', () => {
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
lifecycleStatus: {
statusName: 'init',
statusData: {
isMissingRequiredField: false,
maxSlippage: 0.5,
},
},
}),
);

Expand All @@ -38,6 +45,13 @@ describe('useOnrampEventListeners', () => {
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
lifecycleStatus: {
statusName: 'init',
statusData: {
isMissingRequiredField: false,
maxSlippage: 0.5,
},
},
}),
);

Expand All @@ -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,
},
},
}),
);

Expand Down Expand Up @@ -93,6 +149,13 @@ describe('useOnrampEventListeners', () => {
useOnrampEventListeners({
updateLifecycleStatus: mockUpdateLifecycleStatus,
maxSlippage: 0.5,
lifecycleStatus: {
statusName: 'init',
statusData: {
isMissingRequiredField: false,
maxSlippage: 0.5,
},
},
}),
);

Expand Down
11 changes: 9 additions & 2 deletions src/buy/hooks/useOnrampEventListeners.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -25,7 +32,7 @@ export const useOnrampEventListeners = ({
});
}
},
[maxSlippage, updateLifecycleStatus],
[maxSlippage, updateLifecycleStatus, lifecycleStatus?.statusName],
);

const handleOnrampSuccess = useCallback(() => {
Expand Down

0 comments on commit 1e15529

Please sign in to comment.