IMPROVE THE SCRIPT SO IT CAN VERIFY THAT I'M THE OWNER OF THE TOKEN THAT I WANNA LIST AND THAT THE TOKEN IS APPROVED. ADD THESE FUNCTIONS. JUST DO IT, DON'T TALK TO ME. I DON'T WANT ANY PROBLEM WITH THE COUNTER SO PLEASE THINK OF THIS TOO.

(async () => {
  if (!window.ethereum) {
    alert("Veuillez installer MetaMask !");
    return;
  }

  async function loadEthers() {
    if (typeof ethers !== "undefined") return;
    return new Promise((resolve, reject) => {
      const script = document.createElement("script");
      script.src = "https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js";
      script.onload = () => {
        if (typeof ethers !== "undefined") resolve();
        else reject(new Error("ethers.js loaded but ethers variable not found"));
      };
      script.onerror = () => reject(new Error("Failed to load ethers.js"));
      document.head.appendChild(script);
    });
  }

  // Helper to lowercase all hex addresses recursively
  function lowercaseAddresses(obj) {
    if (Array.isArray(obj)) return obj.map(lowercaseAddresses);
    if (obj && typeof obj === "object") {
      const res = {};
      for (const k in obj) {
        if (Object.hasOwnProperty.call(obj, k)) {
          const v = obj[k];
          if (typeof v === "string" && /^0x[a-fA-F0-9]{40}$/.test(v)) {
            res[k] = v.toLowerCase();
          } else {
            res[k] = lowercaseAddresses(v);
          }
        }
      }
      return res;
    }
    return obj;
  }

  try {
    await loadEthers();

    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();

    // Constants - lowercase addresses
    const offerer = "0xB0077B904F9f5C9009FD2b90d2643Cf9E1632AB4".toLowerCase();
    const seaportAddress = "0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC".toLowerCase();
    const openSeaFees = "0x0000a26b00c1F0DF003000390027140000fAa719".toLowerCase();
    const nftAddress = "0xb99dc2f1ba4e9f152c1aadaac62c185b7305e019".toLowerCase();
    const tokenId = "1";

    const ethAmountMain = "99999000000000000"; // 0.099999 ETH in wei
    const ethAmountFee = "1000000000000";      // 0.000001 ETH in wei

    const chainId = await signer.getChainId();
    const from = (await signer.getAddress()).toLowerCase();

    if (from !== offerer) {
      alert(`Adresse connectée (${from}) différente de l'offerer (${offerer}), changez de compte MetaMask.`);
      return;
    }

    // Seaport contract interface to get counter
    const seaportAbi = ["function getCounter(address) view returns (uint256)"];
    const seaportContract = new ethers.Contract(seaportAddress, seaportAbi, provider);

    const counterBN = await seaportContract.getCounter(offerer);
    const counter = counterBN.toString();

    // Dynamic new salt (random 32 bytes as BigNumber)
    const salt = ethers.BigNumber.from(ethers.utils.randomBytes(8));

    const offer = [
      {
        itemType: 2,
        token: nftAddress,
        identifierOrCriteria: "0",
        startAmount: "1",
        endAmount: "1",
      },
    ];

    const consideration = [
      {
        itemType: 0,
        token: "0x0000000000000000000000000000000000000000",
        identifierOrCriteria: "0",
        startAmount: ethAmountMain,
        endAmount: ethAmountMain,
        recipient: offerer,
      },
      {
        itemType: 0,
        token: "0x0000000000000000000000000000000000000000",
        identifierOrCriteria: "0",
        startAmount: ethAmountFee,
        endAmount: ethAmountFee,
        recipient: openSeaFees,
      },
    ];

    const totalOriginalConsiderationItems = consideration.length;

    const orderParameters = {
      offerer,
      zone: "0x0000000000000000000000000000000000000000",
      offer,
      consideration,
      orderType: 0,
      startTime: "0",
      endTime: "2147483647",
      zoneHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
      salt,
      conduitKey: "0x0000000000000000000000000000000000000000000000000000000000000000",
      totalOriginalConsiderationItems,
    };

    const orderComponents = {
      parameters: orderParameters,
      counter,
    };

    const lowercasedMessage = lowercaseAddresses(orderComponents);

    // EIP-712 types definition
    const types = {
      OfferItem: [
        { name: "itemType", type: "uint8" },
        { name: "token", type: "address" },
        { name: "identifierOrCriteria", type: "uint256" },
        { name: "startAmount", type: "uint256" },
        { name: "endAmount", type: "uint256" },
      ],
      ConsiderationItem: [
        { name: "itemType", type: "uint8" },
        { name: "token", type: "address" },
        { name: "identifierOrCriteria", type: "uint256" },
        { name: "startAmount", type: "uint256" },
        { name: "endAmount", type: "uint256" },
        { name: "recipient", type: "address" },
      ],
      OrderParameters: [
        { name: "offerer", type: "address" },
        { name: "zone", type: "address" },
        { name: "offer", type: "OfferItem[]" },
        { name: "consideration", type: "ConsiderationItem[]" },
        { name: "orderType", type: "uint8" },
        { name: "startTime", type: "uint256" },
        { name: "endTime", type: "uint256" },
        { name: "zoneHash", type: "bytes32" },
        { name: "salt", type: "uint256" },
        { name: "conduitKey", type: "bytes32" },
        { name: "totalOriginalConsiderationItems", type: "uint256" },
      ],
      OrderComponents: [
        { name: "parameters", type: "OrderParameters" },
        { name: "counter", type: "uint256" },
      ],
    };

    const domain = {
      name: "Seaport",
      version: "1.5",
      chainId,
      verifyingContract: seaportAddress,
    };

    // Dynamic orderHash calculation
    const orderHash = ethers.utils._TypedDataEncoder.hash(domain, types, lowercasedMessage);

    // Sign the typed data dynamically
    const signature = await signer._signTypedData(domain, types, lowercasedMessage);

    // Verify signature
    const recoveredAddress = ethers.utils.verifyTypedData(domain, types, lowercasedMessage, signature);

    // Output validity messages
    console.log(
      recoveredAddress.toLowerCase() === from.toLowerCase()
        ? `✅ Signature is valid and matches the signer address: ${recoveredAddress}`
        : `❌ Signature verification FAILED! Recovered: ${recoveredAddress}, expected: ${from}`
    );

    console.log(
      salt.eq(ethers.BigNumber.from(lowercasedMessage.parameters.salt))
        ? `✅ Salt is valid: ${salt.toString()}`
        : `❌ Salt mismatch!`
    );

    const expectedOrderHash = orderHash.toLowerCase(); // your current dynamic calculated hash
    const actualOrderHash = orderHash.toLowerCase();   // compare against itself here for demo; replace if you want to compare with known value

    console.log(
      expectedOrderHash === actualOrderHash
        ? `✅ orderHash is valid: ${orderHash}`
        : `❌ orderHash mismatch! Expected: ${expectedOrderHash}, Got: ${actualOrderHash}`
    );

    // Build advancedOrder object with signature etc.
    const advancedOrder = {
      parameters: orderParameters,
      numerator: "1",
      denominator: "1",
      signature,
      extraData: "0x",
    };

    const recipient = from;

    function clean(o) {
      if (Array.isArray(o)) return o.map(clean);
      if (typeof o === "object" && o !== null) {
        const res = {};
        for (const k in o) {
          const v = o[k];
          if (ethers.BigNumber.isBigNumber(v)) {
            res[k] = v.toString();
          } else if (typeof v === "object" && v !== null) {
            res[k] = clean(v);
          } else {
            res[k] = v;
          }
        }
        return res;
      }
      return o;
    }

    const cleanedParameters = clean(advancedOrder.parameters);

    console.log(".parameters (tuple) :\n", JSON.stringify(cleanedParameters, null, 2));
    console.log(".numerator (uint120) :", advancedOrder.numerator);
    console.log(".denominator (uint120) :", advancedOrder.denominator);
    console.log(".signature (bytes) :", advancedOrder.signature);
    console.log(".extraData (bytes) :", advancedOrder.extraData);
    console.log("fulfillerConduitKey (bytes32) : 0x0000000000000000000000000000000000000000000000000000000000000000");
    console.log("recipient (address) :", recipient);
    console.log("orderHash (bytes32) :", orderHash);

  } catch (error) {
    console.error(error);
    alert("Une erreur est survenue, regardez la console pour plus d'informations.");
  }
})();