Skip to content

Instantly share code, notes, and snippets.

@ankushswar1
Last active July 25, 2023 11:03
Show Gist options
  • Save ankushswar1/5e17eada3e9e48dc97c3dc281b47b427 to your computer and use it in GitHub Desktop.
Save ankushswar1/5e17eada3e9e48dc97c3dc281b47b427 to your computer and use it in GitHub Desktop.
USDC Permit on Mumbai
import { getClient, type ReservoirWallet } from '@reservoir0x/reservoir-sdk';
import { GelatoRelay } from "@gelatonetwork/relay-sdk";
import { ConnectedWallet } from '@privy-io/react-auth';
import { ethers } from 'ethers';
import { getTaskStatus } from './poll';
import USDC_ABI from './usdcABI.json';
import {ethers} from 'ethers';
const GELATO_API_KEY = process.env.NEXT_PUBLIC_GELATO_API_KEY || "";
const CHAIN_ID = `0x${getClient().chains[0].id.toString(16)}`; // 0x13881
const USDC_CONTRACT_ADDRESS = process.env.NEXT_PUBLIC_USDC_CONTRACT_ADDRESS || ""; // 0x0FA8781a83E46826621b3BC094Ea2A0212e71B23
const SEAPORT_CONDUIT_CONTRACT_ADDRESS = process.env.NEXT_PUBLIC_SEAPORT_CONDUIT_CONTRACT_ADDRESS || ""; // 0x1E0049783F008A0085193E00003D00cd54003c71
const PERMIT_DOMAIN = {
"name": "USD Coin (PoS)",
"version": "1",
"verifyingContract": USDC_CONTRACT_ADDRESS,
"salt": ethers.utils.hexZeroPad(CHAIN_ID, 32)
}
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 relay = new GelatoRelay();
export const permitUSDC = async (wallet: ConnectedWallet, price: string, expiration: number) => {
// Switch to desired network
const ethereumProvider = await wallet.getEthereumProvider();
try {
ethereumProvider.request({
method: 'wallet_switchEthereumChain',
params: [{chainId: CHAIN_ID}]
})
} catch (error) {
throw new Error(`Failed to switch wallet to chainId ${CHAIN_ID} with error ${error}`);
}
const ethersProvider = await wallet.getEthersProvider();
const signer = ethersProvider.getSigner();
const usdc = new ethers.Contract(USDC_CONTRACT_ADDRESS, USDC_ABI, signer);
// Construct values for USDC Permit
const nonce = await usdc.nonces(wallet.address);
const permitAmount = ethers.BigNumber.from(price);
const values = {
owner: wallet.address,
spender: SEAPORT_CONDUIT_CONTRACT_ADDRESS,
nonce: nonce,
deadline: expiration,
value: permitAmount
}
// Sign USDC permit
const signature = await signer?._signTypedData(PERMIT_DOMAIN, PERMIT_TYPES, values);
const {v, r, s} = ethers.utils.splitSignature(signature as string);
// Relay USDC permit transaction
try {
const {data} = await usdc.populateTransaction.permit!(wallet.address, SEAPORT_CONDUIT_CONTRACT_ADDRESS, permitAmount, expiration, v, r, s);
const request = {
chainId: CHAIN_ID,
target: USDC_CONTRACT_ADDRESS,
data: data as string,
user: wallet.address
}
const relayResponse = await relay.sponsoredCallERC2771(request, ethersProvider, GELATO_API_KEY)
const txHash = await getTaskStatus(relayResponse.taskId);
return txHash;
} catch (error) {
throw new Error(`Failed to permit USDC with Gelato with error ${error}`);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment