UNPKG

@web3auth/no-modal

Version:
133 lines (127 loc) 5.26 kB
import _defineProperty from '@babel/runtime/helpers/defineProperty'; import { randomId } from '@toruslabs/base-controllers'; import { THEME_MODES } from '@web3auth/auth'; import loglevel from 'loglevel'; import { NFT_CHECKOUT_BUILD_ENV, NFT_CHECKOUT_URLS, NFT_CHECKOUT_EMBED_MESSAGE_TYPES } from './enums.js'; import { getTheme, htmlToElement } from './utils.js'; // preload for iframe doesn't work https://bugs.chromium.org/p/chromium/issues/detail?id=593267 (async function preLoadIframe() { try { if (typeof document === "undefined") return; const nftCheckoutIframeHtml = document.createElement("link"); const nftCheckoutUrl = NFT_CHECKOUT_URLS.testing; // TODO: use production by default once we have it nftCheckoutIframeHtml.href = `${nftCheckoutUrl}`; nftCheckoutIframeHtml.crossOrigin = "anonymous"; nftCheckoutIframeHtml.type = "text/html"; nftCheckoutIframeHtml.rel = "prefetch"; if (nftCheckoutIframeHtml.relList && nftCheckoutIframeHtml.relList.supports) { if (nftCheckoutIframeHtml.relList.supports("prefetch")) { document.head.appendChild(nftCheckoutIframeHtml); } } } catch (error) { loglevel.warn(error); } })(); class NFTCheckoutEmbed { constructor({ modalZIndex = 99999, clientId }) { _defineProperty(this, "clientId", void 0); _defineProperty(this, "isInitialized", void 0); _defineProperty(this, "modalZIndex", void 0); _defineProperty(this, "buildEnv", void 0); _defineProperty(this, "embedNonce", randomId()); this.isInitialized = false; this.modalZIndex = modalZIndex; this.clientId = clientId; } async init(params) { if (this.isInitialized) throw new Error("Already initialized"); if (this.getIframe()) throw new Error("Already initialized NFT Checkout iframe"); const { buildEnv = NFT_CHECKOUT_BUILD_ENV.TESTING, // TODO: use production by default once we have it whiteLabel } = params || {}; this.buildEnv = buildEnv; // construct nft checkout url const nftCheckoutIframeUrl = new URL(NFT_CHECKOUT_URLS[this.buildEnv]); const hashParams = new URLSearchParams(); hashParams.append("origin", window.location.origin); nftCheckoutIframeUrl.hash = hashParams.toString(); // create iframe const colorScheme = getTheme((whiteLabel === null || whiteLabel === void 0 ? void 0 : whiteLabel.mode) || THEME_MODES.light); const nftCheckoutIframe = htmlToElement(`<iframe id="nftCheckoutIframe-${this.embedNonce}" class="nftCheckoutIframe-${this.embedNonce}" sandbox="allow-popups allow-scripts allow-same-origin allow-forms allow-modals allow-downloads allow-popups-to-escape-sandbox" src="${nftCheckoutIframeUrl.href}" style="display: none; position: fixed; top: 0; right: 0; width: 100%; height: 100%; border: none; border-radius: 0; z-index: ${this.modalZIndex.toString()}; color-scheme: ${colorScheme}" allow="clipboard-write" ></iframe>`); return new Promise((resolve, reject) => { try { window.document.body.appendChild(nftCheckoutIframe); const handleMessage = async ev => { if (ev.origin !== nftCheckoutIframeUrl.origin) return; if (ev.data.type === NFT_CHECKOUT_EMBED_MESSAGE_TYPES.SETUP_COMPLETE) { // send init params here nftCheckoutIframe.contentWindow.postMessage({ type: NFT_CHECKOUT_EMBED_MESSAGE_TYPES.INIT, clientId: this.clientId, whiteLabel }, nftCheckoutIframeUrl.origin); this.isInitialized = true; resolve(); } else if (ev.data.type === NFT_CHECKOUT_EMBED_MESSAGE_TYPES.HIDE_NFT_CHECKOUT) { this.hide(); } }; window.addEventListener("message", handleMessage); } catch (error) { reject(error); } }); } show({ receiverAddress, contractId }) { if (!this.isInitialized) throw new Error("Call init() first"); const nftCheckoutIframe = this.getIframe(); if (!nftCheckoutIframe) throw new Error("Iframe is not initialized"); // send message to iframe const nftCheckoutOrigin = new URL(NFT_CHECKOUT_URLS[this.buildEnv]).origin; nftCheckoutIframe.contentWindow.postMessage({ type: NFT_CHECKOUT_EMBED_MESSAGE_TYPES.SHOW_NFT_CHECKOUT, contractId, receiverAddress }, nftCheckoutOrigin); // show iframe nftCheckoutIframe.style.display = "block"; } hide() { if (!this.isInitialized) throw new Error("Call init() first"); const nftCheckoutIframe = this.getIframe(); if (!nftCheckoutIframe) throw new Error("Iframe is not initialized"); // hide iframe nftCheckoutIframe.style.display = "none"; } cleanup() { const nftCheckoutIframe = this.getIframe(); if (nftCheckoutIframe) nftCheckoutIframe.remove(); } getIframe() { function isElement(element) { return element instanceof Element || element instanceof Document; } const nftCheckoutIframe = window.document.getElementById(`nftCheckoutIframe-${this.embedNonce}`); if (!isElement(nftCheckoutIframe)) return null; return nftCheckoutIframe; } } export { NFTCheckoutEmbed };