From df56482d79a797c3153604387898646149c85e3b Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 27 Aug 2024 09:35:05 +0200 Subject: [PATCH 1/3] feat: defi section ledger open app gate --- .../fox-farming/hooks/useFoxFarming.ts | 37 +++++++++++++++++-- .../Deposit/components/Approve.tsx | 9 ++++- .../Deposit/components/Confirm.tsx | 9 ++++- .../Withdraw/components/Approve.tsx | 10 ++++- .../Withdraw/components/Confirm.tsx | 9 ++++- .../Deposit/components/Approve.tsx | 10 ++++- .../univ2/hooks/useUniV2LiquidityPool.ts | 15 +++++++- .../utils/thorchain/hooks/useSendThorTx.tsx | 25 ++++++++----- 8 files changed, 104 insertions(+), 20 deletions(-) diff --git a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts index 22d822648bb..62025a5cbff 100644 --- a/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts +++ b/src/features/defi/providers/fox-farming/hooks/useFoxFarming.ts @@ -1,4 +1,4 @@ -import { ethAssetId, fromAccountId, fromAssetId } from '@shapeshiftoss/caip' +import { ethAssetId, ethChainId, fromAccountId } from '@shapeshiftoss/caip' import { CONTRACT_INTERACTION } from '@shapeshiftoss/chain-adapters' import { supportsETH } from '@shapeshiftoss/hdwallet-core' import { getFees } from '@shapeshiftoss/utils/dist/evm' @@ -7,6 +7,7 @@ import { getOrCreateContractByAddress } from 'contracts/contractManager' import { useCallback, useMemo } from 'react' import { encodeFunctionData, getAddress, maxUint256 } from 'viem' import { useFoxEth } from 'context/FoxEthProvider/FoxEthProvider' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { toBaseUnit } from 'lib/math' import { isValidAccountNumber } from 'lib/utils/accounts' @@ -36,6 +37,8 @@ export const useFoxFarming = ( contractAddress: FoxEthStakingContractAddress, { skip }: UseFoxFarmingOptions = {}, ) => { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) + const { farmingAccountId } = useFoxEth() const ethAsset = useAppSelector(state => selectAssetById(state, ethAssetId)) const lpAsset = useAppSelector(state => selectAssetById(state, foxEthLpAssetId)) @@ -49,7 +52,7 @@ export const useFoxFarming = ( const wallet = useWallet().state.wallet - const adapter = useMemo(() => assertGetEvmChainAdapter(fromAssetId(ethAssetId).chainId), []) + const adapter = useMemo(() => assertGetEvmChainAdapter(ethChainId), []) const foxFarmingContract = useMemo( () => getOrCreateContractByAddress(contractAddress), @@ -82,6 +85,8 @@ export const useFoxFarming = ( wallet, }) + await checkLedgerAppOpenIfLedgerConnected(ethChainId) + const txid = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -102,6 +107,7 @@ export const useFoxFarming = ( lpAsset.precision, adapter, contractAddress, + checkLedgerAppOpenIfLedgerConnected, ], ) @@ -126,6 +132,8 @@ export const useFoxFarming = ( wallet, }) + await checkLedgerAppOpenIfLedgerConnected(ethChainId) + const txid = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -146,6 +154,7 @@ export const useFoxFarming = ( lpAsset.precision, adapter, contractAddress, + checkLedgerAppOpenIfLedgerConnected, ], ) @@ -271,6 +280,8 @@ export const useFoxFarming = ( const fees = await getApproveFees() if (!fees) return + await checkLedgerAppOpenIfLedgerConnected(ethChainId) + const txid = await buildAndBroadcast({ adapter, receiverAddress: CONTRACT_INTERACTION, // no receiver for this contract call @@ -285,7 +296,14 @@ export const useFoxFarming = ( }) return txid - }, [accountNumber, adapter, contractAddress, getApproveFees, wallet]) + }, [ + accountNumber, + adapter, + checkLedgerAppOpenIfLedgerConnected, + contractAddress, + getApproveFees, + wallet, + ]) const claimRewards = useCallback(async () => { if (skip || !isValidAccountNumber(accountNumber) || !wallet || !userAddress) return @@ -305,6 +323,8 @@ export const useFoxFarming = ( wallet, }) + await checkLedgerAppOpenIfLedgerConnected(ethChainId) + const txid = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -312,7 +332,16 @@ export const useFoxFarming = ( }) return txid - }, [accountNumber, adapter, contractAddress, foxFarmingContract.abi, skip, userAddress, wallet]) + }, [ + accountNumber, + adapter, + checkLedgerAppOpenIfLedgerConnected, + contractAddress, + foxFarmingContract.abi, + skip, + userAddress, + wallet, + ]) return { allowance, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx index c535ba6d772..47def276a0e 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Approve.tsx @@ -12,6 +12,7 @@ import { useCallback, useContext, useMemo } from 'react' import { useTranslate } from 'react-polyglot' import { useHistory } from 'react-router-dom' import type { StepComponentProps } from 'components/DeFi/components/Steps' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -27,6 +28,7 @@ import { DepositContext } from '../DepositContext' type ApproveProps = StepComponentProps & { accountId: AccountId | undefined } export const Approve: React.FC = ({ accountId, onNext }) => { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(DepositContext) @@ -99,7 +101,8 @@ export const Approve: React.FC = ({ accountId, onNext }) => { foxyApi && dispatch && bip44Params && - state + state && + feeAsset ) ) return @@ -109,6 +112,8 @@ export const Approve: React.FC = ({ accountId, onNext }) => { if (!supportsETH(walletState.wallet)) throw new Error(`handleApprove: wallet does not support ethereum`) + await checkLedgerAppOpenIfLedgerConnected(feeAsset.chainId) + await foxyApi.approve({ tokenContractAddress: assetReference, contractAddress, @@ -163,6 +168,8 @@ export const Approve: React.FC = ({ accountId, onNext }) => { dispatch, bip44Params, state, + feeAsset, + checkLedgerAppOpenIfLedgerConnected, contractAddress, asset.precision, poll, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx index 42eb6cee32d..98cc8a5d1f7 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Deposit/components/Confirm.tsx @@ -16,6 +16,7 @@ import type { StepComponentProps } from 'components/DeFi/components/Steps' import { Row } from 'components/Row/Row' import { RawText, Text } from 'components/Text' import type { TextPropTypes } from 'components/Text/Text' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -32,6 +33,7 @@ import { DepositContext } from '../DepositContext' type ConfirmProps = StepComponentProps & { accountId: AccountId | undefined } export const Confirm: React.FC = ({ onNext, accountId }) => { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(DepositContext) @@ -73,7 +75,8 @@ export const Confirm: React.FC = ({ onNext, accountId }) => { walletState.wallet && foxyApi && bip44Params && - dispatch + dispatch && + feeAsset ) ) return @@ -83,6 +86,8 @@ export const Confirm: React.FC = ({ onNext, accountId }) => { if (!supportsETH(walletState.wallet)) throw new Error(`handleDeposit: wallet does not support ethereum`) + await checkLedgerAppOpenIfLedgerConnected(feeAsset.chainId) + const txid = await foxyApi.deposit({ amountDesired: bnOrZero(state?.deposit.cryptoAmount) .times(bn(10).pow(asset.precision)) @@ -131,6 +136,8 @@ export const Confirm: React.FC = ({ onNext, accountId }) => { foxyApi, bip44Params, dispatch, + feeAsset, + checkLedgerAppOpenIfLedgerConnected, state?.deposit.cryptoAmount, asset.precision, contractAddress, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx index 0626a0ce29d..84008cad1e5 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Approve.tsx @@ -11,6 +11,7 @@ import { useFoxyQuery } from 'features/defi/providers/foxy/components/FoxyManage import { useCallback, useContext, useMemo } from 'react' import { useTranslate } from 'react-polyglot' import type { StepComponentProps } from 'components/DeFi/components/Steps' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -26,6 +27,7 @@ import { WithdrawContext } from '../WithdrawContext' type ApproveProps = StepComponentProps & { accountId: AccountId | undefined } export const Approve: React.FC = ({ accountId, onNext }) => { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(WithdrawContext) @@ -115,7 +117,8 @@ export const Approve: React.FC = ({ accountId, onNext }) => { state?.withdraw && foxyApi && dispatch && - bip44Params + bip44Params && + feeAsset ) ) return @@ -124,6 +127,9 @@ export const Approve: React.FC = ({ accountId, onNext }) => { if (!supportsETH(walletState.wallet)) throw new Error(`handleApprove: wallet does not support ethereum`) dispatch({ type: FoxyWithdrawActionType.SET_LOADING, payload: true }) + + await checkLedgerAppOpenIfLedgerConnected(feeAsset.chainId) + await foxyApi.approve({ tokenContractAddress: rewardId, contractAddress, @@ -167,9 +173,11 @@ export const Approve: React.FC = ({ accountId, onNext }) => { }, [ asset.precision, bip44Params, + checkLedgerAppOpenIfLedgerConnected, contractAddress, dispatch, estimatedGasCryptoBaseUnit, + feeAsset, foxyApi, getWithdrawGasEstimate, onNext, diff --git a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx index b7910700f64..d4c16e28da5 100644 --- a/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx +++ b/src/features/defi/providers/foxy/components/FoxyManager/Withdraw/components/Confirm.tsx @@ -17,6 +17,7 @@ import type { StepComponentProps } from 'components/DeFi/components/Steps' import { Row } from 'components/Row/Row' import { RawText, Text } from 'components/Text' import type { TextPropTypes } from 'components/Text/Text' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { usePoll } from 'hooks/usePoll/usePoll' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' @@ -34,6 +35,7 @@ export const Confirm: React.FC { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const foxyApi = getFoxyApi() const { state, dispatch } = useContext(WithdrawContext) @@ -78,7 +80,8 @@ export const Confirm: React.FC = ({ accountId, onNext }) => { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { poll } = usePoll() const { state, dispatch } = useContext(DepositContext) const estimatedGasCryptoPrecision = state?.approve.estimatedGasCryptoPrecision @@ -156,6 +158,9 @@ export const Approve: React.FC = ({ accountId, onNext }) => { }) const adapter = assertGetEvmChainAdapter(chainId) + + await checkLedgerAppOpenIfLedgerConnected(asset.chainId) + const buildCustomTxInput = await createBuildCustomTxInput({ accountNumber, from: fromAccountId(accountId).account, @@ -205,10 +210,13 @@ export const Approve: React.FC = ({ accountId, onNext }) => { }, [ accountId, accountNumber, - asset, + asset.assetId, + asset.chainId, + asset.precision, assetId, assets, chainId, + checkLedgerAppOpenIfLedgerConnected, dispatch, inboundAddress, onNext, diff --git a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts index 7e4641bb0ba..468d3ba176a 100644 --- a/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts +++ b/src/features/defi/providers/univ2/hooks/useUniV2LiquidityPool.ts @@ -12,6 +12,7 @@ import isNumber from 'lodash/isNumber' import { useCallback, useMemo } from 'react' import type { Address } from 'viem' import { encodeFunctionData, getAddress, maxUint256 } from 'viem' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { fromBaseUnit, toBaseUnit } from 'lib/math' @@ -53,6 +54,8 @@ export const useUniV2LiquidityPool = ({ assetId1: AssetId lpAssetId: AssetId } & UseUniV2LiquidityPoolOptions) => { + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) + const assetId0OrWeth = assetId0 === ethAssetId ? wethAssetId : assetId0 const assetId1OrWeth = assetId1 === ethAssetId ? wethAssetId : assetId1 @@ -199,6 +202,8 @@ export const useUniV2LiquidityPool = ({ try { if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return + await checkLedgerAppOpenIfLedgerConnected(fromAssetId(assetId0OrWeth).chainId) + const maybeEthAmount = (() => { if (assetId0OrWeth === wethAssetId) return token0Amount if (assetId1OrWeth === wethAssetId) return token1Amount @@ -232,6 +237,7 @@ export const useUniV2LiquidityPool = ({ adapter, assetId0OrWeth, assetId1OrWeth, + checkLedgerAppOpenIfLedgerConnected, makeAddLiquidityData, skip, uniswapRouterContract, @@ -322,6 +328,8 @@ export const useUniV2LiquidityPool = ({ try { if (skip || !isNumber(accountNumber) || !uniswapRouterContract || !wallet) return + await checkLedgerAppOpenIfLedgerConnected(fromAssetId(assetId0OrWeth).chainId) + const data = makeRemoveLiquidityData({ asset0ContractAddress, asset1ContractAddress, @@ -356,6 +364,8 @@ export const useUniV2LiquidityPool = ({ accountNumber, uniswapRouterContract, wallet, + checkLedgerAppOpenIfLedgerConnected, + assetId0OrWeth, makeRemoveLiquidityData, asset0ContractAddress, asset1ContractAddress, @@ -594,6 +604,9 @@ export const useUniV2LiquidityPool = ({ async (contractAddress: Address) => { if (skip || !wallet || !isNumber(accountNumber)) return + // UNI-V2 is hardcoded to Ethereum Mainnet + await checkLedgerAppOpenIfLedgerConnected(ethChainId) + const contract = getOrCreateContractByType({ address: contractAddress, type: ContractType.ERC20, @@ -627,7 +640,7 @@ export const useUniV2LiquidityPool = ({ return txid }, - [accountNumber, adapter, getApproveFees, skip, wallet], + [accountNumber, adapter, checkLedgerAppOpenIfLedgerConnected, getApproveFees, skip, wallet], ) return { diff --git a/src/lib/utils/thorchain/hooks/useSendThorTx.tsx b/src/lib/utils/thorchain/hooks/useSendThorTx.tsx index ef0993d164f..4631b5b687e 100644 --- a/src/lib/utils/thorchain/hooks/useSendThorTx.tsx +++ b/src/lib/utils/thorchain/hooks/useSendThorTx.tsx @@ -15,6 +15,7 @@ import { selectInboundAddressData } from 'react-queries/selectors' import { getAddress, zeroAddress } from 'viem' import type { SendInput } from 'components/Modals/Send/Form' import { estimateFees, handleSend } from 'components/Modals/Send/utils' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { bn, bnOrZero } from 'lib/bignumber/bignumber' import { getTxLink } from 'lib/getTxLink' @@ -75,6 +76,7 @@ export const useSendThorTx = ({ const [txId, setTxId] = useState(null) const [serializedTxIndex, setSerializedTxIndex] = useState(null) + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const wallet = useWallet().state.wallet const toast = useToast() const translate = useTranslate() @@ -333,6 +335,8 @@ export const useSendThorTx = ({ wallet, }) + await checkLedgerAppOpenIfLedgerConnected(asset.chainId) + const _txId = await buildAndBroadcast({ adapter, buildCustomTxInput, @@ -408,22 +412,23 @@ export const useSendThorTx = ({ return _txId }, [ - accountId, - accountNumber, - amountOrDustCryptoBaseUnit, + memo, asset, - depositWithExpiryInputData, + wallet, + accountId, + transactionType, estimateFeesArgs, - fromAddress, + accountNumber, inboundAddressData, - memo, - selectedCurrency, + action, shouldUseDustAmount, + amountOrDustCryptoBaseUnit, toast, - transactionType, translate, - wallet, - action, + depositWithExpiryInputData, + checkLedgerAppOpenIfLedgerConnected, + fromAddress, + selectedCurrency, ]) return { From 0135fe0cc1151f2b27bf4d314f08beee1832c60c Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 27 Aug 2024 11:10:06 +0200 Subject: [PATCH 2/3] feat: cosmos too --- .../cosmos/hooks/useStakingAction/useStakingAction.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx b/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx index 820653d73cc..9321e343c7f 100644 --- a/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx +++ b/src/plugins/cosmos/hooks/useStakingAction/useStakingAction.tsx @@ -11,6 +11,7 @@ import { checkIsMetaMaskImpersonator, checkIsSnapInstalled, } from 'hooks/useIsSnapInstalled/useIsSnapInstalled' +import { useLedgerOpenApp } from 'hooks/useLedgerOpenApp/useLedgerOpenApp' import { useWallet } from 'hooks/useWallet/useWallet' import { SHAPESHIFT_COSMOS_VALIDATOR_ADDRESS } from 'state/slices/opportunitiesSlice/resolvers/cosmosSdk/constants' @@ -34,6 +35,7 @@ type StakingInput = { export const useStakingAction = () => { const chainAdapterManager = getChainAdapterManager() + const checkLedgerAppOpenIfLedgerConnected = useLedgerOpenApp({ isSigning: true }) const { state: { wallet }, } = useWallet() @@ -68,8 +70,10 @@ export const useStakingAction = () => { const memo = shapeshiftValidators.includes(validator) ? 'Delegated with ShapeShift' : '' const { accountNumber } = bip44Params + + await checkLedgerAppOpenIfLedgerConnected(asset.chainId) + const address = await adapter.getAddress({ accountNumber, wallet }) const { txToSign, receiverAddress } = await (async () => { - const address = await adapter.getAddress({ accountNumber, wallet }) switch (action) { case StakingAction.Claim: return { @@ -116,9 +120,8 @@ export const useStakingAction = () => { throw new Error(`unsupported staking action: ${action}`) } })() - const senderAddress = await adapter.getAddress({ accountNumber, wallet }) return adapter.signAndBroadcastTransaction({ - senderAddress, + senderAddress: address, receiverAddress, signTxInput: { txToSign, wallet }, }) From 18ee33667994969732dbb198aab69dffa71e4634 Mon Sep 17 00:00:00 2001 From: gomes <17035424+gomesalexandre@users.noreply.github.com> Date: Tue, 27 Aug 2024 12:02:17 +0200 Subject: [PATCH 3/3] fix: derp --- src/lib/utils/thorchain/hooks/useSendThorTx.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/utils/thorchain/hooks/useSendThorTx.tsx b/src/lib/utils/thorchain/hooks/useSendThorTx.tsx index 4631b5b687e..96e3193a0e5 100644 --- a/src/lib/utils/thorchain/hooks/useSendThorTx.tsx +++ b/src/lib/utils/thorchain/hooks/useSendThorTx.tsx @@ -280,6 +280,8 @@ export const useSendThorTx = ({ ) throw new Error('invalid amount specified') + await checkLedgerAppOpenIfLedgerConnected(asset.chainId) + const { account } = fromAccountId(accountId) const { _txId, _serializedTxIndex } = await (async () => { @@ -335,8 +337,6 @@ export const useSendThorTx = ({ wallet, }) - await checkLedgerAppOpenIfLedgerConnected(asset.chainId) - const _txId = await buildAndBroadcast({ adapter, buildCustomTxInput,