import { ethers, BigNumber, Contract } from 'ethers';
const API_URL = 'https://api.delora.build/v1';
const ERC20_ABI = [
'function allowance(address owner, address spender) view returns (uint256)',
'function approve(address spender, uint256 amount) returns (bool)',
] as const;
const getQuote = async (params: {
originChainId: number;
destinationChainId: number;
amount: string;
originCurrency: string;
destinationCurrency: string;
tradeType: 'EXACT_INPUT' | 'EXACT_OUTPUT';
senderAddress?: string;
receiverAddress?: string;
}) => {
const query = new URLSearchParams();
for (const [key, value] of Object.entries(params)) {
if (value !== undefined) {
query.append(key, String(value));
}
}
const url = `${API_URL}/quotes?${query.toString()}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to get quote: ${response.status} ${response.statusText}`);
}
return response.json();
};
export const executeSwap = async (provider: ethers.providers.Web3Provider) => {
await provider.send('eth_requestAccounts', []);
const wallet = provider.getSigner();
const walletAddress = await wallet.getAddress();
const originChainId = 137;
const destinationChainId = 137;
const originCurrency: string = '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359';
const destinationCurrency = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174';
const amount = ethers.utils.parseUnits('100', 6).toString();
const quote = await getQuote({
originChainId,
destinationChainId,
amount,
originCurrency,
destinationCurrency,
tradeType: 'EXACT_INPUT',
senderAddress: walletAddress,
receiverAddress: walletAddress,
});
if (originCurrency !== ethers.constants.AddressZero) {
const token = new Contract(originCurrency, ERC20_ABI, wallet);
const allowance = await token.allowance(walletAddress, quote.calldata.to);
if (allowance.lt(BigNumber.from(quote.inputAmount))) {
await (await token.approve(quote.calldata.to, ethers.constants.MaxUint256)).wait();
}
}
const tx = await wallet.sendTransaction({
to: quote.calldata.to,
data: quote.calldata.data,
value: quote.calldata.value,
...(quote.gas?.gasLimit && { gasLimit: BigNumber.from(quote.gas.gasLimit) }),
...(quote.gas?.maxFeePerGas && { maxFeePerGas: BigNumber.from(quote.gas.maxFeePerGas) }),
...(quote.gas?.maxPriorityFeePerGas && { maxPriorityFeePerGas: BigNumber.from(quote.gas.maxPriorityFeePerGas) }),
...(quote.gas?.gasPrice && { gasPrice: BigNumber.from(quote.gas.gasPrice) }),
});
await tx.wait();
return tx.hash;
};