forked from wormhole-foundation/wormhole-connect
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moving calls into routes from Bridge view to separate hooks (wormhole…
…-foundation#2170) --------- Signed-off-by: Emre Bogazliyanlioglu <emre@wormholelabs.xyz>
- Loading branch information
Showing
20 changed files
with
433 additions
and
247 deletions.
There are no files selected for viewing
125 changes: 125 additions & 0 deletions
125
wormhole-connect/src/hooks/useComputeDestinationTokens.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import config from 'config'; | ||
import { useEffect } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
|
||
import { | ||
setDestToken, | ||
setSupportedDestTokens, | ||
setAllSupportedDestTokens, | ||
getNativeVersionOfToken, | ||
} from 'store/transferInput'; | ||
|
||
import type { Route } from 'config/types'; | ||
import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; | ||
|
||
import { isPorticoRoute } from 'routes/porticoBridge/utils'; | ||
import { ETHBridge } from 'routes/porticoBridge/ethBridge'; | ||
import { wstETHBridge } from 'routes/porticoBridge/wstETHBridge'; | ||
import RouteOperator from 'routes/operator'; | ||
|
||
import { getWrappedToken } from 'utils'; | ||
|
||
type Props = { | ||
sourceChain: ChainName | undefined; | ||
sourceToken: string; | ||
destChain: ChainName | undefined; | ||
destToken: string; | ||
route: Route | undefined; | ||
}; | ||
|
||
export const useComputeDestinationTokens = (props: Props): void => { | ||
const { sourceChain, destChain, sourceToken, destToken, route } = props; | ||
|
||
const dispatch = useDispatch(); | ||
|
||
useEffect(() => { | ||
if (!destChain) { | ||
return; | ||
} | ||
|
||
let canceled = false; | ||
|
||
const computeDestTokens = async () => { | ||
let supported = await RouteOperator.allSupportedDestTokens( | ||
config.tokens[sourceToken], | ||
sourceChain, | ||
destChain, | ||
); | ||
if (sourceToken) { | ||
// If any of the tokens are native to the chain, only select those. | ||
// This is to avoid users inadvertently receiving wrapped versions of the token. | ||
const nativeTokens = supported.filter( | ||
(t) => t.nativeChain === destChain, | ||
); | ||
if (nativeTokens.length > 0) { | ||
supported = nativeTokens; | ||
} | ||
} | ||
dispatch(setSupportedDestTokens(supported)); | ||
const allSupported = await RouteOperator.allSupportedDestTokens( | ||
undefined, | ||
sourceChain, | ||
destChain, | ||
); | ||
dispatch(setAllSupportedDestTokens(allSupported)); | ||
if (destChain && supported.length === 1) { | ||
if (!canceled) { | ||
dispatch(setDestToken(supported[0].key)); | ||
} | ||
} | ||
|
||
// If all the supported tokens are the same token | ||
// select the native version for applicable tokens | ||
const symbols = supported.map((t) => t.symbol); | ||
if ( | ||
destChain && | ||
symbols.every((s) => s === symbols[0]) && | ||
['USDC', 'tBTC'].includes(symbols[0]) | ||
) { | ||
const key = supported.find( | ||
(t) => | ||
t.symbol === symbols[0] && | ||
t.nativeChain === t.tokenId?.chain && | ||
t.nativeChain === destChain, | ||
)?.key; | ||
if (!canceled && key) { | ||
dispatch(setDestToken(key)); | ||
} | ||
} | ||
|
||
// If the source token is supported by a Portico bridge route, | ||
// then select the native version on the dest chain | ||
if ( | ||
sourceToken && | ||
destToken === '' && | ||
destChain && | ||
(!route || isPorticoRoute(route)) | ||
) { | ||
const tokenSymbol = config.tokens[sourceToken]?.symbol; | ||
const porticoTokens = [ | ||
...ETHBridge.SUPPORTED_TOKENS, | ||
...wstETHBridge.SUPPORTED_TOKENS, | ||
]; | ||
if (porticoTokens.includes(tokenSymbol)) { | ||
const isTokenSupported = | ||
sourceToken && supported.some((t) => t.key === sourceToken); | ||
let key = getNativeVersionOfToken(tokenSymbol, destChain); | ||
if (!key) { | ||
const wrapped = getWrappedToken(config.tokens[sourceToken]); | ||
key = getNativeVersionOfToken(wrapped.symbol, destChain); | ||
} | ||
if (!canceled && key && isTokenSupported) { | ||
dispatch(setDestToken(key)); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
computeDestTokens(); | ||
|
||
return () => { | ||
canceled = true; | ||
}; | ||
// IMPORTANT: do not include destToken in dependency array | ||
}, [route, sourceToken, sourceChain, destChain, dispatch]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { useEffect } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
|
||
import { isPorticoRoute } from 'routes/porticoBridge/utils'; | ||
import RouteOperator from 'routes/operator'; | ||
|
||
import { | ||
setReceiveAmount, | ||
setFetchingReceiveAmount, | ||
setReceiveAmountError, | ||
} from 'store/transferInput'; | ||
|
||
import type { Route } from 'config/types'; | ||
import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; | ||
import type { PorticoBridgeState } from 'store/porticoBridge'; | ||
|
||
type Props = { | ||
sourceChain: ChainName | undefined; | ||
sourceToken: string; | ||
destChain: ChainName | undefined; | ||
destToken: string; | ||
route: Route | undefined; | ||
amount: string; | ||
portico: PorticoBridgeState; | ||
toNativeToken: number; | ||
relayerFee: number | undefined; | ||
}; | ||
|
||
export const useComputeReceiveAmount = (props: Props): void => { | ||
const { | ||
sourceChain, | ||
destChain, | ||
sourceToken, | ||
destToken, | ||
amount, | ||
portico, | ||
route, | ||
toNativeToken, | ||
relayerFee, | ||
} = props; | ||
|
||
const dispatch = useDispatch(); | ||
|
||
useEffect(() => { | ||
if ( | ||
!route || | ||
!amount || | ||
!sourceToken || | ||
!destToken || | ||
!sourceChain || | ||
!destChain | ||
) { | ||
return; | ||
} | ||
|
||
const recomputeReceive = async () => { | ||
try { | ||
const routeOptions = isPorticoRoute(route) | ||
? portico | ||
: { toNativeToken, relayerFee }; | ||
|
||
dispatch(setFetchingReceiveAmount()); | ||
|
||
const newReceiveAmount = await RouteOperator.computeReceiveAmount( | ||
route, | ||
Number.parseFloat(amount), | ||
sourceToken, | ||
destToken, | ||
sourceChain, | ||
destChain, | ||
routeOptions, | ||
); | ||
dispatch(setReceiveAmount(newReceiveAmount.toString())); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
} catch (e: any) { | ||
dispatch(setReceiveAmountError(e.message)); | ||
} | ||
}; | ||
recomputeReceive(); | ||
}, [ | ||
amount, | ||
toNativeToken, | ||
relayerFee, | ||
route, | ||
sourceToken, | ||
destToken, | ||
destChain, | ||
sourceChain, | ||
portico, | ||
dispatch, | ||
]); | ||
}; |
46 changes: 46 additions & 0 deletions
46
wormhole-connect/src/hooks/useComputeReceiverNativeBalance.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import config from 'config'; | ||
import { useEffect } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
import { BigNumber } from 'ethers'; | ||
import { setReceiverNativeBalance } from 'store/transferInput'; | ||
|
||
import type { WalletData } from 'store/wallet'; | ||
import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; | ||
|
||
import { getTokenDecimals } from 'utils'; | ||
import { toChainId } from 'utils/sdk'; | ||
import { toDecimals } from 'utils/balance'; | ||
|
||
type Props = { | ||
sourceChain: ChainName | undefined; | ||
destChain: ChainName | undefined; | ||
receiving: WalletData; | ||
}; | ||
|
||
export const useComputeReceiverNativeBalance = (props: Props): void => { | ||
const { sourceChain, destChain, receiving } = props; | ||
const dispatch = useDispatch(); | ||
// check destination native balance | ||
useEffect(() => { | ||
if (!sourceChain || !destChain || !receiving.address) { | ||
return; | ||
} | ||
|
||
const chainConfig = config.chains?.[destChain]; | ||
|
||
config.wh | ||
.getNativeBalance(receiving.address, destChain) | ||
.then((res: BigNumber) => { | ||
const tokenConfig = chainConfig?.gasToken | ||
? config.tokens[chainConfig.gasToken] | ||
: undefined; | ||
if (!tokenConfig) | ||
throw new Error('Could not get native gas token config'); | ||
const decimals = getTokenDecimals( | ||
toChainId(tokenConfig.nativeChain), | ||
'native', | ||
); | ||
dispatch(setReceiverNativeBalance(toDecimals(res, decimals, 6))); | ||
}); | ||
}, [sourceChain, destChain, receiving.address, dispatch]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import config from 'config'; | ||
import { useEffect } from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
|
||
import { setToken, setSupportedSourceTokens } from 'store/transferInput'; | ||
|
||
import type { Route } from 'config/types'; | ||
import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; | ||
|
||
import RouteOperator from 'routes/operator'; | ||
|
||
type Props = { | ||
sourceChain: ChainName | undefined; | ||
sourceToken: string; | ||
destChain: ChainName | undefined; | ||
destToken: string; | ||
route: Route | undefined; | ||
}; | ||
|
||
export const useComputeSourceTokens = (props: Props): void => { | ||
const { sourceChain, destChain, sourceToken, destToken, route } = props; | ||
|
||
const dispatch = useDispatch(); | ||
|
||
useEffect(() => { | ||
if (!sourceChain) { | ||
return; | ||
} | ||
|
||
let active = true; | ||
|
||
const computeSrcTokens = async () => { | ||
const supported = await RouteOperator.allSupportedSourceTokens( | ||
config.tokens[destToken], | ||
sourceChain, | ||
destChain, | ||
); | ||
if (active) { | ||
dispatch(setSupportedSourceTokens(supported)); | ||
const isTokenSupported = | ||
sourceToken && supported.some((t) => t.key === sourceToken); | ||
if (!isTokenSupported) { | ||
dispatch(setToken('')); | ||
} | ||
if (supported.length === 1 && sourceToken === '') { | ||
dispatch(setToken(supported[0].key)); | ||
} | ||
} | ||
}; | ||
|
||
computeSrcTokens(); | ||
|
||
return () => { | ||
active = false; | ||
}; | ||
// IMPORTANT: do not include token in dependency array | ||
}, [route, sourceChain, destToken, dispatch]); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import config from 'config'; | ||
import RouteOperator from 'routes/operator'; | ||
import { getWrappedToken } from 'utils'; | ||
|
||
import type { ChainName } from '@wormhole-foundation/wormhole-connect-sdk'; | ||
import type { Route } from 'config/types'; | ||
|
||
type Props = { | ||
destChain: ChainName | undefined; | ||
destToken: string; | ||
route: Route | undefined; | ||
valid: boolean; | ||
isTransactionInProgress: boolean; | ||
}; | ||
|
||
export const useGasSlider = ( | ||
props: Props, | ||
): { | ||
disabled: boolean; | ||
showGasSlider: boolean | undefined; | ||
} => { | ||
const { destChain, destToken, route, isTransactionInProgress, valid } = props; | ||
|
||
const disabled = !valid || isTransactionInProgress; | ||
const toChainConfig = destChain ? config.chains[destChain] : undefined; | ||
const gasTokenConfig = toChainConfig | ||
? config.tokens[toChainConfig.gasToken] | ||
: undefined; | ||
const wrappedGasTokenConfig = gasTokenConfig | ||
? getWrappedToken(gasTokenConfig) | ||
: undefined; | ||
const willReceiveGasToken = | ||
wrappedGasTokenConfig && destToken === wrappedGasTokenConfig.key; | ||
const showGasSlider = | ||
route && | ||
RouteOperator.getRoute(route).NATIVE_GAS_DROPOFF_SUPPORTED && | ||
!willReceiveGasToken; | ||
|
||
return { | ||
disabled, | ||
showGasSlider, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.