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
);
}