type Pending = {
  resolve: (value: unknown) => void;
  reject: (reason?: unknown) => void;
};

const pending = new Map<string, Pending>();

window.addEventListener("message", (event) => {
  if (event.source !== window || event.data?.source !== "contractless-wallet") return;
  const request = pending.get(event.data.id);
  if (!request) return;
  pending.delete(event.data.id);
  if (event.data.response?.ok) request.resolve(event.data.response.result);
  else request.reject(new Error(event.data.response?.error ?? "Wallet request failed."));
});

const provider = Object.freeze({
  isContractless: true,
  request({ method, params }: { method: string; params?: unknown }): Promise<unknown> {
    const id = crypto.randomUUID();
    return new Promise((resolve, reject) => {
      pending.set(id, { resolve, reject });
      window.postMessage(
        { source: "contractless-page", id, method, params },
        window.location.origin
      );
    });
  }
});

Object.defineProperty(window, "contractless", {
  value: provider,
  writable: false,
  configurable: false
});

