diff --git a/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts b/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts index ff0e34945f..96a675dff9 100644 --- a/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts +++ b/packages/checkout/sdk/src/widgets/definitions/events/orchestration.ts @@ -1,3 +1,5 @@ +import { Web3Provider } from '@ethersproject/providers'; + /** * Enum representing different types of orchestration events. */ @@ -66,6 +68,8 @@ export type RequestOnrampEvent = { tokenAddress: string; /** The amount of tokens to onramp. */ amount: string; + /** The connected provider. */ + provider?: Web3Provider; }; /** diff --git a/packages/checkout/widgets-lib/src/components/ConnectLoader/ConnectLoader.tsx b/packages/checkout/widgets-lib/src/components/ConnectLoader/ConnectLoader.tsx index c13f9afe13..45a7c7c50d 100644 --- a/packages/checkout/widgets-lib/src/components/ConnectLoader/ConnectLoader.tsx +++ b/packages/checkout/widgets-lib/src/components/ConnectLoader/ConnectLoader.tsx @@ -29,6 +29,7 @@ import { identifyUser } from '../../lib/analytics/identifyUser'; export interface ConnectLoaderProps { children?: React.ReactNode; params: ConnectLoaderParams; + successEvent?: () => void; closeEvent: () => void; widgetConfig: StrongCheckoutWidgetsConfig; goBackEvent?: () => void; @@ -48,6 +49,7 @@ export function ConnectLoader({ children, params, widgetConfig, + successEvent, closeEvent, goBackEvent, showBackButton, @@ -251,6 +253,7 @@ export function ConnectLoader({ web3Provider={provider} checkout={checkout} deepLink={deepLink} + sendSuccessEventOverride={successEvent} sendCloseEventOverride={closeEvent} allowedChains={allowedChains} isCheckNetworkEnabled={isCheckNetworkEnabled ?? true} diff --git a/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx b/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx index 626bc744ab..18fd848884 100644 --- a/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx +++ b/packages/checkout/widgets-lib/src/widgets/add-tokens/views/AddTokens.tsx @@ -120,6 +120,7 @@ export function AddTokens({ eventTargetState: { eventTarget }, } = useContext(EventTargetContext); + const [payWithCardClicked, setPayWithCardClicked] = useState(false); const [showOptionsDrawer, setShowOptionsDrawer] = useState(false); const [showPayWithDrawer, setShowPayWithDrawer] = useState(false); const [showDeliverToDrawer, setShowDeliverToDrawer] = useState(false); @@ -220,6 +221,7 @@ export function AddTokens({ providersState: { fromProviderInfo, toProviderInfo, + toProvider, fromAddress, toAddress, lockedToProvider, @@ -393,7 +395,7 @@ export function AddTokens({ setSelectedToken(token); }, []); - const handleCardClick = () => { + const sendRequestOnRampEvent = () => { track({ userJourney: UserJourney.ADD_TOKENS, screen: 'InputScreen', @@ -408,6 +410,7 @@ export function AddTokens({ tokenAddress: selectedToken?.address ?? '', amount: selectedAmount ?? '', showBackButton: true, + provider: toProvider, }; orchestrationEvents.sendRequestOnrampEvent( eventTarget, @@ -416,6 +419,21 @@ export function AddTokens({ ); }; + const handleCardClick = () => { + setPayWithCardClicked(true); + if (!toProvider) { + setShowDeliverToDrawer(true); + return; + } + sendRequestOnRampEvent(); + }; + + useEffect(() => { + if (toProvider && payWithCardClicked) { + sendRequestOnRampEvent(); + } + }, [toProvider]); + const handleRouteClick = (route: RouteData) => { setShowOptionsDrawer(false); setShowPayWithDrawer(false); @@ -423,6 +441,13 @@ export function AddTokens({ setSelectedRouteData(route); }; + const handleDeliverToClose = (connectedToAddress?: string) => { + if (!connectedToAddress) { + setPayWithCardClicked(false); + } + setShowDeliverToDrawer(false); + }; + const handleReviewClick = () => { if (!selectedRouteData || !selectedToken?.address) return; @@ -749,7 +774,7 @@ export function AddTokens({ setShowDeliverToDrawer(false)} + onClose={handleDeliverToClose} /> diff --git a/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx b/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx index ffebb70e8e..bfea631412 100644 --- a/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/connect/ConnectWidget.tsx @@ -60,6 +60,7 @@ import { SwitchNetworkZkEVM } from './views/SwitchNetworkZkEVM'; export type ConnectWidgetInputs = ConnectWidgetParams & { config: StrongCheckoutWidgetsConfig deepLink?: ConnectWidgetViews; + sendSuccessEventOverride?: () => void; sendCloseEventOverride?: () => void; allowedChains?: ChainId[]; checkout: Checkout; @@ -71,6 +72,7 @@ export type ConnectWidgetInputs = ConnectWidgetParams & { export default function ConnectWidget({ config, + sendSuccessEventOverride, sendCloseEventOverride, web3Provider, checkout, @@ -210,6 +212,10 @@ export default function ConnectWidget({ } } + if (sendSuccessEventOverride) { + sendSuccessEventOverride(); + return; + } sendConnectSuccessEvent(eventTarget, provider, walletProviderName ?? undefined, walletProviderInfo); }, [provider, identify]); diff --git a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/CommerceWidget.tsx b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/CommerceWidget.tsx index a91879bfc0..c2a44f6dc4 100644 --- a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/CommerceWidget.tsx +++ b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/CommerceWidget.tsx @@ -1,5 +1,9 @@ import { - Suspense, useCallback, useEffect, useMemo, + Suspense, + useCallback, + useEffect, + useMemo, + useReducer, } from 'react'; import { CommerceEventType, @@ -10,7 +14,6 @@ import { } from '@imtbl/checkout-sdk'; import { useTranslation } from 'react-i18next'; import { Web3Provider } from '@ethersproject/providers'; -import { CommerceWidgetContextProvicer } from './context/CommerceContextProvider'; import { useViewState, SharedViews, @@ -38,6 +41,12 @@ import { useWidgetEvents } from './hooks/useWidgetEvents'; import { getConnectLoaderParams } from './functions/getConnectLoaderParams'; import { commerceFlows } from './functions/isValidCommerceFlow'; import { ProvidersContextProvider } from '../../context/providers-context/ProvidersContext'; +import { + CommerceActions, + CommerceContext, + commerceReducer, + initialCommerceState, +} from './context/CommerceContext'; export type CommerceWidgetInputs = { checkout: Checkout; @@ -57,11 +66,24 @@ export default function CommerceWidget(props: CommerceWidgetInputs) { const [{ view, history }, viewDispatch] = viewState; const [{ eventTarget }] = useEventTargetState(); + const [commerceState, commerceDispatch] = useReducer( + commerceReducer, + initialCommerceState, + ); + const commerceReducerValues = useMemo( + () => ({ commerceState, commerceDispatch }), + [commerceState, commerceDispatch], + ); + + const { provider } = commerceState; + const connectLoaderParams = useMemo( - () => getConnectLoaderParams(view, checkout, web3Provider), - [view, checkout, web3Provider], + () => getConnectLoaderParams(view, checkout, provider || web3Provider), + [view, checkout, provider, web3Provider], ); + const connectLoaderSuccessEvent = flowParams.flow === CommerceFlowType.ADD_TOKENS ? () => {} : undefined; + const goToPreviousView = useCallback(() => { const sharedViews = [ SharedViews.LOADING_VIEW, @@ -86,10 +108,34 @@ export default function CommerceWidget(props: CommerceWidgetInputs) { } }, [history]); + const handleProviderUpdated = useMemo( + () => (updatedProvider: Web3Provider) => { + commerceDispatch({ + payload: { + type: CommerceActions.SET_PROVIDER, + provider: updatedProvider, + }, + }); + }, + [commerceDispatch], + ); + /** * Subscribe and Handle widget events */ - useWidgetEvents(eventTarget, viewState); + useWidgetEvents(eventTarget, viewState, handleProviderUpdated); + + useEffect(() => { + if (!web3Provider) { + return; + } + commerceDispatch({ + payload: { + type: CommerceActions.SET_PROVIDER, + provider: web3Provider, + }, + }); + }, [commerceDispatch, web3Provider]); /** * Mount the view according to set flow in params @@ -156,7 +202,7 @@ export default function CommerceWidget(props: CommerceWidgetInputs) { return ( - + {/* --- Status Views --- */} {view.type === SharedViews.LOADING_VIEW && ( @@ -216,6 +262,7 @@ export default function CommerceWidget(props: CommerceWidgetInputs) { { sendCheckoutEvent(eventTarget, { type: CommerceEventType.CLOSE, @@ -271,7 +318,7 @@ export default function CommerceWidget(props: CommerceWidgetInputs) { )} - + ); } diff --git a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/context/CommerceContextProvider.tsx b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/context/CommerceContextProvider.tsx deleted file mode 100644 index b0fa6fb659..0000000000 --- a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/context/CommerceContextProvider.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { ReactNode, useMemo, useReducer } from 'react'; -import { - CommerceContext, - commerceReducer, - initialCommerceState, -} from './CommerceContext'; -import { useConnectLoaderState } from '../../../context/connect-loader-context/ConnectLoaderContext'; - -export const useCommerceWidgetState = () => { - const [viewState, viewDispatch] = useReducer( - commerceReducer, - initialCommerceState, - ); - - return [viewState, viewDispatch] as const; -}; - -type CommerceContextProviderProps = { - children: ReactNode; -}; - -export function CommerceWidgetContextProvicer({ - children, -}: CommerceContextProviderProps) { - const [{ checkout, provider }] = useConnectLoaderState(); - const [commerceState, commerceDispatch] = useCommerceWidgetState(); - - const values = useMemo( - () => ({ - commerceState: { ...commerceState, checkout, provider }, - commerceDispatch, - }), - [commerceState, commerceDispatch, checkout, provider], - ); - - return ( - - {children} - - ); -} diff --git a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/hooks/useWidgetEvents.ts b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/hooks/useWidgetEvents.ts index 2c0826ceda..69c7510c3a 100644 --- a/packages/checkout/widgets-lib/src/widgets/immutable-commerce/hooks/useWidgetEvents.ts +++ b/packages/checkout/widgets-lib/src/widgets/immutable-commerce/hooks/useWidgetEvents.ts @@ -3,7 +3,9 @@ import { IMTBLWidgetEvents, OrchestrationEvent, OrchestrationEventType, + RequestOnrampEvent, } from '@imtbl/checkout-sdk'; +import { Web3Provider } from '@ethersproject/providers'; import { getCommerceWidgetEvent } from '../functions/getCommerceWidgetEvent'; import { sendCheckoutEvent } from '../CommerceWidgetEvents'; import { @@ -30,6 +32,7 @@ const widgetEvents = [ export function useWidgetEvents( eventTarget: Window | EventTarget, viewState: ReturnType, + handleProviderUpdated: (provider: Web3Provider) => void, ) { const [{ history }, viewDispatch] = viewState; @@ -52,6 +55,13 @@ export function useWidgetEvents( return; } + if (type === OrchestrationEventType.REQUEST_ONRAMP) { + const onRampEvent = data as RequestOnrampEvent; + if (onRampEvent.provider) { + handleProviderUpdated(onRampEvent.provider); + } + } + const flow = getViewFromOrchestrationEventType(type); if (!flow) return; diff --git a/packages/checkout/widgets-sample-app/src/components/ui/add-tokens/addTokens.tsx b/packages/checkout/widgets-sample-app/src/components/ui/add-tokens/addTokens.tsx index 1ec8b05f41..50fb3700a8 100644 --- a/packages/checkout/widgets-sample-app/src/components/ui/add-tokens/addTokens.tsx +++ b/packages/checkout/widgets-sample-app/src/components/ui/add-tokens/addTokens.tsx @@ -118,6 +118,7 @@ function AddTokensUI() { }); addTokens.addListener(OrchestrationEventType.REQUEST_ONRAMP, (data: any) => { console.log("REQUEST_ONRAMP", data); + factory.updateProvider(data.provider); addTokens.unmount(); onRamp.addListener(OnRampEventType.CLOSE_WIDGET, (data: any) => { console.log("CLOSE_WIDGET", data);