diff --git a/wormhole-connect/package-lock.json b/wormhole-connect/package-lock.json index daff70db1..41f58d912 100644 --- a/wormhole-connect/package-lock.json +++ b/wormhole-connect/package-lock.json @@ -24,7 +24,7 @@ "@ledgerhq/hw-transport-webhid": "6.27.1", "@ledgerhq/logs": "6.12.0", "@manahippo/aptos-wallet-adapter": "^1.0.8", - "@mayanfinance/wormhole-sdk-route": "^0.4.0", + "@mayanfinance/wormhole-sdk-route": "^0.4.1", "@mui/icons-material": "^5.11.0", "@mui/material": "^5.11.4", "@mysten/sui.js": "^0.32.2", @@ -4952,9 +4952,9 @@ } }, "node_modules/@mayanfinance/wormhole-sdk-route": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@mayanfinance/wormhole-sdk-route/-/wormhole-sdk-route-0.4.0.tgz", - "integrity": "sha512-SGzp0rLnJvQ6/F0CQkElqG2wpovjS6+2klMWDf0NexZbBpkAcAuZcqREpThe+LKEUjUIEOHBxx0CMr46atl13w==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@mayanfinance/wormhole-sdk-route/-/wormhole-sdk-route-0.4.1.tgz", + "integrity": "sha512-Qb/DMYesDOgFFjmNAxrn1bmN48nRuFSSMqTkDznu8MVeCwe0cf64u1Hr67/XUvJAqjsOVW08NwnSgpLuUAlQnA==", "dependencies": { "@mayanfinance/swap-sdk": "9.0.0", "@wormhole-foundation/sdk-connect": "^0.10.0", diff --git a/wormhole-connect/package.json b/wormhole-connect/package.json index 612a0056b..db9bda706 100644 --- a/wormhole-connect/package.json +++ b/wormhole-connect/package.json @@ -33,7 +33,7 @@ "@ledgerhq/hw-transport-webhid": "6.27.1", "@ledgerhq/logs": "6.12.0", "@manahippo/aptos-wallet-adapter": "^1.0.8", - "@mayanfinance/wormhole-sdk-route": "^0.4.0", + "@mayanfinance/wormhole-sdk-route": "^0.4.1", "@mui/icons-material": "^5.11.0", "@mui/material": "^5.11.4", "@mysten/sui.js": "^0.32.2", diff --git a/wormhole-connect/src/components/DemoApp/index.tsx b/wormhole-connect/src/components/DemoApp/index.tsx index 907da3157..6767b19ef 100644 --- a/wormhole-connect/src/components/DemoApp/index.tsx +++ b/wormhole-connect/src/components/DemoApp/index.tsx @@ -53,7 +53,7 @@ const parseConfig = (config: string): WormholeConnectConfig => { /* @ts-ignore */ window.TokenBridgeRoute = routes.TokenBridgeRoute; /* @ts-ignore */ - window.ManualCCTPRoute = routes.ManualCCTPRoute; + window.CCTPRoute = routes.CCTPRoute; /* @ts-ignore */ window.MayanRoute = MayanRoute; /* @ts-ignore */ @@ -191,7 +191,7 @@ function DemoApp() { {'RouteConstructor'}
  • -
    ManualCCTPRoute
    +
    CCTPRoute
    {'RouteConstructor'}
  • diff --git a/wormhole-connect/src/hooks/useRoutesQuotesBulk.ts b/wormhole-connect/src/hooks/useRoutesQuotesBulk.ts index e498bb932..75a5f0bab 100644 --- a/wormhole-connect/src/hooks/useRoutesQuotesBulk.ts +++ b/wormhole-connect/src/hooks/useRoutesQuotesBulk.ts @@ -1,7 +1,14 @@ import { useState, useEffect, useMemo } from 'react'; import { useSelector } from 'react-redux'; import type { RootState } from 'store'; -import { Chain, routes } from '@wormhole-foundation/sdk'; +import { + Wormhole, + Chain, + Network, + routes, + circle, + amount, +} from '@wormhole-foundation/sdk'; import { QuoteParams } from 'routes/operator'; import { calculateUSDPriceRaw } from 'utils'; @@ -23,6 +30,8 @@ type HookReturn = { isFetching: boolean; }; +const MAYAN_SWIFT_LIMIT = 1000; // USD + const useRoutesQuotesBulk = (routes: string[], params: Params): HookReturn => { const [isFetching, setIsFetching] = useState(false); const [quotes, setQuotes] = useState([]); @@ -82,17 +91,56 @@ const useRoutesQuotesBulk = (routes: string[], params: Params): HookReturn => { [routes.join(), quotes], ); - // TODO temporary + // TODO temporary logic for beta Mayan support const mayanQuote = quotesMap['MayanSwap']; - if (usdAmount !== undefined && usdAmount > 1000 && mayanQuote !== undefined) { - if ( - mayanQuote.success && - mayanQuote.details?.type.toLowerCase() === 'swift' - ) { + if ( + mayanQuote !== undefined && + mayanQuote.success && + mayanQuote.details?.type.toLowerCase() === 'swift' + ) { + // There are two special cases here for Mayan Swift transfers + // + // 1) Disallow transfers >$1000 (temporary, while in beta) + // 2) For transfers <=$1000, calculate network costs manually, because Mayan API doesn't + // expose relayer fee info for Swift quotes. + // + // TODO all of the code here is horrible and would ideally not exist + + if (usdAmount !== undefined && usdAmount > MAYAN_SWIFT_LIMIT) { + // Temporarily disallow Swift quotes above $1000 + // TODO revisit this quotesMap['MayanSwap'] = { success: false, - error: new Error('Amount exceeds limit of $1000 USD'), + error: new Error(`Amount exceeds limit of $${MAYAN_SWIFT_LIMIT} USD`), }; + } else { + const approxInputUsdValue = calculateUSDPriceRaw( + params.amount, + usdPrices.data, + tokenConfig, + ); + const approxOutputUsdValue = calculateUSDPriceRaw( + amount.display(mayanQuote.destinationToken.amount), + usdPrices.data, + config.tokens[params.destToken], + ); + + if (approxInputUsdValue && approxOutputUsdValue) { + const approxUsdNetworkCost = approxInputUsdValue - approxOutputUsdValue; + + if (!isNaN(approxUsdNetworkCost) && approxUsdNetworkCost > 0) { + (quotesMap['MayanSwap'] as routes.Quote).relayFee = { + token: { + chain: 'Solana' as Chain, + address: Wormhole.parseAddress( + 'Solana', + circle.usdcContract.get('Mainnet', 'Solana') as string, + ), + }, + amount: amount.parse(amount.denoise(approxUsdNetworkCost, 6), 6), + }; + } + } } } diff --git a/wormhole-connect/src/views/v2/Bridge/Routes/SingleRoute.tsx b/wormhole-connect/src/views/v2/Bridge/Routes/SingleRoute.tsx index 2a27cd98a..c60333015 100644 --- a/wormhole-connect/src/views/v2/Bridge/Routes/SingleRoute.tsx +++ b/wormhole-connect/src/views/v2/Bridge/Routes/SingleRoute.tsx @@ -47,6 +47,7 @@ type Props = { const SingleRoute = (props: Props) => { const { classes } = useStyles(); const theme = useTheme(); + const routeConfig = config.routes.get(props.route.name); const { toChain: destChain, @@ -68,6 +69,10 @@ const SingleRoute = (props: Props) => { ); const relayerFee = useMemo(() => { + if (!routeConfig.AUTOMATIC_DEPOSIT) { + return <>You pay gas on {destChain}; + } + if (!quote?.relayFee) { return <>; } @@ -95,19 +100,25 @@ const SingleRoute = (props: Props) => { return <>; } + let feeValue = isFetchingQuote ? ( + + ) : ( + {`${toFixedDecimals(relayFee.toString(), 4)} ${ + feeTokenConfig.symbol + } (${feePrice})`} + ); + + // Wesley made me do it + if (props.route.name === 'MayanSwap') { + feeValue = {`${feePrice}`}; + } + return ( - Relayer fee + Network cost - {isFetchingQuote ? ( - - ) : ( - {`${toFixedDecimals( - relayFee.toString(), - 4, - )} ${feeTokenConfig.symbol} (${feePrice})`} - )} + {feeValue} ); }, [destToken, isFetchingQuote, quote?.relayFee, tokenPrices]); @@ -168,8 +179,6 @@ const SingleRoute = (props: Props) => { return false; } - const routeConfig = config.routes.get(props.route.name); - return !routeConfig.AUTOMATIC_DEPOSIT; }, [props.route.name]);