mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-12 12:47:14 +01:00
9d70c60c22
* Connect ledger via webhid if that option is available * Explicitly setting preference for webhid * Use ledgerTransportType enum instead of booleans for ledger live and webhid preferences * Use single setLEdgerTransport preference methods and property * Temp * Lint fix * Unit test fix * Remove async keyword from setLedgerTransportPreference function definition in preferences controller * Fix ledgelive setting toggle logic * Migrate useLedgerLive preference property to ledgerTransportType * Use shared constants for ledger transport type enums * Use constant for ledger usb vendor id * Use correct property to check if ledgerLive preference is set when deciding whether to ask for webhid connection * Update eth-ledger-bridge-keyring to v0.9.0 * Only show ledger live transaction helper messages if using ledger live * Only show ledger live part of tutorial if ledger live setting is on * Fix ledger related prop type errors * Explicitly use u2f enum instead of empty string as a transport type; default transport type to webhid if available; use constants for u2f and webhid * Cleanup * Wrap ledger webhid device request in try/catch * Clean up * Lint fix * Ensure user can easily connect their ledger wallet when they need to. * Fix locales * Fix/improve locales changes * Remove unused isFirefox property from confirm-transaction-base.container.js * Disable transaction and message signing confirmation if ledger webhid requires connection * Ensure translation keys for ledger connection options in settings dropdown can be properly detected by verify-locales * Drop .component from ledger-instruction-field file name * Move renderLedgerLiveStep to module scope * Remove ledgerLive from function and message names in ledger-instruction-field * Wrap ledger connection logic in ledger-instruction-field in try catch * Clean up signature-request.component.js * Check whether the signing address, and not the selected address, is a ledger account in singature-request.container * Ensure ledger instructions and webhid connection button are shown on signature-request-original signatures * Improve webhid selection handling in select-ledger-transport-type onChange handler * Move metamask redux focused ledger selectors to metamask duck * Lint fix * Use async await in checkWebHidStatusRef.current * Remove unnecessary use of ref in ledger-instruction-field.js * Lint fix * Remove unnecessary try/catch in ledger-instruction-field.js * Check if from address, not selected address, is from a ledger account in confirm-approve * Move findKeyringForAddress to metamask duck * Fix typo in function name * Ensure isEqualCaseInsensitive handles possible differences in address casing * Fix Learn More link size in advanced settings tab * Update app/scripts/migrations/066.js Co-authored-by: Mark Stacey <markjstacey@gmail.com> * Update ui/pages/settings/advanced-tab/advanced-tab.component.test.js Co-authored-by: Mark Stacey <markjstacey@gmail.com> * Add jsdoc comments for new selectors * Use jest.spyOn for mocking navigator in ledger webhid migration tests * Use LEDGER_TRANSPORT_TYPES values to set proptype of ledgerTransportType * Use LEDGER_TRANSPORT_TYPES values to set proptype of ledgerTransportType * Fix font size of link in ledger connection description in advanced settings * Fix return type in setLedgerTransportPreference comment * Clean up connectHardware code for webhid connection in actions.js * Update app/scripts/migrations/066.test.js Co-authored-by: Mark Stacey <markjstacey@gmail.com> * Update ui/ducks/metamask/metamask.js Co-authored-by: Mark Stacey <markjstacey@gmail.com> * Add migration test for when useLedgerLive is true in a browser that supports webhid * Lint fix * Fix inline-link size Co-authored-by: Mark Stacey <markjstacey@gmail.com>
240 lines
7.9 KiB
JavaScript
240 lines
7.9 KiB
JavaScript
import React, { useEffect, useRef, useState } from 'react';
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
import { useParams } from 'react-router-dom';
|
|
import ConfirmTransactionBase from '../confirm-transaction-base';
|
|
import { EDIT_GAS_MODES } from '../../../shared/constants/gas';
|
|
import {
|
|
showModal,
|
|
updateCustomNonce,
|
|
getNextNonce,
|
|
} from '../../store/actions';
|
|
import { getTokenData } from '../../helpers/utils/transactions.util';
|
|
import {
|
|
calcTokenAmount,
|
|
getTokenAddressParam,
|
|
getTokenValueParam,
|
|
} from '../../helpers/utils/token-util';
|
|
import { useTokenTracker } from '../../hooks/useTokenTracker';
|
|
import { getTokens, getNativeCurrency } from '../../ducks/metamask/metamask';
|
|
import {
|
|
transactionFeeSelector,
|
|
txDataSelector,
|
|
getCurrentCurrency,
|
|
getDomainMetadata,
|
|
getUseNonceField,
|
|
getCustomNonceValue,
|
|
getNextSuggestedNonce,
|
|
doesAddressRequireLedgerHidConnection,
|
|
} from '../../selectors';
|
|
|
|
import { useApproveTransaction } from '../../hooks/useApproveTransaction';
|
|
|
|
import { currentNetworkTxListSelector } from '../../selectors/transactions';
|
|
import Loading from '../../components/ui/loading-screen';
|
|
import EditGasPopover from '../../components/app/edit-gas-popover/edit-gas-popover.component';
|
|
import { isEqualCaseInsensitive } from '../../helpers/utils/util';
|
|
import { getCustomTxParamsData } from './confirm-approve.util';
|
|
import ConfirmApproveContent from './confirm-approve-content';
|
|
|
|
const doesAddressRequireLedgerHidConnectionByFromAddress = (address) => (
|
|
state,
|
|
) => {
|
|
return doesAddressRequireLedgerHidConnection(state, address);
|
|
};
|
|
|
|
export default function ConfirmApprove() {
|
|
const dispatch = useDispatch();
|
|
const { id: paramsTransactionId } = useParams();
|
|
const {
|
|
id: transactionId,
|
|
txParams: { to: tokenAddress, data, from } = {},
|
|
} = useSelector(txDataSelector);
|
|
|
|
const currentCurrency = useSelector(getCurrentCurrency);
|
|
const nativeCurrency = useSelector(getNativeCurrency);
|
|
const currentNetworkTxList = useSelector(currentNetworkTxListSelector);
|
|
const domainMetadata = useSelector(getDomainMetadata);
|
|
const tokens = useSelector(getTokens);
|
|
const useNonceField = useSelector(getUseNonceField);
|
|
const nextNonce = useSelector(getNextSuggestedNonce);
|
|
const customNonceValue = useSelector(getCustomNonceValue);
|
|
|
|
const ledgerWalletRequiredHidConnection = useSelector(
|
|
doesAddressRequireLedgerHidConnectionByFromAddress(from),
|
|
);
|
|
|
|
const transaction =
|
|
currentNetworkTxList.find(
|
|
({ id }) => id === (Number(paramsTransactionId) || transactionId),
|
|
) || {};
|
|
const { ethTransactionTotal, fiatTransactionTotal } = useSelector((state) =>
|
|
transactionFeeSelector(state, transaction),
|
|
);
|
|
|
|
const currentToken = (tokens &&
|
|
tokens.find(({ address }) =>
|
|
isEqualCaseInsensitive(tokenAddress, address),
|
|
)) || {
|
|
address: tokenAddress,
|
|
};
|
|
|
|
const { tokensWithBalances } = useTokenTracker([currentToken]);
|
|
const tokenTrackerBalance = tokensWithBalances[0]?.balance || '';
|
|
|
|
const tokenSymbol = currentToken?.symbol;
|
|
const decimals = Number(currentToken?.decimals);
|
|
const tokenData = getTokenData(data);
|
|
const tokenValue = getTokenValueParam(tokenData);
|
|
const toAddress = getTokenAddressParam(tokenData);
|
|
const tokenAmount =
|
|
tokenData && calcTokenAmount(tokenValue, decimals).toString(10);
|
|
|
|
const [customPermissionAmount, setCustomPermissionAmount] = useState('');
|
|
|
|
const previousTokenAmount = useRef(tokenAmount);
|
|
|
|
const {
|
|
approveTransaction,
|
|
showCustomizeGasPopover,
|
|
closeCustomizeGasPopover,
|
|
} = useApproveTransaction();
|
|
|
|
useEffect(() => {
|
|
if (customPermissionAmount && previousTokenAmount.current !== tokenAmount) {
|
|
setCustomPermissionAmount(tokenAmount);
|
|
}
|
|
previousTokenAmount.current = tokenAmount;
|
|
}, [customPermissionAmount, tokenAmount]);
|
|
|
|
const [submitWarning, setSubmitWarning] = useState('');
|
|
const prevNonce = useRef(nextNonce);
|
|
const prevCustomNonce = useRef(customNonceValue);
|
|
useEffect(() => {
|
|
if (
|
|
prevNonce.current !== nextNonce ||
|
|
prevCustomNonce.current !== customNonceValue
|
|
) {
|
|
if (nextNonce !== null && customNonceValue > nextNonce) {
|
|
setSubmitWarning(
|
|
`Nonce is higher than suggested nonce of ${nextNonce}`,
|
|
);
|
|
} else {
|
|
setSubmitWarning('');
|
|
}
|
|
}
|
|
prevCustomNonce.current = customNonceValue;
|
|
prevNonce.current = nextNonce;
|
|
}, [customNonceValue, nextNonce]);
|
|
const { origin } = transaction;
|
|
const formattedOrigin = origin
|
|
? origin[0].toUpperCase() + origin.slice(1)
|
|
: '';
|
|
|
|
const { icon: siteImage = '' } = domainMetadata[origin] || {};
|
|
|
|
const tokensText = `${Number(tokenAmount)} ${tokenSymbol}`;
|
|
const tokenBalance = tokenTrackerBalance
|
|
? calcTokenAmount(tokenTrackerBalance, decimals).toString(10)
|
|
: '';
|
|
const customData = customPermissionAmount
|
|
? getCustomTxParamsData(data, { customPermissionAmount, decimals })
|
|
: null;
|
|
|
|
return tokenSymbol === undefined ? (
|
|
<Loading />
|
|
) : (
|
|
<ConfirmTransactionBase
|
|
toAddress={toAddress}
|
|
identiconAddress={tokenAddress}
|
|
showAccountInHeader
|
|
title={tokensText}
|
|
contentComponent={
|
|
<>
|
|
<ConfirmApproveContent
|
|
decimals={decimals}
|
|
siteImage={siteImage}
|
|
setCustomAmount={setCustomPermissionAmount}
|
|
customTokenAmount={String(customPermissionAmount)}
|
|
tokenAmount={tokenAmount}
|
|
origin={formattedOrigin}
|
|
tokenSymbol={tokenSymbol}
|
|
tokenBalance={tokenBalance}
|
|
showCustomizeGasModal={approveTransaction}
|
|
showEditApprovalPermissionModal={({
|
|
/* eslint-disable no-shadow */
|
|
customTokenAmount,
|
|
decimals,
|
|
origin,
|
|
setCustomAmount,
|
|
tokenAmount,
|
|
tokenBalance,
|
|
tokenSymbol,
|
|
/* eslint-enable no-shadow */
|
|
}) =>
|
|
dispatch(
|
|
showModal({
|
|
name: 'EDIT_APPROVAL_PERMISSION',
|
|
customTokenAmount,
|
|
decimals,
|
|
origin,
|
|
setCustomAmount,
|
|
tokenAmount,
|
|
tokenBalance,
|
|
tokenSymbol,
|
|
}),
|
|
)
|
|
}
|
|
data={customData || data}
|
|
toAddress={toAddress}
|
|
currentCurrency={currentCurrency}
|
|
nativeCurrency={nativeCurrency}
|
|
ethTransactionTotal={ethTransactionTotal}
|
|
fiatTransactionTotal={fiatTransactionTotal}
|
|
useNonceField={useNonceField}
|
|
nextNonce={nextNonce}
|
|
customNonceValue={customNonceValue}
|
|
updateCustomNonce={(value) => {
|
|
dispatch(updateCustomNonce(value));
|
|
}}
|
|
getNextNonce={() => dispatch(getNextNonce())}
|
|
showCustomizeNonceModal={({
|
|
/* eslint-disable no-shadow */
|
|
useNonceField,
|
|
nextNonce,
|
|
customNonceValue,
|
|
updateCustomNonce,
|
|
getNextNonce,
|
|
/* eslint-disable no-shadow */
|
|
}) =>
|
|
dispatch(
|
|
showModal({
|
|
name: 'CUSTOMIZE_NONCE',
|
|
useNonceField,
|
|
nextNonce,
|
|
customNonceValue,
|
|
updateCustomNonce,
|
|
getNextNonce,
|
|
}),
|
|
)
|
|
}
|
|
warning={submitWarning}
|
|
txData={transaction}
|
|
ledgerWalletRequiredHidConnection={
|
|
ledgerWalletRequiredHidConnection
|
|
}
|
|
/>
|
|
{showCustomizeGasPopover && (
|
|
<EditGasPopover
|
|
onClose={closeCustomizeGasPopover}
|
|
mode={EDIT_GAS_MODES.MODIFY_IN_PLACE}
|
|
transaction={transaction}
|
|
/>
|
|
)}
|
|
</>
|
|
}
|
|
hideSenderToRecipient
|
|
customTxParamsData={customData}
|
|
/>
|
|
);
|
|
}
|