"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// app/hooks/index.ts
var hooks_exports = {};
__export(hooks_exports, {
  useFarcasterFrameContext: () => useFarcasterFrameContext,
  useFarcasterIdentity: () => useFarcasterIdentity,
  useXmtpFrameContext: () => useXmtpFrameContext,
  useXmtpIdentity: () => useXmtpIdentity
});
module.exports = __toCommonJS(hooks_exports);

// app/hooks/use-farcaster-context.tsx
var import_react = require("react");

// app/constants.ts
var LOCAL_STORAGE_KEYS = {
  FARCASTER_USER: "farcasterUser",
  XMTP_SIGNER: "xmtpSigner",
  SELECTED_PROTOCOL: "selectedProtocol",
  FARCASTER_FRAME_CONTEXT: "farcasterFrameContext",
  XMTP_FRAME_CONTEXT: "xmtpFrameContext"
};

// app/hooks/use-farcaster-context.tsx
function useFarcasterFrameContext({
  fallbackContext
}) {
  const [frameContext, setFrameContext] = (0, import_react.useState)(null);
  (0, import_react.useEffect)(() => {
    const storedData = localStorage.getItem(
      LOCAL_STORAGE_KEYS.FARCASTER_FRAME_CONTEXT
    );
    if (storedData) {
      setFrameContext(JSON.parse(storedData));
    }
  }, []);
  (0, import_react.useEffect)(() => {
    if (frameContext) {
      localStorage.setItem(
        LOCAL_STORAGE_KEYS.FARCASTER_FRAME_CONTEXT,
        JSON.stringify(frameContext)
      );
    }
  }, [frameContext]);
  function resetFrameContext() {
    localStorage.removeItem(LOCAL_STORAGE_KEYS.FARCASTER_FRAME_CONTEXT);
    setFrameContext(null);
  }
  return {
    frameContext: frameContext || fallbackContext,
    setFrameContext,
    resetFrameContext
  };
}

// app/hooks/use-farcaster-identity.tsx
var import_react2 = require("react");

// app/lib/crypto.ts
var ed = __toESM(require("@noble/ed25519"), 1);
function convertKeypairToHex({
  privateKeyBytes,
  publicKeyBytes
}) {
  return {
    publicKey: "0x" + Buffer.from(publicKeyBytes).toString("hex"),
    privateKey: "0x" + Buffer.from(privateKeyBytes).toString("hex")
  };
}
async function createKeypairEDDSA() {
  const privateKeyBytes = ed.utils.randomPrivateKey();
  const publicKeyBytes = await ed.getPublicKeyAsync(privateKeyBytes);
  return {
    privateKeyBytes,
    publicKeyBytes
  };
}

