diff --git a/package.json b/package.json index 7d7e57e7..797eb046 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "lint": "next lint" }, "dependencies": { + "@1inch/fusion-sdk": "2.1.7", "@chakra-ui/icons": "^2.0.12", "@chakra-ui/react": "2.8.2", "@defillama/sdk": "^3.0.25", @@ -23,9 +24,11 @@ "@tanstack/react-query": "5.55.4", "@tanstack/react-virtual": "^3.0.0-beta.36", "ariakit": "^2.0.0-next.41", + "axios": "^1.7.9", "bignumber.js": "^9.0.2", "echarts": "^5.4.1", "framer-motion": "^6", + "json-bigint": "^1.0.0", "lodash": "^4.17.21", "next": "12.3.1", "react": "^18.2.0", diff --git a/src/components/Aggregator/adapters/1inch.ts b/src/components/Aggregator/adapters/1inch.ts deleted file mode 100644 index 2f792457..00000000 --- a/src/components/Aggregator/adapters/1inch.ts +++ /dev/null @@ -1,122 +0,0 @@ -// Source https://portal.1inch.dev/documentation/apis/swap/classic-swap/introduction - -import { applyArbitrumFees } from '../utils/arbitrumFees'; -import { altReferralAddress } from '../constants'; -import { sendTx } from '../utils/sendTx'; -import { estimateGas } from 'wagmi/actions'; -import { config } from '../../WalletProvider'; -import { zeroAddress } from 'viem'; - -export const chainToId = { - ethereum: 1, - bsc: 56, - polygon: 137, - optimism: 10, - arbitrum: 42161, - gnosis: 100, - avax: 43114, - fantom: 250, - klaytn: 8217, - aurora: 1313161554, - zksync: 324, - base: 8453 -}; - -const spenders = { - ethereum: '0x111111125421ca6dc452d289314280a0f8842a65', - bsc: '0x111111125421ca6dc452d289314280a0f8842a65', - polygon: '0x111111125421ca6dc452d289314280a0f8842a65', - optimism: '0x111111125421ca6dc452d289314280a0f8842a65', - arbitrum: '0x111111125421ca6dc452d289314280a0f8842a65', - gnosis: '0x111111125421ca6dc452d289314280a0f8842a65', - avax: '0x111111125421ca6dc452d289314280a0f8842a65', - fantom: '0x111111125421ca6dc452d289314280a0f8842a65', - klaytn: '0x111111125421ca6dc452d289314280a0f8842a65', - aurora: '0x111111125421ca6dc452d289314280a0f8842a65', - zksync: '0x6fd4383cb451173d5f9304f041c7bcbf27d561ff', - base: '0x111111125421ca6dc452d289314280a0f8842a65' -}; - -export const name = '1inch'; -export const token = '1INCH'; -export const referral = true; - -export function approvalAddress(chain: string) { - // https://api.1inch.io/v6.0/1/approve/spender - return spenders[chain]; -} -const nativeToken = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - -export async function getQuote(chain: string, from: string, to: string, amount: string, extra) { - // ethereum = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE - // amount should include decimals - - const tokenFrom = from === zeroAddress ? nativeToken : from; - const tokenTo = to === zeroAddress ? nativeToken : to; - const authHeader = process.env.INCH_API_KEY ? { 'auth-key': process.env.INCH_API_KEY as string } : {}; - const tokenApprovalAddress = spenders[chain]; - - const [data, swapData] = await Promise.all([ - fetch( - `https://api-defillama.1inch.io/v6.0/${chainToId[chain]}/quote?src=${tokenFrom}&dst=${tokenTo}&amount=${amount}&includeGas=true&excludedProtocols=PMM1,PMM2,PMM3,PMM4,PMM2MM1,PMM9,PMM8,PMM11,PMM8_2,PMM12,PMM15,PMM17,PMM18,PMM16,PMM20,PMM22,PMM23`, - { headers: authHeader as any } - ).then((r) => r.json()), - extra.userAddress !== zeroAddress - ? fetch( - `https://api-defillama.1inch.io/v6.0/${chainToId[chain]}/swap?src=${tokenFrom}&dst=${tokenTo}&amount=${amount}&from=${extra.userAddress}&slippage=${extra.slippage}&referrer=${altReferralAddress}&disableEstimate=true&excludedProtocols=PMM1,PMM2,PMM3,PMM4,PMM2MM1,PMM9,PMM8,PMM11,PMM8_2,PMM12,PMM15,PMM17,PMM18,PMM16,PMM20,PMM22,PMM23`, - { headers: authHeader as any } - ).then((r) => r.json()) - : null - ]); - - if(swapData && swapData.tx.to.toLowerCase() !== tokenApprovalAddress.toLowerCase()){ - throw new Error("approval address doesn't match") - } - - const estimatedGas = data.gas || 0; - - let gas = estimatedGas; - - if (chain === 'arbitrum') - gas = swapData === null ? null : await applyArbitrumFees(swapData.tx.to, swapData.tx.data, gas); - - return { - amountReturned: swapData?.dstAmount ?? data.dstAmount, - estimatedGas: gas, - tokenApprovalAddress, - rawQuote: swapData === null ? null : { ...swapData, tx: swapData.tx }, - logo: 'https://icons.llamao.fi/icons/protocols/1inch-network?w=48&q=75' - }; -} - -export async function swap({ rawQuote }) { - const txObject = { - from: rawQuote.tx.from, - to: rawQuote.tx.to, - data: rawQuote.tx.data, - value: rawQuote.tx.value - }; - - const gasPrediction = await estimateGas(config, txObject).catch(() => null); - - const tx = await sendTx({ - ...txObject, - // Increase gas +20% + 2 erc20 txs - ...(gasPrediction ? { gas: (gasPrediction * 12n) / 10n + 86000n } : {}) - }); - return tx; -} - -export const getTxData = ({ rawQuote }) => rawQuote?.tx?.data; - -export const getTx = ({ rawQuote }) => { - if (rawQuote === null) { - return {}; - } - return { - from: rawQuote.tx.from, - to: rawQuote.tx.to, - data: rawQuote.tx.data, - value: rawQuote.tx.value - }; -}; diff --git a/src/components/Aggregator/adapters/1inch.test.ts b/src/components/Aggregator/adapters/1inch/1inch.test.ts similarity index 90% rename from src/components/Aggregator/adapters/1inch.test.ts rename to src/components/Aggregator/adapters/1inch/1inch.test.ts index 73df5ad0..868974f6 100644 --- a/src/components/Aggregator/adapters/1inch.test.ts +++ b/src/components/Aggregator/adapters/1inch/1inch.test.ts @@ -1,4 +1,4 @@ -import { approvalAddress, chainToId } from './1inch'; +import { approvalAddress, chainToId } from './'; import fetch from 'node-fetch'; export async function testApprovalAddresses() { diff --git a/src/components/Aggregator/adapters/1inch/classic-swap.ts b/src/components/Aggregator/adapters/1inch/classic-swap.ts new file mode 100644 index 00000000..b21adbab --- /dev/null +++ b/src/components/Aggregator/adapters/1inch/classic-swap.ts @@ -0,0 +1,58 @@ +import { AUTH_HEADER, CHAIN_TO_ID, SPENDERS } from '~/components/Aggregator/adapters/1inch/constants'; +import { altReferralAddress } from '~/components/Aggregator/constants'; +import { applyArbitrumFees } from '~/components/Aggregator/utils/arbitrumFees'; +import { sendTx } from '~/components/Aggregator/utils/sendTx'; +import { zeroAddress } from 'viem'; +import { estimateGas } from 'wagmi/actions'; +import { config } from '../../../WalletProvider'; + +const CLASSIC_ENDPOINT = 'http://localhost:8888/swap/v6.0/'; + +export async function getClassicQuote(chain: string, tokenFrom: string, tokenTo: string, amount: string, extra) { + const quoteUrl = `${CLASSIC_ENDPOINT}${CHAIN_TO_ID[chain]}/quote?src=${tokenFrom}&dst=${tokenTo}&amount=${amount}&includeGas=true`; + const swapUrl = extra.userAddress !== zeroAddress + ? `${CLASSIC_ENDPOINT}${CHAIN_TO_ID[chain]}/swap?src=${tokenFrom}&dst=${tokenTo}&amount=${amount}&from=${extra.userAddress}&slippage=${extra.slippage}&referrer=${altReferralAddress}&disableEstimate=true` + : null; + + const quotePromise = fetch(quoteUrl, { headers: AUTH_HEADER as any }).then((r) => r.json()); + const swapPromise = swapUrl + ? fetch(swapUrl, { headers: AUTH_HEADER as any }).then((r) => r.json()) + : null; + + return await Promise.all([quotePromise, swapPromise]); +} + +export async function parseClassicQuote(chain: string, quote) { + const [data, swapData] = quote; + const tokenApprovalAddress = SPENDERS[chain]; + let gas = data.gas || 0; + + if (chain === 'arbitrum') + gas = swapData === null ? null : await applyArbitrumFees(swapData.tx.to, swapData.tx.data, gas); + + return { + amountReturned: swapData?.dstAmount ?? data.dstAmount, + estimatedGas: gas, + tokenApprovalAddress, + rawQuote: swapData, + logo: 'https://icons.llamao.fi/icons/protocols/1inch-network?w=48&q=75' + }; +} + +export async function classicSwap(rawQuote) { + const txObject = { + from: rawQuote.tx.from, + to: rawQuote.tx.to, + data: rawQuote.tx.data, + value: rawQuote.tx.value + }; + + const gasPrediction = await estimateGas(config, txObject).catch(() => null); + + const tx = await sendTx({ + ...txObject, + // Increase gas +20% + 2 erc20 txs + ...(gasPrediction && { gas: (gasPrediction * 12n) / 10n + 86000n }) + }); + return tx; +} \ No newline at end of file diff --git a/src/components/Aggregator/adapters/1inch/constants.ts b/src/components/Aggregator/adapters/1inch/constants.ts new file mode 100644 index 00000000..dc363ff7 --- /dev/null +++ b/src/components/Aggregator/adapters/1inch/constants.ts @@ -0,0 +1,46 @@ +export const AUTH_HEADER = process.env.INCH_API_KEY ? { 'auth-key': process.env.INCH_API_KEY } : {}; + +export const NATIVE_TOKEN = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; + +export const CHAIN_TO_ID = { + ethereum: 1, + bsc: 56, + polygon: 137, + optimism: 10, + arbitrum: 42161, + gnosis: 100, + avax: 43114, + fantom: 250, + klaytn: 8217, + aurora: 1313161554, + zksync: 324, + base: 8453 +}; + +export const SPENDERS = { + ethereum: '0x111111125421ca6dc452d289314280a0f8842a65', + bsc: '0x111111125421ca6dc452d289314280a0f8842a65', + polygon: '0x111111125421ca6dc452d289314280a0f8842a65', + optimism: '0x111111125421ca6dc452d289314280a0f8842a65', + arbitrum: '0x111111125421ca6dc452d289314280a0f8842a65', + gnosis: '0x111111125421ca6dc452d289314280a0f8842a65', + avax: '0x111111125421ca6dc452d289314280a0f8842a65', + fantom: '0x111111125421ca6dc452d289314280a0f8842a65', + klaytn: '0x111111125421ca6dc452d289314280a0f8842a65', + aurora: '0x111111125421ca6dc452d289314280a0f8842a65', + zksync: '0x6fd4383cb451173d5f9304f041c7bcbf27d561ff', + base: '0x111111125421ca6dc452d289314280a0f8842a65' +}; + +export const AVAILABLE_CHAINS_FOR_FUSION = new Set([ + CHAIN_TO_ID.ethereum, + CHAIN_TO_ID.bsc, + CHAIN_TO_ID.polygon, + CHAIN_TO_ID.optimism, + CHAIN_TO_ID.arbitrum, + CHAIN_TO_ID.gnosis, + CHAIN_TO_ID.avax, + CHAIN_TO_ID.fantom, + CHAIN_TO_ID.zksync, + CHAIN_TO_ID.base, +]); diff --git a/src/components/Aggregator/adapters/1inch/fusion-swap.ts b/src/components/Aggregator/adapters/1inch/fusion-swap.ts new file mode 100644 index 00000000..359c39d7 --- /dev/null +++ b/src/components/Aggregator/adapters/1inch/fusion-swap.ts @@ -0,0 +1,123 @@ +import { AVAILABLE_CHAINS_FOR_FUSION, CHAIN_TO_ID, SPENDERS } from './constants'; +import { FusionSDK, OrderStatus } from '@1inch/fusion-sdk'; +import { formatUnits, parseUnits } from 'ethers/lib/utils'; +import { call, signTypedData } from 'wagmi/actions'; +import { config } from '~/components/WalletProvider'; +import { Hex } from 'viem/types/misc'; +import { OrderInfo } from '@1inch/fusion-sdk/dist/types/src/sdk/types'; + +// const FUSION_QUOTE_ENDPOINT = 'https://api-defillama.1inch.io/v2.0/fusion'; +const FUSION_SDK_ENDPOINT = 'http://localhost:8888/fusion'; +const SOURCE = 'f012a792'; + +export function isFusionSupportedByChain(chainId: number): boolean { + return AVAILABLE_CHAINS_FOR_FUSION.has(chainId); +} + +export async function getFusionQuoteResponse(params: { + chain: string, + tokenFrom: string, + tokenTo: string, + amount: string, + address: string, +}) { + const { chain, tokenFrom, tokenTo, amount, address } = params; + const sdk = new FusionSDK({ + url: FUSION_SDK_ENDPOINT, + network: CHAIN_TO_ID[chain] + }); + + return await sdk.getQuote({ + fromTokenAddress: tokenFrom, + toTokenAddress: tokenTo, + amount, + walletAddress: address, + source: SOURCE, + }); +} + +export async function fusionSwap(chain, quote, fromAddress): Promise { + const sdk = new FusionSDK({ + url: FUSION_SDK_ENDPOINT, + network: CHAIN_TO_ID[chain], + blockchainProvider: { + signTypedData: (_, typedData) => signTypedData(config, { + domain: typedData.domain, + types: typedData.types, + primaryType: typedData.primaryType, + message: typedData.message + }), + ethCall: (contractAddress: Hex, callData: Hex) => + call( + config, + { + account: fromAddress, + data: callData, + to: contractAddress, + }, + ).then((result) => result.data as string), + } + }); + + return await sdk.placeOrder({ + fromTokenAddress: quote.params.fromTokenAddress.val, + toTokenAddress: quote.params.toTokenAddress.val, + walletAddress: quote.params.walletAddress.val, + amount: quote.params.amount, + source: SOURCE, + }); +} + +export const getOrderStatus = ({ chain, hash }) => async (onSuccess, maxRetries = 300, delay = 1000) => { + const sdk = new FusionSDK({ + url: FUSION_SDK_ENDPOINT, + network: CHAIN_TO_ID[chain], + }); + + let attempt = 0; + + while (attempt < maxRetries) { + try { + const data = await sdk.getOrderStatus(hash); + + if (data.status === OrderStatus.Filled) { + onSuccess(); + return; + } + + if (data.status !== OrderStatus.Pending) { + return; + } + } catch (error) { + console.error('Error fetching fusion order status:', error); + } + + attempt++; + if (attempt >= maxRetries) { + throw new Error('Max retries reached. Unable to fetch order status.'); + } + + await new Promise((resolve) => setTimeout(resolve, delay)); + } +}; + +export function parseFusionQuote(chain: string, quote, extra) { + const { presets, recommendedPreset, toTokenAmount } = quote; + const { auctionStartAmount, auctionEndAmount } = presets[recommendedPreset]; + const dstTokenDecimals = extra.toToken.decimals; + + const start = formatUnits(auctionStartAmount, dstTokenDecimals); + const end = formatUnits(auctionEndAmount, dstTokenDecimals); + const amount = formatUnits(toTokenAmount, dstTokenDecimals); + + const receivedAmount = amount < start ? amount : start; + const returnedAmount = end > receivedAmount ? end : receivedAmount; + + return { + amountReturned: parseUnits(returnedAmount, dstTokenDecimals).toString(), + estimatedGas: 0, + tokenApprovalAddress: SPENDERS[chain], + rawQuote: quote, + logo: 'https://icons.llamao.fi/icons/protocols/1inch-network?w=48&q=75' + }; +} \ No newline at end of file diff --git a/src/components/Aggregator/adapters/1inch/index.ts b/src/components/Aggregator/adapters/1inch/index.ts new file mode 100644 index 00000000..8c31bc7e --- /dev/null +++ b/src/components/Aggregator/adapters/1inch/index.ts @@ -0,0 +1,92 @@ +// Source https://portal.1inch.dev/documentation/apis/swap/classic-swap/introduction + +import { CHAIN_TO_ID, NATIVE_TOKEN, SPENDERS } from './constants'; +import { classicSwap, getClassicQuote, parseClassicQuote } from './classic-swap'; +import { + fusionSwap, + getFusionQuoteResponse, + getOrderStatus, + isFusionSupportedByChain, + parseFusionQuote +} from './fusion-swap'; +import { zeroAddress } from 'viem'; + +export const name = '1inch'; +export const token = '1INCH'; +export const referral = true; +export const chainToId = CHAIN_TO_ID; + +export function approvalAddress(chain: string) { + // https://api.1inch.io/v6.0/1/approve/spender + return SPENDERS[chain]; +} + +export async function getQuote(chain: string, from: string, to: string, amount: string, extra) { + const quote = await getFusionOrClassicQuote(chain, from, to, amount, extra); + + return typeof quote === "object" && "recommendedPreset" in quote + ? parseFusionQuote(chain, quote, extra) + : await parseClassicQuote(chain, quote); +} + +export async function swap({ chain, rawQuote, fromAddress }) { + const isFusionQuote = typeof rawQuote === "object" && "recommendedPreset" in rawQuote; + + if (isFusionQuote) { + const data = await fusionSwap(chain, rawQuote, fromAddress); + + return { + ...data, + hash: data.orderHash, + waitForOrder: getOrderStatus({ chain, hash: data.orderHash }) + }; + } + + return await classicSwap(rawQuote); +} + +async function getFusionOrClassicQuote (chain: string, from: string, to: string, amount: string, extra) { + // ethereum = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE + // amount should include decimals + const tokenFrom = from === zeroAddress ? NATIVE_TOKEN : from; + const tokenTo = to === zeroAddress ? NATIVE_TOKEN : to; + const address = extra.userAddress; + + if (isFusionSupportedByChain(CHAIN_TO_ID[chain])) { + try { + const quote = await getFusionQuoteResponse({ chain, tokenFrom, tokenTo, amount, address }); + if (quote.silippage > +extra.slippage) { + throw new Error('slippage does not match slippage'); + } + return quote; + } catch { + return await getClassicQuote(chain, tokenFrom, tokenTo, amount, extra); + } + } else { + return await getClassicQuote(chain, tokenFrom, tokenTo, amount, extra); + } +} + +export const getTxData = ({ rawQuote }) => rawQuote?.tx?.data; + +export const getTx = ({ rawQuote }) => { + if (rawQuote === null) { + return {}; + } + + if ("recommendedPreset" in rawQuote) { + return { + from: rawQuote.params.fromTokenAddress, + to: rawQuote.params.toTokenAddress, + // data: rawQuote.tx.data, // ??? + // value: rawQuote.tx.value // ??? + }; + } + + return { + from: rawQuote.tx.from, + to: rawQuote.tx.to, + data: rawQuote.tx.data, + value: rawQuote.tx.value + }; +}; diff --git a/src/components/Aggregator/adapters/utils.ts b/src/components/Aggregator/adapters/utils.ts index a95afa48..fece0508 100644 --- a/src/components/Aggregator/adapters/utils.ts +++ b/src/components/Aggregator/adapters/utils.ts @@ -1,3 +1,5 @@ +import JSONBig from 'json-bigint'; + export const redirectQuoteReq = async ( protocol: string, chain: string, @@ -41,7 +43,7 @@ interface SwapEvent { export const sendSwapEvent = async (event: SwapEvent) => { const data = await fetch(`https://llamaswap-stats.llama.fi/saveEvent`, { method: 'POST', - body: JSON.stringify(event) + body: JSONBig.stringify(event) }).then((res) => res.json()); return data; diff --git a/src/components/Aggregator/index.tsx b/src/components/Aggregator/index.tsx index 3098cd66..68375c6f 100644 --- a/src/components/Aggregator/index.tsx +++ b/src/components/Aggregator/index.tsx @@ -552,7 +552,7 @@ export function AggregatorContainer({ tokenList }) { ...route, isFailed: gasData?.[route.name]?.isFailed || false, route, - gasUsd: gasUsd === 0 && route.name !== 'CowSwap' && !route.isGasless ? 'Unknown' : gasUsd, + gasUsd: gasUsd === 0 && !['CowSwap', '1inch'].includes(route.name) && !route.isGasless ? 'Unknown' : gasUsd, amountUsd, amount, netOut, @@ -901,7 +901,7 @@ export function AggregatorContainer({ tokenList }) { }); } else { setTxModalOpen(true); - txUrl = `https://explorer.cow.fi/orders/${data.id}`; + txUrl = variables.adapter === '1inch' ? '' : `https://explorer.cow.fi/orders/${data.id}`; setTxUrl(txUrl); data.waitForOrder(() => { forceRefreshTokenBalance(); @@ -1000,8 +1000,15 @@ export function AggregatorContainer({ tokenList }) { const isAmountSynced = debouncedAmount === formatAmount(amount) && formatAmount(amountOut) === debouncedAmountOut; const isUnknownPrice = !fromTokenPrice || !toTokenPrice; const isPriceImpactNotKnown = !selectedRoutesPriceImpact && selectedRoutesPriceImpact !== 0; + const is1inchFusionSwap = selectedRoute ? selectedRoute.gasUsd === 0 : false; const warnings = [ + aggregator === '1inch' && is1inchFusionSwap ? ( + + + 1inch Fusion sources all market liquidity to offer best rates for gas-free, MEV-resistant swaps, while ensuring top-tier AML compliance. + + ) : null, aggregator === 'CowSwap' ? ( <> {finalSelectedFromToken?.value === zeroAddress && Number(slippage) < 2 ? ( diff --git a/src/components/Aggregator/router.ts b/src/components/Aggregator/router.ts index cc1668fa..b601dd0e 100644 --- a/src/components/Aggregator/router.ts +++ b/src/components/Aggregator/router.ts @@ -42,7 +42,8 @@ export async function swap({ adapter, rawQuote, tokens, - approvalData + approvalData, + route, }) { const aggregator = adaptersMap[adapter]; @@ -53,6 +54,7 @@ export async function swap({ to, amount, fromAddress, + fromAmount: route.fromAmount, slippage, rawQuote, tokens, diff --git a/src/components/SwapRoute/index.tsx b/src/components/SwapRoute/index.tsx index 025c81d0..efa008b7 100644 --- a/src/components/SwapRoute/index.tsx +++ b/src/components/SwapRoute/index.tsx @@ -74,7 +74,10 @@ const Route = ({ chain: selectedChain }); - if (!price.amountReturned || (Number(gasUsd) === 0 && name !== 'CowSwap' && !isGasless)) return null; + if ( + !price.amountReturned + || (Number(gasUsd) === 0 && !['CowSwap', '1inch'].includes(name) && !isGasless) + ) return null; const amount = +price.amountReturned / 10 ** +toToken?.decimals; @@ -172,7 +175,7 @@ const Route = ({ ) : null} - {name === 'CowSwap' ? ( + {name === 'CowSwap' || (name === '1inch' && gasUsd === 0) ? ( {isGasNotKnown ? null : } diff --git a/src/components/TransactionModal/index.tsx b/src/components/TransactionModal/index.tsx index 4c5fe82a..0ee29ded 100644 --- a/src/components/TransactionModal/index.tsx +++ b/src/components/TransactionModal/index.tsx @@ -44,20 +44,22 @@ export const TransactionModal = ({ open, setOpen, link }) => { - - View on explorer - + { + !!link && + View on explorer + + } ); diff --git a/yarn.lock b/yarn.lock index 09e589e6..0dc62063 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,45 @@ # yarn lockfile v1 +"@1inch/byte-utils@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@1inch/byte-utils/-/byte-utils-2.2.1.tgz#e542fa675fd034378e35b995823abd74f755888d" + integrity sha512-ESIUUGcRu8cL+rFEJedSLOMMXUmLC3A0zyHcWH1fxLAzUsY+bdjqUX/jWQIbOqg+k1XKyXBu6vkREDna3JCp6w== + +"@1inch/byte-utils@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@1inch/byte-utils/-/byte-utils-2.3.0.tgz#08342ba6fd2559af550140b96f6c3320b218d9b5" + integrity sha512-SKRlhemGFKc+15uTgSzsEs0T4WTpVv7lwcWdMTtUdf7tXDVCz+Dvr36pLk4UJxeKW/HqHCQXv9w1rF+yCgG4Tw== + +"@1inch/fusion-sdk@2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@1inch/fusion-sdk/-/fusion-sdk-2.1.7.tgz#008507a0fb0e5fe43ebfacec7251cc65f2dbea44" + integrity sha512-UxIEYnELK2dK4oPpIQRnOVyiVPfT8YrVGgBjAkKHhModPE265oSU3v7bU7MxrBL1O1nUUJzBP1RDnxvyja26ww== + dependencies: + "@1inch/byte-utils" "2.3.0" + "@1inch/limit-order-sdk" "^4.9.3-rc.1" + ethers "^6.13.1" + tslib "^2.6.3" + ws "^8.17.1" + +"@1inch/limit-order-sdk@^4.9.3-rc.1": + version "4.9.3-rc.1" + resolved "https://registry.yarnpkg.com/@1inch/limit-order-sdk/-/limit-order-sdk-4.9.3-rc.1.tgz#0b7477f779527c4ecaa4df0d663657435f1335b5" + integrity sha512-J0vQS3wpbYHzKt8LNnqgsL8lLU8misz2MrP7F2Wb1qgGNPBt5IQLMaw2JX6nqvxBSnOQ4z9nMDa6yTFpUGLeCQ== + dependencies: + "@1inch/byte-utils" "2.2.1" + ethers "6.13.1" + "@adraffy/ens-normalize@1.10.0": version "1.10.0" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@adraffy/ens-normalize@^1.10.1": version "1.11.0" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33" @@ -2010,6 +2044,13 @@ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.1.tgz#27d71a95247a9eaee03d47adee7e3bd594514136" integrity sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA== +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + "@noble/curves@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" @@ -2031,6 +2072,11 @@ dependencies: "@noble/hashes" "1.6.0" +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + "@noble/hashes@1.4.0", "@noble/hashes@~1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" @@ -2495,6 +2541,18 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.8.tgz#50d680c8a8a78fe30abe6906453b21ad8ab0ad7b" integrity sha512-YofkM6fGv4gDJq78g4j0mMuGMkZVxZDgtU0JRdx6FgiJDG+0fY0GKVolOV8WqVmEhLCXkQRjwDdKyPxJp/uucg== +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + +"@types/node@22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -2984,6 +3042,11 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -3102,6 +3165,11 @@ async-mutex@^0.2.6: dependencies: tslib "^2.0.0" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + atomic-sleep@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" @@ -3117,6 +3185,15 @@ axe-core@^4.4.3: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.5.2.tgz#823fdf491ff717ac3c58a52631d4206930c1d9f7" integrity sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA== +axios@^1.7.9: + version "1.7.9" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a" + integrity sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -3162,6 +3239,11 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +bignumber.js@^9.0.0: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + bignumber.js@^9.0.2: version "9.1.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.0.tgz#8d340146107fe3a6cb8d40699643c302e8773b62" @@ -3377,6 +3459,13 @@ color2k@^2.0.2: resolved "https://registry.yarnpkg.com/color2k/-/color2k-2.0.3.tgz#a771244f6b6285541c82aa65ff0a0c624046e533" integrity sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog== +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^6.2.0: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -3627,6 +3716,11 @@ defu@^6.1.4: resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + destr@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.3.tgz#7f9e97cb3d16dbdca7be52aca1644ce402cfe449" @@ -4094,6 +4188,19 @@ ethereum-cryptography@^2.0.0: "@scure/bip32" "1.4.0" "@scure/bip39" "1.3.0" +ethers@6.13.1: + version "6.13.1" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.1.tgz#2b9f9c7455cde9d38b30fe6589972eb083652961" + integrity sha512-hdJ2HOxg/xx97Lm9HdCWk949BfYqYWpyw4//78SiwOLgASyfrNszfMUNB2joKjvGUdwhHfaiMMFFwacVVoLR9A== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.17.1" + ethers@^5.4.5: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" @@ -4130,6 +4237,19 @@ ethers@^5.4.5: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" +ethers@^6.13.1: + version "6.13.5" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.5.tgz#8c1d6ac988ac08abc3c1d8fabbd4b8b602851ac4" + integrity sha512-+knKNieu5EKRThQJWwqaJ10a6HE9sSehGeqWN65//wE7j47ZpFhKAnHB/JJFibwwg61I/koxaPsXbXpD/skNOQ== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "22.7.5" + aes-js "4.0.0-beta.5" + tslib "2.7.0" + ws "8.17.1" + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -4283,6 +4403,11 @@ focus-lock@^1.3.5: dependencies: tslib "^2.0.3" +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + for-each@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -4290,6 +4415,15 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +form-data@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + framer-motion@^6: version "6.5.1" resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-6.5.1.tgz#802448a16a6eb764124bf36d8cbdfa6dd6b931a7" @@ -4878,6 +5012,13 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-bigint@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-1.0.0.tgz#ae547823ac0cad8398667f8cd9ef4730f5b01ff1" + integrity sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ== + dependencies: + bignumber.js "^9.0.0" + json-buffer@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" @@ -5124,6 +5265,18 @@ micromatch@^4.0.5: braces "^3.0.3" picomatch "^2.3.1" +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mime@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" @@ -5680,6 +5833,11 @@ proxy-compare@2.5.1: resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.5.1.tgz#17818e33d1653fbac8c2ec31406bce8a2966f600" integrity sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + pump@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" @@ -6395,11 +6553,21 @@ tslib@2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== +tslib@^2.6.3: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -6458,6 +6626,11 @@ uncrypto@^0.1.3: resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + unenv@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.10.0.tgz#c3394a6c6e4cfe68d699f87af456fe3f0db39571" @@ -6745,7 +6918,7 @@ ws@8.17.1, ws@~8.17.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== -ws@8.18.0: +ws@8.18.0, ws@^8.17.1: version "8.18.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==