import { ethers } from "ethers";
import { AllowanceProvider, AllowanceTransfer } from "@uniswap/permit2-sdk";
const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
// Step 1: User approves Permit2 for token (one-time)
async function approvePermit2(tokenContract, signer) {
  const tx = await tokenContract.approve(
    PERMIT2_ADDRESS,
    ethers.MaxUint256
  );
  await tx.wait();
  console.log("Permit2 approved for token");
}
// Step 2: Create and sign permit
async function createPermit(token, spender, amount, deadline, signer) {
  const permit = {
    details: {
      token: token,
      amount: amount,
      expiration: deadline,
      nonce: 0, // Get current nonce from contract
    },
    spender: spender,
    sigDeadline: deadline,
  };
  // Create permit data
  const { domain, types, values } = AllowanceTransfer.getPermitData(
    permit,
    PERMIT2_ADDRESS,
    await signer.provider.getNetwork().then(n => n.chainId)
  );
  // Sign permit
  const signature = await signer._signTypedData(domain, types, values);
  return { permit, signature };
}
// Step 3: Execute transfer with permit
async function transferWithPermit(permit, signature, transferDetails) {
  const permit2 = new ethers.Contract(
    PERMIT2_ADDRESS,
    ["function transferFrom(address,address,uint160,address)"],
    signer
  );
  // First, submit the permit
  await permit2.permit(
    signer.address,
    permit,
    signature
  );
  // Then transfer
  await permit2.transferFrom(
    transferDetails.from,
    transferDetails.to,
    transferDetails.amount,
    transferDetails.token
  );
}