Skip to content

Instantly share code, notes, and snippets.

@ankushswar1
Last active July 21, 2023 14:04
Show Gist options
  • Save ankushswar1/4ba19615a26f16d240957121b5bc9562 to your computer and use it in GitHub Desktop.
Save ankushswar1/4ba19615a26f16d240957121b5bc9562 to your computer and use it in GitHub Desktop.
Permit USDC with Gelato
// These values are for Goerli
const CHAIN_ID = '0x5';
const USDC_ABI = 'import USDC ABI as JSON';
const USDC_ADDRESS = '0x07865c6e87b9f70255377e024ace6630c1eaa37f';
const SEAPORT_CONDUIT_ADDRESS = '0x1E0049783F008A0085193E00003D00cd54003c71';
const PERMIT_DOMAIN = {
"name": "USD Coin",
"version": "2",
"chainId": CHAIN_ID,
"verifyingContract": USDC_ADDRESS
}
const PERMIT_TYPES = {
"Permit": [
{
"name": "owner",
"type": "address"
},
{
"name": "spender",
"type": "address"
},
{
"name": "value",
"type": "uint256"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
}
]
}
const {wallets} = useWallets();
const wallet = wallets[0];
if (!wallet) throw new Error('No wallet');
const provider = await wallet?.getEthersProvider();
const signer = provider?.getSigner();
// Initialize ethers contract
const usdcContract = new ethers.Contract(USDC_ADDRESS, USDC_ABI, signer);
// Construct permit
const nonce = await usdcContract.nonces(wallet.address);
const value = ethers.utils.parseEther("1000"); // Replace this with the amount of USDC in wei for the permit
const deadline = Math.floor(Date.now() / 1000) + (60 * 60 * 24); // Replace this with your desired permit expiration
const values = {
owner: wallet.address,
spender: SEAPORT_CONDUIT_ADDRESS,
nonce: nonce,
deadline: deadline,
value: value
}
// Sign permit
const signature = await signer?._signTypedData(PERMIT_DOMAIN, PERMIT_TYPES, values);
const {v, r, s} = ethers.utils.splitSignature(signature as string);
// Produce transaction calldata
const {data} = await usdcContract.populateTransaction.permit!(wallet.address, SEAPORT_CONDUIT_ADDRESS, values, v, r, s);
const request = {
chainId: CHAIN_ID,
target: USDC_ADDRESS,
data: data as string,
user: wallet.address
}
// Relay permit transaction with Gelato
const {taskId} = await relay.sponsoredCallERC2771(request, provider, process.env.NEXT_PUBLIC_GELATO_API_KEY as string)
// Then poll taskId for a transaction hash as usual
// https://docs.gelato.network/developer-services/relay/tracking-your-relay-request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment