-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6790dbe
commit 1435e74
Showing
10 changed files
with
479 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './postMessageHandler'; |
77 changes: 77 additions & 0 deletions
77
packages/checkout/sdk/src/postMessageHandler/postMessageHandler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
export type PostMessageHandlerConfiguration = { | ||
targetOrigin: string; | ||
eventTarget: MinimalEventTargetInterface; | ||
eventSource?: MinimalEventSourceInterface; | ||
}; | ||
// todo put these in a types file | ||
export enum PostMessageHandlerEventType { | ||
PROVIDER_RELAY = 'PROVIDER_RELAY', | ||
} | ||
|
||
export type PostMessageData = { | ||
type: PostMessageHandlerEventType; | ||
payload: any; | ||
}; | ||
|
||
export interface MinimalEventSourceInterface { | ||
addEventListener(eventType: 'message', handler: (message: MessageEvent) => void): void; | ||
removeEventListener(eventType: 'message', handler: (message: MessageEvent) => void): void; | ||
} | ||
|
||
export interface MinimalEventTargetInterface { | ||
postMessage(message: any, targetOrigin?: string): void; | ||
} | ||
|
||
export class PostMessageHandler { | ||
private eventHandlers: Map<PostMessageHandlerEventType, (data: any) => void> = new Map(); | ||
|
||
private targetOrigin!: string; | ||
|
||
private eventTarget!: MinimalEventTargetInterface; | ||
|
||
private eventSource!: MinimalEventSourceInterface; | ||
|
||
constructor({ | ||
targetOrigin, | ||
eventTarget, | ||
eventSource = window, | ||
}: PostMessageHandlerConfiguration) { | ||
this.handleMessage = this.handleMessage.bind(this); | ||
this.targetOrigin = targetOrigin; | ||
this.eventSource = eventSource; | ||
this.eventTarget = eventTarget; | ||
this.eventHandlers = new Map(); | ||
|
||
this.eventSource.addEventListener('message', this.handleMessage); | ||
} | ||
|
||
public sendMessage(type: PostMessageHandlerEventType, payload: any) { | ||
const message: PostMessageData = { type, payload }; | ||
this.eventTarget.postMessage(message, this.targetOrigin); | ||
} | ||
|
||
public addEventHandler(type: PostMessageHandlerEventType, handler: (data: any) => void): void { | ||
this.eventHandlers.set(type, handler); | ||
} | ||
|
||
public removeEventHandler(type: PostMessageHandlerEventType): void { | ||
this.eventHandlers.delete(type); | ||
} | ||
|
||
private handleMessage(event: MessageEvent) { | ||
if (event.origin !== this.targetOrigin) { | ||
return; | ||
} | ||
|
||
const message: PostMessageData = event.data; | ||
|
||
const handler = this.eventHandlers.get(message.type); | ||
if (handler) { | ||
handler(message.payload); | ||
} | ||
} | ||
|
||
public destroy() { | ||
this.eventSource.removeEventListener('message', this.handleMessage); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
175 changes: 175 additions & 0 deletions
175
packages/checkout/widgets-lib/src/widgets/checkout/context/CheckoutContext.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
import { Web3Provider } from '@ethersproject/providers'; | ||
import { createContext } from 'react'; | ||
import { | ||
Checkout, EIP6963ProviderInfo, PostMessageHandler, WalletProviderName, | ||
} from '@imtbl/checkout-sdk'; | ||
import { Passport } from '@imtbl/passport'; | ||
import { ProviderRelay } from './ProviderRelay'; | ||
|
||
export interface CheckoutState { | ||
checkout: Checkout | null; | ||
provider: Web3Provider | undefined; | ||
passport: Passport | undefined; | ||
iframeUrl: string | undefined; | ||
checkoutAppIframe: Window | undefined; | ||
postMessageHandler: PostMessageHandler | undefined; | ||
providerRelay: ProviderRelay | undefined; | ||
walletProviderName: WalletProviderName | null; | ||
walletProviderInfo: EIP6963ProviderInfo | null; | ||
sendCloseEvent: () => void; | ||
} | ||
|
||
export const initialCheckoutState: CheckoutState = { | ||
checkout: null, | ||
provider: undefined, | ||
passport: undefined, | ||
iframeUrl: undefined, | ||
checkoutAppIframe: undefined, | ||
postMessageHandler: undefined, | ||
providerRelay: undefined, | ||
walletProviderInfo: null, | ||
walletProviderName: null, | ||
sendCloseEvent: () => { }, | ||
}; | ||
|
||
export interface CheckoutContextState { | ||
checkoutState: CheckoutState; | ||
checkoutDispatch: React.Dispatch<CheckoutAction>; | ||
} | ||
|
||
export interface CheckoutAction { | ||
payload: ActionPayload; | ||
} | ||
|
||
type ActionPayload = | ||
| SetCheckoutPayload | ||
| SetProviderPayload | ||
| SetIframeUrlPayload | ||
| SetPostMessageHandlerPayload | ||
| SetCheckoutAppIframePayload | ||
| SetProviderRelayPayload | ||
| SetPassportPayload | ||
| SetProviderNamePayload | ||
| SetSendCloseEventPayload; | ||
|
||
export enum CheckoutActions { | ||
SET_CHECKOUT = 'SET_CHECKOUT', | ||
SET_PROVIDER = 'SET_PROVIDER', | ||
SET_IFRAME_URL = 'SET_IFRAME_URL', | ||
SET_POST_MESSAGE_HANDLER = 'SET_POST_MESSAGE_HANDLER', | ||
SET_CHECKOUT_APP_IFRAME = 'SET_CHECKOUT_APP_IFRAME', | ||
SET_PROVIDER_RELAY = 'SET_PROVIDER_RELAY', | ||
SET_PASSPORT = 'SET_PASSPORT', | ||
SET_WALLET_PROVIDER_NAME = 'SET_WALLET_PROVIDER_NAME', | ||
SET_SEND_CLOSE_EVENT = 'SET_SEND_CLOSE_EVENT', | ||
} | ||
|
||
export interface SetCheckoutPayload { | ||
type: CheckoutActions.SET_CHECKOUT; | ||
checkout: Checkout; | ||
} | ||
|
||
export interface SetProviderPayload { | ||
type: CheckoutActions.SET_PROVIDER; | ||
provider: Web3Provider; | ||
} | ||
|
||
export interface SetIframeUrlPayload { | ||
type: CheckoutActions.SET_IFRAME_URL; | ||
iframeUrl: string; | ||
} | ||
|
||
export interface SetCheckoutAppIframePayload { | ||
type: CheckoutActions.SET_CHECKOUT_APP_IFRAME; | ||
checkoutAppIframe: Window; | ||
} | ||
|
||
export interface SetPostMessageHandlerPayload { | ||
type: CheckoutActions.SET_POST_MESSAGE_HANDLER; | ||
postMessageHandler: PostMessageHandler; | ||
} | ||
|
||
export interface SetProviderRelayPayload { | ||
type: CheckoutActions.SET_PROVIDER_RELAY; | ||
providerRelay: ProviderRelay; | ||
} | ||
|
||
export interface SetPassportPayload { | ||
type: CheckoutActions.SET_PASSPORT; | ||
passport: Passport; | ||
} | ||
|
||
export interface SetProviderNamePayload { | ||
type: CheckoutActions.SET_WALLET_PROVIDER_NAME; | ||
walletProviderName: WalletProviderName; | ||
} | ||
|
||
export interface SetSendCloseEventPayload { | ||
type: CheckoutActions.SET_SEND_CLOSE_EVENT; | ||
sendCloseEvent: () => void; | ||
} | ||
|
||
// eslint-disable-next-line @typescript-eslint/naming-convention | ||
export const CheckoutContext = createContext<CheckoutContextState>({ | ||
checkoutState: initialCheckoutState, | ||
checkoutDispatch: () => { }, | ||
}); | ||
|
||
CheckoutContext.displayName = 'CheckoutContext'; // help with debugging Context in browser | ||
|
||
export type Reducer<S, A> = (prevState: S, action: A) => S; | ||
|
||
export const checkoutReducer: Reducer<CheckoutState, CheckoutAction> = ( | ||
state: CheckoutState, | ||
action: CheckoutAction, | ||
) => { | ||
switch (action.payload.type) { | ||
case CheckoutActions.SET_CHECKOUT: | ||
return { | ||
...state, | ||
checkout: action.payload.checkout, | ||
}; | ||
case CheckoutActions.SET_PROVIDER: | ||
return { | ||
...state, | ||
provider: action.payload.provider, | ||
}; | ||
case CheckoutActions.SET_PASSPORT: | ||
return { | ||
...state, | ||
passport: action.payload.passport, | ||
}; | ||
case CheckoutActions.SET_IFRAME_URL: | ||
return { | ||
...state, | ||
iframeUrl: action.payload.iframeUrl, | ||
}; | ||
case CheckoutActions.SET_CHECKOUT_APP_IFRAME: | ||
return { | ||
...state, | ||
checkoutAppIframe: action.payload.checkoutAppIframe, | ||
}; | ||
case CheckoutActions.SET_POST_MESSAGE_HANDLER: | ||
return { | ||
...state, | ||
postMessageHandler: action.payload.postMessageHandler, | ||
}; | ||
case CheckoutActions.SET_PROVIDER_RELAY: | ||
return { | ||
...state, | ||
providerRelay: action.payload.providerRelay, | ||
}; | ||
case CheckoutActions.SET_WALLET_PROVIDER_NAME: | ||
return { | ||
...state, | ||
walletProviderName: action.payload.walletProviderName, | ||
}; | ||
case CheckoutActions.SET_SEND_CLOSE_EVENT: | ||
return { | ||
...state, | ||
sendCloseEvent: action.payload.sendCloseEvent, | ||
}; | ||
default: | ||
return state; | ||
} | ||
}; |
Oops, something went wrong.