@web3auth/no-modal
Version:
Multi chain wallet aggregator for web3Auth
133 lines (127 loc) • 5.26 kB
JavaScript
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 };