).buildSendTransaction({
+ const adapter = assertGetUtxoChainAdapter(chainId)
+ return adapter.buildSendTransaction({
to,
value,
wallet,
@@ -205,7 +197,7 @@ export const handleSend = async ({
chainSpecific: { gas: fees.chainSpecific.gasLimit, fee: fees.txFee },
sendMax: sendInput.sendMax,
}
-
+ const adapter = assertGetCosmosSdkChainAdapter(chainId)
return adapter.buildSendTransaction(params)
}
@@ -214,6 +206,8 @@ export const handleSend = async ({
const txToSign = result.txToSign
+ const adapter = assertGetChainAdapter(chainId)
+
const senderAddress = await adapter.getAddress({
accountNumber: accountMetadata.bip44Params.accountNumber,
accountType: accountMetadata.accountType,
diff --git a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts
index f79efc92ba3..649ca643668 100644
--- a/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts
+++ b/src/components/MultiHopTrade/hooks/useGetTradeQuotes/getTradeQuoteArgs.ts
@@ -1,4 +1,3 @@
-import type { EvmChainAdapter, UtxoChainAdapter } from '@shapeshiftoss/chain-adapters'
import type { HDWallet } from '@shapeshiftoss/hdwallet-core'
import { supportsETH } from '@shapeshiftoss/hdwallet-core'
import type { GetTradeQuoteInput } from '@shapeshiftoss/swapper'
@@ -9,8 +8,9 @@ import {
isUtxoSwap,
} from 'components/MultiHopTrade/hooks/useGetTradeQuotes/typeGuards'
import type { TradeQuoteInputCommonArgs } from 'components/MultiHopTrade/types'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { toBaseUnit } from 'lib/math'
+import { assertGetEvmChainAdapter } from 'lib/utils/evm'
+import { assertGetUtxoChainAdapter } from 'lib/utils/utxo'
export type GetTradeQuoteInputArgs = {
sellAsset: Asset
@@ -64,9 +64,7 @@ export const getTradeQuoteArgs = async ({
}
if (isEvmSwap(sellAsset?.chainId) || isCosmosSdkSwap(sellAsset?.chainId)) {
const supportsEIP1559 = supportsETH(wallet) && (await wallet.ethSupportsEIP1559())
- const sellAssetChainAdapter = getChainAdapterManager().get(
- sellAsset.chainId,
- ) as unknown as EvmChainAdapter
+ const sellAssetChainAdapter = assertGetEvmChainAdapter(sellAsset.chainId)
const sendAddress = await sellAssetChainAdapter.getAddress({
accountNumber: sellAccountNumber,
wallet,
@@ -81,9 +79,7 @@ export const getTradeQuoteArgs = async ({
}
} else if (isUtxoSwap(sellAsset?.chainId)) {
if (!sellAccountType) return
- const sellAssetChainAdapter = getChainAdapterManager().get(
- sellAsset.chainId,
- ) as unknown as UtxoChainAdapter
+ const sellAssetChainAdapter = assertGetUtxoChainAdapter(sellAsset.chainId)
const sendAddress = await sellAssetChainAdapter.getAddress({
accountNumber: sellAccountNumber,
wallet,
diff --git a/src/components/MultiHopTrade/hooks/useTradeExecution/helpers.ts b/src/components/MultiHopTrade/hooks/useTradeExecution/helpers.ts
index 598b2fe4751..74f063ff159 100644
--- a/src/components/MultiHopTrade/hooks/useTradeExecution/helpers.ts
+++ b/src/components/MultiHopTrade/hooks/useTradeExecution/helpers.ts
@@ -1,9 +1,9 @@
import type { ChainId } from '@shapeshiftoss/caip'
-import type { UtxoChainAdapter } from '@shapeshiftoss/chain-adapters'
import type { HDWallet } from '@shapeshiftoss/hdwallet-core'
import type { FromOrXpub } from '@shapeshiftoss/swapper'
import type { AccountMetadata } from '@shapeshiftoss/types'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
+import { assertGetChainAdapter } from 'lib/utils'
+import { assertGetUtxoChainAdapter } from 'lib/utils/utxo'
import { isUtxoChainId } from 'state/slices/portfolioSlice/utils'
export type WithFromOrXpubParams = {
@@ -19,23 +19,17 @@ export const withFromOrXpub =
{ chainId, accountMetadata, wallet }: WithFromOrXpubParams,
fnParams: Omit,
): Promise => {
- const chainAdapterManager = getChainAdapterManager()
- const adapter = chainAdapterManager.get(chainId)
- if (!adapter) throw new Error(`No adapter for ChainId: ${chainId}`)
-
const accountNumber = accountMetadata.bip44Params.accountNumber
if (isUtxoChainId(chainId)) {
const accountType = accountMetadata.accountType
if (!accountType) throw new Error('Account number required')
- const { xpub } = await (adapter as unknown as UtxoChainAdapter).getPublicKey(
- wallet,
- accountNumber,
- accountType,
- )
+ const adapter = assertGetUtxoChainAdapter(chainId)
+ const { xpub } = await adapter.getPublicKey(wallet, accountNumber, accountType)
return wrappedFunction({ ...fnParams, xpub } as P)
} else {
+ const adapter = assertGetChainAdapter(chainId)
const from = await adapter.getAddress({ wallet, accountNumber })
return wrappedFunction({ ...fnParams, from } as P)
}
diff --git a/src/components/Sweep.tsx b/src/components/Sweep.tsx
index 2c6c71abd13..b5f65069135 100644
--- a/src/components/Sweep.tsx
+++ b/src/components/Sweep.tsx
@@ -1,14 +1,13 @@
import { Box, Button, Divider, Flex, Skeleton, Stack, Text as CText } from '@chakra-ui/react'
import { type AccountId, type AssetId, fromAssetId } from '@shapeshiftoss/caip'
-import type { UtxoBaseAdapter, UtxoChainId } from '@shapeshiftoss/chain-adapters'
import { FeeDataKey } from '@shapeshiftoss/chain-adapters'
import { useCallback, useEffect, useState } from 'react'
import { useTranslate } from 'react-polyglot'
import { Row } from 'components/Row/Row'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { useWallet } from 'hooks/useWallet/useWallet'
import { fromBaseUnit } from 'lib/math'
import { sleep } from 'lib/poll/poll'
+import { assertGetUtxoChainAdapter } from 'lib/utils/utxo'
import { useGetEstimatedFeesQuery } from 'pages/Lending/hooks/useGetEstimatedFeesQuery'
import { selectAssetById } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'
@@ -90,7 +89,7 @@ export const Sweep = ({
}
}, [accountId, assetId, estimatedFeesData, fromAddress, wallet])
- const adapter = getChainAdapterManager().get(fromAssetId(assetId).chainId)
+ const adapter = assertGetUtxoChainAdapter(fromAssetId(assetId).chainId)
useEffect(() => {
if (!adapter || !fromAddress) return
@@ -99,7 +98,7 @@ export const Sweep = ({
if (!txId) return
;(async () => {
await sleep(15_000)
- const utxos = await (adapter as unknown as UtxoBaseAdapter).getUtxos({
+ const utxos = await adapter.getUtxos({
pubkey: fromAddress,
})
if (utxos.some(utxo => utxo.txid === txId)) handleSwepSeen()
diff --git a/src/context/PluginProvider/PluginProvider.tsx b/src/context/PluginProvider/PluginProvider.tsx
index 7de8edc722f..34da47aa585 100644
--- a/src/context/PluginProvider/PluginProvider.tsx
+++ b/src/context/PluginProvider/PluginProvider.tsx
@@ -59,7 +59,7 @@ export const PluginProvider = ({ children }: PluginProviderProps): JSX.Element =
let pluginRoutes: Route[] = []
// newly registered will be default + what comes from plugins
- const newChainAdapters: { [k in ChainId]?: () => ChainAdapter } = {}
+ const newChainAdapters: { [k in ChainId]?: () => ChainAdapter } = {}
// register providers from each plugin
for (const plugin of pluginManager.values()) {
diff --git a/src/features/defi/providers/cosmos/components/CosmosManager/Claim/CosmosClaim.tsx b/src/features/defi/providers/cosmos/components/CosmosManager/Claim/CosmosClaim.tsx
index a8e3d7f884b..218fc057ae4 100644
--- a/src/features/defi/providers/cosmos/components/CosmosManager/Claim/CosmosClaim.tsx
+++ b/src/features/defi/providers/cosmos/components/CosmosManager/Claim/CosmosClaim.tsx
@@ -1,7 +1,6 @@
import { Center, CircularProgress } from '@chakra-ui/react'
import type { AccountId } from '@shapeshiftoss/caip'
import { toAssetId } from '@shapeshiftoss/caip'
-import type { CosmosSdkBaseAdapter, CosmosSdkChainId } from '@shapeshiftoss/chain-adapters'
import { DefiModalContent } from 'features/defi/components/DefiModal/DefiModalContent'
import { DefiModalHeader } from 'features/defi/components/DefiModal/DefiModalHeader'
import type {
@@ -15,9 +14,9 @@ import { useTranslate } from 'react-polyglot'
import type { AccountDropdownProps } from 'components/AccountDropdown/AccountDropdown'
import type { DefiStepProps } from 'components/DeFi/components/Steps'
import { Steps } from 'components/DeFi/components/Steps'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter'
import { useWallet } from 'hooks/useWallet/useWallet'
+import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk'
import { serializeUserStakingId, toValidatorId } from 'state/slices/opportunitiesSlice/utils'
import {
selectAssetById,
@@ -69,10 +68,7 @@ export const CosmosClaim: React.FC = ({
try {
if (!earnOpportunityData) return
- const chainAdapterManager = getChainAdapterManager()
- const chainAdapter = chainAdapterManager.get(
- chainId,
- ) as unknown as CosmosSdkBaseAdapter
+ const chainAdapter = assertGetCosmosSdkChainAdapter(chainId)
if (!(walletState.wallet && validatorAddress && chainAdapter)) return
dispatch({
type: CosmosClaimActionType.SET_OPPORTUNITY,
diff --git a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
index 041a1458b8e..0de40656ba4 100644
--- a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
+++ b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts
@@ -1,17 +1,20 @@
import { MaxUint256 } from '@ethersproject/constants'
-import { ethAssetId, fromAccountId } from '@shapeshiftoss/caip'
-import type { ethereum } from '@shapeshiftoss/chain-adapters'
+import { ethAssetId, fromAccountId, fromAssetId } from '@shapeshiftoss/caip'
import { supportsETH } from '@shapeshiftoss/hdwallet-core'
import { ETH_FOX_POOL_CONTRACT_ADDRESS } from 'contracts/constants'
import { getOrCreateContractByAddress } from 'contracts/contractManager'
import { useCallback, useMemo } from 'react'
import { encodeFunctionData, getAddress } from 'viem'
import { useFoxEth } from 'context/FoxEthProvider/FoxEthProvider'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { useWallet } from 'hooks/useWallet/useWallet'
import { toBaseUnit } from 'lib/math'
import { isValidAccountNumber } from 'lib/utils'
-import { buildAndBroadcast, createBuildCustomTxInput, getFees } from 'lib/utils/evm'
+import {
+ assertGetEvmChainAdapter,
+ buildAndBroadcast,
+ createBuildCustomTxInput,
+ getFees,
+} from 'lib/utils/evm'
import type { FoxEthStakingContractAddress } from 'state/slices/opportunitiesSlice/constants'
import { foxEthLpAssetId } from 'state/slices/opportunitiesSlice/constants'
import { selectAccountNumberByAccountId, selectAssetById } from 'state/slices/selectors'
@@ -45,10 +48,7 @@ export const useFoxFarming = (
const wallet = useWallet().state.wallet
- const chainAdapterManager = getChainAdapterManager()
- const adapter = chainAdapterManager.get(ethAsset.chainId) as unknown as
- | ethereum.ChainAdapter
- | undefined
+ const adapter = useMemo(() => assertGetEvmChainAdapter(fromAssetId(ethAssetId).chainId), [])
const foxFarmingContract = useMemo(
() => getOrCreateContractByAddress(contractAddress),
@@ -60,8 +60,6 @@ export const useFoxFarming = (
try {
if (skip || !isValidAccountNumber(accountNumber) || !wallet) return
- if (!adapter) throw new Error(`no adapter available for ${ethAsset.chainId}`)
-
const data = encodeFunctionData({
abi: foxFarmingContract.abi,
functionName: 'stake',
@@ -93,7 +91,6 @@ export const useFoxFarming = (
accountNumber,
wallet,
adapter,
- ethAsset.chainId,
foxFarmingContract.abi,
lpAsset.precision,
contractAddress,
@@ -105,8 +102,6 @@ export const useFoxFarming = (
try {
if (skip || !isValidAccountNumber(accountNumber) || !wallet) return
- if (!adapter) throw new Error(`no adapter available for ${ethAsset.chainId}`)
-
const data = encodeFunctionData({
abi: foxFarmingContract.abi,
functionName: isExiting ? 'exit' : 'withdraw',
@@ -133,16 +128,7 @@ export const useFoxFarming = (
console.error(err)
}
},
- [
- adapter,
- accountNumber,
- contractAddress,
- ethAsset.chainId,
- foxFarmingContract,
- lpAsset.precision,
- wallet,
- skip,
- ],
+ [adapter, accountNumber, contractAddress, foxFarmingContract, lpAsset.precision, wallet, skip],
)
const allowance = useCallback(async () => {
@@ -155,7 +141,7 @@ export const useFoxFarming = (
}, [farmingAccountId, contractAddress, skip])
const getApproveFees = useCallback(() => {
- if (!adapter || !isValidAccountNumber(accountNumber) || !wallet) return
+ if (!isValidAccountNumber(accountNumber) || !wallet) return
const data = encodeFunctionData({
abi: uniV2LPContract.abi,
@@ -175,7 +161,7 @@ export const useFoxFarming = (
const getStakeFees = useCallback(
(lpAmount: string) => {
- if (skip || !adapter || !isValidAccountNumber(accountNumber) || !wallet) return
+ if (skip || !isValidAccountNumber(accountNumber) || !wallet) return
const data = encodeFunctionData({
abi: foxFarmingContract.abi,
@@ -197,7 +183,7 @@ export const useFoxFarming = (
const getUnstakeFees = useCallback(
(lpAmount: string, isExiting: boolean) => {
- if (skip || !adapter || !isValidAccountNumber(accountNumber) || !wallet) return
+ if (skip || !isValidAccountNumber(accountNumber) || !wallet) return
const data = encodeFunctionData({
abi: foxFarmingContract.abi,
@@ -219,7 +205,7 @@ export const useFoxFarming = (
const getClaimFees = useCallback(
async (userAddress: string) => {
- if (!adapter || !userAddress || !wallet) return
+ if (!userAddress || !wallet) return
const data = encodeFunctionData({
abi: foxFarmingContract.abi,
@@ -241,8 +227,6 @@ export const useFoxFarming = (
const approve = useCallback(async () => {
if (!wallet || !isValidAccountNumber(accountNumber)) return
- if (!adapter) throw new Error(`no adapter available for ${ethAsset.chainId}`)
-
const data = encodeFunctionData({
abi: uniV2LPContract.abi,
functionName: 'approve',
@@ -266,13 +250,11 @@ export const useFoxFarming = (
})
return txid
- }, [accountNumber, adapter, ethAsset.chainId, contractAddress, getApproveFees, wallet])
+ }, [accountNumber, adapter, contractAddress, getApproveFees, wallet])
const claimRewards = useCallback(async () => {
if (skip || !isValidAccountNumber(accountNumber) || !wallet) return
- if (!adapter) throw new Error(`no adapter available for ${ethAsset.chainId}`)
-
const data = encodeFunctionData({
abi: foxFarmingContract.abi,
functionName: 'getReward',
@@ -294,7 +276,7 @@ export const useFoxFarming = (
})
return txid
- }, [accountNumber, adapter, ethAsset.chainId, contractAddress, foxFarmingContract, skip, wallet])
+ }, [accountNumber, adapter, contractAddress, foxFarmingContract, skip, wallet])
return {
allowance,
diff --git a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx
index 3228a5a37b1..7e0517004a8 100644
--- a/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx
+++ b/src/features/defi/providers/thorchain-savers/components/ThorchainSaversManager/Withdraw/components/Withdraw.tsx
@@ -2,7 +2,7 @@ import { Alert, AlertIcon, Skeleton, useToast } from '@chakra-ui/react'
import { AddressZero } from '@ethersproject/constants'
import type { AccountId } from '@shapeshiftoss/caip'
import { fromAccountId, fromAssetId, toAssetId } from '@shapeshiftoss/caip'
-import type { GetFeeDataInput, UtxoBaseAdapter, UtxoChainId } from '@shapeshiftoss/chain-adapters'
+import type { GetFeeDataInput, UtxoChainId } from '@shapeshiftoss/chain-adapters'
import type { Asset } from '@shapeshiftoss/types'
import { Err, Ok, type Result } from '@sniptt/monads'
import { useQueryClient } from '@tanstack/react-query'
@@ -24,7 +24,6 @@ import type { StepComponentProps } from 'components/DeFi/components/Steps'
import { Row } from 'components/Row/Row'
import { Text } from 'components/Text'
import type { TextPropTypes } from 'components/Text/Text'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter'
import { getSupportedEvmChainIds } from 'hooks/useEvm/useEvm'
import { useWallet } from 'hooks/useWallet/useWallet'
@@ -43,6 +42,7 @@ import {
queryFn as getThorchainSaversWithdrawQuoteQueryFn,
useGetThorchainSaversWithdrawQuoteQuery,
} from 'lib/utils/thorchain/hooks/useGetThorchainSaversWithdrawQuoteQuery'
+import { assertGetUtxoChainAdapter } from 'lib/utils/utxo'
import { useGetEstimatedFeesQuery } from 'pages/Lending/hooks/useGetEstimatedFeesQuery'
import { useIsSweepNeededQuery } from 'pages/Lending/hooks/useIsSweepNeededQuery'
import type { ThorchainSaversWithdrawQuoteResponseSuccess } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/types'
@@ -245,8 +245,6 @@ export const Withdraw: React.FC = ({ accountId, fromAddress, onNe
// re-returning the outbound fee error, which should take precedence over the withdraw gas estimation one
if (maybeOutboundFeeCryptoBaseUnit.isErr()) return maybeOutboundFeeCryptoBaseUnit
- const chainAdapters = getChainAdapterManager()
-
if (isTokenWithdraw) {
if (!saversRouterContractAddress)
return Err(`No router contract address found for feeAsset: ${feeAsset.assetId}`)
@@ -310,7 +308,7 @@ export const Withdraw: React.FC = ({ accountId, fromAddress, onNe
const quote = maybeQuote.unwrap()
// We're lying to Ts, this isn't always an UtxoBaseAdapter
// But typing this as any chain-adapter won't narrow down its type and we'll have errors at `chainSpecific` property
- const adapter = chainAdapters.get(chainId) as unknown as UtxoBaseAdapter
+ const adapter = assertGetUtxoChainAdapter(chainId)
const getFeeDataInput: GetFeeDataInput = {
to: quote.inbound_address,
value: dustAmountCryptoBaseUnit,
diff --git a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts
index e6380005e4a..ff903724b56 100644
--- a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts
+++ b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts
@@ -1,7 +1,6 @@
import { MaxUint256 } from '@ethersproject/constants'
import type { AccountId, AssetId } from '@shapeshiftoss/caip'
import { ethAssetId, ethChainId, fromAccountId, fromAssetId, toAssetId } from '@shapeshiftoss/caip'
-import type { ethereum } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import {
UNISWAP_V2_ROUTER_02_CONTRACT_ADDRESS,
@@ -13,11 +12,15 @@ import { ethers } from 'ethers'
import isNumber from 'lodash/isNumber'
import { useCallback, useMemo } from 'react'
import { type Address, encodeFunctionData, getAddress } from 'viem'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { useWallet } from 'hooks/useWallet/useWallet'
import { bn, bnOrZero } from 'lib/bignumber/bignumber'
import { fromBaseUnit, toBaseUnit } from 'lib/math'
-import { buildAndBroadcast, createBuildCustomTxInput, getFees } from 'lib/utils/evm'
+import {
+ assertGetEvmChainAdapter,
+ buildAndBroadcast,
+ createBuildCustomTxInput,
+ getFees,
+} from 'lib/utils/evm'
import { uniswapV2Router02AssetId } from 'state/slices/opportunitiesSlice/constants'
import {
selectAccountNumberByAccountId,
@@ -68,10 +71,7 @@ export const useUniV2LiquidityPool = ({
const wallet = useWallet().state.wallet
const asset0Price = useAppSelector(state => selectMarketDataById(state, assetId0OrWeth)).price
- const chainAdapterManager = getChainAdapterManager()
- const adapter = chainAdapterManager.get(ethChainId) as unknown as
- | ethereum.ChainAdapter
- | undefined
+ const adapter = useMemo(() => assertGetEvmChainAdapter(ethChainId), [])
const uniswapRouterContract = useMemo(
() => (skip ? null : getOrCreateContractByAddress(UNISWAP_V2_ROUTER_02_CONTRACT_ADDRESS)),
@@ -196,8 +196,6 @@ export const useUniV2LiquidityPool = ({
try {
if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return
- if (!adapter) throw new Error(`no adapter available for ${asset0.chainId}`)
-
const maybeEthAmount = (() => {
if (assetId0OrWeth === wethAssetId) return token0Amount
if (assetId1OrWeth === wethAssetId) return token1Amount
@@ -227,7 +225,6 @@ export const useUniV2LiquidityPool = ({
[
accountNumber,
adapter,
- asset0,
assetId0OrWeth,
assetId1OrWeth,
makeAddLiquidityData,
@@ -321,8 +318,6 @@ export const useUniV2LiquidityPool = ({
try {
if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return
- if (!adapter) throw new Error(`no adapter available for ${asset0.chainId}`)
-
const data = makeRemoveLiquidityData({
asset0ContractAddress,
asset1ContractAddress,
@@ -357,7 +352,6 @@ export const useUniV2LiquidityPool = ({
accountNumber,
uniswapRouterContract,
wallet,
- asset0.chainId,
makeRemoveLiquidityData,
asset0ContractAddress,
asset1ContractAddress,
@@ -444,7 +438,7 @@ export const useUniV2LiquidityPool = ({
const getApproveFees = useCallback(
(contractAddress: Address) => {
- if (skip || !adapter || !isNumber(accountNumber) || !wallet) return
+ if (skip || !isNumber(accountNumber) || !wallet) return
const contract = getOrCreateContractByType({
address: contractAddress,
@@ -477,14 +471,7 @@ export const useUniV2LiquidityPool = ({
const getDepositFees = useCallback(
({ token0Amount, token1Amount }: { token0Amount: string; token1Amount: string }) => {
- if (
- skip ||
- !adapter ||
- !accountId ||
- !isNumber(accountNumber) ||
- !uniswapRouterContract ||
- !wallet
- )
+ if (skip || !accountId || !isNumber(accountNumber) || !uniswapRouterContract || !wallet)
return
// https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#addliquidityeth
@@ -571,7 +558,7 @@ export const useUniV2LiquidityPool = ({
const getWithdrawFees = useCallback(
(lpAmount: string, asset0Amount: string, asset1Amount: string) => {
- if (skip || !adapter || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return
+ if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return
const data = makeRemoveLiquidityData({
lpAmount,
@@ -606,8 +593,6 @@ export const useUniV2LiquidityPool = ({
async (contractAddress: Address) => {
if (skip || !wallet || !isNumber(accountNumber)) return
- if (!adapter) throw new Error(`no adapter available for ${ethChainId}`)
-
const contract = getOrCreateContractByType({
address: contractAddress,
type: ContractType.ERC20,
diff --git a/src/lib/account/cosmosSdk.ts b/src/lib/account/cosmosSdk.ts
index c25ce7b215b..085f761a7e1 100644
--- a/src/lib/account/cosmosSdk.ts
+++ b/src/lib/account/cosmosSdk.ts
@@ -1,9 +1,7 @@
import { CHAIN_REFERENCE, fromChainId, toAccountId } from '@shapeshiftoss/caip'
-import type { CosmosSdkChainId } from '@shapeshiftoss/chain-adapters'
-import { cosmosSdkChainIds } from '@shapeshiftoss/chain-adapters'
import { supportsCosmos, supportsThorchain } from '@shapeshiftoss/hdwallet-core'
import type { AccountMetadataById } from '@shapeshiftoss/types'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
+import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk'
import type { DeriveAccountIdsAndMetadata } from './account'
@@ -12,10 +10,8 @@ export const deriveCosmosSdkAccountIdsAndMetadata: DeriveAccountIdsAndMetadata =
const result = await (async () => {
let acc: AccountMetadataById = {}
for (const chainId of chainIds) {
- if (!cosmosSdkChainIds.includes(chainId as CosmosSdkChainId))
- throw new Error(`${chainId} does not exist in ${cosmosSdkChainIds}`)
const { chainReference } = fromChainId(chainId)
- const adapter = getChainAdapterManager().get(chainId)!
+ const adapter = assertGetCosmosSdkChainAdapter(chainId)
if (chainReference === CHAIN_REFERENCE.CosmosHubMainnet) {
if (!supportsCosmos(wallet)) continue
}
diff --git a/src/lib/account/evm.ts b/src/lib/account/evm.ts
index e07f88fb62f..a3aeca114e5 100644
--- a/src/lib/account/evm.ts
+++ b/src/lib/account/evm.ts
@@ -1,6 +1,4 @@
import { CHAIN_REFERENCE, fromChainId, toAccountId } from '@shapeshiftoss/caip'
-import type { EvmChainId } from '@shapeshiftoss/chain-adapters'
-import { evmChainIds } from '@shapeshiftoss/chain-adapters'
import {
supportsArbitrum,
supportsArbitrumNova,
@@ -12,7 +10,7 @@ import {
supportsPolygon,
} from '@shapeshiftoss/hdwallet-core'
import type { AccountMetadataById } from '@shapeshiftoss/types'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
+import { assertGetEvmChainAdapter } from 'lib/utils/evm'
import type { DeriveAccountIdsAndMetadata } from './account'
@@ -22,11 +20,8 @@ export const deriveEvmAccountIdsAndMetadata: DeriveAccountIdsAndMetadata = async
const result = await (async () => {
let acc: AccountMetadataById = {}
for (const chainId of chainIds) {
- if (!evmChainIds.includes(chainId as EvmChainId))
- throw new Error(`${chainId} does not exist in ${evmChainIds}`)
-
const { chainReference } = fromChainId(chainId)
- const adapter = getChainAdapterManager().get(chainId)!
+ const adapter = assertGetEvmChainAdapter(chainId)
if (chainReference === CHAIN_REFERENCE.EthereumMainnet) {
if (!supportsETH(wallet)) continue
diff --git a/src/lib/account/utxo.ts b/src/lib/account/utxo.ts
index 38992cffe5f..6e9e5f5214d 100644
--- a/src/lib/account/utxo.ts
+++ b/src/lib/account/utxo.ts
@@ -1,5 +1,5 @@
import { toAccountId } from '@shapeshiftoss/caip'
-import type { UtxoBaseAdapter, UtxoChainId } from '@shapeshiftoss/chain-adapters'
+import type { UtxoChainId } from '@shapeshiftoss/chain-adapters'
import {
convertXpubVersion,
toRootDerivationPath,
@@ -10,7 +10,7 @@ import { bip32ToAddressNList, supportsBTC } from '@shapeshiftoss/hdwallet-core'
import { MetaMaskShapeShiftMultiChainHDWallet } from '@shapeshiftoss/hdwallet-shapeshift-multichain'
import type { AccountMetadataById } from '@shapeshiftoss/types'
import { UtxoAccountType } from '@shapeshiftoss/types'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
+import { assertGetUtxoChainAdapter } from 'lib/utils/utxo'
import type { DeriveAccountIdsAndMetadata } from './account'
@@ -22,9 +22,7 @@ export const deriveUtxoAccountIdsAndMetadata: DeriveAccountIdsAndMetadata = asyn
for (const chainId of chainIds) {
if (!utxoChainIds.includes(chainId as UtxoChainId))
throw new Error(`${chainId} does not exist in ${utxoChainIds}`)
- const adapter = getChainAdapterManager().get(
- chainId,
- ) as unknown as UtxoBaseAdapter
+ const adapter = assertGetUtxoChainAdapter(chainId)
let supportedAccountTypes = adapter.getSupportedAccountTypes()
if (wallet instanceof MetaMaskShapeShiftMultiChainHDWallet) {
diff --git a/src/lib/swapper/swappers/ThorchainSwapper/utils/test-data/setupThorswapDeps.ts b/src/lib/swapper/swappers/ThorchainSwapper/utils/test-data/setupThorswapDeps.ts
index 3661746bd83..e7971c9bdc5 100644
--- a/src/lib/swapper/swappers/ThorchainSwapper/utils/test-data/setupThorswapDeps.ts
+++ b/src/lib/swapper/swappers/ThorchainSwapper/utils/test-data/setupThorswapDeps.ts
@@ -38,6 +38,6 @@ export const mockChainAdapterManager: ChainAdapterManager = new Map([
},
}),
),
- } as unknown as ChainAdapter<'eip155'>,
+ } as unknown as ChainAdapter,
],
])
diff --git a/src/lib/utils/cosmosSdk.ts b/src/lib/utils/cosmosSdk.ts
index 3500999e2de..8ba0c0f7fd7 100644
--- a/src/lib/utils/cosmosSdk.ts
+++ b/src/lib/utils/cosmosSdk.ts
@@ -1,7 +1,11 @@
import type { ChainId } from '@shapeshiftoss/caip'
-import type { CosmosSdkChainAdapter, CosmosSdkChainId } from '@shapeshiftoss/chain-adapters'
+import type {
+ CosmosSdkChainAdapter,
+ CosmosSdkChainId,
+ thorchain,
+} from '@shapeshiftoss/chain-adapters'
import { cosmosSdkChainIds } from '@shapeshiftoss/chain-adapters'
-import type { KnownChainIds } from '@shapeshiftoss/types'
+import { KnownChainIds } from '@shapeshiftoss/types'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
export const isCosmosSdkChainAdapter = (
@@ -24,3 +28,7 @@ export const assertGetCosmosSdkChainAdapter = (
return adapter
}
+
+export const assertGetThorchainChainAdapter = (): thorchain.ChainAdapter => {
+ return assertGetCosmosSdkChainAdapter(KnownChainIds.ThorchainMainnet) as thorchain.ChainAdapter
+}
diff --git a/src/lib/utils/evm.ts b/src/lib/utils/evm.ts
index e13972e0e9a..8d4b5067c49 100644
--- a/src/lib/utils/evm.ts
+++ b/src/lib/utils/evm.ts
@@ -7,13 +7,9 @@ import type {
SignTx,
} from '@shapeshiftoss/chain-adapters'
import { evmChainIds } from '@shapeshiftoss/chain-adapters'
-import type { ETHSignTx, HDWallet } from '@shapeshiftoss/hdwallet-core'
+import type { HDWallet } from '@shapeshiftoss/hdwallet-core'
import { supportsETH } from '@shapeshiftoss/hdwallet-core'
-import type {
- EvmTransactionExecutionProps,
- EvmTransactionRequest,
- ExecuteTradeArgs,
-} from '@shapeshiftoss/swapper'
+import type { EvmTransactionExecutionProps, EvmTransactionRequest } from '@shapeshiftoss/swapper'
import type { KnownChainIds } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import { getTxStatus } from '@shapeshiftoss/unchained-client/dist/evm'
@@ -272,23 +268,6 @@ export const assertGetEvmChainAdapter = (chainId: ChainId | KnownChainIds): EvmC
return adapter
}
-export const executeEvmTrade = ({
- txToSign,
- wallet,
- chainId,
- senderAddress,
- receiverAddress,
-}: ExecuteTradeArgs) => {
- const adapter = assertGetEvmChainAdapter(chainId)
- return signAndBroadcast({
- adapter,
- wallet,
- txToSign: txToSign as ETHSignTx,
- senderAddress,
- receiverAddress,
- })
-}
-
export const executeEvmTransaction = (
txToSign: EvmTransactionRequest,
callbacks: EvmTransactionExecutionProps,
diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts
index e8590a4757e..947bc953dce 100644
--- a/src/lib/utils/index.ts
+++ b/src/lib/utils/index.ts
@@ -1,12 +1,13 @@
import { skipToken } from '@reduxjs/toolkit/dist/query'
-import type { AssetReference } from '@shapeshiftoss/caip'
-import { ASSET_REFERENCE } from '@shapeshiftoss/caip'
+import type { AssetReference, ChainId, ChainNamespace } from '@shapeshiftoss/caip'
+import { ASSET_REFERENCE, fromChainId } from '@shapeshiftoss/caip'
+import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import type { HDWallet } from '@shapeshiftoss/hdwallet-core'
import type { KeepKeyHDWallet } from '@shapeshiftoss/hdwallet-keepkey'
import type { KeplrHDWallet } from '@shapeshiftoss/hdwallet-keplr'
import type { NativeHDWallet } from '@shapeshiftoss/hdwallet-native'
import type { WalletConnectV2HDWallet } from '@shapeshiftoss/hdwallet-walletconnectv2'
-import type { NestedArray } from '@shapeshiftoss/types'
+import type { KnownChainIds, NestedArray } from '@shapeshiftoss/types'
import type { Result } from '@sniptt/monads'
import { Err, Ok } from '@sniptt/monads'
import crypto from 'crypto-browserify'
@@ -15,6 +16,7 @@ import difference from 'lodash/difference'
import intersection from 'lodash/intersection'
import isUndefined from 'lodash/isUndefined'
import union from 'lodash/union'
+import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
export const isKeepKeyHDWallet = (wallet: HDWallet): wallet is KeepKeyHDWallet => {
return wallet.getVendor() === 'KeepKey'
@@ -217,3 +219,28 @@ export const timeout = (
),
])
}
+
+export const getSupportedChainIdsByChainNamespace = () => {
+ return Array.from(getChainAdapterManager().keys()).reduce>(
+ (acc, chainId) => {
+ const { chainNamespace } = fromChainId(chainId)
+ if (!acc[chainNamespace]) acc[chainNamespace] = []
+ acc[chainNamespace].push(chainId)
+ return acc
+ },
+ {} as Record,
+ )
+}
+
+export const assertGetChainAdapter = (
+ chainId: ChainId | KnownChainIds,
+): ChainAdapter => {
+ const chainAdapterManager = getChainAdapterManager()
+ const adapter = chainAdapterManager.get(chainId)
+
+ if (adapter === undefined) {
+ throw Error(`chain adapter not found for chain id ${chainId}`)
+ }
+
+ return adapter
+}
diff --git a/src/lib/utils/thorchain/index.ts b/src/lib/utils/thorchain/index.ts
index d26f279137d..4a2492b77bb 100644
--- a/src/lib/utils/thorchain/index.ts
+++ b/src/lib/utils/thorchain/index.ts
@@ -1,6 +1,5 @@
import type { AccountId } from '@shapeshiftoss/caip'
import { type AssetId, bchChainId, fromAccountId, fromAssetId } from '@shapeshiftoss/caip'
-import type { UtxoBaseAdapter, UtxoChainId } from '@shapeshiftoss/chain-adapters'
import type { HDWallet } from '@shapeshiftoss/hdwallet-core'
import type { AccountMetadata, Asset } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
@@ -21,6 +20,7 @@ import { thorService } from 'lib/swapper/swappers/ThorchainSwapper/utils/thorSer
import type { getThorchainSaversPosition } from 'state/slices/opportunitiesSlice/resolvers/thorchainsavers/utils'
import { isUtxoAccountId, isUtxoChainId } from 'state/slices/portfolioSlice/utils'
+import { assertGetUtxoChainAdapter } from '../utxo'
import { THOR_PRECISION } from './constants'
import type { getThorchainLendingPosition } from './lending'
@@ -185,9 +185,7 @@ const getAccountAddressesWithBalances = async (
): Promise<{ address: string; balance: string }[]> => {
if (isUtxoAccountId(accountId)) {
const { chainId, account: pubkey } = fromAccountId(accountId)
- const chainAdapters = getChainAdapterManager()
- const adapter = chainAdapters.get(chainId) as unknown as UtxoBaseAdapter
- if (!adapter) throw new Error(`no adapter for ${chainId} not available`)
+ const adapter = assertGetUtxoChainAdapter(chainId)
const {
chainSpecific: { addresses },
diff --git a/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx b/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx
index ba4c4c0efee..0f1e4fd15bd 100644
--- a/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx
+++ b/src/pages/Lending/Pool/components/Repay/RepayConfirm.tsx
@@ -12,7 +12,7 @@ import {
} from '@chakra-ui/react'
import type { AccountId, AssetId } from '@shapeshiftoss/caip'
import { fromAccountId, fromAssetId, thorchainAssetId } from '@shapeshiftoss/caip'
-import type { FeeDataEstimate, thorchain } from '@shapeshiftoss/chain-adapters'
+import type { FeeDataEstimate } from '@shapeshiftoss/chain-adapters'
import { FeeDataKey } from '@shapeshiftoss/chain-adapters'
import type { Asset, KnownChainIds } from '@shapeshiftoss/types'
import { TxStatus } from '@shapeshiftoss/unchained-client'
@@ -37,6 +37,7 @@ import { queryClient } from 'context/QueryClientProvider/queryClient'
import { getSupportedEvmChainIds } from 'hooks/useEvm/useEvm'
import { useWallet } from 'hooks/useWallet/useWallet'
import { bn, bnOrZero } from 'lib/bignumber/bignumber'
+import { assertGetThorchainChainAdapter } from 'lib/utils/cosmosSdk'
import { waitForThorchainUpdate } from 'lib/utils/thorchain'
import type { LendingQuoteClose } from 'lib/utils/thorchain/lending/types'
import { useLendingQuoteCloseQuery } from 'pages/Lending/hooks/useLendingCloseQuery'
@@ -236,7 +237,7 @@ export const RepayConfirm = ({
return (async () => {
const { account } = fromAccountId(repaymentAccountId)
- const adapter = chainAdapter as unknown as thorchain.ChainAdapter
+ const adapter = assertGetThorchainChainAdapter()
// repayment using THOR is a MsgDeposit tx
const { txToSign } = await adapter.buildDepositTransaction({
diff --git a/src/plugins/arbitrum/index.ts b/src/plugins/arbitrum/index.ts
index 370904ca860..4822c15d9c5 100644
--- a/src/plugins/arbitrum/index.ts
+++ b/src/plugins/arbitrum/index.ts
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { arbitrum } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -34,7 +32,7 @@ export default function register(): Plugins {
return new arbitrum.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_ARBITRUM_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/arbitrumNova/index.ts b/src/plugins/arbitrumNova/index.ts
index af7d2552b98..61db46d087a 100644
--- a/src/plugins/arbitrumNova/index.ts
+++ b/src/plugins/arbitrumNova/index.ts
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { arbitrumNova } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -34,7 +32,7 @@ export default function register(): Plugins {
return new arbitrumNova.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_ARBITRUM_NOVA_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/avalanche/index.tsx b/src/plugins/avalanche/index.tsx
index cf2ec972af2..f4dbeb46757 100644
--- a/src/plugins/avalanche/index.tsx
+++ b/src/plugins/avalanche/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { avalanche } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -33,7 +31,7 @@ export default function register(): Plugins {
return new avalanche.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_AVALANCHE_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/bitcoin/index.tsx b/src/plugins/bitcoin/index.tsx
index 81fe51fb2cf..95349eb7f33 100644
--- a/src/plugins/bitcoin/index.tsx
+++ b/src/plugins/bitcoin/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { bitcoin } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -31,7 +29,7 @@ export default function register(): Plugins {
return new bitcoin.ChainAdapter({
providers: { http, ws },
coinName: 'Bitcoin',
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/bitcoincash/index.tsx b/src/plugins/bitcoincash/index.tsx
index e5421c6042c..cee6ad35f24 100644
--- a/src/plugins/bitcoincash/index.tsx
+++ b/src/plugins/bitcoincash/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { bitcoincash } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -31,7 +29,7 @@ export default function register(): Plugins {
return new bitcoincash.ChainAdapter({
providers: { http, ws },
coinName: 'BitcoinCash',
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/bnbsmartchain/index.tsx b/src/plugins/bnbsmartchain/index.tsx
index 616f41ad207..582c9cfe2e2 100644
--- a/src/plugins/bnbsmartchain/index.tsx
+++ b/src/plugins/bnbsmartchain/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { bnbsmartchain } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -34,7 +32,7 @@ export default function register(): Plugins {
return new bnbsmartchain.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_BNBSMARTCHAIN_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/cosmos/index.tsx b/src/plugins/cosmos/index.tsx
index cc6777267c3..e8d5b5a3b19 100644
--- a/src/plugins/cosmos/index.tsx
+++ b/src/plugins/cosmos/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { cosmos } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -33,7 +31,7 @@ export default function register(): Plugins {
return new cosmos.ChainAdapter({
providers: { http, ws },
coinName: 'Cosmos',
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/cosmos/utils.ts b/src/plugins/cosmos/utils.ts
index 5ee7654ad30..fa969b111b8 100644
--- a/src/plugins/cosmos/utils.ts
+++ b/src/plugins/cosmos/utils.ts
@@ -1,14 +1,13 @@
import { fromAssetId } from '@shapeshiftoss/caip'
import type {
cosmossdk,
- CosmosSdkBaseAdapter,
CosmosSdkChainId,
FeeDataKey,
GetFeeDataInput,
} from '@shapeshiftoss/chain-adapters'
import type { Asset } from '@shapeshiftoss/types'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { bnOrZero } from 'lib/bignumber/bignumber'
+import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk'
export type FeePriceValueHuman = {
fiatFee: string
@@ -45,10 +44,7 @@ export const getFormFees = async (asset: Asset, userCurrencyRate: string) => {
},
}
- const chainAdapterManager = getChainAdapterManager()
- const adapter = chainAdapterManager.get(
- fromAssetId(asset.assetId).chainId,
- ) as unknown as CosmosSdkBaseAdapter
+ const adapter = assertGetCosmosSdkChainAdapter(fromAssetId(asset.assetId).chainId)
const getFeeDataInput: Partial> = {}
const feeData = await adapter.getFeeData(getFeeDataInput)
diff --git a/src/plugins/dogecoin/index.tsx b/src/plugins/dogecoin/index.tsx
index ddfb71f6292..2a193011d9c 100644
--- a/src/plugins/dogecoin/index.tsx
+++ b/src/plugins/dogecoin/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { dogecoin } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -31,7 +29,7 @@ export default function register(): Plugins {
return new dogecoin.ChainAdapter({
providers: { http, ws },
coinName: 'Dogecoin',
- }) as unknown as ChainAdapter
+ })
},
],
],
diff --git a/src/plugins/ethereum/index.tsx b/src/plugins/ethereum/index.tsx
index 7aa84cd05bd..ad79dd88138 100644
--- a/src/plugins/ethereum/index.tsx
+++ b/src/plugins/ethereum/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { ethereum } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -33,7 +31,7 @@ export default function register(): Plugins {
return new ethereum.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_ETHEREUM_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/gnosis/index.tsx b/src/plugins/gnosis/index.tsx
index afa5549bf42..2f7bb9f2440 100644
--- a/src/plugins/gnosis/index.tsx
+++ b/src/plugins/gnosis/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { gnosis } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -33,7 +31,7 @@ export default function register(): Plugins {
return new gnosis.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_GNOSIS_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/litecoin/index.tsx b/src/plugins/litecoin/index.tsx
index 31fcfbeca6c..5ebc8213788 100644
--- a/src/plugins/litecoin/index.tsx
+++ b/src/plugins/litecoin/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { litecoin } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -31,7 +29,7 @@ export default function register(): Plugins {
return new litecoin.ChainAdapter({
providers: { http, ws },
coinName: 'Litecoin',
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/optimism/index.tsx b/src/plugins/optimism/index.tsx
index 20e2873b3b5..fb6602bc220 100644
--- a/src/plugins/optimism/index.tsx
+++ b/src/plugins/optimism/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { optimism } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -34,7 +32,7 @@ export default function register(): Plugins {
return new optimism.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_OPTIMISM_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/polygon/index.ts b/src/plugins/polygon/index.ts
index 6fc77ad21d0..e55d201bde7 100644
--- a/src/plugins/polygon/index.ts
+++ b/src/plugins/polygon/index.ts
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { polygon } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -34,7 +32,7 @@ export default function register(): Plugins {
return new polygon.ChainAdapter({
providers: { http, ws },
rpcUrl: getConfig().REACT_APP_POLYGON_NODE_URL,
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/thorchain/index.tsx b/src/plugins/thorchain/index.tsx
index 3e15a409833..124f885a80d 100644
--- a/src/plugins/thorchain/index.tsx
+++ b/src/plugins/thorchain/index.tsx
@@ -1,5 +1,3 @@
-import type { ChainId } from '@shapeshiftoss/caip'
-import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
import { thorchain } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import * as unchained from '@shapeshiftoss/unchained-client'
@@ -31,7 +29,7 @@ export default function register(): Plugins {
return new thorchain.ChainAdapter({
providers: { http, ws },
coinName: 'Thorchain',
- }) as unknown as ChainAdapter // FIXME: this is silly
+ })
},
],
],
diff --git a/src/plugins/types.ts b/src/plugins/types.ts
index 008e70545fc..92f0fa66124 100644
--- a/src/plugins/types.ts
+++ b/src/plugins/types.ts
@@ -1,5 +1,6 @@
import type { ChainId } from '@shapeshiftoss/caip'
import type { ChainAdapter } from '@shapeshiftoss/chain-adapters'
+import type { KnownChainIds } from '@shapeshiftoss/types'
import type { Route } from 'Routes/helpers'
import type { FeatureFlags } from 'state/slices/preferencesSlice/preferencesSlice'
@@ -11,7 +12,7 @@ export interface Plugin {
featureFlag?: (keyof FeatureFlags)[]
onLoad?: () => void
providers?: {
- chainAdapters?: [ChainId, () => ChainAdapter][]
+ chainAdapters?: [ChainId, () => ChainAdapter][]
}
routes?: Route[]
}
diff --git a/src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx b/src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx
index c237cf919ae..f3cbd70c4b1 100644
--- a/src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx
+++ b/src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx
@@ -9,12 +9,6 @@ import {
VStack,
} from '@chakra-ui/react'
import { formatJsonRpcError } from '@json-rpc-tools/utils'
-import type {
- ChainAdapter,
- CosmosSdkChainId,
- EvmBaseAdapter,
- EvmChainId,
-} from '@shapeshiftoss/chain-adapters'
import type { SessionTypes } from '@walletconnect/types'
import { getSdkError } from '@walletconnect/utils'
import { CosmosSignMessageConfirmationModal } from 'plugins/walletConnectToDapps/components/modals/CosmosSignMessageConfirmation'
@@ -44,6 +38,8 @@ import { WalletConnectIcon } from 'components/Icons/WalletConnectIcon'
import { Text } from 'components/Text'
import { useWallet } from 'hooks/useWallet/useWallet'
import { assertUnreachable } from 'lib/utils'
+import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk'
+import { assertGetEvmChainAdapter } from 'lib/utils/evm'
type WalletConnectModalManagerProps = WalletConnectContextType
@@ -79,7 +75,7 @@ export const WalletConnectModalManager: FC = ({
}) => {
const { wallet, isConnected } = useWallet().state
const sessionProposalRef = useRef(null)
- const { chainAdapter, requestEvent, accountMetadata, accountId } = useWalletConnectState(state)
+ const { chainId, requestEvent, accountMetadata, accountId } = useWalletConnectState(state)
const { activeModal, web3wallet } = state
@@ -92,13 +88,16 @@ export const WalletConnectModalManager: FC = ({
const handleConfirmEIP155Request = useCallback(
async (customTransactionData?: CustomTransactionData) => {
- if (!requestEvent || !chainAdapter || !wallet || !chainAdapter || !web3wallet || !topic)
+ if (!requestEvent || !chainId || !wallet || !web3wallet || !topic) {
return
+ }
+
+ const chainAdapter = assertGetEvmChainAdapter(chainId)
const response = await approveEIP155Request({
wallet,
requestEvent,
- chainAdapter: chainAdapter as unknown as EvmBaseAdapter,
+ chainAdapter,
accountMetadata,
customTransactionData,
accountId,
@@ -109,27 +108,21 @@ export const WalletConnectModalManager: FC = ({
})
handleClose()
},
- [
- accountId,
- accountMetadata,
- chainAdapter,
- handleClose,
- requestEvent,
- topic,
- wallet,
- web3wallet,
- ],
+ [accountId, accountMetadata, chainId, handleClose, requestEvent, topic, wallet, web3wallet],
)
const handleConfirmCosmosRequest = useCallback(
async (customTransactionData?: CustomTransactionData) => {
- if (!requestEvent || !chainAdapter || !wallet || !chainAdapter || !web3wallet || !topic)
+ if (!requestEvent || !chainId || !wallet || !web3wallet || !topic) {
return
+ }
+
+ const chainAdapter = assertGetCosmosSdkChainAdapter(chainId)
const response = await approveCosmosRequest({
wallet,
requestEvent,
- chainAdapter: chainAdapter as ChainAdapter,
+ chainAdapter,
accountMetadata,
customTransactionData,
accountId,
@@ -140,16 +133,7 @@ export const WalletConnectModalManager: FC = ({
})
handleClose()
},
- [
- accountId,
- accountMetadata,
- chainAdapter,
- handleClose,
- requestEvent,
- topic,
- wallet,
- web3wallet,
- ],
+ [accountId, accountMetadata, chainId, handleClose, requestEvent, topic, wallet, web3wallet],
)
const handleRejectRequest = useCallback(async () => {
diff --git a/src/plugins/walletConnectToDapps/hooks/useCallRequestEvmFees.ts b/src/plugins/walletConnectToDapps/hooks/useCallRequestEvmFees.ts
index 9dad0c0ae91..ce582454b57 100644
--- a/src/plugins/walletConnectToDapps/hooks/useCallRequestEvmFees.ts
+++ b/src/plugins/walletConnectToDapps/hooks/useCallRequestEvmFees.ts
@@ -1,47 +1,44 @@
import { fromAccountId } from '@shapeshiftoss/caip'
-import type { EvmBaseAdapter, EvmChainId } from '@shapeshiftoss/chain-adapters'
import { FeeDataKey } from '@shapeshiftoss/chain-adapters'
import { useWalletConnectState } from 'plugins/walletConnectToDapps/hooks/useWalletConnectState'
import type { WalletConnectState } from 'plugins/walletConnectToDapps/types'
import { getFeesForTx } from 'plugins/walletConnectToDapps/utils'
import { useEffect, useMemo, useState } from 'react'
import type { FeePrice } from 'components/Modals/Send/views/Confirm'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { bn, bnOrZero } from 'lib/bignumber/bignumber'
+import { assertGetChainAdapter } from 'lib/utils'
+import { assertGetEvmChainAdapter } from 'lib/utils/evm'
import { selectAssets, selectMarketDataById } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'
export function useCallRequestEvmFees(state: WalletConnectState) {
const [fees, setFees] = useState()
const [isLoading, setIsLoading] = useState(false)
- const { chainAdapter, chainId, accountId, transaction } = useWalletConnectState(state)
+ const { chainId, accountId, transaction } = useWalletConnectState(state)
const assets = useAppSelector(selectAssets)
const feeAsset = useMemo(() => {
+ const chainAdapter = chainId ? assertGetChainAdapter(chainId) : undefined
const feeAssetId = chainAdapter?.getFeeAssetId()
if (!feeAssetId) return null
// TODO(Q): this shouldn't be feeAsset, get the real asset from request
const feeAsset = assets[feeAssetId]
if (!feeAsset) return null
return feeAsset
- }, [assets, chainAdapter])
+ }, [assets, chainId])
const feeAssetPrice =
useAppSelector(state => selectMarketDataById(state, feeAsset?.assetId ?? ''))?.price ?? '0'
useEffect(() => {
if (!transaction || !accountId || !chainId) return
const { account: address } = fromAccountId(accountId)
- const adapter = getChainAdapterManager().get(chainId)
- if (!(address && chainId && feeAsset && feeAssetPrice && adapter)) return
+ if (!(address && chainId && feeAsset && feeAssetPrice)) return
;(async () => {
+ const adapter = assertGetEvmChainAdapter(chainId)
setIsLoading(true)
- const estimatedFees = await getFeesForTx(
- transaction,
- adapter as unknown as EvmBaseAdapter,
- accountId,
- )
+ const estimatedFees = await getFeesForTx(transaction, adapter, accountId)
const initialFees: FeePrice = {
slow: {
diff --git a/src/plugins/walletConnectToDapps/hooks/useWalletConnectState.ts b/src/plugins/walletConnectToDapps/hooks/useWalletConnectState.ts
index 8d191f522b7..77f9281c04f 100644
--- a/src/plugins/walletConnectToDapps/hooks/useWalletConnectState.ts
+++ b/src/plugins/walletConnectToDapps/hooks/useWalletConnectState.ts
@@ -15,7 +15,6 @@ import {
getWalletAddressFromEthSignParams,
} from 'plugins/walletConnectToDapps/utils'
import { useMemo } from 'react'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { selectPortfolioAccountMetadata } from 'state/slices/portfolioSlice/selectors'
import { useAppSelector } from 'state/store'
@@ -68,7 +67,6 @@ export const useWalletConnectState = (state: WalletConnectState) => {
? getSignParamsMessage(request.params, true)
: undefined
const method: KnownSigningMethod | undefined = requestEvent?.params.request.method
- const chainAdapter = chainId && getChainAdapterManager().get(chainId)
return {
isInteractingWithContract,
@@ -76,7 +74,6 @@ export const useWalletConnectState = (state: WalletConnectState) => {
transaction,
message,
method,
- chainAdapter,
requestEvent,
connectedAccounts,
accountId,
diff --git a/src/state/apis/foxy/foxyApiSingleton.ts b/src/state/apis/foxy/foxyApiSingleton.ts
index 9b2ae5962ba..97d35bc547f 100644
--- a/src/state/apis/foxy/foxyApiSingleton.ts
+++ b/src/state/apis/foxy/foxyApiSingleton.ts
@@ -1,8 +1,8 @@
import type { EvmBaseAdapter } from '@shapeshiftoss/chain-adapters'
import { KnownChainIds } from '@shapeshiftoss/types'
import { getConfig } from 'config'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { foxyAddresses, FoxyApi } from 'lib/investor/investor-foxy'
+import { assertGetEvmChainAdapter } from 'lib/utils/evm'
// don't export me, access me through the getter
let _foxyApi: FoxyApi | undefined = undefined
@@ -14,9 +14,9 @@ export const getFoxyApi = (): FoxyApi => {
if (_foxyApi) return _foxyApi
const foxyApi = new FoxyApi({
- adapter: getChainAdapterManager().get(
+ adapter: assertGetEvmChainAdapter(
KnownChainIds.EthereumMainnet,
- ) as unknown as EvmBaseAdapter,
+ ) as EvmBaseAdapter,
providerUrl: getConfig()[RPC_PROVIDER_ENV],
foxyAddresses,
})
diff --git a/src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts b/src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
index c45a14cd151..121c1c69232 100644
--- a/src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
+++ b/src/state/slices/opportunitiesSlice/resolvers/cosmosSdk/index.ts
@@ -1,8 +1,7 @@
import { cosmosChainId, fromAccountId } from '@shapeshiftoss/caip'
-import type { CosmosSdkBaseAdapter, CosmosSdkChainId } from '@shapeshiftoss/chain-adapters'
-import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { bn, bnOrZero } from 'lib/bignumber/bignumber'
import { isFulfilled, isRejected, isSome } from 'lib/utils'
+import { assertGetCosmosSdkChainAdapter } from 'lib/utils/cosmosSdk'
import type { ReduxState } from 'state/reducer'
import { selectAssetById } from 'state/slices/assetsSlice/selectors'
import { selectWalletAccountIds } from 'state/slices/common-selectors'
@@ -32,7 +31,6 @@ export const cosmosSdkOpportunityIdsResolver = async ({
}> => {
const state = reduxApi.getState() as ReduxState
- const chainAdapters = getChainAdapterManager()
const portfolioAccountIds = selectWalletAccountIds(state)
const cosmosSdkChainIdsWhitelist = [cosmosChainId]
@@ -44,9 +42,7 @@ export const cosmosSdkOpportunityIdsResolver = async ({
const cosmosSdkAccounts = await Promise.allSettled(
cosmosSdkAccountIds.map(accountId => {
const { account: pubKey, chainId } = fromAccountId(accountId)
- const adapter = chainAdapters.get(
- chainId,
- ) as unknown as CosmosSdkBaseAdapter
+ const adapter = assertGetCosmosSdkChainAdapter(chainId)
return adapter.getAccount(pubKey)
}),
).then(settledAccountsPromises =>
@@ -85,10 +81,7 @@ export const cosmosSdkStakingOpportunitiesMetadataResolver = async ({
const { account: validatorAddress, chainId } = fromAccountId(validatorId)
try {
- const chainAdapters = getChainAdapterManager()
- const adapter = chainAdapters.get(
- chainId,
- ) as unknown as CosmosSdkBaseAdapter
+ const adapter = assertGetCosmosSdkChainAdapter(chainId)
const data = await adapter.getValidator(validatorAddress)
@@ -183,8 +176,8 @@ export const cosmosSdkStakingOpportunitiesUserDataResolver = async ({
data: { byId: emptyStakingOpportunitiesUserDataByUserStakingId, type: defiType },
})
}
- const chainAdapters = getChainAdapterManager()
- const adapter = chainAdapters.get(chainId) as unknown as CosmosSdkBaseAdapter
+
+ const adapter = assertGetCosmosSdkChainAdapter(chainId)
const cosmosAccount = await adapter.getAccount(pubKey)
const assetId = accountIdToFeeAssetId(accountId)
From b6c9b8875a8b29ab2fe59011e276d98ce83a83e4 Mon Sep 17 00:00:00 2001
From: woody <125113430+woodenfurniture@users.noreply.github.com>
Date: Tue, 12 Dec 2023 15:38:52 +1100
Subject: [PATCH 4/6] fix: several multi-hop fixes and improvements (#5836)
---
.../components/HopTransactionStep.tsx | 10 ++++++++--
.../MultiHopTradeConfirm/hooks/useTradeExecution.tsx | 6 +++++-
src/lib/swapper/constants.ts | 2 +-
src/lib/swapper/swappers/LifiSwapper/endpoints.ts | 12 +++++++++---
src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts | 8 ++++++++
src/state/slices/tradeQuoteSlice/types.ts | 1 +
6 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx
index d84412457c6..0c11e671de4 100644
--- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx
+++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/HopTransactionStep.tsx
@@ -1,5 +1,5 @@
import { CheckCircleIcon } from '@chakra-ui/icons'
-import { Button, Card, CardBody, Link, VStack } from '@chakra-ui/react'
+import { Button, Card, CardBody, Link, Tooltip, VStack } from '@chakra-ui/react'
import type { SwapperName, TradeQuoteStep } from '@shapeshiftoss/swapper'
import type { KnownChainIds } from '@shapeshiftoss/types'
import type Polyglot from 'node-polyglot'
@@ -45,7 +45,7 @@ export const HopTransactionStep = ({
const translate = useTranslate()
const {
- swap: { state: swapTxState, sellTxHash, buyTxHash },
+ swap: { state: swapTxState, sellTxHash, buyTxHash, message },
} = useAppSelector(state => selectHopExecutionMetadata(state, hopIndex))
const isError = useMemo(() => swapTxState === TransactionExecutionState.Failed, [swapTxState])
@@ -168,6 +168,11 @@ export const HopTransactionStep = ({
{`${sellAmountCryptoFormatted}.${sellChainSymbol} -> ${buyAmountCryptoFormatted}.${buyChainSymbol}`}
{isError && }
+ {Boolean(message) && (
+
+ {message}
+
+ )}
{txLink && (
@@ -178,6 +183,7 @@ export const HopTransactionStep = ({
}, [
errorTranslation,
isError,
+ message,
toCrypto,
tradeQuoteStep.buyAmountBeforeFeesCryptoBaseUnit,
tradeQuoteStep.buyAsset.chainId,
diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx
index ec8fd629840..42f4fcbda26 100644
--- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx
+++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useTradeExecution.tsx
@@ -61,6 +61,8 @@ export const useTradeExecution = (hopIndex: number) => {
dispatch(tradeQuoteSlice.actions.setSwapTxPending({ hopIndex }))
const onFail = (e: unknown) => {
+ const { message } = (e ?? { message: undefined }) as { message?: string }
+ dispatch(tradeQuoteSlice.actions.setSwapTxMessage({ hopIndex, message }))
dispatch(tradeQuoteSlice.actions.setSwapTxFailed({ hopIndex }))
showErrorToast(e)
resolve()
@@ -71,10 +73,12 @@ export const useTradeExecution = (hopIndex: number) => {
execution.on(TradeExecutionEvent.SellTxHash, ({ sellTxHash }) => {
dispatch(tradeQuoteSlice.actions.setSwapSellTxHash({ hopIndex, sellTxHash }))
})
- execution.on(TradeExecutionEvent.Status, ({ buyTxHash }) => {
+ execution.on(TradeExecutionEvent.Status, ({ buyTxHash, message }) => {
+ dispatch(tradeQuoteSlice.actions.setSwapTxMessage({ hopIndex, message }))
buyTxHash && tradeQuoteSlice.actions.setSwapBuyTxHash({ hopIndex, buyTxHash })
})
execution.on(TradeExecutionEvent.Success, () => {
+ dispatch(tradeQuoteSlice.actions.setSwapTxMessage({ hopIndex, message: undefined }))
dispatch(tradeQuoteSlice.actions.setSwapTxComplete({ hopIndex }))
resolve()
})
diff --git a/src/lib/swapper/constants.ts b/src/lib/swapper/constants.ts
index 46e07dd67ca..af19a2cdc0f 100644
--- a/src/lib/swapper/constants.ts
+++ b/src/lib/swapper/constants.ts
@@ -11,7 +11,7 @@ import { thorchainSwapper } from 'lib/swapper/swappers/ThorchainSwapper/Thorchai
import { zrxApi } from 'lib/swapper/swappers/ZrxSwapper/endpoints'
import { zrxSwapper } from 'lib/swapper/swappers/ZrxSwapper/ZrxSwapper'
-export const QUOTE_TIMEOUT_MS = 10_000
+export const QUOTE_TIMEOUT_MS = 60_000
export const QUOTE_TIMEOUT_ERROR = makeSwapErrorRight({
message: `quote timed out after ${QUOTE_TIMEOUT_MS / 1000}s`,
diff --git a/src/lib/swapper/swappers/LifiSwapper/endpoints.ts b/src/lib/swapper/swappers/LifiSwapper/endpoints.ts
index 9b724596e09..205aae6198d 100644
--- a/src/lib/swapper/swappers/LifiSwapper/endpoints.ts
+++ b/src/lib/swapper/swappers/LifiSwapper/endpoints.ts
@@ -130,6 +130,7 @@ export const lifiApi: SwapperApi = {
checkTradeStatus: async ({
quoteId,
txHash,
+ stepIndex,
}): Promise<{ status: TxStatus; buyTxHash: string | undefined; message: string | undefined }> => {
const lifiRoute = tradeQuoteMetadata.get(quoteId)
if (!lifiRoute) throw Error(`missing trade quote metadata for quoteId ${quoteId}`)
@@ -141,14 +142,19 @@ export const lifiApi: SwapperApi = {
// url: 'https://li.quest/v1/status',
// })
+ const {
+ action: { fromChainId, toChainId },
+ tool,
+ } = lifiRoute.steps[stepIndex]
+
// don't use lifi sdk here because all status responses are cached, negating the usefulness of polling
// i.e don't do `await getLifi().getStatus(getStatusRequest)`
const url = new URL('https://li.quest/v1/status')
const getStatusRequestParams: { [Key in keyof GetStatusRequest]: string } = {
txHash,
- bridge: lifiRoute.steps[0].tool,
- fromChain: lifiRoute.fromChainId.toString(),
- toChain: lifiRoute.toChainId.toString(),
+ bridge: tool,
+ fromChain: fromChainId.toString(),
+ toChain: toChainId.toString(),
}
url.search = new URLSearchParams(getStatusRequestParams).toString()
const response = await fetch(url, { cache: 'no-store' }) // don't cache!
diff --git a/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts b/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts
index 36bf4a63af0..19e4f14a093 100644
--- a/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts
+++ b/src/state/slices/tradeQuoteSlice/tradeQuoteSlice.ts
@@ -97,6 +97,14 @@ export const tradeQuoteSlice = createSlice({
const key = hopIndex === 0 ? 'firstHop' : 'secondHop'
state.tradeExecution[key].swap.state = TransactionExecutionState.Failed
},
+ setSwapTxMessage: (
+ state,
+ action: PayloadAction<{ hopIndex: number; message: string | undefined }>,
+ ) => {
+ const { hopIndex, message } = action.payload
+ const key = hopIndex === 0 ? 'firstHop' : 'secondHop'
+ state.tradeExecution[key].swap.message = message
+ },
setSwapTxComplete: (state, action: PayloadAction<{ hopIndex: number }>) => {
const { hopIndex } = action.payload
const isMultiHopTrade =
diff --git a/src/state/slices/tradeQuoteSlice/types.ts b/src/state/slices/tradeQuoteSlice/types.ts
index 84c95b9f19b..b5fe7006a5a 100644
--- a/src/state/slices/tradeQuoteSlice/types.ts
+++ b/src/state/slices/tradeQuoteSlice/types.ts
@@ -49,6 +49,7 @@ export type SwapExecutionMetadata = {
sellTxHash?: string
buyTxHash?: string
streamingSwap?: StreamingSwapMetadata
+ message?: string
}
export type HopExecutionMetadata = {
From 6d964eb767d5ba96ee6b3dc9c8083beaa628bec5 Mon Sep 17 00:00:00 2001
From: Apotheosis <0xapotheosis@gmail.com>
Date: Tue, 12 Dec 2023 20:26:17 +1100
Subject: [PATCH 5/6] feat: add cross-account trading for 1inch (#5834)
---
src/lib/swapper/swappers/OneInchSwapper/endpoints.ts | 1 +
.../OneInchSwapper/getTradeQuote/getTradeQuote.ts | 1 +
.../swappers/OneInchSwapper/utils/fetchOneInchSwap.ts | 8 ++++----
src/lib/swapper/swappers/OneInchSwapper/utils/types.ts | 1 +
src/state/helpers.ts | 2 +-
5 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/lib/swapper/swappers/OneInchSwapper/endpoints.ts b/src/lib/swapper/swappers/OneInchSwapper/endpoints.ts
index 6de09f12e1f..f11ff091504 100644
--- a/src/lib/swapper/swappers/OneInchSwapper/endpoints.ts
+++ b/src/lib/swapper/swappers/OneInchSwapper/endpoints.ts
@@ -53,6 +53,7 @@ export const oneInchApi: SwapperApi = {
sellAmountIncludingProtocolFeesCryptoBaseUnit,
sellAsset,
maximumSlippageDecimalPercentage: slippageTolerancePercentageDecimal,
+ sendAddress: from,
})
return {
diff --git a/src/lib/swapper/swappers/OneInchSwapper/getTradeQuote/getTradeQuote.ts b/src/lib/swapper/swappers/OneInchSwapper/getTradeQuote/getTradeQuote.ts
index 5e4420d0bd8..07a4cadca1a 100644
--- a/src/lib/swapper/swappers/OneInchSwapper/getTradeQuote/getTradeQuote.ts
+++ b/src/lib/swapper/swappers/OneInchSwapper/getTradeQuote/getTradeQuote.ts
@@ -52,6 +52,7 @@ export async function getTradeQuote(
const params: OneInchQuoteApiInput = {
fromTokenAddress: getOneInchTokenAddress(sellAsset),
toTokenAddress: getOneInchTokenAddress(buyAsset),
+ receiver: receiveAddress,
amount: sellAmountIncludingProtocolFeesCryptoBaseUnit,
...(maybeTreasuryAddress && {
fee: buyTokenPercentageFee,
diff --git a/src/lib/swapper/swappers/OneInchSwapper/utils/fetchOneInchSwap.ts b/src/lib/swapper/swappers/OneInchSwapper/utils/fetchOneInchSwap.ts
index c2ddd8a4914..7ac14564df5 100644
--- a/src/lib/swapper/swappers/OneInchSwapper/utils/fetchOneInchSwap.ts
+++ b/src/lib/swapper/swappers/OneInchSwapper/utils/fetchOneInchSwap.ts
@@ -16,6 +16,7 @@ export type FetchOneInchSwapInput = {
sellAmountIncludingProtocolFeesCryptoBaseUnit: string
sellAsset: Asset
maximumSlippageDecimalPercentage: string
+ sendAddress: string
}
export const fetchOneInchSwap = async ({
@@ -25,6 +26,7 @@ export const fetchOneInchSwap = async ({
sellAmountIncludingProtocolFeesCryptoBaseUnit,
sellAsset,
maximumSlippageDecimalPercentage,
+ sendAddress,
}: FetchOneInchSwapInput) => {
const apiUrl = getConfig().REACT_APP_ONE_INCH_API_URL
@@ -46,10 +48,8 @@ export const fetchOneInchSwap = async ({
const params: OneInchSwapApiInput = {
fromTokenAddress: getOneInchTokenAddress(sellAsset),
toTokenAddress: getOneInchTokenAddress(buyAsset),
- // HACK: use the receive address as the send address
- // 1inch uses this to check allowance on their side
- // this swapper is not cross-account so this works
- fromAddress: receiveAddress,
+ receiver: receiveAddress,
+ fromAddress: sendAddress,
amount: sellAmountIncludingProtocolFeesCryptoBaseUnit,
slippage: maximumSlippagePercentage,
allowPartialFill: false,
diff --git a/src/lib/swapper/swappers/OneInchSwapper/utils/types.ts b/src/lib/swapper/swappers/OneInchSwapper/utils/types.ts
index 0d39378f214..55fe2b53703 100644
--- a/src/lib/swapper/swappers/OneInchSwapper/utils/types.ts
+++ b/src/lib/swapper/swappers/OneInchSwapper/utils/types.ts
@@ -15,6 +15,7 @@ export type OneInchQuoteApiInput = {
fromTokenAddress: string
toTokenAddress: string
amount: string
+ receiver: string
fee?: number // fee as a percentage, e.g. to set a fee to 1.5%: fee=1.5, paid to the referrerAddress
}
diff --git a/src/state/helpers.ts b/src/state/helpers.ts
index 58b64755f12..9a84bd0d355 100644
--- a/src/state/helpers.ts
+++ b/src/state/helpers.ts
@@ -5,12 +5,12 @@ import { assertUnreachable } from '../lib/utils'
export const isCrossAccountTradeSupported = (swapperName: SwapperName) => {
switch (swapperName) {
case SwapperName.Thorchain:
+ case SwapperName.OneInch:
return true
// NOTE: Before enabling cross-account for LIFI and OneInch - we must pass the sending address
// to the swappers up so allowance checks work. They're currently using the receive address
// assuming it's the same address as the sending address.
case SwapperName.LIFI:
- case SwapperName.OneInch:
case SwapperName.Zrx:
case SwapperName.CowSwap:
case SwapperName.Test:
From 10fca9c25b2a41f62e493f08594a2932ee94d08c Mon Sep 17 00:00:00 2001
From: Apotheosis <0xapotheosis@gmail.com>
Date: Tue, 12 Dec 2023 22:37:35 +1100
Subject: [PATCH 6/6] feat: enable lifi cross-account trades (#5835)
---
.../swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts | 3 ---
src/state/helpers.ts | 5 +----
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/lib/swapper/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts b/src/lib/swapper/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts
index 1ddad399b1b..a5cda27948e 100644
--- a/src/lib/swapper/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts
+++ b/src/lib/swapper/swappers/LifiSwapper/getTradeQuote/getTradeQuote.ts
@@ -72,9 +72,6 @@ export async function getTradeQuote(
toChainId: Number(fromChainId(buyAsset.chainId).chainReference),
fromTokenAddress: getLifiEvmAssetAddress(sellAsset),
toTokenAddress: getLifiEvmAssetAddress(buyAsset),
- // HACK: use the receive address as the send address
- // lifi's exchanges may use this to check allowance on their side
- // this swapper is not cross-account so this works
fromAddress: sendAddress,
toAddress: receiveAddress,
fromAmount: sellAmountIncludingProtocolFeesCryptoBaseUnit,
diff --git a/src/state/helpers.ts b/src/state/helpers.ts
index 9a84bd0d355..7c83b5184fb 100644
--- a/src/state/helpers.ts
+++ b/src/state/helpers.ts
@@ -5,12 +5,9 @@ import { assertUnreachable } from '../lib/utils'
export const isCrossAccountTradeSupported = (swapperName: SwapperName) => {
switch (swapperName) {
case SwapperName.Thorchain:
+ case SwapperName.LIFI:
case SwapperName.OneInch:
return true
- // NOTE: Before enabling cross-account for LIFI and OneInch - we must pass the sending address
- // to the swappers up so allowance checks work. They're currently using the receive address
- // assuming it's the same address as the sending address.
- case SwapperName.LIFI:
case SwapperName.Zrx:
case SwapperName.CowSwap:
case SwapperName.Test: