UNPKG

@yak-spirit/yak-swap-ui

Version:

A reusable React component for swapping with Yield Yak Router. The YY Router can be found [here](https://github.com/yieldyak/yak-aggregator).

146 lines (145 loc) 6.69 kB
import Web3 from 'web3'; import PairABI from '../abis/PairABI.json'; import YakRouterABI from '../abis/YakRouter.json'; import { ADDRESSES } from '../utils/constants.js'; import { BigNumber } from 'bignumber.js'; import { userState } from '../state/index.js'; import { tokenList } from './tokenList.js'; import { toast } from 'react-toastify'; import { signERC2612Permit } from 'eth-permit'; const MaxUint256 = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; const yakRouterAddress = ADDRESSES.helpers.yakRouter; const fee = 0; export const swap = async (payload) => { const provider = window.ethereum; const web3 = new Web3(provider); const userAddress = userState.userAddress; if (userAddress) { const { trade, fromAVAX, toAVAX } = payload; const yakRouterContract = new web3.eth.Contract(YakRouterABI, yakRouterAddress, { from: userAddress, }); try { if (fromAVAX) { const tx = await yakRouterContract.methods .swapNoSplitFromAVAX({ amountIn: trade.amounts[0], amountOut: trade.amounts[trade.amounts.length - 1], path: trade.path, adapters: trade.adapters, }, userAddress, fee) .send({ from: userAddress, value: trade.amounts[0] }); if (tx.status) { toast.success('Swap success'); } else { toast.error('Swap failed'); } return tx; } else { // handle approval const fromTokenAddress = trade.path[0]; const permitSupported = tokenList.find((token) => token.address.toLowerCase() === fromTokenAddress.toLowerCase())?.permitSupported; const tokenContract = new web3.eth.Contract(PairABI, fromTokenAddress, { from: userAddress, }); const approvedBalance = await tokenContract.methods.allowance(userAddress, yakRouterAddress).call(); try { if (!permitSupported) { throw new Error('Permit not supported'); } if (new BigNumber(approvedBalance).gte(trade.amounts[0])) { throw new Error('Permit not needed'); } const signature = await signERC2612Permit(provider, trade.path[0], userAddress, yakRouterAddress, trade.amounts[0]); if (toAVAX) { const tx = await yakRouterContract.methods .swapNoSplitToAvaxWithPermit({ amountIn: trade.amounts[0], amountOut: trade.amounts[trade.amounts.length - 1], path: trade.path, adapters: trade.adapters, }, userAddress, fee, signature.deadline, signature.v, signature.r, signature.s) .send({ from: userAddress }); if (tx.status) { toast.success('Swap success'); } else { toast.error('Swap failed'); } return tx; } else { const tx = await yakRouterContract.methods .swapNoSplitWithPermit({ amountIn: trade.amounts[0], amountOut: trade.amounts[trade.amounts.length - 1], path: trade.path, adapters: trade.adapters, }, userAddress, fee, signature.deadline, signature.v, signature.r, signature.s) .send({ from: userAddress }); if (tx.status) { toast.success('Swap success'); } else { toast.error('Swap failed'); } return tx; } } catch { try { if (new BigNumber(approvedBalance).lt(trade.amounts[0])) { await tokenContract.methods.approve(yakRouterAddress, MaxUint256).send({ from: userAddress }); } if (toAVAX) { const tx = await yakRouterContract.methods .swapNoSplitToAVAX({ amountIn: trade.amounts[0], amountOut: trade.amounts[trade.amounts.length - 1], path: trade.path, adapters: trade.adapters, }, userAddress, fee) .send({ from: userAddress }); if (tx.status) { toast.success('Swap success'); } else { toast.error('Swap failed'); } return tx; } else { const tx = await yakRouterContract.methods .swapNoSplit({ amountIn: trade.amounts[0], amountOut: trade.amounts[trade.amounts.length - 1], path: trade.path, adapters: trade.adapters, }, userAddress, fee) .send({ from: userAddress }); if (tx.status) { toast.success('Swap success'); } else { toast.error('Swap failed'); } return tx; } } catch (err) { console.error('swap', err); toast.error('Swap error'); return false; } } } } catch (err) { console.error('swap', err); toast.error('Swap error'); return false; } } };