diff --git a/chain-registry b/chain-registry index 4e2369d0..e265ffb1 160000 --- a/chain-registry +++ b/chain-registry @@ -1 +1 @@ -Subproject commit 4e2369d031a2a8b0133f583d8623ee1f921f1103 +Subproject commit e265ffb1bd05f5394cac721f1c493fe079b53295 diff --git a/package-lock.json b/package-lock.json index 94bad844..1dc5be92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "^1.3.0", + "@skip-router/core": "^1.3.2", "@tailwindcss/forms": "^0.5.7", "@tanstack/query-sync-storage-persister": "^5.18.1", "@tanstack/react-query": "^5.18.1", @@ -7680,9 +7680,9 @@ } }, "node_modules/@skip-router/core": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-1.3.0.tgz", - "integrity": "sha512-DUKqiv+lKANn3pamabCIAA8Wv/9Mycw5DRj3VP1/j8Mhb9zmYFzcavWJIeAmLZk2A3bGN4tQIwLVI49/mMiktA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-1.3.2.tgz", + "integrity": "sha512-AFfxWOH9S3C5/BSBf6TW4qPCGcwYpItfvukU41qiiEBwuYHYe+/bcbrjORCaUvCk0s5LolXo+59Qsf3T7PEDDw==", "dependencies": { "@cosmjs/amino": "0.31.x", "@cosmjs/cosmwasm-stargate": "0.31.x", diff --git a/package.json b/package.json index 9f4a3a7a..42131afa 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "^1.3.0", + "@skip-router/core": "^1.3.2", "@tailwindcss/forms": "^0.5.7", "@tanstack/query-sync-storage-persister": "^5.18.1", "@tanstack/react-query": "^5.18.1", diff --git a/src/components/TransactionDialog/TransactionDialogContent.tsx b/src/components/TransactionDialog/TransactionDialogContent.tsx index 1363c429..88fdb265 100644 --- a/src/components/TransactionDialog/TransactionDialogContent.tsx +++ b/src/components/TransactionDialog/TransactionDialogContent.tsx @@ -13,6 +13,7 @@ import { useBroadcastedTxsStatus, useSkipClient } from "@/solve"; import { getChainGasPrice } from "@/utils/chain.client"; import { isUserRejectedRequestError } from "@/utils/error"; import { getExplorerUrl } from "@/utils/explorer"; +import { isCCTPLedgerBrokenInOperation, isEthermintLedgerInOperation } from "@/utils/ledger-warning"; import { randomId } from "@/utils/random"; import { cn } from "@/utils/ui"; @@ -35,12 +36,6 @@ export interface BroadcastedTx { explorerLink: string; } -const isCCTPFromNobleInOperation = (route: RouteResponse) => { - return route.operations.some( - (operation) => "cctpTransfer" in operation && operation.cctpTransfer.fromChainID === "noble-1", - ); -}; - function TransactionDialogContent({ route, onClose, isAmountError, transactionCount }: Props) { const skipClient = useSkipClient(); @@ -58,7 +53,10 @@ function TransactionDialogContent({ route, onClose, isAmountError, transactionCo const srcAccount = useAccount("source"); const dstAccount = useAccount("destination"); - const showLedgerWarning = isCCTPFromNobleInOperation(route) && srcAccount?.wallet?.mode === "ledger"; + const showCCTPLedgerWarning = isCCTPLedgerBrokenInOperation(route) && srcAccount?.wallet?.isLedger; + const showEthermintLikeLedgerWarning = isEthermintLedgerInOperation(route) && srcAccount?.wallet?.isLedger; + + const showLedgerWarning = showCCTPLedgerWarning || showEthermintLikeLedgerWarning; const { data: userAddresses } = useWalletAddresses(route.chainIDs); @@ -253,7 +251,7 @@ function TransactionDialogContent({ route, onClose, isAmountError, transactionCo )} - {showLedgerWarning && ( + {showCCTPLedgerWarning && ( WARNING: ibc.fun does not support signing with Ledger when transferring over CCTP to the Ethereum ecosystem. - We're actively working on fixing this. We apologize for the inconvenience + We're actively working on fixing this with the Noble/Circle teams. We apologize for the + inconvenience +

