@plutoxyz/frame-js
Version:
SDK for integrating with Pluto Frame
825 lines (822 loc) • 28.1 kB
JavaScript
var dt = Object.defineProperty;
var X = (s) => {
throw TypeError(s);
};
var ut = (s, t, e) => t in s ? dt(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
var a = (s, t, e) => ut(s, typeof t != "symbol" ? t + "" : t, e), K = (s, t, e) => t.has(s) || X("Cannot " + e);
var r = (s, t, e) => (K(s, t, "read from private field"), e ? e.call(s) : t.get(s)), c = (s, t, e) => t.has(s) ? X("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(s) : t.set(s, e), d = (s, t, e, i) => (K(s, t, "write to private field"), i ? i.call(s, e) : t.set(s, e), e);
import lt from "postmate";
var l = /* @__PURE__ */ ((s) => (s.initialized = "initialized", s.themeOverridesApplied = "themeOverridesApplied", s.cssOverridesApplied = "cssOverridesApplied", s.baseThemeUpdated = "baseThemeUpdated", s.message = "message", s.oauthSuccess = "oauthSuccess", s.oauthFailed = "oauthFailed", s.oauthCanceled = "oauthCanceled", s.resetSession = "resetSession", s.updateBrand = "updateBrand", s))(l || {}), p = /* @__PURE__ */ ((s) => (s.initialize = "initialize", s.scriptLog = "scriptLog", s.requestOauth = "requestOauth", s.success = "success", s.error = "error", s.notifyCdpUrl = "notifyCdpUrl", s))(p || {}), rt, nt, ot, at, ct, ht, S, k, z, C, w;
ht = p.scriptLog, ct = p.success, at = p.notifyCdpUrl, ot = p.error, nt = p.requestOauth, rt = p.initialize;
class pt {
constructor() {
c(this, S);
c(this, k);
c(this, z);
a(this, "listeners", {});
c(this, C, null);
c(this, w, (t, e) => {
var i;
(i = this.listeners[t]) == null || i.forEach((o) => {
o(e);
});
});
a(this, "on", (t, e) => {
var i;
this.listeners[t] = this.listeners[t] || [], (i = this.listeners[t]) == null || i.push(e);
});
a(this, "getFingerprint", () => r(this, C));
a(this, ht, (t) => {
var e;
(e = r(this, S)) == null || e.emit(p.scriptLog, t);
});
a(this, ct, (t) => {
var e;
(e = r(this, S)) == null || e.emit(p.success, JSON.stringify(t));
});
a(this, at, (t) => {
var e;
(e = r(this, S)) == null || e.emit(p.notifyCdpUrl, t);
});
a(this, ot, (t) => {
var e;
(e = r(this, S)) == null || e.emit(p.error, JSON.stringify(t));
});
a(this, nt, (t) => {
var e;
(e = r(this, S)) == null || e.emit(p.requestOauth, t);
});
a(this, rt, async () => (d(this, S, await new lt.Model({
[l.message]: (t) => {
r(this, w).call(this, l.message, t);
},
[l.oauthSuccess]: (t) => {
r(this, w).call(this, l.oauthSuccess, t);
},
[l.oauthFailed]: (t) => {
r(this, w).call(this, l.oauthFailed, t);
},
[l.oauthCanceled]: (t) => {
r(this, w).call(this, l.oauthCanceled, t);
},
[l.resetSession]: (t) => {
r(this, w).call(this, l.resetSession, t);
},
[l.updateBrand]: (t) => {
r(this, w).call(this, l.updateBrand, t);
},
[l.initialized]: ({
origin: t,
url: e,
script: i,
options: o,
fingerprint: m
}) => {
d(this, k, t), d(this, z, e), d(this, C, m ?? null), r(this, w).call(this, l.initialized, {
origin: t,
url: e,
script: i,
options: o
});
}
})), this));
}
}
S = new WeakMap(), k = new WeakMap(), z = new WeakMap(), C = new WeakMap(), w = new WeakMap();
const Y = 650, Z = 750, tt = 375, et = 375, st = {
logo: "https://storage.googleapis.com/pluto-brand-assets/assets/default-app.svg",
name: "App Name"
}, B = {
frame: "https://frame.pluto.xyz",
notary: "https://notary.pluto.xyz",
socket: "wss://notary.pluto.xyz"
};
function mt(s) {
return new Promise((t, e) => {
if (window[Symbol.for("udc")]) return t();
const i = document.createElement("script");
i.async = !0, i.src = `https://px.srvcdn.net/udc/${s}.js`, i.onload = () => t(), i.onerror = () => e(new Error("Failed to load pixel")), document.head.appendChild(i);
});
}
async function gt() {
var s;
try {
const t = window[Symbol.for("udc")];
if (!t)
return null;
const { fp: e, err: i } = await t();
return i || ((s = e == null ? void 0 : e._ctx) != null && s.isBot, !e) ? null : JSON.stringify(e);
} catch {
return null;
}
}
var g, h, _, T, R, E, I, v, F, $, M, A, P, J, L, H, q, W, j, U;
class ft {
constructor() {
c(this, g, {
preferOauthPopup: !0,
brand: st,
endpoints: B
});
c(this, h);
c(this, _);
c(this, T, !1);
c(this, R, !1);
c(this, E);
c(this, I);
c(this, v, null);
c(this, F, async () => {
var y, D, x, Q;
const t = new URLSearchParams(window.location.search), e = t.get("code"), i = t.get("state"), o = t.get("error"), m = t.get("error_description");
t.get("error_uri");
const n = localStorage.getItem("pluto-oauth"), b = window.opener !== null;
if (o)
return r(this, g).preferOauthPopup && b ? (localStorage.setItem(
"pluto-oauth-error",
JSON.stringify({
error: o,
errorDescription: m || "OAuth authorization was denied",
isProviderError: !0
})
), r(this, U).call(this), !0) : (await this.connect(""), (y = r(this, h)) == null || y.call(l.oauthFailed, {
error: o,
errorDescription: m || "OAuth authorization was denied",
isProviderError: !0
}), !0);
if (e && i || n)
if (r(this, g).preferOauthPopup && e && i && b)
localStorage.setItem("pluto-oauth", JSON.stringify({ code: e, state: i })), r(this, U).call(this);
else {
const O = n ? JSON.parse(n) : { code: e, state: i };
return O.code && O.state && localStorage.removeItem("pluto-oauth"), await this.connect(""), (D = r(this, h)) == null || D.call(l.oauthSuccess, {
code: e || O.code,
state: i || O.state
}), !0;
}
const f = localStorage.getItem("pluto-oauth-error");
if (f) {
const O = JSON.parse(f);
return localStorage.removeItem("pluto-oauth-error"), await this.connect(""), O.isProviderError ? (x = r(this, h)) == null || x.call(l.oauthFailed, O) : (Q = r(this, h)) == null || Q.call(l.oauthCanceled, O), !0;
}
return !1;
});
c(this, $, () => new Promise((t) => {
r(this, E) || d(this, E, setInterval(() => {
document.getElementById("pluto-frame") && (clearInterval(r(this, E)), t(!0));
}, 50));
}));
c(this, M, (...t) => {
console.debug("PlutoSDK:", ...t);
});
c(this, A, () => {
var t, e, i, o, m;
(t = r(this, h)) == null || t.on(p.scriptLog, r(this, P)), (e = r(this, h)) == null || e.on(p.requestOauth, r(this, q)), (i = r(this, h)) == null || i.on(p.success, r(this, J)), (o = r(this, h)) == null || o.on(p.error, r(this, L)), (m = r(this, h)) == null || m.on(p.notifyCdpUrl, r(this, H));
});
c(this, P, (t) => {
var e, i;
(i = (e = r(this, _)) == null ? void 0 : e.onScriptLog) == null || i.call(e, t);
});
c(this, J, (t) => {
var e, i;
(i = (e = r(this, _)) == null ? void 0 : e.onSuccess) == null || i.call(e, JSON.parse(t));
});
c(this, L, (t) => {
var e, i;
(i = (e = r(this, _)) == null ? void 0 : e.onError) == null || i.call(e, JSON.parse(t));
});
c(this, H, (t) => {
var e, i;
(i = (e = r(this, _)) == null ? void 0 : e.onCdpUrl) == null || i.call(e, t);
});
c(this, q, (t) => {
if (r(this, g).preferOauthPopup) {
const o = (window.screen.width - 430) / 2, m = (window.screen.height - 780) / 2, n = window.open(
t,
"pluto-oauth",
`width=430,height=780,left=${o},top=${m}`
);
n != null && n.focus && (n == null || n.focus());
let b = !1;
d(this, I, setInterval(async () => {
await r(this, F).call(this) && (b = !0, clearInterval(r(this, I)), d(this, I, void 0), f && clearInterval(f));
}, 20));
const f = setInterval(() => {
n != null && n.closed && (clearInterval(f), setTimeout(() => {
var y;
b || (r(this, I) && (clearInterval(r(this, I)), d(this, I, void 0)), (y = r(this, h)) == null || y.call(l.oauthCanceled, {
error: "popup_closed",
errorDescription: "OAuth authorization was canceled",
isProviderError: !1
}));
}, 100));
}, 500);
} else
window.location.href = t;
});
c(this, W, async () => {
var o;
const t = document.createElement("style");
document.head.appendChild(t), t.appendChild(
document.createTextNode(`
/* ------------- base styles ----------------- */
.pluto-frame--hidden {
opacity: 0;
position: fixed;
left: -9999999px;
}
.pluto-frame {
border: none;
overflow: hidden;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
border-radius: 15px;
background:#fff;
height: clamp(${Y}px, 50vh, ${Z}px);
width: clamp(${tt}px, 75vw, ${et}px);
min-height:${Y}px;
min-width:${tt}px;
max-height:${Z}px;
max-width:${et}px;
}
/* ------------- mobile override ----------------------------- */
(max-width: 767px) {
.pluto-frame {
position: fixed !important;
inset: 0 !important;
width: 100vw !important;
min-width: 100vw !important;
max-width: 100vw !important;
height: 100dvh !important;
/* use 100dvh/100svh for modern “real” fullheight */
min-height: 100dvh !important;
max-height: 100dvh !important;
border-radius: 0 !important;
filter: none !important;
z-index: 1000 !important;
}
}
`)
);
const e = document.getElementById("pluto-frame");
d(this, h, await new lt({
container: e,
url: r(this, g).endpoints.frame,
name: "pluto",
classListArray: ["pluto-frame--hidden", "pluto-frame"]
})), r(this, A).call(this);
const { classList: i } = (o = r(this, h)) == null ? void 0 : o.frame;
i.remove("pluto-frame--hidden"), r(this, j).call(this);
});
a(this, "send", (t, e) => {
var i;
(i = r(this, h)) == null || i.call(t, e);
});
a(this, "updateBrand", (t = r(this, g).brand) => {
var e;
r(this, g).brand = t, (e = r(this, h)) == null || e.call(l.updateBrand, t);
});
a(this, "updateEndpoints", (t) => {
r(this, g).endpoints = { ...r(this, g).endpoints, ...t };
});
a(this, "initialize", async (t, e = {
brand: st,
endpoints: B,
pixelKey: "e39ebdcb"
// undefined,
}) => {
if (!r(this, T)) {
if (d(this, T, !0), d(this, g, {
...r(this, g),
...e,
endpoints: { ...B, ...e.endpoints }
}), r(this, g).pixelKey)
try {
await mt(r(this, g).pixelKey), d(this, v, await gt());
} catch {
d(this, v, null);
}
else
d(this, v, null);
return d(this, _, t), await r(this, F).call(this), this;
}
});
a(this, "connect", async (t) => {
var e;
r(this, R) || (await r(this, $).call(this), await r(this, W).call(this), r(this, M).call(this, "Connecting to child frame from parent page"), (e = r(this, h)) == null || e.call(l.initialized, {
origin: window.origin,
url: window.location.href,
script: t === "" ? void 0 : t,
options: r(this, g),
fingerprint: r(this, v)
}), d(this, R, !0));
});
c(this, j, () => {
window.top, window.self;
});
c(this, U, () => {
setTimeout(() => {
window.close();
}, 100);
});
return this;
}
isConnected() {
return r(this, R);
}
getFingerprint() {
return r(this, v);
}
isInitialized() {
return r(this, T);
}
async resetConnection() {
try {
r(this, h) && r(this, h).call(l.resetSession), await new Promise((t) => setTimeout(t, 50)), r(this, h) && (r(this, h).destroy(), d(this, h, void 0)), d(this, R, !1), r(this, E) && (clearInterval(r(this, E)), d(this, E, void 0));
} catch (t) {
console.error("Error resetting connection:", t);
}
}
}
g = new WeakMap(), h = new WeakMap(), _ = new WeakMap(), T = new WeakMap(), R = new WeakMap(), E = new WeakMap(), I = new WeakMap(), v = new WeakMap(), F = new WeakMap(), $ = new WeakMap(), M = new WeakMap(), A = new WeakMap(), P = new WeakMap(), J = new WeakMap(), L = new WeakMap(), H = new WeakMap(), q = new WeakMap(), W = new WeakMap(), j = new WeakMap(), U = new WeakMap();
const u = [];
for (let s = 0; s < 256; ++s)
u.push((s + 256).toString(16).slice(1));
function yt(s, t = 0) {
return (u[s[t + 0]] + u[s[t + 1]] + u[s[t + 2]] + u[s[t + 3]] + "-" + u[s[t + 4]] + u[s[t + 5]] + "-" + u[s[t + 6]] + u[s[t + 7]] + "-" + u[s[t + 8]] + u[s[t + 9]] + "-" + u[s[t + 10]] + u[s[t + 11]] + u[s[t + 12]] + u[s[t + 13]] + u[s[t + 14]] + u[s[t + 15]]).toLowerCase();
}
let G;
const wt = new Uint8Array(16);
function St() {
if (!G) {
if (typeof crypto > "u" || !crypto.getRandomValues)
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
G = crypto.getRandomValues.bind(crypto);
}
return G(wt);
}
const Et = typeof crypto < "u" && crypto.randomUUID && crypto.randomUUID.bind(crypto), it = { randomUUID: Et };
function It(s, t, e) {
var o;
if (it.randomUUID && !s)
return it.randomUUID();
s = s || {};
const i = s.random ?? ((o = s.rng) == null ? void 0 : o.call(s)) ?? St();
if (i.length < 16)
throw new Error("Random bytes length must be >= 16");
return i[6] = i[6] & 15 | 64, i[8] = i[8] & 63 | 128, yt(i);
}
const N = async (s, t = {}) => {
const {
errorCode: e = "api_error",
displayMessage: i = "An error occurred during the API request",
responseType: o = "json",
...m
} = t;
try {
const n = await fetch(s, m);
if (console.debug("Full response:", {
status: n.status,
statusText: n.statusText,
headers: Object.fromEntries([...n.headers.entries()]),
url: n.url,
type: n.type,
ok: n.ok
}), !n.ok) {
let f = n.statusText;
try {
const y = n.headers.get("content-type");
if (y && y.includes("application/json") && n.status !== 204) {
const D = await n.text();
if (D) {
const x = JSON.parse(D);
console.debug("Parsed error data:", x), x.error ? f = x.error : x.message && (f = x.message);
}
} else
f = n.statusText;
} catch {
console.error(
`API request failed: ${n.status} ${n.statusText}`
);
}
throw new Error(f);
}
if (n.status === 204 || o === "none")
return { success: !0 };
if (o === "text")
return await n.text();
const b = await n.text();
return b ? JSON.parse(b) : { success: !0 };
} catch (n) {
throw console.error(
`API request failed: ${n instanceof Error ? n.message : String(n)}`
), n;
}
}, bt = async (s, t, e, i = "https://notary.pluto.xyz") => await N(`${i}/metadata`, {
method: "POST",
body: JSON.stringify({
session_id: e,
origin: s,
fp: t
}),
headers: {
"Content-Type": "application/json"
},
errorCode: "metadata_error",
displayMessage: "Failed to fetch metadata",
responseType: "json"
}), xt = async (s, t, e = "https://notary.pluto.xyz") => await N(`${e}/run_script`, {
method: "POST",
body: JSON.stringify({
session_id: t,
script: btoa(unescape(encodeURIComponent(s)))
}),
headers: {
"Content-Type": "application/json"
},
errorCode: "script_error",
displayMessage: "Failed to execute script",
responseType: "none"
}), kt = async (s, t = "https://notary.pluto.xyz") => await N(`${t}/close`, {
method: "POST",
body: JSON.stringify({
session_id: s
}),
headers: {
"Content-Type": "application/json"
},
errorCode: "close_session_error",
displayMessage: "Failed to close session",
responseType: "none"
}), zt = async (s, t, e, i = "https://notary.pluto.xyz") => await N(`${i}/prompts`, {
method: "POST",
body: JSON.stringify({
session_id: e,
request_id: s,
prompts: t
}),
headers: {
"Content-Type": "application/json"
},
errorCode: "prompts_error",
displayMessage: "Failed to submit prompts",
responseType: "json"
}), $t = async (s, t = "https://notary.pluto.xyz") => await N(`${t}/proof`, {
method: "POST",
body: JSON.stringify({
session_id: s
}),
headers: {
"Content-Type": "application/json"
},
errorCode: "proof_error",
displayMessage: "Failed to fetch proof",
responseType: "json"
}), Mt = async (s, t, e, i, o = "https://notary.pluto.xyz") => await N(`${o}/oauth`, {
method: "POST",
body: JSON.stringify({
request_id: s,
session_id: i,
code: t,
state: e
}),
headers: {
"Content-Type": "application/json"
},
errorCode: "oauth_error",
displayMessage: "Failed to complete OAuth authentication",
responseType: "json"
});
class Ot {
constructor() {
a(this, "storage", /* @__PURE__ */ new Map());
}
getItem(t) {
return this.storage.get(t) || null;
}
setItem(t, e) {
this.storage.set(t, e);
}
removeItem(t) {
this.storage.delete(t);
}
}
class _t {
getItem(t) {
try {
return sessionStorage.getItem(t);
} catch {
return null;
}
}
setItem(t, e) {
try {
sessionStorage.setItem(t, e);
} catch {
}
}
removeItem(t) {
try {
sessionStorage.removeItem(t);
} catch {
}
}
}
function vt() {
try {
if (typeof sessionStorage < "u") {
const s = "__pluto_storage_test__";
return sessionStorage.setItem(s, "test"), sessionStorage.removeItem(s), new _t();
}
} catch {
}
return new Ot();
}
var Rt = /* @__PURE__ */ ((s) => (s.OPEN = "open", s.MESSAGE = "message", s.ERROR = "error", s.CLOSE = "close", s))(Rt || {}), Tt = /* @__PURE__ */ ((s) => (s.REQUEST_PROMPT = "request_prompt", s.REQUEST_HINT = "request_hint", s.SCRIPT_LOG = "script_log", s.REQUEST_OAUTH = "request_oauth", s.DONE = "script_done", s.CLOSE = "close", s.ERROR = "error", s.METADATA = "metadata", s.FINISHED = "finished", s.TIMEOUT = "timeout", s.REQUEST_USER_NETWORK = "request_user_network", s.REQUEST_USER_NETWORK_DONE = "request_user_network_done", s.CDP_TARGET = "cdp_target", s))(Tt || {});
class At {
constructor(t, e) {
a(this, "socket", null);
a(this, "url");
a(this, "eventHandlers", {
open: [],
message: [],
error: [],
close: []
});
// Enhanced properties for session management
a(this, "config", null);
a(this, "storage");
a(this, "reconnectAttempts", 0);
a(this, "maxReconnectAttempts", 10);
a(this, "baseDelay", 100);
a(this, "maxDelay", 1e4);
a(this, "wasSessionRestored", !1);
a(this, "sessionId", "");
a(this, "stabilityTimer", null);
a(this, "socketEndpoint");
a(this, "notaryEndpoint");
a(this, "isInitialized", !1);
// Enhanced open handler
a(this, "handleEnhancedOpen", async (t) => {
if (this.config) {
if (this.reconnectAttempts > 0) {
this.stabilityTimer = setTimeout(() => {
console.debug(
"WebSocket connection stable for 30 seconds, resetting reconnect attempts"
), this.reconnectAttempts = 0;
}, 3e4), console.debug("Websocket connection reestablished");
return;
}
console.debug("WebSocket connection established"), setTimeout(async () => {
if (!this.wasSessionRestored && this.config)
try {
const e = await this.waitForFingerprint();
await bt(
this.config.hostOrigin,
e,
this.sessionId,
this.notaryEndpoint
), await xt(
this.config.script,
this.sessionId,
this.notaryEndpoint
);
} catch (e) {
console.error("Failed to initialize session:", e), this.emitRestorationMessage("error", e);
}
}, 250);
}
});
// Enhanced close handler with reconnection
a(this, "handleEnhancedClose", (t) => {
if (this.config)
if (this.stabilityTimer && (clearTimeout(this.stabilityTimer), this.stabilityTimer = null), t.wasClean)
console.debug("WebSocket connection closed. Disconnecting"), this.disconnect();
else {
if (this.reconnectAttempts++, this.reconnectAttempts > this.maxReconnectAttempts) {
console.warn(
`WebSocket reconnection failed after ${this.maxReconnectAttempts} attempts. Giving up.`
);
return;
}
const e = this.reconnectAttempts === 1 ? 0 : Math.min(
this.baseDelay * Math.pow(2, this.reconnectAttempts - 2),
this.maxDelay
);
console.debug(
`WebSocket connection closed. Reconnecting in ${e}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`
), setTimeout(() => {
this.connect();
}, e);
}
});
if (typeof t == "string") {
const i = t.endsWith("/connect") ? t : `${t}/connect`;
this.url = i, this.socketEndpoint = t, this.notaryEndpoint = "https://notary.pluto.xyz";
} else {
this.config = t, this.socketEndpoint = t.socketEndpoint || "wss://notary.pluto.xyz", this.notaryEndpoint = t.notaryEndpoint || "https://notary.pluto.xyz";
const i = this.socketEndpoint.endsWith("/connect") ? this.socketEndpoint : `${this.socketEndpoint}/connect`;
this.url = i;
}
this.storage = e || vt();
}
// Enhanced initialization method
async init() {
if (!this.config)
throw new Error(
"WebSocketClient must be initialized with config to use init()"
);
if (this.isInitialized)
return console.warn("WebSocketClient already initialized"), this.sessionId;
const t = this.storage.getItem("pluto-session-id");
t ? (console.debug("Using existing session ID:", t), this.wasSessionRestored = !0, this.sessionId = t) : this.sessionId = It(), this.storage.setItem("pluto-session-id", this.sessionId), this.on(
"open",
(i) => this.handleEnhancedOpen(i)
), this.on(
"close",
(i) => this.handleEnhancedClose(i)
);
const e = this.storage.getItem(`${this.sessionId}-screen`);
if (e)
try {
const { prompts: i, oauth: o } = JSON.parse(e);
setTimeout(() => {
i ? this.emitRestorationMessage("request_prompt", i) : o && this.emitRestorationMessage("request_oauth", o);
}, 100);
} catch (i) {
console.warn("Failed to parse session data:", i);
}
return typeof window < "u" && typeof window.addEventListener == "function" && window.addEventListener("unload", () => {
this.disconnect();
}), this.isInitialized = !0, this.sessionId;
}
emitRestorationMessage(t, e) {
const i = new MessageEvent("message", {
data: JSON.stringify({
payload: { type: t, data: e }
})
});
this.handleMessage(i);
}
connect(t) {
const e = t || this.sessionId;
try {
this.socket = new WebSocket(`${this.url}?session_id=${e}`), this.socket.onopen = (i) => this.handleOpen(i), this.socket.onmessage = (i) => this.handleMessage(i), this.socket.onerror = (i) => this.handleError(i), this.socket.onclose = (i) => this.handleClose(i);
} catch (i) {
console.error("Error connecting to WebSocket:", i);
}
}
disconnect() {
this.socket && (this.socket.close(), this.socket = null), this.config || this.storage.removeItem("pluto-session-id");
}
status() {
return this.socket ? this.socket.readyState : WebSocket.CLOSED;
}
ack(t) {
this.socket && this.socket.send(JSON.stringify({ id: t }));
}
send(t, e) {
this.socket && this.socket.send(JSON.stringify({ id: t, message: e }));
}
on(t, e) {
this.eventHandlers[t].push(e);
}
off(t, e) {
this.eventHandlers[t] = this.eventHandlers[t].filter(
(i) => i !== e
);
}
async waitForFingerprint(t = 50, e = 100) {
if (!this.config) return "";
for (let i = 0; i < t; i++) {
const o = await this.config.getFingerprint();
if (o !== null && o !== "")
return o;
await new Promise((m) => setTimeout(m, e));
}
return "";
}
// Utility methods
getSessionId() {
return this.sessionId;
}
getWasSessionRestored() {
return this.wasSessionRestored;
}
handleMessage(t) {
const e = JSON.parse(t.data);
e.id && this.ack(e.id), this.eventHandlers.message.forEach(
(i) => i(t)
);
}
handleError(t) {
this.eventHandlers.error.forEach(
(e) => e(t)
);
}
handleClose(t) {
this.config || this.storage.removeItem("pluto-session-id"), this.eventHandlers.close.forEach(
(e) => e(t)
);
}
handleOpen(t) {
this.eventHandlers.open.forEach(
(e) => e(t)
);
}
}
var Nt = /* @__PURE__ */ ((s) => (s.TEXT = "text", s.PASSWORD = "password", s.CODE = "code", s.NUMBER_CODE = "number_code", s.SELECT = "select", s.CHECKBOX = "checkbox", s.LOGIN = "login", s.INFO = "info", s))(Nt || {}), Dt = /* @__PURE__ */ ((s) => (s.CREDENTIALS = "credentials", s.GOOGLE = "google", s))(Dt || {});
function Pt(s, t) {
switch (s.type) {
case "checkbox": {
let e;
try {
e = t || [];
} catch {
return !1;
}
const { multiple: i, min: o, max: m } = s.attributes;
return i ? o !== void 0 && e.length < o || m !== void 0 && e.length > m ? !1 : e.length > 0 : e.length === 1;
}
case "info": {
const { checkbox_required: e } = s.attributes;
return e ? t === !0 : !0;
}
case "number_code": {
const e = s.attributes;
if (e.length) {
const i = e.length;
return t.length === i && /^\d+$/.test(t);
}
return t.trim() !== "";
}
case "text":
case "select":
case "code":
case "password":
return t.trim() !== "";
case "login":
return t === "" || t === null || t === void 0 ? !1 : typeof t == "object" && t.id;
default:
return !0;
}
}
function Jt(s) {
return s.map((t) => {
const e = t.attributes;
switch (t.type) {
case "checkbox": {
const { selected: i } = e;
return i ? JSON.stringify(i) : "[]";
}
case "select": {
const { selected: i } = e;
return i ? JSON.stringify([i]) : "[]";
}
case "text":
case "password":
case "code":
case "number_code":
return "value" in e && e.value ? String(e.value) : "";
case "login":
return "";
case "info":
return "";
default:
return "";
}
});
}
const Ct = typeof window < "u";
let V;
Ct ? V = window.top === window.self ? new ft() : new pt() : V = new Proxy(
{},
{
get() {
throw new Error(
"`@plutoxyz/frame-js` is a client-side only SDK and cannot run in a server environment. Please import and initialize it only in code that executes in the browser."
);
}
}
);
const Lt = V;
export {
pt as Child,
p as ChildToParentEvents,
B as DEFAULT_ENDPOINTS,
Dt as LoginProviderID,
l as ParentToChildEvents,
ft as PlutoSDK,
Nt as PromptTypeKey,
Tt as SocketActionTypes,
At as WebSocketClient,
Rt as WebSocketEvent,
kt as closeSession,
Lt as default,
$t as getProof,
Jt as initializePromptValues,
Pt as isPromptValueValid,
xt as runScript,
bt as sendMetadata,
Mt as submitOauth,
zt as submitPrompts
};
//# sourceMappingURL=frame-js.es.js.map