// app/hooks/use-farcaster-identity.tsx
var import_render = require("@frames.js/render");
function useFarcasterIdentity() {
  const [isLoading, setLoading] = (0, import_react2.useState)(false);
  const [farcasterUser, setFarcasterSigner] = (0, import_react2.useState)(
    getSignerFromLocalStorage()
  );
  async function impersonateUser({ fid }) {
    const keypair = await createKeypairEDDSA();
    const { privateKey, publicKey } = convertKeypairToHex(keypair);
    const signer = {
      status: "impersonating",
      fid,
      // signature: "1",
      // is ignored for non pending
      // deadline: new Date().getTime(),
      privateKey,
      publicKey
    };
    localStorage.setItem(
      LOCAL_STORAGE_KEYS.FARCASTER_USER,
      JSON.stringify(signer)
    );
    setFarcasterSigner(signer);
  }
  function getSignerFromLocalStorage() {
    if (typeof window !== "undefined") {
      const storedData = localStorage.getItem(
        LOCAL_STORAGE_KEYS.FARCASTER_USER
      );
      if (storedData) {
        const signer = JSON.parse(storedData);
        if (signer.status === "pending_approval") {
          if (signer.deadline && signer.deadline < Math.floor(Date.now() / 1e3)) {
            localStorage.removeItem(LOCAL_STORAGE_KEYS.FARCASTER_USER);
            return null;
          }
        }
        return signer;
      }
      return null;
    }
    return null;
  }
  (0, import_react2.useEffect)(() => {
    const signer = getSignerFromLocalStorage();
    if (signer)
      setFarcasterSigner(signer);
  }, []);
  function logout() {
    localStorage.setItem(LOCAL_STORAGE_KEYS.FARCASTER_USER, "");
    setFarcasterSigner(null);
  }
  (0, import_react2.useEffect)(() => {
    if (farcasterUser && farcasterUser.status === "pending_approval") {
      let intervalId;
      const startPolling = () => {
        intervalId = setInterval(async () => {
          try {
            const fcSignerRequestResponse = await fetch(
              `https://api.warpcast.com/v2/signed-key-request?token=${farcasterUser.token}`,
              {
                method: "GET",
                headers: {
                  "Content-Type": "application/json"
                }
              }
            );
            const responseBody = await fcSignerRequestResponse.json();
            if (responseBody.result.signedKeyRequest.state !== "completed") {
              throw new Error("hasnt succeeded yet");
            }
            const user = {
              ...farcasterUser,
              ...responseBody.result,
              fid: responseBody.result.signedKeyRequest.userFid,
              status: "approved"
            };
            localStorage.setItem(
              LOCAL_STORAGE_KEYS.FARCASTER_USER,
              JSON.stringify(user)
            );
            setFarcasterSigner(user);
            clearInterval(intervalId);
          } catch (error) {
            console.info(error);
          }
        }, 2e3);
      };
      const stopPolling = () => {
        clearInterval(intervalId);
      };
      const handleVisibilityChange = () => {
        if (document.hidden) {
          stopPolling();
        } else {
          startPolling();
        }
      };
      document.addEventListener("visibilitychange", handleVisibilityChange);
      startPolling();
      return () => {
        document.removeEventListener(
          "visibilitychange",
          handleVisibilityChange
        );
        clearInterval(intervalId);
      };
    }
  }, [farcasterUser]);
  async function onSignerlessFramePress() {
    setLoading(true);
    await createAndStoreSigner();
    setLoading(false);
  }
  async function createAndStoreSigner() {
    try {
      const keypair = await createKeypairEDDSA();
      const keypairString = convertKeypairToHex(keypair);
      const authorizationResponse = await fetch(`/signer`, {
        method: "POST",
        body: JSON.stringify({
          publicKey: keypairString.publicKey
        })
      });
      const authorizationBody = await authorizationResponse.json();
      if (authorizationResponse.status === 200) {
        const { signature, requestFid, deadline } = authorizationBody;
        const {
          result: { signedKeyRequest }
        } = await (await fetch(`https://api.warpcast.com/v2/signed-key-requests`, {
          method: "POST",
          headers: {
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            key: keypairString.publicKey,
            signature,
            requestFid,
            deadline
          })
        })).json();
        const signer = {
          ...authorizationBody,
          publicKey: keypairString.publicKey,
          deadline,
          token: signedKeyRequest.token,
          signerApprovalUrl: signedKeyRequest.deeplinkUrl,
          privateKey: keypairString.privateKey,
          status: "pending_approval"
        };
        localStorage.setItem(
          LOCAL_STORAGE_KEYS.FARCASTER_USER,
          JSON.stringify(signer)
        );
        setFarcasterSigner(signer);
      } else if (authorizationBody.code === 1) {
        window.alert(
          authorizationBody.message
        );
      }
    } catch (error) {
      console.error("frames.js: API Call failed", error);
    }
  }
  return {
    signer: farcasterUser,
    hasSigner: !!farcasterUser?.fid && !!farcasterUser.privateKey,
    signFrameAction: import_render.signFrameAction,
    isLoading: null,
    isLoadingSigner: isLoading,
    impersonateUser,
    onSignerlessFramePress,
    logout
  };
}

