Cross-Chain USDC Supply to AAVE with Gasless Fusion Orchestration
This guide demonstrates how to use Relay Protocol together with Biconomy’s Modular Execution Environment (MEE) to perform a cross-chain supply of USDC into AAVE, completely gasless using Fusion Orchestration.
First, create the Relay Service file. Copy and paste this entire code block into a new file called relay-service.ts:
Copy
Ask AI
// relay-service.tsimport type { Address, Hex } from 'viem'/** * ------------------------------------------------------------- * Relay Protocol Service — typed with viem * ------------------------------------------------------------- */export type TradeType = 'EXACT_INPUT' | 'EXACT_OUTPUT'export type Transaction = { to: Address value: string data: Hex}export type AppFee = { recipient: Address fee: string}export type GetQuoteParameters = { user: Address recipient: Address originChainId: number destinationChainId: number originCurrency: Address destinationCurrency: Address amount: string tradeType: TradeType txs?: Transaction[] txsGasLimit?: number referrer?: string referrerAddress?: Address refundTo?: Address refundOnOrigin?: boolean topupGas?: boolean useReceiver?: boolean useProtocol?: boolean useExternalLiquidity?: boolean usePermit?: boolean useDepositAddress?: boolean slippageTolerance?: string appFees?: AppFee[] gasLimitForDepositSpecifiedTxs?: number userOperationGasOverhead?: number forceSolverExecution?: boolean includedSwapSources?: string[] excludedSwapSources?: string[]}export type Currency = { chainId: number address: Address symbol: string name: string decimals: number metadata: { logoURI: string verified: boolean isNative: boolean }}export type CurrencyAmount = { currency: Currency amount: string amountFormatted: string amountUsd: string minimumAmount: string}export type TransactionData = { from: Address to: Address data: Hex value: string maxFeePerGas: string maxPriorityFeePerGas: string chainId: number}export type CheckEndpoint = { endpoint: string method: 'GET' | 'POST' | 'PUT' | 'DELETE'}export type StepItem = { status: 'incomplete' | 'complete' | 'failed' data: TransactionData check: CheckEndpoint}export type Step = { id: string action: string description: string kind: 'transaction' | 'signature' | 'permit' requestId: Hex items: StepItem[]}export type Fees = { gas: CurrencyAmount relayer: CurrencyAmount relayerGas: CurrencyAmount relayerService: CurrencyAmount app: CurrencyAmount}export type Impact = { usd: string percent: string}export type SlippageTolerance = { origin: { usd: string value: string percent: string } destination: { usd: string value: string percent: string }}export type Details = { operation: string sender: string recipient: string currencyIn: CurrencyAmount currencyOut: CurrencyAmount currencyGasTopup: CurrencyAmount totalImpact: Impact swapImpact: Impact rate: string slippageTolerance: SlippageTolerance timeEstimate: number userBalance: string}export type RelayerTransaction = { steps: Step[] fees: Fees details: Details}export type GetQuoteReturnType = RelayerTransactionexport type GetQuoteErrorType = Errorexport async function getRelayQuote( parameters: GetQuoteParameters): Promise<GetQuoteReturnType> { const response = await fetch('https://api.relay.link/quote', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(parameters), }) if (!response.ok) { const error = await response.text() throw new Error(`Relayer API error: ${response.status} - ${error}`) } return response.json() as Promise<GetQuoteReturnType>}
Now, import the dependencies in your main file:
Copy
Ask AI
import { createMeeClient, toMultichainNexusAccount, createChainAddressMap, runtimeERC20BalanceOf, greaterThanOrEqualTo, type Trigger, getMEEVersion, MEEVersion} from "@biconomy/abstractjs"import { getRelayQuote } from "./relay-service" // Import the service you just createdimport { base, optimism } from "viem/chains"import { privateKeyToAccount } from "viem/accounts"import { http, parseAbi, parseUnits } from "viem"
const quote = await getRelayQuote({ // ... other params topupGas: true, // Top up gas on destination usePermit: true, // Use permit for gasless approval useExternalLiquidity: true, // Access external liquidity sources})