To enable crypto asset swapping (e.g. convert USDC to ETH), you can integrate with the exchange of your choice. In this case, we use 0x which offers a huge amount of swapping pairs and great rates. This guide will enable a Privy wallet to convert USDC to ETH.This guide assumes that the Privy wallet has already been created and funded with ETH to pay for transaction fees. Code examples are in Javascript.
Step 2: Approve the Permit2 contract to enable asset movement from your wallet
In order to facilitate a sale of USDC, 0x needs to be able to move USDC from your wallet to the buyer based on the trade. To do so, the wallet owner (user) must approve of this via a signature, which is then verified onchain. All of this can be done invisibly for the user.This is a one time action that won’t have to be done again for any future swapping for this wallet.
Copy
Ask AI
import {maxUint256, erc20Abi, encodeFunctionData, createPublicClient, http} from 'viem';const PERMIT2_ADDRESS = '0x000000000022D473030F116dDEE9F6B43aC78BA3';// USDC contract on Baseconst USDC_ADDRESS = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';// Provider is an instance of an EIP-1193 provider exposed from a Privy SDKconst provider = await wallet.getProvider();// get Privy wallet// prepre transaction to give USDC approvalconst data = encodeFunctionData({ abi: erc20Abi, functionName: 'approve', args: [PERMIT2_ADDRESS, maxUint256]});// execute transactionconst tx = await provider.request({ method: 'eth_sendTransaction', params: [ { from: wallets[0].address, to: USDC_ADDRESS, data } ]});
Finally, you will prepare the transaction to fulfill the order and execute the swap. The user should see additional ETH in their wallet in exchange for their USDC.
Copy
Ask AI
import {numberToHex, concat} from 'viem';// Provider is an instance of an EIP-1193 provider exposed from a Privy SDKconst provider = await wallet.getProvider();// Sign an off-chain signature for the permitconst signature = await provider.request({ method: 'eth_signTypedData_v4', params: [wallet.address, quoteResult.permit2.eip712]});const signatureLengthInHex = numberToHex(size(signature), { signed: false, size: 32});// Pack the transaction for the trade fulfillment, including the off-chain signatureconst transactionData = concat([quoteResult.transaction.data, signatureLengthInHex, signature]);const params = { from: wallet.address, to: quoteResult.transaction.to, data: transactionData, gas: !!quoteResult.transaction.gas ? BigInt(quoteResult.transaction.gas) : undefined};// send the signed permit to be on-chainconst tx = await provider.request({ method: 'eth_sendTransaction', params: [params]});