+ +
+ )} + {showEthermintLikeLedgerWarning && ( + + +

+ WARNING: + ibc.fun does not support signing with Ledger on Ethermint-like chains (e.g. Injective, Dymension, EVMOS, + etc...). We're actively working on fixing this with the Ledger team. We apologize for the + inconvenience.

diff --git a/src/constants/ledger-warning.ts b/src/constants/ledger-warning.ts new file mode 100644 index 00000000..b050d89e --- /dev/null +++ b/src/constants/ledger-warning.ts @@ -0,0 +1,9 @@ +export const knownBrokenCCTPLedgerChainIds = [ + "noble-1", + "evmos_9001-2", + "dymension_1100-1", + "injective-1", + "dimension_37-1", +]; + +export const knownEthermintLedgerChainIds = ["evmos_9001-2", "dymension_1100-1", "injective-1", "dimension_37-1"]; diff --git a/src/hooks/useAccount.ts b/src/hooks/useAccount.ts index fde62a3a..89b6227d 100644 --- a/src/hooks/useAccount.ts +++ b/src/hooks/useAccount.ts @@ -1,10 +1,13 @@ +import { WalletClient } from "@cosmos-kit/core"; import { useManager as useCosmosManager } from "@cosmos-kit/react"; +import { useQuery } from "@tanstack/react-query"; import { useMemo } from "react"; import { useAccount as useWagmiAccount } from "wagmi"; import { EVM_WALLET_LOGOS, INJECTED_EVM_WALLET_LOGOS } from "@/constants/wagmi"; import { trackWallet, TrackWalletCtx, useTrackWallet } from "@/context/track-wallet"; import { useChainByID } from "@/hooks/useChains"; +import { isWalletClientUsingLedger } from "@/utils/wallet"; export function useAccount(context: TrackWalletCtx) { const trackedWallet = useTrackWallet(context); @@ -20,6 +23,20 @@ export function useAccount(context: TrackWalletCtx) { const wagmiAccount = useWagmiAccount(); + const getIsLedger = async (client: WalletClient, chainId: string) => { + const isLedger = await isWalletClientUsingLedger(client, chainId); + return isLedger; + }; + + const cosmosWalletIsLedgerQuery = useQuery({ + queryKey: ["cosmosWallet", cosmosWallet, chain, cosmosWallet?.client, chain?.chainID], + queryFn: () => { + if (!cosmosWallet || !chain) return; + return getIsLedger(cosmosWallet.client, chain.chainID); + }, + enabled: chain && chain.chainType === "cosmos" && !!cosmosWallet, + }); + const account = useMemo(() => { trackedWallet; if (!chain) return; @@ -34,7 +51,7 @@ export function useAccount(context: TrackWalletCtx) { walletInfo: { logo: cosmosWallet.walletInfo.logo, }, - mode: cosmosWallet.walletInfo.mode, + isLedger: !!cosmosWalletIsLedgerQuery.data, } : undefined, chainType: chain.chainType, @@ -79,7 +96,7 @@ export function useAccount(context: TrackWalletCtx) { }, }; } - }, [chain, context, cosmosWallet, trackedWallet, wagmiAccount]); + }, [chain, context, cosmosWallet, trackedWallet, wagmiAccount, cosmosWalletIsLedgerQuery.data]); return account; } diff --git a/src/utils/ledger-warning.ts b/src/utils/ledger-warning.ts new file mode 100644 index 00000000..e9d25f53 --- /dev/null +++ b/src/utils/ledger-warning.ts @@ -0,0 +1,22 @@ +import { RouteResponse } from "@skip-router/core"; + +import { knownBrokenCCTPLedgerChainIds, knownEthermintLedgerChainIds } from "@/constants/ledger-warning"; + +export const isCCTPLedgerBrokenInOperation = (route: RouteResponse) => { + return route.operations.some( + (operation) => + "cctpTransfer" in operation && knownBrokenCCTPLedgerChainIds.includes(operation.cctpTransfer.fromChainID), + ); +}; + +export const isEthermintLedgerInOperation = (route: RouteResponse) => { + return ( + route.operations.some( + (operation) => "transfer" in operation && knownEthermintLedgerChainIds.includes(operation.transfer.chainID), + ) || + route.operations.some( + (operation) => + "axelarTransfer" in operation && knownEthermintLedgerChainIds.includes(operation.axelarTransfer.fromChainID), + ) + ); +};