// src/shared/constants.js
var PROVIDER_NAMESPACE = "xrplWallet";
var MESSAGE_SOURCE = "xrpl-wallet-extension";

// src/inpage/provider.js
function getSafeOrigin() {
  const origin = window.location.origin;
  if (origin === "file://" || origin === "null" || !origin) {
    return "*";
  }
  return origin;
}
function extractErrorMessage(error) {
  if (!error) return null;
  if (typeof error === "string") {
    return error.trim() || null;
  }
  if (error instanceof Error) {
    return error.message || error.toString() || null;
  }
  if (error && typeof error === "object") {
    const message = error.message || error.userMessage || error.error || error.engineResult || error.suggestion || error.description || error.reason;
    if (message && typeof message === "string" && message.trim()) {
      return message.trim();
    }
    try {
      const seen = /* @__PURE__ */ new WeakSet();
      const stringified = JSON.stringify(error, (key, value) => {
        if (typeof value === "object" && value !== null) {
          if (seen.has(value)) {
            return "[Circular]";
          }
          seen.add(value);
        }
        if (value === void 0) {
          return "[undefined]";
        }
        if (typeof value === "function") {
          return "[Function]";
        }
        return value;
      });
      if (stringified && stringified !== "{}" && stringified !== "[object Object]" && stringified.length > 2) {
        return stringified;
      }
    } catch (e) {
    }
    try {
      const props = [];
      for (const key in error) {
        try {
          const value = error[key];
          if (typeof value === "string" && value.trim()) {
            props.push(`${key}: ${value.trim()}`);
          } else if (typeof value === "number" || typeof value === "boolean") {
            props.push(`${key}: ${value}`);
          }
        } catch (e) {
        }
      }
      if (props.length > 0) {
        return props.join(", ");
      }
    } catch (e) {
    }
    try {
      const str = error.toString();
      if (str && str !== "[object Object]" && str !== "[object Error]" && str.length > 10) {
        return str;
      }
    } catch (e) {
    }
  }
  return null;
}
var PENDING_KEY = "__xrpl_universe_pending__";
var PENDING_BY_REQUEST_ID_KEY = "__xrpl_universe_pending_by_request_id__";
function loadPending() {
  try {
    const stored = sessionStorage.getItem(PENDING_KEY);
    if (!stored) return /* @__PURE__ */ new Map();
    const entries = JSON.parse(stored);
    return new Map(entries);
  } catch (e) {
    console.warn("[XRP Universe Provider] Failed to load pending from sessionStorage:", e);
    return /* @__PURE__ */ new Map();
  }
}
function savePending(map) {
  try {
    const entries = Array.from(map.entries()).map(([id, entry]) => [
      id,
      {
        requestId: entry.requestId || null,
        method: entry.method || null,
        origin: entry.origin || null,
        createdAt: entry.createdAt || Date.now(),
        messageId: id
      }
    ]);
    sessionStorage.setItem(PENDING_KEY, JSON.stringify(entries));
  } catch (e) {
    console.warn("[XRP Universe Provider] Failed to save pending to sessionStorage:", e);
  }
}
function loadPendingByRequestId() {
  try {
    const stored = sessionStorage.getItem(PENDING_BY_REQUEST_ID_KEY);
    if (!stored) return /* @__PURE__ */ new Map();
    const entries = JSON.parse(stored);
    return new Map(entries);
  } catch (e) {
    console.warn("[XRP Universe Provider] Failed to load pendingByRequestId from sessionStorage:", e);
    return /* @__PURE__ */ new Map();
  }
}
function savePendingByRequestId(map) {
  try {
    sessionStorage.setItem(PENDING_BY_REQUEST_ID_KEY, JSON.stringify([...map.entries()]));
  } catch (e) {
    console.warn("[XRP Universe Provider] Failed to save pendingByRequestId to sessionStorage:", e);
  }
}
var activePromises = /* @__PURE__ */ new Map();
var pending = loadPending();
var pendingByRequestId = loadPendingByRequestId();
var listeners = /* @__PURE__ */ new Map();
function postRequest(method, params) {
  const id = crypto.randomUUID();
  const origin = getSafeOrigin();
  const payload = { source: MESSAGE_SOURCE, id, method, params };
  const promise = new Promise((resolve, reject) => {
    const timeout = setTimeout(() => {
      const active = activePromises.get(id);
      const metadata2 = pending.get(id);
      if (active && metadata2 && !metadata2.requestId) {
        cleanupRequest(id);
        reject(new Error("Request timed out. The extension may not be responding. Please reload the page."));
      } else if (active && metadata2 && metadata2.requestId) {
        console.log("[XRP Universe Provider] Timeout fired but requestId exists (request is PENDING):", {
          id,
          requestId: metadata2.requestId
        });
      } else {
        reject(new Error("Request timed out. Please reload the page."));
      }
    }, 6e4);
    activePromises.set(id, {
      resolve: (result) => {
        clearTimeout(timeout);
        cleanupRequest(id);
        resolve(result);
      },
      reject: (error) => {
        clearTimeout(timeout);
        cleanupRequest(id);
        reject(error);
      },
      timeout
    });
    const metadata = {
      requestId: null,
      // Will be set when PENDING response arrives
      method,
      origin,
      createdAt: Date.now(),
      messageId: id
    };
    pending.set(id, metadata);
    savePending(pending);
    window.postMessage(payload, getSafeOrigin());
  });
  return promise;
}
function cleanupRequest(id) {
  const metadata = pending.get(id);
  if (metadata?.requestId) {
    pendingByRequestId.delete(metadata.requestId);
    savePendingByRequestId(pendingByRequestId);
  }
  pending.delete(id);
  savePending(pending);
  activePromises.delete(id);
}
window.addEventListener("message", (event) => {
  if (event.source !== window) {
    return;
  }
  const message = event.data;
  if (message && message.source === MESSAGE_SOURCE && message.event) {
    const handlers = listeners.get(message.event) || [];
    handlers.forEach((handler) => handler(message.data));
    return;
  }
  if (message && message.source === MESSAGE_SOURCE && message.id) {
    const syncMetadata = pending.get(message.id);
    const isSyncRequest = syncMetadata && syncMetadata.method === "provider.syncPending";
    const hasPendingRequests = message.response && message.response.result && Array.isArray(message.response.result.pendingRequests);
    if (isSyncRequest || hasPendingRequests) {
      const pendingRequests = message.response?.result?.pendingRequests || [];
      console.log("[XRP Universe Provider] Received sync response:", {
        id: message.id,
        pendingRequestsCount: pendingRequests.length,
        ok: message.response?.ok,
        isSyncRequest: !!isSyncRequest
      });
      if (pendingRequests.length > 0) {
        for (const request of pendingRequests) {
          const { requestId: requestId2, messageId, method, createdAt } = request;
          if (pendingByRequestId.has(requestId2)) {
            continue;
          }
          const metadata2 = {
            requestId: requestId2,
            method,
            origin: window.location.origin,
            createdAt: createdAt || Date.now(),
            messageId: messageId || null
          };
          const id = messageId || crypto.randomUUID();
          pending.set(id, metadata2);
          pendingByRequestId.set(requestId2, id);
          console.log("[XRP Universe Provider] Recovered pending request from sync:", {
            id,
            requestId: requestId2,
            method
          });
        }
        savePending(pending);
        savePendingByRequestId(pendingByRequestId);
      }
      const syncActive = activePromises.get(message.id);
      if (syncActive) {
        cleanupRequest(message.id);
        if (message.response && message.response.ok) {
          syncActive.resolve({ pendingRequests });
        } else {
          syncActive.reject(new Error(message.response?.error || "Sync failed"));
        }
      }
      return;
    }
  }
  if (!message || message.source !== MESSAGE_SOURCE) {
    return;
  }
  if ((message.type === "CONNECT_RESULT" || message.type === "SIGN_SUBMIT_RESULT") && message.requestId) {
    const mappedId = pendingByRequestId.get(message.requestId);
    if (!mappedId) {
      const methodName = message.type === "CONNECT_RESULT" ? "provider.connect" : "provider.signAndSubmit";
      console.warn(`[XRP Universe Provider] Received ${message.type} for unknown requestId:`, {
        requestId: message.requestId,
        originalMessageId: message.id,
        type: message.type
      });
      const staleId = crypto.randomUUID();
      const staleMetadata = {
        requestId: message.requestId,
        method: methodName,
        origin: window.location.origin,
        createdAt: Date.now(),
        messageId: staleId,
        staleResult: message.ok ? { ok: true, result: message.result } : { ok: false, error: message.error }
      };
      pending.set(staleId, staleMetadata);
      pendingByRequestId.set(message.requestId, staleId);
      savePending(pending);
      savePendingByRequestId(pendingByRequestId);
      console.log(`[XRP Universe Provider] Stored stale ${message.type} for future call:`, {
        requestId: message.requestId,
        type: message.type
      });
      return;
    }
    const mappedMetadata = pending.get(mappedId);
    const mappedActive = activePromises.get(mappedId);
    if (!mappedActive) {
      console.warn(`[XRP Universe Provider] Received ${message.type} but no active promise, storing result:`, {
        requestId: message.requestId,
        mappedId,
        type: message.type
      });
      if (mappedMetadata) {
        mappedMetadata.staleResult = message.ok ? { ok: true, result: message.result } : { ok: false, error: message.error };
        savePending(pending);
      }
      if (message.type === "SIGN_SUBMIT_RESULT") {
        cleanupRequest(mappedId);
      }
      return;
    }
    console.log(`[XRP Universe Provider] Received ${message.type}, resolving promise:`, {
      requestId: message.requestId,
      mappedId,
      ok: message.ok,
      type: message.type,
      hasError: !!message.error,
      error: message.error,
      hasResult: !!message.result,
      resultKeys: message.result ? Object.keys(message.result) : [],
      fullMessage: JSON.stringify(message, null, 2)
    });
    cleanupRequest(mappedId);
    if (message.ok) {
      const result = message.result;
      if (result && typeof result === "object") {
        if (result.state === "failed" || result.state === "expired") {
          const errorMessage = extractErrorMessage(result.userMessage) || extractErrorMessage(result.error) || (message.type === "CONNECT_RESULT" ? "Connection failed" : "Transaction failed. Try again.");
          mappedActive.reject(new Error(errorMessage));
          return;
        }
      }
      mappedActive.resolve(message.result);
    } else {
      let errorMessage = extractErrorMessage(message.error);
      if (!errorMessage && message.result && typeof message.result === "object") {
        errorMessage = extractErrorMessage(message.result.error) || extractErrorMessage(message.result.userMessage) || extractErrorMessage(message.result.message);
      }
      if (!errorMessage) {
        errorMessage = message.type === "CONNECT_RESULT" ? "Connection failed" : "Transaction failed. Try again.";
      }
      console.error(`[XRP Universe Provider] ${message.type} failed:`, {
        requestId: message.requestId,
        error: errorMessage,
        hasMessageError: !!message.error,
        errorType: typeof message.error,
        hasResultError: !!(message.result && message.result.error)
      });
      mappedActive.reject(new Error(errorMessage));
    }
    return;
  }
  if (!message.id || typeof message.id !== "string") {
    console.warn("[XRP Universe Provider] Received message with invalid or missing id:", {
      hasMessage: !!message,
      idType: typeof message.id,
      idValue: message.id,
      hasResponse: !!message.response,
      messageType: message.type,
      messageKeys: message ? Object.keys(message) : []
    });
    return;
  }
  if (!message.response && !message.event) {
    return;
  }
  const isPendingResponse = message.response && message.response.ok && (message.response.result?.pending || message.response.result?.status === "PENDING");
  const requestId = message.response?.result?.requestId;
  const metadata = pending.get(message.id);
  const active = activePromises.get(message.id);
  if (message.response) {
    console.log("[XRP Universe Provider] Received message response:", {
      id: message.id,
      ok: message.response?.ok,
      hasPending: !!message.response?.result?.pending,
      status: message.response?.result?.status,
      hasRequestId: !!requestId,
      requestId,
      hasMetadata: !!metadata,
      hasActive: !!active,
      isPendingResponse
    });
  }
  if (isPendingResponse && requestId) {
    if (!metadata) {
      console.warn("[XRP Universe Provider] Received PENDING response but metadata not found, creating entry:", {
        id: message.id,
        requestId,
        status: message.response.result?.status
      });
      const existingId = pendingByRequestId.get(requestId);
      if (existingId && pending.has(existingId)) {
        const existingMetadata = pending.get(existingId);
        existingMetadata.requestId = requestId;
        pendingByRequestId.set(requestId, existingId);
        savePending(pending);
        savePendingByRequestId(pendingByRequestId);
        const existingActive = activePromises.get(existingId);
        if (existingActive) {
          console.log("[XRP Universe Provider] Found existing active promise for requestId:", requestId);
          return;
        }
      }
      const newMetadata = {
        requestId,
        method: null,
        // Unknown method - we'll infer from context
        origin: window.location.origin,
        createdAt: Date.now(),
        messageId: message.id
      };
      pending.set(message.id, newMetadata);
      pendingByRequestId.set(requestId, message.id);
      savePending(pending);
      savePendingByRequestId(pendingByRequestId);
      if (active) {
        console.log("[XRP Universe Provider] PENDING response received, keeping promise pending:", {
          id: message.id,
          requestId
        });
        return;
      }
      return;
    }
    metadata.requestId = requestId;
    pendingByRequestId.set(requestId, message.id);
    savePending(pending);
    savePendingByRequestId(pendingByRequestId);
    console.log("[XRP Universe Provider] Received PENDING response, stored requestId:", {
      id: message.id,
      requestId,
      status: message.response.result?.status
    });
    return;
  }
  if (!metadata) {
    if (requestId) {
      const mappedId = pendingByRequestId.get(requestId);
      if (mappedId) {
        const mappedMetadata = pending.get(mappedId);
        const mappedActive = activePromises.get(mappedId);
        if (mappedActive) {
          console.log("[XRP Universe Provider] Found entry by requestId for response:", {
            id: mappedId,
            requestId,
            originalMessageId: message.id
          });
          cleanupRequest(mappedId);
          if (message.response && message.response.ok) {
            mappedActive.resolve(message.response.result);
          } else {
            const errorMessage = message.response?.error || message.response?.result?.error || "Request failed";
            mappedActive.reject(new Error(errorMessage));
          }
          return;
        }
      }
    }
    const directActive = activePromises.get(message.id);
    if (directActive) {
      console.log("[XRP Universe Provider] Found active promise without metadata (likely after reinjection):", {
        id: message.id
      });
      activePromises.delete(message.id);
      if (message.response && message.response.ok) {
        directActive.resolve(message.response.result);
      } else {
        const errorMessage = message.response?.error || message.response?.result?.error || "Request failed";
        directActive.reject(new Error(errorMessage));
      }
      return;
    }
    if (message.response && !message.response.ok) {
      const safeId = typeof message.id === "string" ? message.id : message.id ? JSON.stringify(message.id) : "undefined";
      console.warn("[XRP Universe Provider] Received error response for unknown request ID:", {
        id: safeId,
        idType: typeof message.id,
        requestId,
        error: message.response?.error,
        pendingMapSize: pending.size,
        pendingIds: Array.from(pending.keys()).slice(0, 10),
        pendingByRequestIdSize: pendingByRequestId.size
      });
    } else if (message.response && message.response.ok) {
      console.warn("[XRP Universe Provider] Received success response for unknown request ID:", {
        id: message.id,
        requestId
      });
    }
    return;
  }
  if (!active) {
    console.warn("[XRP Universe Provider] Received response but no active promise:", {
      id: message.id,
      requestId: metadata.requestId
    });
    cleanupRequest(message.id);
    return;
  }
  cleanupRequest(message.id);
  if (message.response && message.response.ok) {
    active.resolve(message.response.result);
  } else {
    let errorMessage = "Unknown error";
    if (message.response) {
      if (typeof message.response === "string") {
        errorMessage = message.response;
      } else if (message.response.error) {
        errorMessage = message.response.error;
      } else if (message.response.message) {
        errorMessage = message.response.message;
      } else if (!message.response.ok && message.response.result) {
        errorMessage = typeof message.response.result === "string" ? message.response.result : message.response.result?.error || message.response.result?.message || "Unknown error";
      }
    } else if (message.error) {
      errorMessage = typeof message.error === "string" ? message.error : message.error.message || "Unknown error";
    } else if (!message.response) {
      errorMessage = "No response from extension. The extension may not be installed, or the page may need to be reloaded.";
    }
    console.error("[XRP Universe Provider] Request error:", {
      id: message.id,
      error: errorMessage,
      hasResponse: !!message.response
    });
    active.reject(new Error(errorMessage));
  }
});
async function syncPendingRequests() {
  try {
    const origin = window.location.origin;
    const syncPayload = {
      source: MESSAGE_SOURCE,
      id: crypto.randomUUID(),
      method: "provider.syncPending",
      params: { origin }
    };
    window.postMessage(syncPayload, getSafeOrigin());
    console.log("[XRP Universe Provider] Requested sync of pending requests for origin:", origin);
  } catch (e) {
    console.warn("[XRP Universe Provider] Failed to sync pending requests:", e);
  }
}
async function checkStaleConnectResult() {
  for (const [id, metadata] of pending.entries()) {
    if (metadata.method === "provider.connect" && metadata.staleResult) {
      const result = metadata.staleResult;
      cleanupRequest(id);
      if (result.ok) {
        return result.result;
      } else {
        throw new Error(result.error || "Connection failed");
      }
    }
  }
  return null;
}
if (!window[PROVIDER_NAMESPACE]) {
  window[PROVIDER_NAMESPACE] = {
    request({ method, params }) {
      return postRequest(method, params);
    },
    async connect() {
      const staleResult = await checkStaleConnectResult();
      if (staleResult !== null) {
        return staleResult;
      }
      return postRequest("provider.connect");
    },
    getAccounts() {
      return postRequest("provider.getAccounts");
    },
    signTx(tx) {
      return postRequest("provider.signTx", { tx });
    },
    signAndSubmit(tx) {
      return postRequest("provider.signAndSubmit", { tx });
    },
    on(event, handler) {
      const list = listeners.get(event) || [];
      list.push(handler);
      listeners.set(event, list);
    }
  };
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", syncPendingRequests);
  } else {
    setTimeout(syncPendingRequests, 100);
  }
  syncPendingRequests();
}
