@uphold/topper-web-sdk
Version:
Seamless integration of Topper on Web applications
1 lines • 12.9 kB
Source Map (JSON)
{"version":3,"sources":["../src/enums/environments.ts","../src/enums/events.ts","../src/enums/initial-screens.ts","../src/enums/locales.ts","../src/enums/themes.ts","../src/enums/handlers.ts","../src/enums/urls.ts","../src/enums/variants.ts","../src/topper-web-sdk.ts"],"names":["Environments","Events","InitialScreens","Locales","Themes","Handlers","Urls","Variants","queryString","TopperWebSdk","config","handlerName","data","resolve","reject","handleResponse","event","eventName","mainWindow","name","payload","handler","bootstrapToken","bootstrapTokens","iframeElement","baseUrl","bt","isTopperSelfEmbed","queryParams","url","handlerResult","error"],"mappings":"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","sourcesContent":["export enum Environments {\n PRODUCTION = 'production',\n SANDBOX = 'sandbox'\n}\n","export enum Events {\n ALL = '*',\n ORDER_CONTINUE_BUTTON_CLICKED = 'orderContinueButtonClicked',\n ORDER_PLACED = 'orderPlaced',\n ORDER_WALLET_SEND_BUTTON_CLICKED = 'orderWalletSendButtonClicked',\n WIDGET_CONTINUE_BUTTON_CLICKED = 'widgetContinueButtonClicked'\n}\n","export enum InitialScreens {\n AUTHENTICATION = 'authentication'\n}\n","export enum Locales {\n EN = 'en',\n EN_US = 'en-US',\n PT = 'pt',\n PT_BR = 'pt-BR',\n ES = 'es',\n ES_ES = 'es-ES'\n}\n","export enum Themes {\n DARK = 'dark',\n LIGHT = 'light'\n}\n","export enum Handlers {\n SIGN_AND_BROADCAST_TRANSACTION = 'signAndBroadcastTransaction'\n}\n","export enum Urls {\n PRODUCTION = 'https://app.topperpay.com',\n SANDBOX = 'https://app.sandbox.topperpay.com',\n WEBSITE = 'https://www.topperpay.com/'\n}\n","export enum Variants {\n IFRAME = 'iframe',\n NEW_TAB = 'new-tab',\n SAME_TAB = 'same-tab'\n}\n","import { Config } from './interfaces';\nimport { Environments, Events, Handlers, Sources, Urls, Variants } from './enums';\nimport { EventHandler, Handler } from 'types';\nimport { InternalEvents } from './enums/internal-events';\nimport queryString from 'query-string';\n\nclass TopperWebSdk {\n private eventHandlers: { [key in Events]?: EventHandler[] } = {};\n private handlers: { [key in Handlers]?: Handler } = {};\n private handleMessage: ((event: MessageEvent) => void) | null = null;\n private isInitialized: boolean = false;\n private targetWindow: Window | null = null;\n\n public config: Config;\n\n constructor(config: Config = {}) {\n this.config = {\n active_flow: null,\n environment: Environments.PRODUCTION,\n initial_screen: null,\n is_android_app: false,\n is_android_webview: false,\n is_ios_app: false,\n is_ios_webview: false,\n variant: Variants.NEW_TAB,\n ...config\n };\n }\n\n static getMainWindow() {\n return window.self !== window.top ? window.parent : window.opener;\n }\n\n static handle<T = any>(handlerName: Handlers, data?: any): Promise<T> {\n const mainWindow = this.getMainWindow();\n\n mainWindow.postMessage(\n {\n name: InternalEvents.RESOLVE_HANDLER,\n payload: { data, handlerName },\n source: Sources.HANDLER\n },\n '*'\n );\n\n return new Promise((resolve, reject) => {\n const handleResponse = (event: MessageEvent) => {\n if (\n event.data.name === InternalEvents.RESOLVE_HANDLER &&\n event.data.payload &&\n event.data.source === Sources.HANDLER\n ) {\n window.removeEventListener('message', handleResponse);\n\n if (event.data.payload.error) {\n reject(event.data.payload.error);\n\n return;\n }\n\n resolve(event.data.payload);\n }\n };\n\n window.addEventListener('message', handleResponse);\n });\n }\n\n static triggerEvent(eventName: Events, data?: any): void {\n const mainWindow = this.getMainWindow();\n\n if (!mainWindow) {\n return;\n }\n\n mainWindow.postMessage(\n {\n name: eventName,\n payload: data,\n source: Sources.EVENT\n },\n '*'\n );\n }\n\n private triggerEvent(name: Events, payload?: any): void {\n this.eventHandlers[Events.ALL]?.forEach(handler => handler({ data: payload, name }));\n\n this.eventHandlers[name]?.forEach(handler => handler({ data: payload }));\n }\n\n private setConfig(config: Config): void {\n this.config = { ...this.config, ...config };\n }\n\n private initializeMessageListener(): void {\n this.handleMessage = (event: MessageEvent) => {\n const allowedOrigins = [Urls.PRODUCTION, Urls.SANDBOX];\n\n if (!allowedOrigins.includes(event.origin as Urls) || event.source !== this.targetWindow) {\n return;\n }\n\n if (event.data.name && event.data.source === Sources.EVENT) {\n this.triggerEvent(event.data.name as Events, event.data.payload);\n }\n\n if (\n event.data.name === InternalEvents.RESOLVE_HANDLER &&\n event.data.payload &&\n event.data.source === Sources.HANDLER\n ) {\n this.resolveHandler(event.data.payload.handlerName as Handlers, event.data.payload.data);\n }\n };\n\n window.addEventListener('message', this.handleMessage);\n }\n\n dispose(): void {\n window.removeEventListener('message', this.handleMessage as EventListener, false);\n this.eventHandlers = {};\n }\n\n initialize({\n bootstrapToken,\n bootstrapTokens,\n config,\n iframeElement\n }: {\n bootstrapToken?: string;\n bootstrapTokens?: string[];\n iframeElement?: HTMLIFrameElement;\n config?: Config;\n }): void {\n if (this.isInitialized) {\n throw new Error('This TopperWebSdk instance was already initialized.');\n }\n\n this.isInitialized = true;\n\n if (config) {\n this.setConfig(config);\n }\n\n const baseUrl = this.config.environment === Environments.SANDBOX ? Urls.SANDBOX : Urls.PRODUCTION;\n const bt = bootstrapTokens ? bootstrapTokens.join(';') : bootstrapToken;\n const isTopperSelfEmbed = window.location.href.includes(Urls.WEBSITE);\n\n const queryParams = {\n bt,\n ...(this.config.active_flow && { active_flow: this.config.active_flow }),\n ...(isTopperSelfEmbed && { embed: 1 }),\n ...(this.eventHandlers &&\n Object.keys(this.eventHandlers).length && { events: Object.keys(this.eventHandlers).join(',') }),\n ...(this.handlers && Object.keys(this.handlers).length && { handlers: Object.keys(this.handlers).join(',') }),\n ...(this.config.is_android_app && { is_android_app: 1 }),\n ...(this.config.is_android_webview && { is_android_webview: 1 }),\n ...(this.config.is_ios_app && { is_ios_app: 1 }),\n ...(this.config.is_ios_webview && { is_ios_webview: 1 }),\n ...(this.config.initial_screen && { initial_screen: this.config.initial_screen }),\n ...(this.config.locale && { locale: this.config.locale }),\n ...(this.config.theme && { theme: this.config.theme })\n };\n\n const url = queryString.stringifyUrl({ query: queryParams, url: `${baseUrl}/` });\n\n if (this.config.variant === Variants.IFRAME) {\n if (!iframeElement) {\n throw new Error('iframeElement is required for iframe variant');\n }\n\n iframeElement.src = url;\n this.targetWindow = iframeElement.contentWindow;\n } else if (this.config.variant === Variants.NEW_TAB) {\n this.targetWindow = window.open(url, '_blank');\n } else if (this.config.variant === Variants.SAME_TAB) {\n window.location.href = url;\n\n return;\n }\n\n this.initializeMessageListener();\n }\n\n on(eventName: Events, handler: EventHandler): void {\n if (!this.eventHandlers[eventName]) {\n this.eventHandlers[eventName] = [];\n }\n\n this.eventHandlers[eventName]?.push(handler);\n }\n\n registerHandler(handlerName: Handlers, handler: Handler): void {\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function.');\n }\n\n this.handlers[handlerName] = handler;\n }\n\n async resolveHandler(handlerName: Handlers, data?: any) {\n const handler = this.handlers[handlerName];\n\n if (!handler) {\n throw new Error(`Handler \"${handlerName}\" is not registered.`);\n }\n\n try {\n const handlerResult = await handler(data);\n\n this.targetWindow?.postMessage(\n {\n name: InternalEvents.RESOLVE_HANDLER,\n payload: handlerResult,\n source: Sources.HANDLER\n },\n '*'\n );\n } catch (error) {\n this.targetWindow?.postMessage(\n {\n name: InternalEvents.RESOLVE_HANDLER,\n payload: {\n error: {\n message: error instanceof Error ? error.message : String(error),\n name: error instanceof Error ? error.name : 'Error'\n }\n },\n source: Sources.HANDLER\n },\n '*'\n );\n }\n }\n}\n\nexport { TopperWebSdk };\n"]}