Last active
July 25, 2023 11:03
-
-
Save ankushswar1/5e17eada3e9e48dc97c3dc281b47b427 to your computer and use it in GitHub Desktop.
USDC Permit on Mumbai
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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