UNPKG

@particle-network/wallet

Version:

A wallet component that can be easily injected into the developer's website to provide rich custom styles.

4 lines 93.5 kB
{ "version": 3, "sources": ["../../src/index.ts", "../../src/walletPlugin.ts", "../../src/utils.ts", "../../src/config.ts", "../../src/html.ts", "../../src/iconsBase64.ts", "../../src/messageHandler.ts", "../../src/types.ts", "../../src/style.ts", "../../src/walletUrl.ts"], "sourcesContent": ["import { WalletEntryPlugin } from './walletPlugin';\n\nexport type {\n CustomEventHandler,\n CustomMessageType,\n EthereumProvider,\n MessageType,\n ProjectConfig,\n SolanaWallet,\n WalletConfig,\n WalletCore,\n WalletCustomStyle,\n WalletOption,\n} from './types';\n\nexport { EntryPosition } from './types';\n\nconst walletEntryPlugin = new WalletEntryPlugin();\n\nexport { walletEntryPlugin, type WalletEntryPlugin };\n", "import debounce from 'lodash/debounce.js';\nimport globalConfig from './config';\nimport htmlRender from './html';\nimport { downArrowDarkBase64, walletIconDarkBase64 } from './iconsBase64';\nimport { handleCustomEvent, handleRpc, sendEthereumEvent } from './messageHandler';\nimport styleRender from './style';\nimport {\n EntryPosition,\n IframeWalletMessageType,\n MessageType,\n walletIframeId,\n walletIframeMask,\n type ProjectConfig,\n type WalletConfig,\n type WalletCore,\n type WalletOption,\n} from './types';\nimport { isNullish, isServer } from './utils';\nimport { walletUrl } from './walletUrl';\n\nconst fullScreenClass = 'particle-pwe-full-screen-iframe-content';\n\nlet isListen = false;\n\nlet timer: any = null;\n\nlet draggie: any;\n\nexport class WalletEntryPlugin {\n static WALLET_BTN_POSITION = 'walletBtnPosition';\n\n private _walletOptions!: WalletOption;\n\n private projectConfig: ProjectConfig | undefined;\n\n private _walletCore: WalletCore | undefined;\n\n /**\n * wallet is center\n */\n private centerWallet = false;\n\n walletCreated = false;\n\n get walletCore() {\n return this._walletCore;\n }\n\n get walletOptions() {\n return this._walletOptions;\n }\n\n constructor() {\n if (typeof window !== 'undefined') {\n window.addEventListener('message', (event) => {\n if (event?.data?.name === 'particle-network-wallet') {\n console.log('handleWalletEvent', event);\n const type = event?.data?.data?.type;\n if (type === 'logout') {\n this.walletEntryDestroy();\n }\n }\n });\n\n // @ts-ignore\n window.walletEntryPlugin = this;\n }\n }\n\n init(projectConfig: ProjectConfig, options: WalletOption = {}) {\n this.projectConfig = projectConfig;\n this._walletOptions = {\n entryPosition: EntryPosition.BR,\n themeType: 'light',\n ...options,\n widgetIntegration: options.widgetIntegration ?? 'modal',\n visible: options.visible ?? true,\n };\n\n if (options.walletUrl) {\n globalConfig.updateWalletUrl(options.walletUrl);\n }\n\n const storedPosition = this.getButtonStorageData().position;\n if (storedPosition && storedPosition !== this._walletOptions.entryPosition) {\n localStorage.removeItem(WalletEntryPlugin.WALLET_BTN_POSITION);\n localStorage.removeItem(WalletEntryPlugin.WALLET_BTN_POSITION + '_window');\n this.setInitialButtonPosition();\n }\n\n this.centerWallet = Boolean(this._walletOptions.entryPosition === EntryPosition.MC || !this._walletOptions.visible);\n\n if (this.centerWallet) {\n this._walletOptions.topMenuType = 'close';\n }\n\n this.destroy();\n if (typeof window !== 'undefined') {\n window.removeEventListener('message', this.#onMessage);\n window.addEventListener('message', this.#onMessage);\n }\n }\n\n private setInitialButtonPosition() {\n const position = this._walletOptions.entryPosition;\n const { innerWidth, innerHeight } = window;\n let x, y, direction;\n\n switch (position) {\n case EntryPosition.BR:\n x = innerWidth;\n y = innerHeight;\n direction = 'right';\n break;\n case EntryPosition.BL:\n x = 0;\n y = innerHeight;\n direction = 'left';\n break;\n case EntryPosition.TR:\n x = innerWidth;\n y = 0;\n direction = 'right';\n break;\n case EntryPosition.TL:\n x = 0;\n y = 0;\n direction = 'left';\n break;\n default:\n x = innerWidth;\n y = innerHeight;\n direction = 'right';\n }\n\n this.setButtonStorageData({ x, y, direction });\n }\n\n overrideWalletOption(options: Partial<WalletOption>) {\n if (!this.projectConfig) {\n throw new Error('Please init wallet entry plugin first!');\n }\n this._walletOptions = {\n ...this._walletOptions,\n ...options,\n };\n\n if (this.walletCore && this.walletCreated) {\n this.walletEntryCreate();\n } else {\n this.walletEntryDestroy();\n }\n }\n\n setWalletCore(walletCore: WalletCore) {\n if (!this.projectConfig) {\n throw new Error('Please init wallet entry plugin first!');\n }\n if (!walletCore.ethereum && !walletCore.solana) {\n throw new Error('Please provide ethereum or solana wallet!');\n }\n if (this._walletCore) {\n this._walletCore.ethereum?.removeListener?.('accountsChanged', this.#onEthereumAccountsChanged);\n this._walletCore.ethereum?.removeListener?.('chainChanged', this.#onEthereumChainChanged);\n }\n this._walletCore = walletCore;\n if (this._walletCore.ethereum) {\n this._walletCore.ethereum?.removeListener?.('accountsChanged', this.#onEthereumAccountsChanged);\n this._walletCore.ethereum?.on?.('accountsChanged', this.#onEthereumAccountsChanged);\n\n this._walletCore.ethereum?.removeListener?.('chainChanged', this.#onEthereumChainChanged);\n this._walletCore.ethereum?.on?.('chainChanged', this.#onEthereumChainChanged);\n }\n }\n\n walletEntryCreate() {\n this.destroy();\n if (this._walletOptions?.widgetIntegration !== 'embedded') {\n this.walletEntryRander();\n\n if (this._walletOptions.preload) {\n const iframe: HTMLIFrameElement = this.getWalletIFrameImpl();\n const iframeContent = document.querySelector('.particle-pwe-iframe-content') as HTMLDivElement;\n if (!iframeContent?.childElementCount) {\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframeContent?.appendChild(iframe);\n }\n }\n }\n this.walletCreated = true;\n }\n\n walletEntryDestroy() {\n this.destroy();\n }\n\n destroy() {\n if (isServer()) return;\n draggie?.destroy?.();\n window.removeEventListener('resize', this?.resize?.(), false);\n document.querySelector('.particle-wallet-entry-container')?.remove?.();\n\n const walletBtn = document.querySelector('.particle-pwe-btn') as HTMLButtonElement;\n walletBtn && walletBtn.removeAttribute('data-position');\n\n const iframe = document.getElementById(walletIframeId);\n if (iframe) {\n iframe.remove();\n }\n this.walletCreated = false;\n }\n\n private getWalletUrl(options?: WalletConfig): string {\n if (!this.projectConfig) {\n throw new Error('Please init wallet entry plugin first!');\n }\n const url = walletUrl({\n options,\n projectConfig: this.projectConfig,\n walletOptions: this._walletOptions,\n customEventHandler: this._walletCore?.customEventHandler,\n });\n return url;\n }\n\n public getWalletIFrame(options?: WalletConfig): HTMLIFrameElement {\n if (this._walletOptions.widgetIntegration !== 'embedded') {\n throw new Error('Only `embedded` mode can control the iframe.');\n }\n\n return this.getWalletIFrameImpl(options);\n }\n\n private getWalletIFrameImpl(options?: WalletConfig): HTMLIFrameElement {\n if (!this.projectConfig) {\n throw new Error('Please init wallet entry plugin first!');\n }\n if (!this._walletCore) {\n throw new Error('Please call `setWalletCore` first!');\n }\n\n let iframe: HTMLIFrameElement | null = document.getElementById(walletIframeId) as HTMLIFrameElement;\n if (!iframe) {\n iframe = this.createIFrame();\n }\n\n const url = this.getWalletUrl(options);\n if (url != iframe.getAttribute('src')) {\n iframe.src = url;\n }\n return iframe;\n }\n\n private getWalletIFrameMask() {\n let mask: HTMLDivElement | null = document.getElementById(walletIframeMask) as HTMLDivElement;\n if (!mask) {\n mask = document.createElement('div');\n mask.setAttribute('id', walletIframeMask);\n mask.style.position = 'fixed';\n mask.style.top = '0';\n mask.style.left = '0';\n mask.style.width = '100%';\n mask.style.height = '100%';\n mask.style.zIndex = '1000';\n mask.style.backgroundColor = 'rgba(71, 88, 107, 0.24)';\n mask.style.backdropFilter = 'blur(6px)';\n mask.style.display = 'none';\n document.body.appendChild(mask);\n }\n return mask;\n }\n\n private createIFrame() {\n let iframe: HTMLIFrameElement | null = document.getElementById(walletIframeId) as HTMLIFrameElement;\n if (!iframe) {\n iframe = document.createElement('iframe');\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframe.style.border = 'none';\n iframe.allow = 'camera';\n iframe.id = walletIframeId;\n iframe.src = this.getWalletUrl();\n }\n\n return iframe;\n }\n\n /**\n * open modal wallet\n * @param params\n * @param params.windowSize large | small\n * @param params.pathName The path to the web wallet page, which is '/' by default.\n * @param params.query Go to the query parameter of the wallet page\n * @returns\n */\n public openWallet(\n params?: {\n windowSize?: 'large' | 'small';\n } & WalletConfig\n ) {\n console.log('open wallet', this._walletOptions, params);\n if (this._walletOptions?.widgetIntegration === 'embedded') {\n throw new Error('embedded mode not support `openWallet`');\n }\n\n const walletIcon = document.querySelector('.particle-pwe-wallet-icon') as HTMLDivElement;\n const downArrow = document.querySelector('.particle-pwe-down-arrow');\n const iframeContent = document.querySelector('.particle-pwe-iframe-content') as HTMLDivElement;\n\n if (params?.windowSize === 'large' || window.screen.width < 600) {\n iframeContent?.classList.add(fullScreenClass);\n }\n const modalBorderRadius =\n this._walletOptions?.customStyle?.[this._walletOptions?.themeType || 'light']?.cardBorderRadius ?? 18;\n if (!isNullish(modalBorderRadius)) {\n iframeContent.style.borderRadius = `${modalBorderRadius}px`;\n }\n iframeContent?.classList.add('particle-pwe-iframe-content-show');\n\n const uiMode = this._walletOptions?.themeType || 'light';\n\n if (uiMode == 'dark') {\n iframeContent?.classList.add('particle-pwe-iframe-content-dark');\n iframeContent?.classList.remove('particle-pwe-iframe-content-light');\n } else {\n iframeContent?.classList.add('particle-pwe-iframe-content-light');\n iframeContent?.classList.remove('particle-pwe-iframe-content-dark');\n }\n\n if (this.centerWallet) {\n iframeContent.classList.add('particle-pwe-iframe-center-content');\n }\n\n const iframe: HTMLIFrameElement = this.getWalletIFrameImpl(params);\n if (!iframeContent.childElementCount) {\n iframe.style.width = '100%';\n iframe.style.height = '100%';\n iframeContent?.appendChild(iframe);\n }\n\n walletIcon?.classList.add('particle-pwe-wallet-icon-hide');\n downArrow?.classList.remove('particle-pwe-down-arrow-hide');\n if (this.centerWallet) {\n const iframeMask = this.getWalletIFrameMask();\n iframeMask.style.display = 'block';\n }\n this.updateIframeContentPosition();\n }\n\n // ----- wallet event\n\n #onMessage = (event: MessageEvent) => {\n if (event.data?.type === IframeWalletMessageType && this._walletCore) {\n const messageType = event.data?.message?.messageType;\n if (messageType === MessageType.EthereumRpc || messageType === MessageType.SolanaRpc) {\n handleRpc(event, this._walletCore);\n } else {\n handleCustomEvent(event, this._walletCore.customEventHandler);\n }\n }\n };\n\n #onEthereumAccountsChanged = (args: unknown) => {\n sendEthereumEvent('accountsChanged', args);\n };\n\n #onEthereumChainChanged = (args: unknown) => {\n sendEthereumEvent('chainChanged', args);\n };\n\n // ---- render wallet icon\n\n private setWalletIcon() {\n const walletIconEl = document.querySelector('.particle-pwe-wallet-icon') as HTMLImageElement;\n const downArrowEl = document.querySelector('.particle-pwe-down-arrow') as HTMLImageElement;\n\n walletIconEl && walletIconEl.setAttribute('src', walletIconDarkBase64);\n downArrowEl && downArrowEl.setAttribute('src', downArrowDarkBase64);\n\n const walletBtn = document.querySelector('.particle-pwe-btn') as HTMLButtonElement;\n if (walletBtn && this._walletOptions.visible && this._walletOptions.entryPosition !== EntryPosition.MC) {\n walletBtn.style.opacity = '1';\n }\n }\n\n private updateIframeContentPosition() {\n const iframeContent = document.querySelector('.particle-pwe-iframe-content') as HTMLDivElement;\n if (!iframeContent || iframeContent?.style?.display === 'none') {\n return;\n }\n const walletBtn = document.querySelector('.particle-pwe-btn') as HTMLButtonElement;\n\n if (!this._walletOptions.visible) {\n walletBtn.style.display = 'none';\n }\n\n const walletBtnRect = walletBtn.getBoundingClientRect();\n const iframeContentRect = iframeContent.getBoundingClientRect();\n const windowHeight = window.innerHeight;\n const windowWidth = window.innerWidth;\n const iframeContentHeight = iframeContentRect.height;\n const iframeContentWidth = iframeContentRect.width;\n const walletBtnHeight = walletBtnRect.height;\n // const walletBtnWidth = walletBtnRect.width;\n const walletBtnTop = walletBtnRect.top;\n const walletBtnLeft = walletBtnRect.left;\n const walletBtnBottom = walletBtnRect.bottom;\n const walletBtnRight = walletBtnRect.right;\n\n if (this.centerWallet) {\n // Screen center\n iframeContent.style.top = `${(windowHeight - iframeContentHeight) / 2}px`;\n iframeContent.style.left = `${(windowWidth - iframeContentWidth) / 2}px`;\n } else if (\n walletBtnBottom + iframeContentHeight + 10 < windowHeight &&\n walletBtnRight + iframeContentWidth + 10 < windowWidth\n ) {\n iframeContent.style.top = walletBtnBottom + 10 + 'px';\n iframeContent.style.left = walletBtnLeft + 'px';\n } else if (\n walletBtnBottom + iframeContentHeight + 10 < windowHeight &&\n walletBtnLeft - iframeContentWidth - 10 > 0\n ) {\n iframeContent.style.top = walletBtnBottom + 10 + 'px';\n iframeContent.style.left = walletBtnRight - iframeContentWidth + 'px';\n } else if (walletBtnTop - iframeContentHeight - 10 > 0 && walletBtnRight + iframeContentWidth + 10 < windowWidth) {\n iframeContent.style.top = walletBtnTop - iframeContentHeight - 10 + 'px';\n iframeContent.style.left = walletBtnLeft + 'px';\n } else if (walletBtnTop - iframeContentHeight - 10 > 0 && walletBtnLeft - iframeContentWidth - 10 > 0) {\n iframeContent.style.top = walletBtnTop - iframeContentHeight - 10 + 'px';\n iframeContent.style.left = walletBtnRight - iframeContentWidth + 'px';\n } else if (walletBtnRight + iframeContentWidth + 10 < windowWidth) {\n const top = walletBtnTop + walletBtnHeight / 2 - iframeContentHeight / 2;\n iframeContent.style.top =\n top < 30\n ? 30 + 'px'\n : top > windowHeight - iframeContentHeight - 30\n ? windowHeight - iframeContentHeight - 30 + 'px'\n : top + 'px';\n iframeContent.style.left = walletBtnRight + 10 + 'px';\n } else if (walletBtnLeft - iframeContentWidth - 10 > 0) {\n const top = walletBtnTop + walletBtnHeight / 2 - iframeContentHeight / 2;\n iframeContent.style.top =\n top < 30\n ? 30 + 'px'\n : top > windowHeight - iframeContentHeight - 30\n ? windowHeight - iframeContentHeight - 30 + 'px'\n : top + 'px';\n iframeContent.style.left = walletBtnLeft - iframeContentWidth - 10 + 'px';\n } else {\n console.log('no space');\n }\n }\n\n private setButtonStorageData(data: any) {\n const { innerWidth, innerHeight } = window;\n const position = this._walletOptions.entryPosition || EntryPosition.BR;\n localStorage.setItem(WalletEntryPlugin.WALLET_BTN_POSITION, `${data.x},${data.y},${data.direction},${position}`);\n localStorage.setItem(WalletEntryPlugin.WALLET_BTN_POSITION + '_window', `${innerWidth},${innerHeight}`);\n }\n\n private getButtonStorageData() {\n const { innerWidth, innerHeight } = window;\n const [x, y, direction, position] =\n localStorage?.getItem(WalletEntryPlugin.WALLET_BTN_POSITION)?.split?.(',') || [];\n let [width, height]: any =\n localStorage.getItem(WalletEntryPlugin.WALLET_BTN_POSITION + '_window')?.split?.(',') || [];\n width = Number(width || 0);\n height = Number(height || 0);\n if (width && height && (width != innerWidth || height != innerHeight)) {\n localStorage.removeItem(WalletEntryPlugin.WALLET_BTN_POSITION);\n localStorage.removeItem(WalletEntryPlugin.WALLET_BTN_POSITION + '_window');\n return this.getInitialPositionData();\n }\n\n return {\n x: Number(x) || 0,\n y: Number(y) || 0,\n position: position || this._walletOptions?.entryPosition,\n direction: direction || this.getDirectionFromPosition(this._walletOptions?.entryPosition),\n };\n }\n\n private getInitialPositionData() {\n const position = this._walletOptions?.entryPosition || EntryPosition.BR;\n const { innerWidth, innerHeight } = window;\n let x, y;\n\n switch (position) {\n case EntryPosition.BR:\n x = innerWidth;\n y = innerHeight;\n break;\n case EntryPosition.BL:\n x = 0;\n y = innerHeight;\n break;\n case EntryPosition.TR:\n x = innerWidth;\n y = 0;\n break;\n case EntryPosition.TL:\n x = 0;\n y = 0;\n break;\n default:\n x = innerWidth;\n y = innerHeight;\n }\n\n return {\n x,\n y,\n position,\n direction: this.getDirectionFromPosition(position),\n };\n }\n\n private getDirectionFromPosition(position?: EntryPosition): 'left' | 'right' {\n return position === EntryPosition.BL || position === EntryPosition.TL ? 'left' : 'right';\n }\n\n private updateWalletBtnPosition(x: number, y: number, type = '') {\n const { width } = document.body.getBoundingClientRect();\n const { direction } = this.getButtonStorageData();\n const isRight = x > width / 2 || (type == 'windowResize' && direction === 'right');\n let left = isRight ? width - 60 : 0;\n let top = y;\n let newDirection = 'left';\n\n const safeDistance = window.screen.width > 600 ? 30 : 10;\n\n if (left < safeDistance) {\n left = safeDistance;\n newDirection = 'left';\n } else if (left > width - (60 + safeDistance)) {\n left = width - (60 + safeDistance);\n newDirection = 'right';\n }\n if (top < safeDistance) {\n top = safeDistance;\n } else if (top > window.innerHeight - (60 + safeDistance)) {\n top = window.innerHeight - (60 + safeDistance);\n }\n\n return {\n left,\n top,\n direction: newDirection,\n };\n }\n\n public closeWallet() {\n const iframeContent: HTMLDivElement | null = document.querySelector('.particle-pwe-iframe-content');\n iframeContent?.classList.remove('particle-pwe-iframe-content-show');\n iframeContent?.classList.remove(fullScreenClass);\n const walletIcon = document.querySelector('.particle-pwe-wallet-icon') as HTMLDivElement;\n const downArrow = document.querySelector('.particle-pwe-down-arrow');\n walletIcon?.classList.remove('particle-pwe-wallet-icon-hide');\n downArrow?.classList.add('particle-pwe-down-arrow-hide');\n const iframeMask = this.getWalletIFrameMask();\n iframeMask.style.display = 'none';\n }\n\n private resize() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const that = this;\n return () => {\n if (isServer()) return;\n clearTimeout(timer);\n\n timer = setTimeout(() => {\n const walletBtn: HTMLDivElement | null = document.querySelector('.particle-pwe-btn');\n\n const { x: btnX, y: btnY, position } = this.getButtonStorageData();\n\n let x, y;\n if (btnX && btnY) {\n x = btnX;\n y = btnY;\n } else {\n switch (position) {\n case EntryPosition.BL:\n x = 0;\n y = window.innerHeight;\n break;\n case EntryPosition.TL:\n x = 0;\n y = 0;\n break;\n case EntryPosition.TR:\n x = window.innerWidth;\n y = 0;\n break;\n case EntryPosition.BR:\n default:\n x = window.innerWidth;\n y = window.innerHeight;\n break;\n }\n }\n\n const { left, top, direction } = that.updateWalletBtnPosition(x, y, 'windowResize');\n if (walletBtn) {\n walletBtn.style.left = left + 'px';\n walletBtn.style.top = top + 'px';\n }\n\n this.setButtonStorageData({\n x: left,\n y: top,\n direction,\n });\n\n that.updateIframeContentPosition();\n\n (async () => {\n let count = 0;\n do {\n count++;\n await this.sleep(100);\n this.updateIframeContentPosition();\n } while (count < 15);\n })();\n }, 10);\n };\n }\n\n private async sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n private async walletEntryRander() {\n if (isServer()) return;\n styleRender();\n htmlRender();\n this.setWalletIcon();\n\n const walletBtn = document.querySelector('.particle-pwe-btn') as HTMLButtonElement;\n // const maxZIndex = Math.max.apply(\n // null,\n // Array.from(document.querySelectorAll('*')).map((item) => {\n // return Number(window.getComputedStyle(item).zIndex) || 0;\n // })\n // );\n\n // walletBtn.style.zIndex = maxZIndex + 1;\n\n const { x: btnX, y: btnY } = this.getButtonStorageData();\n\n if (btnX && btnY) {\n if ((Number(btnX) || 0) < window.innerWidth && (Number(btnY) || 0) < window.innerHeight) {\n const { left, top } = this.updateWalletBtnPosition(Number(btnX) || 0, Number(btnY) || 0);\n walletBtn.style.left = left + 'px';\n walletBtn.style.top = top + 'px';\n this.updateIframeContentPosition();\n } else {\n const { left, top } = this.updateWalletBtnPosition(window.innerWidth, window.innerHeight);\n walletBtn.style.left = left + 'px';\n walletBtn.style.top = top + 'px';\n this.updateIframeContentPosition();\n }\n } else {\n // default wallet btn position\n const position = this._walletOptions.entryPosition || EntryPosition.BL;\n let top, left;\n if (position === EntryPosition.BR) {\n top = window.innerHeight;\n left = window.innerWidth;\n } else if (position === EntryPosition.TR) {\n top = 0;\n left = window.innerWidth;\n } else if (position === EntryPosition.TL) {\n top = 0;\n left = 0;\n } else {\n top = window.innerHeight;\n left = 0;\n }\n\n const positionData = this.updateWalletBtnPosition(left, top);\n walletBtn.style.left = positionData.left + 'px';\n walletBtn.style.top = positionData.top + 'px';\n walletBtn.setAttribute('data-position', position?.toLowerCase());\n this.updateIframeContentPosition();\n }\n\n let isDraggie = false;\n\n const Module = await import('draggabilly');\n const Draggabilly = Module.default ? Module.default : Module;\n //@ts-ignore\n draggie = new Draggabilly(walletBtn);\n\n draggie.on('dragStart', () => {\n isDraggie = true;\n walletBtn.style.cursor = 'move';\n });\n\n draggie.on('dragMove', () => {\n this.updateIframeContentPosition();\n });\n\n draggie.on('dragEnd', (event: any, pointer: any) => {\n event.stopPropagation();\n walletBtn.style.cursor = 'pointer';\n const { clientX: x, clientY: y } = pointer;\n const { left, top, direction } = this.updateWalletBtnPosition(x, y - 35);\n walletBtn.style.left = left + 'px';\n walletBtn.style.top = top + 'px';\n this.updateIframeContentPosition();\n\n (async () => {\n let count = 0;\n do {\n count++;\n await this.sleep(20);\n this.updateIframeContentPosition();\n } while (count < 70);\n })();\n\n this.setButtonStorageData({\n x: left,\n y: top,\n direction,\n });\n\n setTimeout(() => {\n isDraggie = false;\n }, 50);\n });\n\n const controlIframe = debounce(() => {\n if (!isDraggie) {\n const iframeContent = document.querySelector('.particle-pwe-iframe-content') as HTMLDivElement;\n if (iframeContent?.classList?.contains?.('particle-pwe-iframe-content-show')) {\n this.closeWallet();\n } else {\n this.openWallet();\n }\n }\n }, 30);\n\n walletBtn.addEventListener('touchend', (event: any) => {\n setTimeout(() => {\n controlIframe();\n });\n });\n\n walletBtn.addEventListener('click', (event: any) => {\n event?.stopPropagation?.();\n setTimeout(() => {\n controlIframe();\n });\n });\n\n if (!isListen) {\n isListen = true;\n\n // @ts-ignore\n window.addEventListener('resize', window.walletEntryPlugin.resize(), false);\n window.addEventListener(\n 'message',\n (events: any) => {\n if ((window as any).walletEntryPlugin?.walletOptions?.widgetIntegration === 'embedded') {\n return;\n }\n if (events?.data?.type === 'PARTICLE_WALLET_RESIZE_IFRAME') {\n const walletEntryPlugin = (window as any).walletEntryPlugin;\n const iframeContent = document.querySelector('.particle-pwe-iframe-content') as HTMLDivElement;\n const classList = iframeContent?.classList;\n if (classList?.contains?.(fullScreenClass)) {\n if (!this._walletOptions?.visible || window.screen.width < 600) {\n walletEntryPlugin.closeWallet();\n } else {\n classList?.remove?.(fullScreenClass);\n walletEntryPlugin.resize();\n walletEntryPlugin.updateIframeContentPosition();\n }\n } else {\n classList?.add?.(fullScreenClass);\n }\n } else if (events?.data?.type === 'PARTICLE_WALLET_CLOSE_IFRAME') {\n // @ts-ignore\n window.walletEntryPlugin.closeWallet();\n }\n },\n false\n );\n }\n }\n}\n", "export const isServer = () => {\n return typeof window === 'undefined';\n};\n\nexport function isNullish(x: unknown): boolean {\n return x === undefined || x === null;\n}\n", "import { isServer } from './utils';\n\ntype Env = {\n walletUrl: string;\n};\n\nclass GlobalConfig {\n /**\n * custom wallet url\n */\n #customWalletUrl: string | undefined;\n\n #devEnv: Env = {\n walletUrl: 'https://wallet-debug.particle.network',\n };\n\n #stagingEnv: Env = {\n walletUrl: 'https://wallet-staging.particle.network',\n };\n\n #productionEnv: Env = {\n walletUrl: 'https://wallet.particle.network',\n };\n\n get version() {\n // replace when build\n return 'web_' + '2.1.1';\n }\n\n get env() {\n let currentEnv = this.#productionEnv;\n\n // @ts-ignore\n if (!isServer() && window.__PARTICLE_ENVIRONMENT__ === 'development') {\n currentEnv = this.#devEnv;\n // @ts-ignore\n } else if (!isServer() && window.__PARTICLE_ENVIRONMENT__ === 'staging') {\n currentEnv = this.#stagingEnv;\n } else {\n currentEnv = this.#productionEnv;\n }\n\n if (this.#customWalletUrl) {\n currentEnv.walletUrl = this.#customWalletUrl;\n }\n\n return currentEnv;\n }\n\n updateWalletUrl(url: string) {\n if (url) {\n this.#customWalletUrl = url;\n }\n }\n}\n\nconst globalConfig = new GlobalConfig();\nexport default globalConfig;\n", "const html = `\n <button class=\"particle-pwe-btn\">\n <img class=\"particle-pwe-img particle-pwe-wallet-icon\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=\" alt=\"\" />\n <img class=\"particle-pwe-img particle-pwe-down-arrow particle-pwe-down-arrow-hide\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=\" alt=\"\" />\n </button>\n <div class=\"particle-pwe-iframe-content\">\n </div>\n`;\n\nconst walletEntryRender = () => {\n const className = 'particle-wallet-entry-container';\n const el = document.querySelector('.' + className);\n el && el.remove();\n const EL = document.createElement('div');\n EL.classList.add(className);\n EL.innerHTML = html;\n document.body.appendChild(EL);\n};\n\nexport default walletEntryRender;\n", "export const walletIconDarkBase64 =\n 'data:image/png;base64,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';\n\nexport const downArrowDarkBase64 =\n 'data:image/png;base64,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