// app/hooks/use-xmtp-identity.tsx
var import_rainbowkit = require("@rainbow-me/rainbowkit");
var import_frames_client = require("@xmtp/frames-client");
var import_xmtp_js = require("@xmtp/xmtp-js");
var import_react3 = require("react");
var import_viem = require("viem");
var import_wagmi = require("wagmi");
var import_actions = require("wagmi/actions");
function useXmtpIdentity() {
  const [isLoading, setLoading] = (0, import_react3.useState)(false);
  const [xmtpSigner, setXmtpSigner] = (0, import_react3.useState)(null);
  const [xmtpClient, setXmtpClient] = (0, import_react3.useState)(null);
  const config = (0, import_wagmi.useConfig)();
  const connect = (0, import_rainbowkit.useConnectModal)();
  const { address } = (0, import_wagmi.useAccount)();
  const walletSigner = (0, import_react3.useMemo)(
    () => address ? {
      getAddress() {
        return Promise.resolve(address);
      },
      signMessage(message) {
        return (0, import_actions.signMessage)(config, {
          message: {
            raw: typeof message === "string" ? Buffer.from(message) : Buffer.from(message)
          }
        });
      }
    } : null,
    [address, config]
  );
  function getSignerFromLocalStorage() {
    if (typeof window !== "undefined") {
      const storedData = localStorage.getItem(LOCAL_STORAGE_KEYS.XMTP_SIGNER);
      if (storedData) {
        const signerRaw = JSON.parse(storedData);
        const signer = {
          walletAddress: signerRaw.walletAddress,
          keys: Buffer.from(signerRaw.keys, "hex")
        };
        return signer;
      }
      return null;
    }
    return null;
  }
  (0, import_react3.useEffect)(() => {
    const signer = getSignerFromLocalStorage();
    if (signer)
      setXmtpSigner(signer);
  }, []);
  (0, import_react3.useEffect)(() => {
    if (xmtpSigner) {
      import_xmtp_js.Client.create(null, {
        privateKeyOverride: xmtpSigner.keys
      }).then((client) => setXmtpClient(client));
    }
  }, [xmtpSigner]);
  function logout() {
    localStorage.removeItem(LOCAL_STORAGE_KEYS.XMTP_SIGNER);
    setXmtpSigner(null);
  }
  async function onSignerlessFramePress() {
    setLoading(true);
    await createAndStoreSigner();
    setLoading(false);
  }
  async function createAndStoreSigner() {
    try {
      if (!xmtpSigner) {
        if (!walletSigner) {
          connect.openConnectModal?.();
          return;
        }
        import_xmtp_js.Client.getKeys(walletSigner, {
          env: "dev",
          skipContactPublishing: true,
          persistConversations: false
        }).then((keys) => {
          const walletAddress = (0, import_actions.getAccount)(config).address || import_viem.zeroAddress;
          localStorage.setItem(
            LOCAL_STORAGE_KEYS.XMTP_SIGNER,
            JSON.stringify({
              walletAddress,
              keys: Buffer.from(keys).toString("hex")
            })
          );
          setXmtpSigner({
            keys,
            walletAddress
          });
        });
      }
    } catch (error) {
      console.error("frames.js: API Call failed", error);
    }
  }
  return {
    signer: xmtpSigner,
    hasSigner: !!xmtpSigner?.keys,
    async signFrameAction(actionContext) {
      if (!xmtpClient) {
        throw new Error("No xmtp client");
      }
      if (!address) {
        throw new Error("No address");
      }
      const framesClient = new import_frames_client.FramesClient(xmtpClient);
      const payload = await framesClient.signFrameAction({
        frameUrl: actionContext.url,
        inputText: actionContext.inputText,
        state: actionContext.state,
        buttonIndex: actionContext.buttonIndex,
        conversationTopic: actionContext.frameContext.conversationTopic,
        participantAccountAddresses: actionContext.frameContext.participantAccountAddresses,
        ...actionContext.frameContext.groupId ? { groupId: actionContext.frameContext.groupId } : {},
        ...actionContext.frameContext.groupSecret ? { groupSecret: actionContext.frameContext.groupSecret } : {}
      });
      const searchParams = new URLSearchParams({
        postType: actionContext.transactionId ? "post" : actionContext.frameButton.action,
        postUrl: actionContext.frameButton.target ?? ""
      });
      return {
        body: payload,
        searchParams
      };
    },
    isLoading: null,
    isLoadingSigner: isLoading,
    onSignerlessFramePress,
    logout
  };
}

// app/hooks/use-xmtp-context.tsx
var import_react4 = require("react");
function useXmtpFrameContext({
  fallbackContext
}) {
  const [frameContext, setFrameContext] = (0, import_react4.useState)(
    null
  );
  (0, import_react4.useEffect)(() => {
    const storedData = localStorage.getItem(
      LOCAL_STORAGE_KEYS.XMTP_FRAME_CONTEXT
    );
    if (storedData) {
      setFrameContext(JSON.parse(storedData));
    }
  }, []);
  (0, import_react4.useEffect)(() => {
    if (frameContext) {
      localStorage.setItem(
        LOCAL_STORAGE_KEYS.XMTP_FRAME_CONTEXT,
        JSON.stringify(frameContext)
      );
    }
  }, [frameContext]);
  function resetFrameContext() {
    localStorage.removeItem(LOCAL_STORAGE_KEYS.XMTP_FRAME_CONTEXT);
    setFrameContext(null);
  }
  return {
    frameContext: frameContext || fallbackContext,
    setFrameContext,
    resetFrameContext
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  useFarcasterFrameContext,
  useFarcasterIdentity,
  useXmtpFrameContext,
  useXmtpIdentity
});
