import { CLOUDFLARE_CDN_FOR_QRCODE, IDAPP_HOSTS } from "../core";
import concordiumLogo from "../../public/concordium_logo.svg";
import appStoreLogo from "../../public/app_store.svg";
import playStoreLogo from "../../public/play_store.svg";
export class ConcordiumIDAppPoup {
private static injectPopupStyles() {
if (document.getElementById("sdk-popup-styles")) return;
const style = document.createElement("style");
style.id = "sdk-popup-styles";
style.innerHTML = `
.authCode {
margin: 16px auto;
width: 86px;
height: 86px;
border: 2px solid #0047ab;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
font-size: 20px;
color: #0047ab;
border-radius: 100%;
border: 2.15px solid #1143A7;
background: linear-gradient(180deg, #FFF 0%, #EEE 100%);
}
.sdk-popup-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
}
.sdk-popup-box {
position: relative;
background: #fff;
border-radius: 12px;
text-align: center;
max-width: 330px;
width: 100%;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
.app-message {
padding: 1.5rem 2rem;
}
.no-app-msg{
padding: 1.5rem 2rem;
background: #F2F1F1;
border-radius: 0 0 12px 12px;
}
/* Close button */
.sdk-close-btn {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: none;
border: none;
font-size: 1.5rem;
line-height: 1;
cursor: pointer;
color: #555;
}
/* Hide both steps by default */
.sdk-step { display: block; }
/* Only show step 1 initially */
.sdk-step--1 { display: block;}
.sdk-step--2 { display: block; }
/* Logo */
.sdk-logo {
display: block;
margin: 0 auto 1rem;
max-width: 120px;
}
/* Main copy */
.sdk-copy {
color: #0D121C;
text-align: center;
font-size: 16px;
font-style: normal;
font-weight: 600;
line-height: 130%;
letter-spacing: -0.25px;
margin-bottom: 32px;
}
/* Buttons */
.sdk-btns {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin: 32px 0 0 0;
}
.sdk-btn {
width: 100%;
padding: 0.75rem 1rem;
font-size: 1rem;
font-weight: 600;
border-radius: 6px;
border: none;
cursor: pointer;
}
.sdk-btn--primary {
background-color: #004a93;
color: #fff;
}
.sdk-btn--secondary {
background-color: #fff;
color: #000;
border: 2px solid #000;
}
/* Install copy (only step 1) */
.sdk-install {
color: #0D121C;
text-align: center;
font-size: 13px;
font-style: normal;
font-weight: 600;
line-height: 130%; /* 16.9px */
letter-spacing: -0.25px;
margin: 0 0 20px 0;
}
/* Store badges */
.sdk-store-links {
display: flex;
justify-content: center;
gap: 1rem;
}
.sdk-store-links img {
height: 36px;
display: block;
}
.wc-session {
max-width: 95%;
word-wrap: break-word;
color: grey;
display: none
}
.Rtable {
display: flex;
flex-wrap: wrap;
padding: 0;
}
.Rtable-cell {
box-sizing: border-box;
flex-grow: 1;
width: 100%;
list-style: none;
background: fade(green, 20%);
text-align: center;
}
.dot {
height: 16px;
width: 16px;
background-color: #1143A7;
border-radius: 50%;
display: inline-block;
z-index: 2;
position: relative;
}
.dot-no-fill {
height: 16px;
width: 16px;
background-color: white;
border: 1px solid black;
border-radius: 50%;
display: inline-block;
z-index: 2;
position: relative;
}
.Rtable--3cols > .Rtable-cell {
width: 33.33%;
}
.Rtable {
position: relative;
}
.Rtable-cell .text {
color: rgba(13, 18, 28, 0.70);
text-align: center;
font-size: 11px;
font-style: normal;
font-weight: 500;
line-height: 120%;
}
.Rtable-cell .text.active {
color: #0D121C;
text-align: center;
font-size: 11px;
font-style: normal;
font-weight: 700;
line-height: 120%;
}
.line-no-fill {
width: 100%;
height: 1px;
display: block;
position: relative;
background: rgba(10, 12, 30, 0.2);
top: -15px;
left: 50%;
margin: 0 auto;
}
.hr-line{
margin: 16px 0;
}
`;
document.head.appendChild(style);
}
/**
* Closes the popup and removes styles.
*/
static closePopup() {
const wrapper = document.getElementById("sdk-popup-wrapper");
if (wrapper) wrapper.remove();
const style = document.getElementById("sdk-popup-styles");
if (style) style.remove();
}
/**
* Opens the ID App using a deep link.
* This method is used to redirect the user to the ID App on mobile devices or open on desktop.
* @param param0
*/
static openIdapp = ({
wallectConnectMobileUrl,
walletConnectDesktopUrl,
}: {
wallectConnectMobileUrl: string;
walletConnectDesktopUrl?: string;
}) => {
// On mobile, hand off to the native app:
if (/Android|iPhone|iPad|iPod/i.test(navigator.userAgent)) {
window.location.href = wallectConnectMobileUrl;
} else {
// Desktop fallback: show instructions or open a popup for testing
if (walletConnectDesktopUrl) {
const width = 400;
const height = 700;
const top = 0;
const left = window.screen.availWidth - width;
window.open(
walletConnectDesktopUrl,
"Idapp",
`width=${width},height=${height},top=${top},left=${left}`,
);
}
}
};
/**
* Injects the popup HTML and styles, then invokes the ID App deep link.
* This function creates a popup that prompts the user to open the ID App for account activation.
* @param param0
*/
static async invokeIdAppDeepLinkPopup({
walletConnectUri,
actionType = "create-account",
}: {
walletConnectUri: string;
actionType?: "create-account" | "generate-proof";
}) {
if (!navigator && !window) {
throw new Error(
"ConcordiumIDAppPoup.invokeIdAppDeepLinkPopup() requires a browser environment",
);
}
if (!walletConnectUri) {
throw new Error(
"ConcordiumIDAppPoup.invokeIdAppDeepLinkPopup() requires a valid walletConnectUri",
);
}
ConcordiumIDAppPoup.injectPopupStyles();
const wallectConnectMobileUrl = `${IDAPP_HOSTS.mobile}wallet-connect?encodedUri=${walletConnectUri}`;
// const walletConnectDesktopUrl = `${IDAPP_HOSTS.web}wallet-connect?encodedUri=${walletConnectUri}`;
const isGenerateProof = actionType === "generate-proof";
const lastStepText = isGenerateProof
? "Generate
Proof"
: "Create
Account";
const copyText = isGenerateProof
? "Please follow and complete the
proof generation in [ID App]."
: "Please follow and complete the
account setup in [ID App].";
const wrapper = document.createElement("div");
wrapper.id = "sdk-popup-wrapper";
wrapper.innerHTML = `