Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 34 additions & 18 deletions app/components/UI/TransactionElement/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import {
} from '@metamask/transaction-controller';
import { ThemeContext, mockTheme } from '../../../util/theme';
import { selectTickerByChainId } from '../../../selectors/networkController';
import { selectSelectedInternalAccount } from '../../../selectors/accountsController';
import {
selectSelectedInternalAccount,
selectSelectedInternalAccountAddress,
} from '../../../selectors/accountsController';
import { selectSelectedAccountGroupInternalAccounts } from '../../../selectors/multichainAccounts/accountTreeController';
import { selectPrimaryCurrency } from '../../../selectors/settings';
import {
Expand Down Expand Up @@ -56,7 +59,7 @@ import {
selectCurrencyRates,
} from '../../../selectors/currencyRateController';
import { selectContractExchangeRatesByChainId } from '../../../selectors/tokenRatesController';
import { selectTokensByChainIdAndAddress } from '../../../selectors/tokensController';
import { selectTokensByChainIdAndWalletAddress } from '../../../selectors/tokensController';
import Routes from '../../../constants/navigation/Routes';
import {
hasGasFeeTokenSelected,
Expand Down Expand Up @@ -224,6 +227,10 @@ class TransactionElement extends PureComponent {
* Chain Id
*/
txChainId: PropTypes.string,
/**
* Selected wallet address for decoding and token map (optional override from parent)
*/
selectedAddress: PropTypes.string,
/**
* Ticker
*/
Expand Down Expand Up @@ -278,7 +285,8 @@ class TransactionElement extends PureComponent {
componentDidUpdate(prevProps) {
if (
prevProps.txChainId !== this.props.txChainId ||
prevProps.swapsTransactions !== this.props.swapsTransactions
prevProps.swapsTransactions !== this.props.swapsTransactions ||
prevProps.selectedAddress !== this.props.selectedAddress
) {
this.componentDidMount();
}
Expand Down Expand Up @@ -738,21 +746,29 @@ class TransactionElement extends PureComponent {
}
}

const mapStateToProps = (state, ownProps) => ({
selectedInternalAccount: selectSelectedInternalAccount(state),
selectSelectedAccountGroupInternalAccounts:
selectSelectedAccountGroupInternalAccounts(state),
primaryCurrency: selectPrimaryCurrency(state),
swapsTransactions: selectSwapsTransactions(state),
ticker: selectTickerByChainId(state, ownProps.txChainId),
conversionRate: selectConversionRateByChainId(state, ownProps.txChainId),
currencyRates: selectCurrencyRates(state),
contractExchangeRates: selectContractExchangeRatesByChainId(
state,
ownProps.txChainId,
),
tokens: selectTokensByChainIdAndAddress(state, ownProps.txChainId),
});
const mapStateToProps = (state, ownProps) => {
const walletAddressForTokens =
ownProps.selectedAddress ?? selectSelectedInternalAccountAddress(state);
return {
selectedInternalAccount: selectSelectedInternalAccount(state),
selectSelectedAccountGroupInternalAccounts:
selectSelectedAccountGroupInternalAccounts(state),
primaryCurrency: selectPrimaryCurrency(state),
swapsTransactions: selectSwapsTransactions(state),
ticker: selectTickerByChainId(state, ownProps.txChainId),
conversionRate: selectConversionRateByChainId(state, ownProps.txChainId),
currencyRates: selectCurrencyRates(state),
contractExchangeRates: selectContractExchangeRatesByChainId(
state,
ownProps.txChainId,
),
tokens: selectTokensByChainIdAndWalletAddress(
state,
ownProps.txChainId,
walletAddressForTokens,
),
};
};

TransactionElement.contextType = ThemeContext;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,9 @@ const UnifiedTransactionsView = ({
i={index}
navigation={navigation}
txChainId={getEvmChainId(item.tx)}
selectedAddress={selectedInternalAccount?.address}
selectedAddress={
selectedAccountGroupEvmAddress || selectedInternalAccount?.address
}
onSpeedUpAction={onSpeedUpAction}
onCancelAction={onCancelAction}
signQRTransaction={signQRTransaction}
Expand Down
29 changes: 29 additions & 0 deletions app/selectors/tokensController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
selectAllDetectedTokensForSelectedAddress,
selectAllDetectedTokensFlat,
selectTokensByChainIdAndAddress,
selectTokensByChainIdAndWalletAddress,
getChainIdsToPoll,
selectSingleTokenByAddressAndChainId,
} from './tokensController';
Expand Down Expand Up @@ -337,6 +338,34 @@ describe('TokensController Selectors', () => {
});
});

describe('selectTokensByChainIdAndWalletAddress', () => {
it('returns tokens for the given chain and explicit wallet address', () => {
expect(
selectTokensByChainIdAndWalletAddress(
mockRootState,
'0x1',
'0xAddress2',
),
).toStrictEqual({ '0xToken2': mockToken2 });
});

it('returns empty object when wallet address has no tokens on that chain', () => {
expect(
selectTokensByChainIdAndWalletAddress(
mockRootState,
'0x2',
'0xAddress1',
),
).toStrictEqual({});
});

it('returns empty object when wallet address is undefined', () => {
expect(
selectTokensByChainIdAndWalletAddress(mockRootState, '0x1', undefined),
).toStrictEqual({});
});
});

describe('getChainIdsToPoll', () => {
const mockNetworkConfigurations = {
'0x1': { chainId: '0x1' } as unknown as NetworkConfiguration,
Expand Down
28 changes: 28 additions & 0 deletions app/selectors/tokensController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,34 @@
) ?? {},
);

/**
* Like {@link selectTokensByChainIdAndAddress} but uses an explicit account
* address (e.g. the EVM address for the account group) instead of the globally
* selected account. Needed when the UI shows EVM activity while a non-EVM
* account is still selected.
*/
export const selectTokensByChainIdAndWalletAddress = createDeepEqualSelector(
getTokensControllerAllTokens,
(_state: RootState, chainId: Hex, _walletAddress: Hex | string | undefined) =>

Check warning on line 64 in app/selectors/tokensController.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this union type with a type alias.

See more on https://sonarcloud.io/project/issues?id=metamask-mobile&issues=AZ39pFyeyd-KZZrxolwc&open=AZ39pFyeyd-KZZrxolwc&pullRequest=29794
chainId,
(_state: RootState, _chainId: Hex, walletAddress: Hex | string | undefined) =>
walletAddress,
(
allTokens: TokensControllerState['allTokens'],
chainId: Hex,
walletAddress: Hex | string | undefined,
) =>
!walletAddress
? {}
: (allTokens[chainId]?.[walletAddress as Hex]?.reduce(
(tokensMap: { [address: string]: Token }, token: Token) => ({
...tokensMap,
[token.address]: token,
}),
{},
) ?? {}),
);

export const selectTokensByAddress = createSelector(
selectTokens,
(tokens: Token[]) =>
Expand Down
Loading