From 6c8ea1b23b569eb008b50a4b291d248bdb1cdb1a Mon Sep 17 00:00:00 2001 From: Jhonatan Gonzalez Date: Wed, 28 Aug 2024 09:35:51 +1000 Subject: [PATCH] [NO CHANGELOG][Checkout Widget] fix: Events type (#2111) --- .../postMessageEventTypes.ts | 43 ++++++- .../postMessageHandler/postMessageHandler.ts | 7 +- .../widgets/definitions/events/checkout.ts | 32 +++--- .../hooks/useCheckoutEventsRelayer.ts | 90 +++++++-------- .../src/components/ui/checkout/checkout.tsx | 106 ++++++++---------- 5 files changed, 143 insertions(+), 135 deletions(-) diff --git a/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts b/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts index 81f168b01d..0c6b7eab8d 100644 --- a/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts +++ b/packages/checkout/sdk/src/postMessageHandler/postMessageEventTypes.ts @@ -1,3 +1,6 @@ +import { IMTBLWidgetEvents } from '../widgets/definitions/events/widgets'; +import { WidgetEventData, WidgetType } from '../widgets/definitions/types'; + export enum PostMessageHandlerEventType { SYN = 'IMTBL_POST_MESSAGE_SYN', ACK = 'IMTBL_POST_MESSAGE_ACK', @@ -11,6 +14,40 @@ export type PostMessageProviderRelayData = any; export type PostMessageEIP6963Data = any; -export type PostMessagePayload = - | PostMessageProviderRelayData - | PostMessageEIP6963Data; +export type PostMessageWidgetEventData< + T extends WidgetType = WidgetType.CHECKOUT, +> = { + type: IMTBLWidgetEvents.IMTBL_CHECKOUT_WIDGET_EVENT; + detail: { + [K in keyof WidgetEventData[T]]: { + type: K; + data: WidgetEventData[T][K]; + }; + }[keyof WidgetEventData[T]]; +}; + +export type PostMessageData = + | { + type: PostMessageHandlerEventType.SYN; + payload: any; + } + | { + type: PostMessageHandlerEventType.ACK; + payload: any; + } + | { + type: PostMessageHandlerEventType.PROVIDER_RELAY; + payload: PostMessageProviderRelayData; + } + | { + type: PostMessageHandlerEventType.PROVIDER_UPDATED; + payload: any; + } + | { + type: PostMessageHandlerEventType.EIP_6963_EVENT; + payload: PostMessageEIP6963Data; + } + | { + type: PostMessageHandlerEventType.WIDGET_EVENT; + payload: PostMessageWidgetEventData; + }; diff --git a/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts b/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts index 686094643c..c79bdd135f 100644 --- a/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts +++ b/packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts @@ -1,6 +1,6 @@ import { PostMessageHandlerEventType, - PostMessagePayload, + PostMessageData, } from './postMessageEventTypes'; export type PostMessageHandlerConfiguration = { @@ -9,11 +9,6 @@ export type PostMessageHandlerConfiguration = { eventSource?: WindowProxy; }; -export type PostMessageData = { - type: PostMessageHandlerEventType; - payload: PostMessagePayload; -}; - export class PostMessageHandler { private init: boolean = false; diff --git a/packages/checkout/sdk/src/widgets/definitions/events/checkout.ts b/packages/checkout/sdk/src/widgets/definitions/events/checkout.ts index 19d8fb2310..11d7e17940 100644 --- a/packages/checkout/sdk/src/widgets/definitions/events/checkout.ts +++ b/packages/checkout/sdk/src/widgets/definitions/events/checkout.ts @@ -1,5 +1,4 @@ import { Web3Provider } from '@ethersproject/providers'; -import { CheckoutFlowType } from '../parameters/checkout'; import { ConnectionFailed, ConnectionSuccess } from './connect'; import { SaleFailed, @@ -30,6 +29,9 @@ export enum CheckoutEventType { } export enum CheckoutSuccessEventType { + SWAP_SUCCESS = 'SWAP_SUCCESS', + ONRAMP_SUCCESS = 'ONRAMP_SUCCESS', + CONNECT_SUCCESS = 'CONNECT_SUCCESS', SALE_SUCCESS = 'SALE_SUCCESS', SALE_TRANSACTION_SUCCESS = 'SALE_TRANSACTION_SUCCESS', BRIDGE_SUCCESS = 'BRIDGE_SUCCESS', @@ -41,11 +43,15 @@ export enum CheckoutFailureEventType { BRIDGE_CLAIM_WITHDRAWAL_FAILED = 'BRIDGE_CLAIM_WITHDRAWAL_FAILED', SWAP_FAILED = 'SWAP_FAILED', SWAP_REJECTED = 'SWAP_REJECTED', + CONNECT_FAILED = 'CONNECT_FAILED', + SALE_FAILED = 'SALE_FAILED', + ONRAMP_FAILED = 'ONRAMP_FAILED', } export enum CheckoutUserActionEventType { PAYMENT_METHOD_SELECTED = 'PAYMENT_METHOD_SELECTED', PAYMENT_TOKEN_SELECTED = 'PAYMENT_TOKEN_SELECTED', + NETWORK_SWITCH = 'NETWORK_SWITCH', } export type CheckoutProviderUpdatedEvent = { @@ -58,41 +64,37 @@ export type CheckoutProviderUpdatedEvent = { }; export type CheckoutSaleSuccessEvent = { - flow: CheckoutFlowType.SALE; type: CheckoutSuccessEventType.SALE_SUCCESS; data: SaleSuccess; }; export type CheckoutSaleSuccessfulTransactionEvent = { - flow: CheckoutFlowType.SALE; type: CheckoutSuccessEventType.SALE_TRANSACTION_SUCCESS; data: SaleTransactionSuccess; }; export type CheckoutOnRampSuccessEvent = { - flow: CheckoutFlowType.ONRAMP; + type: CheckoutSuccessEventType.ONRAMP_SUCCESS; data: OnRampSuccess; }; // FIMXE: TransactionSent export type CheckoutBridgeSuccessEvent = { - flow: CheckoutFlowType.BRIDGE; type: CheckoutSuccessEventType.BRIDGE_SUCCESS; data: BridgeTransactionSent; }; // FIMXE: TransactionSent export type CheckoutBridgeClaimWithdrawalSuccessEvent = { - flow: CheckoutFlowType.BRIDGE; type: CheckoutSuccessEventType.BRIDGE_CLAIM_WITHDRAWAL_SUCCESS; data: BridgeClaimWithdrawalSuccess; }; // FIMXE: TransactionSent export type CheckoutSwapSuccessEvent = { - flow: CheckoutFlowType.SWAP; + type: CheckoutSuccessEventType.SWAP_SUCCESS; data: SwapSuccess; }; // FIMXE: TransactionSent export type CheckoutConnectSuccessEvent = { - flow: CheckoutFlowType.CONNECT; + type: CheckoutSuccessEventType.CONNECT_SUCCESS; data: ConnectionSuccess; }; @@ -106,41 +108,37 @@ export type CheckoutSuccessEvent = | CheckoutSaleSuccessfulTransactionEvent; export type CheckoutBridgeFailureEvent = { - flow: CheckoutFlowType.BRIDGE; type: CheckoutFailureEventType.BRIDGE_FAILED; data: BridgeFailed; }; // FIMXE: Error export type CheckoutBridgeClaimWithdrawalFailedEvent = { - flow: CheckoutFlowType.BRIDGE; type: CheckoutFailureEventType.BRIDGE_CLAIM_WITHDRAWAL_FAILED; data: BridgeClaimWithdrawalFailed; }; // FIMXE: Error export type CheckoutConnectFailureEvent = { - flow: CheckoutFlowType.CONNECT; + type: CheckoutFailureEventType.CONNECT_FAILED; data: ConnectionFailed; }; // FIMXE: Error export type CheckoutOnRampFailureEvent = { - flow: CheckoutFlowType.ONRAMP; + type: CheckoutFailureEventType.ONRAMP_FAILED; data: OnRampFailed; }; // FIMXE: Error export type CheckoutSwapFailureEvent = { - flow: CheckoutFlowType.SWAP; type: CheckoutFailureEventType.SWAP_FAILED; data: SwapFailed; }; // FIMXE: Error export type CheckoutSwapRejectedEvent = { - flow: CheckoutFlowType.SWAP; type: CheckoutFailureEventType.SWAP_REJECTED; data: SwapRejected; }; // FIMXE: Error export type CheckoutSaleFailureEvent = { - flow: CheckoutFlowType.SALE; + type: CheckoutFailureEventType.SALE_FAILED; data: SaleFailed; }; @@ -154,19 +152,17 @@ export type CheckoutFailureEvent = | CheckoutSaleFailureEvent; export type CheckoutPaymentMethodSelectedEvent = { - flow: CheckoutFlowType.SALE; type: CheckoutUserActionEventType.PAYMENT_METHOD_SELECTED; data: SalePaymentMethod; }; export type CheckoutPaymentTokenSelectedEvent = { - flow: CheckoutFlowType.SALE; type: CheckoutUserActionEventType.PAYMENT_TOKEN_SELECTED; data: SalePaymentToken; }; export type CheckoutNetworkSwitchEvent = { - flow: CheckoutFlowType.WALLET; + type: CheckoutUserActionEventType.NETWORK_SWITCH; data: WalletNetworkSwitch; }; diff --git a/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useCheckoutEventsRelayer.ts b/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useCheckoutEventsRelayer.ts index f29458f78d..43bf561c10 100644 --- a/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useCheckoutEventsRelayer.ts +++ b/packages/checkout/widgets-lib/src/widgets/checkout/hooks/useCheckoutEventsRelayer.ts @@ -1,72 +1,68 @@ +/* eslint-disable no-case-declarations */ import { useContext, useEffect, useRef } from 'react'; import { - CheckoutConnectSuccessEvent, CheckoutEventType, - CheckoutFlowType, - CheckoutSuccessEvent, - IMTBLWidgetEvents, PostMessageHandlerEventType, - WidgetEventData, - WidgetType, + CheckoutSuccessEventType, } from '@imtbl/checkout-sdk'; import { useCheckoutContext } from '../context/CheckoutContextProvider'; -import { sendCheckoutEvent } from '../CheckoutWidgetEvents'; import { EventTargetContext } from '../../../context/event-target-context/EventTargetContext'; import { CheckoutActions } from '../context/CheckoutContext'; - -function isWidgetEvent(payload: any): payload is { - type: IMTBLWidgetEvents.IMTBL_CHECKOUT_WIDGET_EVENT; - detail: { - type: CheckoutEventType; - data: WidgetEventData[WidgetType.CHECKOUT][keyof WidgetEventData[WidgetType.CHECKOUT]]; - }; -} { - return payload.type === IMTBLWidgetEvents.IMTBL_CHECKOUT_WIDGET_EVENT; -} +import { sendCheckoutEvent } from '../CheckoutWidgetEvents'; export function useCheckoutEventsRelayer() { const [{ postMessageHandler, provider }, checkoutDispatch] = useCheckoutContext(); - const { eventTargetState: { eventTarget } } = useContext(EventTargetContext); + const { + eventTargetState: { eventTarget }, + } = useContext(EventTargetContext); const unsubscribePostMessageHandler = useRef<(() => void) | undefined>(); useEffect(() => { if (!postMessageHandler) return undefined; unsubscribePostMessageHandler.current?.(); - unsubscribePostMessageHandler.current = postMessageHandler.subscribe(({ type, payload }) => { - if (type !== PostMessageHandlerEventType.WIDGET_EVENT || !isWidgetEvent(payload)) return; + unsubscribePostMessageHandler.current = postMessageHandler.subscribe( + ({ type, payload }) => { + if (type !== PostMessageHandlerEventType.WIDGET_EVENT) { + return; + } - if (payload.detail.type === CheckoutEventType.SUCCESS - && (payload.detail.data as CheckoutSuccessEvent).flow === CheckoutFlowType.CONNECT) { - const checkoutConnectSuccessEvent = payload.detail as unknown as CheckoutConnectSuccessEvent; - if (!provider) { - throw new Error('Provider not found, unable to send checkout connect success event'); + const event = { ...payload }; + + if (event.detail.type === CheckoutEventType.INITIALISED) { + checkoutDispatch({ + payload: { + type: CheckoutActions.SET_INITIALISED, + initialised: true, + }, + }); + } + + if (event.detail.type === CheckoutEventType.DISCONNECTED) { + checkoutDispatch({ + payload: { + type: CheckoutActions.SET_PROVIDER, + provider: undefined, + }, + }); } - checkoutConnectSuccessEvent.data.provider = provider; - sendCheckoutEvent(eventTarget, { type: payload.detail.type, data: checkoutConnectSuccessEvent }); - return; - } - if (payload.detail.type === CheckoutEventType.DISCONNECTED) { - checkoutDispatch({ - payload: { - type: CheckoutActions.SET_PROVIDER, - provider: undefined, - }, - }); - } + if ( + event.detail.type === CheckoutEventType.SUCCESS + && event.detail.data.type === CheckoutSuccessEventType.CONNECT_SUCCESS + ) { + if (!provider) { + throw new Error( + 'Provider not found, unable to send checkout connect success event', + ); + } - sendCheckoutEvent(eventTarget, payload.detail); + event.detail.data.data.provider = provider; + } - if (payload.detail.type === CheckoutEventType.INITIALISED) { - checkoutDispatch({ - payload: { - type: CheckoutActions.SET_INITIALISED, - initialised: true, - }, - }); - } - }); + sendCheckoutEvent(eventTarget, event.detail); + }, + ); return () => { unsubscribePostMessageHandler.current?.(); diff --git a/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx b/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx index e25332c2d7..d252eadf94 100644 --- a/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx +++ b/packages/checkout/widgets-sample-app/src/components/ui/checkout/checkout.tsx @@ -113,7 +113,7 @@ function CheckoutUI() { useEffect(() => { if (!checkoutWidget) return; checkoutWidget?.mount("checkout", { - flow: CheckoutFlowType.WALLET, + flow: CheckoutFlowType.CONNECT, }); }, [checkoutWidget]); @@ -132,97 +132,81 @@ function CheckoutUI() { console.log("----------> CLOSE", data); }); - checkoutWidget.addListener(CheckoutEventType.SUCCESS, (payload) => { - if (payload.flow === CheckoutFlowType.CONNECT) { - setWeb3Provider(payload.data.provider); - } + checkoutWidget.addListener(CheckoutEventType.SUCCESS, (event) => { + console.log("🐛 ~ event: ----->", event); - if ( - payload.flow === CheckoutFlowType.SALE && - payload.type === CheckoutSuccessEventType.SALE_SUCCESS - ) { - console.log("----------> SUCCESS SALE_SUCESS", payload); + if (event.type === CheckoutSuccessEventType.CONNECT_SUCCESS) { + console.log("----------> SUCCESS CONNECT_SUCCESS", event); + setWeb3Provider(event.data.provider); } - if ( - payload.flow === CheckoutFlowType.SALE && - payload.type === CheckoutSuccessEventType.SALE_TRANSACTION_SUCCESS - ) { - console.log("----------> SUCCESS SALE_TRANSACTION_SUCCESS", payload); + if (event.type === CheckoutSuccessEventType.SALE_SUCCESS) { + console.log("----------> SUCCESS SALE_SUCESS", event); } - if (payload.flow === CheckoutFlowType.ONRAMP) { - console.log("----------> SUCCESS ONRAMP", payload); + if (event.type === CheckoutSuccessEventType.SALE_TRANSACTION_SUCCESS) { + console.log("----------> SUCCESS SALE_TRANSACTION_SUCCESS", event); } - if ( - payload.flow === CheckoutFlowType.BRIDGE && - payload.type === CheckoutSuccessEventType.BRIDGE_SUCCESS - ) { - console.log("----------> SUCCESS BRIDGE_SUCCESS", payload); + if (event.type === CheckoutSuccessEventType.ONRAMP_SUCCESS) { + console.log("----------> SUCCESS ONRAMP", event); + } + if (event.type === CheckoutSuccessEventType.BRIDGE_SUCCESS) { + console.log("----------> SUCCESS BRIDGE_SUCCESS", event); } if ( - payload.flow === CheckoutFlowType.BRIDGE && - payload.type === CheckoutSuccessEventType.BRIDGE_CLAIM_WITHDRAWAL_SUCCESS + event.type === CheckoutSuccessEventType.BRIDGE_CLAIM_WITHDRAWAL_SUCCESS ) { console.log( "----------> SUCCESS BRIDGE_CLAIM_WITHDRAWAL_SUCCESS", - payload.data + event.data ); } - - console.log("----------> SUCCESS", payload); }); - checkoutWidget.addListener(CheckoutEventType.FAILURE, (data) => { - if ( - data.flow === CheckoutFlowType.BRIDGE && - data.type === CheckoutFailureEventType.BRIDGE_FAILED - ) { - console.log("----------> FAILURE BRIDGE_FAILED", data); + checkoutWidget.addListener(CheckoutEventType.FAILURE, (event) => { + if (event.type === CheckoutFailureEventType.BRIDGE_FAILED) { + console.log("----------> FAILURE BRIDGE_FAILED", event); } if ( - data.flow === CheckoutFlowType.BRIDGE && - data.type === CheckoutFailureEventType.BRIDGE_CLAIM_WITHDRAWAL_FAILED + event.type === CheckoutFailureEventType.BRIDGE_CLAIM_WITHDRAWAL_FAILED ) { console.log( "----------> FAILURE BRIDGE_CLAIM_WITHDRAWAL_FAILED", - data.data + event.data ); } - if (data.flow === CheckoutFlowType.CONNECT) { - console.log("----------> FAILURE CONNECT", data); + if (event.type === CheckoutFailureEventType.CONNECT_FAILED) { + console.log("----------> FAILURE CONNECT", event); } - if (data.flow === CheckoutFlowType.ONRAMP) { - console.log("----------> FAILURE ONRAMP", data); + if (event.type === CheckoutFailureEventType.ONRAMP_FAILED) { + console.log("----------> FAILURE ONRAMP", event); } - if (data.flow === CheckoutFlowType.SWAP) { - console.log("----------> FAILURE SWAP", data); + if (event.type === CheckoutFailureEventType.SWAP_FAILED) { + console.log("----------> FAILURE SWAP", event); } - if (data.flow === CheckoutFlowType.SALE) { - console.log("----------> FAILURE SALE", data); + if (event.type === CheckoutFailureEventType.SALE_FAILED) { + console.log("----------> FAILURE SALE", event); } - console.log("----------> FAILURE", data); + console.log("----------> FAILURE", event); }); - checkoutWidget.addListener(CheckoutEventType.DISCONNECTED, (data) => { - console.log("----------> DISCONNECTED", data); + checkoutWidget.addListener(CheckoutEventType.DISCONNECTED, (event) => { + console.log("----------> DISCONNECTED", event); }); - checkoutWidget.addListener(CheckoutEventType.USER_ACTION, (data) => { - if ( - data.flow === CheckoutFlowType.SALE && - data.type === CheckoutUserActionEventType.PAYMENT_METHOD_SELECTED - ) { - console.log("----------> USER_ACTION PAYMENT_METHOD_SELECTED", data); + checkoutWidget.addListener(CheckoutEventType.USER_ACTION, (event) => { + if (event.type === CheckoutUserActionEventType.PAYMENT_METHOD_SELECTED) { + console.log( + "----------> USER_ACTION PAYMENT_METHOD_SELECTED", + event.data.paymentMethod + ); } - if ( - data.flow === CheckoutFlowType.SALE && - data.type === CheckoutUserActionEventType.PAYMENT_TOKEN_SELECTED - ) { - console.log("----------> USER_ACTION PAYMENT_TOKEN_SELECTED", data); + if (event.type === CheckoutUserActionEventType.PAYMENT_TOKEN_SELECTED) { + console.log("----------> USER_ACTION PAYMENT_TOKEN_SELECTED", event); } - if (data.flow === CheckoutFlowType.WALLET) { - console.log("----------> USER_ACTION WALLET", data); + if (event.type === CheckoutUserActionEventType.NETWORK_SWITCH) { + console.log("----------> USER_ACTION WALLET", event); } - console.log("----------> USER_ACTION", data); + + console.log("----------> USER_ACTION", event); }); }, [checkoutWidget]);