Skip to content

Commit

Permalink
Add HW wallet check
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljscript committed Oct 22, 2024
1 parent 63715ac commit b99c884
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 16 deletions.
7 changes: 7 additions & 0 deletions apps/wallet-mobile/src/features/Discover/common/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const USER_REJECTED_ERROR_MESSAGE = 'User rejected'

export const userRejectedError = () => new Error(USER_REJECTED_ERROR_MESSAGE)

export const isUserRejectedError = (error: Error): boolean => {
return error.message === USER_REJECTED_ERROR_MESSAGE
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {useEffect} from 'react'
import {StyleSheet, View} from 'react-native'
import {TouchableOpacity} from 'react-native-gesture-handler'
import {SafeAreaView} from 'react-native-safe-area-context'
import {useQuery} from 'react-query'
import {useMutation, useQuery} from 'react-query'
import {z} from 'zod'

import {Button} from '../../../../components/Button/Button'
Expand All @@ -17,6 +17,7 @@ import {Icon} from '../../../../components/Icon'
import {ScrollView} from '../../../../components/ScrollView/ScrollView'
import {Spacer} from '../../../../components/Spacer/Spacer'
import {Text} from '../../../../components/Text'
import {logger} from '../../../../kernel/logger/logger'
import {useParams} from '../../../../kernel/navigation'
import {cip30LedgerExtensionMaker} from '../../../../yoroi-wallets/cardano/cip30/cip30-ledger'
import {wrappedCsl} from '../../../../yoroi-wallets/cardano/wrappedCsl'
Expand All @@ -25,6 +26,7 @@ import {asQuantity} from '../../../../yoroi-wallets/utils/utils'
import {usePortfolioTokenInfos} from '../../../Portfolio/common/hooks/usePortfolioTokenInfos'
import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet'
import {useConfirmHWConnectionModal} from '../../common/ConfirmHWConnectionModal'
import {isUserRejectedError, userRejectedError} from '../../common/errors'
import {usePromptRootKey} from '../../common/hooks'
import {useStrings} from '../../common/useStrings'

Expand Down Expand Up @@ -54,7 +56,7 @@ export const ReviewTransaction = () => {

const {styles} = useStyles()

const signTxWithHW = useSignTxWithHW()
const {sign: signTxWithHW} = useSignTxWithHW()

const handleOnConfirm = async () => {
if (!params.isHW) {
Expand All @@ -63,8 +65,13 @@ export const ReviewTransaction = () => {
return
}

const signature = await signTxWithHW(params.cbor, params.partial)
params.onConfirm(signature)
signTxWithHW(
{cbor: params.cbor, partial: params.partial},
{
onSuccess: (signature) => params.onConfirm(signature),
onError: (error) => logger.error('ReviewTransaction::handleOnConfirm', {error}),
},
)
}

useEffect(() => {
Expand Down Expand Up @@ -437,7 +444,7 @@ const useConnectorPromptRootKey = () => {
return Promise.resolve()
},
onClose: () => {
if (shouldResolveOnClose) reject(new Error('User rejected'))
if (shouldResolveOnClose) reject(userRejectedError())
},
})
} catch (error) {
Expand All @@ -451,15 +458,15 @@ export const useSignTxWithHW = () => {
const {confirmHWConnection, closeModal} = useConfirmHWConnectionModal()
const {wallet, meta} = useSelectedWallet()

return React.useCallback(
(cbor: string, partial?: boolean) => {
const mutationFn = React.useCallback(
(options: {cbor: string; partial?: boolean}) => {
return new Promise<Transaction>((resolve, reject) => {
let shouldResolveOnClose = true
confirmHWConnection({
onConfirm: async ({transportType, deviceInfo}) => {
try {
const cip30 = cip30LedgerExtensionMaker(wallet, meta)
const tx = await cip30.signTx(cbor, partial ?? false, deviceInfo, transportType === 'USB')
const tx = await cip30.signTx(options.cbor, options.partial ?? false, deviceInfo, transportType === 'USB')
shouldResolveOnClose = false
return resolve(tx)
} catch (error) {
Expand All @@ -469,11 +476,19 @@ export const useSignTxWithHW = () => {
}
},
onClose: () => {
if (shouldResolveOnClose) reject(new Error('User rejected'))
if (shouldResolveOnClose) reject(userRejectedError())
},
})
})
},
[confirmHWConnection, wallet, meta, closeModal],
)

const mutation = useMutation<Transaction, Error, {cbor: string; partial?: boolean}>({
mutationFn,
useErrorBoundary: (error) => !isUserRejectedError(error),
mutationKey: ['useSignTxWithHW'],
})

return {...mutation, sign: mutation.mutate}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {InteractionManager} from 'react-native'

import {useSelectedWallet} from '../WalletManager/common/hooks/useSelectedWallet'
import {useOpenConfirmConnectionModal} from './common/ConfirmConnectionModal'
import {userRejectedError} from './common/errors'
import {createDappConnector} from './common/helpers'
import {usePromptRootKey} from './common/hooks'
import {useShowHWNotSupportedModal} from './common/HWNotSupportedModal'
Expand Down Expand Up @@ -44,7 +45,7 @@ export const useDappConnectorManager = () => {
onCancel: () => {
if (!shouldResolve) return
shouldResolve = false
reject(new Error('User rejected'))
reject(userRejectedError())
},
})
})
Expand All @@ -67,7 +68,7 @@ export const useDappConnectorManager = () => {
onCancel: () => {
if (!shouldResolve) return
shouldResolve = false
reject(new Error('User rejected'))
reject(userRejectedError())
},
})
})
Expand Down Expand Up @@ -98,7 +99,7 @@ const useSignData = () => {
return Promise.resolve()
},
onClose: () => {
if (shouldResolveOnClose) reject(new Error('User rejected'))
if (shouldResolveOnClose) reject(userRejectedError())
},
})
} catch (error) {
Expand All @@ -120,10 +121,10 @@ const useSignDataWithHW = () => {
onConfirm: () => {
closeModal()
shouldResolveOnClose = false
return reject(new Error('User rejected'))
return reject(userRejectedError())
},
onClose: () => {
if (shouldResolveOnClose) reject(new Error('User rejected'))
if (shouldResolveOnClose) reject(userRejectedError())
},
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ class CIP30LedgerExtension {
async signTx(cbor: string, partial: boolean, hwDeviceInfo: HW.DeviceInfo, useUSB: boolean): Promise<Transaction> {
const {csl, release} = wrappedCsl()
try {
const tx = await csl.FixedTransaction.fromHex(cbor)
const tx = await csl.Transaction.fromHex(cbor)
if (!partial) await assertHasAllSigners(cbor, this.wallet, this.meta)
const txBody = await tx.body()

const transactionSetTag = await has_transaction_set_tag(await txBody.toBytes())
const transactionSetTag = await has_transaction_set_tag(await tx.toBytes())

if (transactionSetTag === TransactionSetsState.MixedSets) {
throw new Error('CIP30LedgerExtension.signTx: Mixed transaction sets are not supported when using a HW wallet')
Expand Down

0 comments on commit b99c884

Please sign in to comment.