Skip to content
Open
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
1 change: 1 addition & 0 deletions packages/transaction-pay-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Bump `@metamask/messenger` from `^1.1.1` to `^1.2.0` ([#8632](https://github.com/MetaMask/core/pull/8632))
- Stop synthesising a native gas-fee required token in `parseRequiredTokens`, only token-transfer assets are returned now ([#8554](https://github.com/MetaMask/core/pull/8554))

## [20.0.1]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { TransactionMeta } from '@metamask/transaction-controller';
import type { Hex } from '@metamask/utils';

import { toHex } from '../../../controller-utils/src';
import { NATIVE_TOKEN_ADDRESS } from '../constants';
import type { TransactionPayControllerMessenger } from '../types';
import { parseRequiredTokens } from './required-tokens';
import { getTokenBalance, getTokenFiatRate, getTokenInfo } from './token';
Expand Down Expand Up @@ -167,7 +166,6 @@ describe('Required Tokens Utils', () => {
skipIfBalance: false,
symbol: 'TST',
},
expect.anything(),
]);
});
});
Expand Down Expand Up @@ -200,7 +198,6 @@ describe('Required Tokens Utils', () => {
skipIfBalance: false,
symbol: 'TST',
},
expect.anything(),
]);
});

Expand Down Expand Up @@ -247,7 +244,6 @@ describe('Required Tokens Utils', () => {
skipIfBalance: false,
symbol: 'TST',
},
expect.anything(),
]);
});

Expand All @@ -270,127 +266,7 @@ describe('Required Tokens Utils', () => {

const result = parseRequiredTokens(transactionMeta, MESSENGER_MOCK);

expect(result).toStrictEqual([expect.anything()]);
});

it('returns gas fee required token', () => {
getTokenInfoMock.mockReturnValue({ decimals: 18, symbol: 'TST' });
getTokenBalanceMock.mockReturnValue('1230000000000000000');

getTokenFiatRateMock.mockReturnValue({
usdRate: '4000',
fiatRate: '2000',
});

const result = parseRequiredTokens(
{
...TRANSACTION_META_MOCK,
txParams: { ...TRANSACTION_META_MOCK.txParams, data: '0x1234' },
},
MESSENGER_MOCK,
);

expect(result).toStrictEqual([
{
address: NATIVE_TOKEN_ADDRESS,
allowUnderMinimum: true,
amountFiat: '2',
amountHuman: '0.001',
amountRaw: '1000000000000000',
amountUsd: '4',
balanceFiat: '2460',
balanceHuman: '1.23',
balanceRaw: '1230000000000000000',
balanceUsd: '4920',
chainId: TRANSACTION_META_MOCK.chainId,
decimals: 18,
skipIfBalance: true,
symbol: 'TST',
},
]);
});

it('returns gas fee required token as one dollar if less than one dollar', () => {
getTokenInfoMock.mockReturnValue({ decimals: 18, symbol: 'TST' });
getTokenBalanceMock.mockReturnValue('900000000000');

getTokenFiatRateMock.mockReturnValue({
usdRate: '4000',
fiatRate: '2000',
});

const result = parseRequiredTokens(
{
...TRANSACTION_META_MOCK,
txParams: {
...TRANSACTION_META_MOCK.txParams,
data: '0x1234',
gas: toHex(100),
},
},
MESSENGER_MOCK,
);

expect(result).toStrictEqual([
{
address: NATIVE_TOKEN_ADDRESS,
allowUnderMinimum: true,
amountFiat: '0.5',
amountHuman: '0.00025',
amountRaw: '250000000000000',
amountUsd: '1',
balanceFiat: '0.0018',
balanceHuman: '0.0000009',
balanceRaw: '900000000000',
balanceUsd: '0.0036',
chainId: TRANSACTION_META_MOCK.chainId,
decimals: 18,
skipIfBalance: true,
symbol: 'TST',
},
]);
});

it('returns gas fee required token as zero if no gas or maxFeePerGas', () => {
getTokenInfoMock.mockReturnValue({ decimals: 18, symbol: 'TST' });
getTokenBalanceMock.mockReturnValue('900000000000');

getTokenFiatRateMock.mockReturnValue({
usdRate: '4000',
fiatRate: '2000',
});

const result = parseRequiredTokens(
{
...TRANSACTION_META_MOCK,
txParams: {
...TRANSACTION_META_MOCK.txParams,
data: '0x1234',
gas: undefined,
maxFeePerGas: undefined,
},
},
MESSENGER_MOCK,
);

expect(result).toStrictEqual([
{
address: NATIVE_TOKEN_ADDRESS,
allowUnderMinimum: true,
amountFiat: '0',
amountHuman: '0',
amountRaw: '0',
amountUsd: '0',
balanceFiat: '0.0018',
balanceHuman: '0.0000009',
balanceRaw: '900000000000',
balanceUsd: '0.0036',
chainId: TRANSACTION_META_MOCK.chainId,
decimals: 18,
skipIfBalance: true,
symbol: 'TST',
},
]);
expect(result).toStrictEqual([]);
});

it('returns empty array if no to', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@ import { Interface } from '@ethersproject/abi';
import { toHex } from '@metamask/controller-utils';
import { abiERC20 } from '@metamask/metamask-eth-abis';
import type { TransactionMeta } from '@metamask/transaction-controller';
import { add0x } from '@metamask/utils';
import type { Hex } from '@metamask/utils';
import { BigNumber } from 'bignumber.js';

import type {
FiatRates,
TransactionPayControllerMessenger,
TransactionPayRequiredToken,
} from '../types';
import {
computeTokenAmounts,
getNativeToken,
getTokenBalance,
getTokenFiatRate,
getTokenInfo,
Expand Down Expand Up @@ -47,10 +43,8 @@ export function parseRequiredTokens(
return assetTokens;
}

return [
getTokenTransferToken(transaction, messenger),
getGasFeeToken(transaction, messenger),
].filter(Boolean) as TransactionPayRequiredToken[];
const transferToken = getTokenTransferToken(transaction, messenger);
return transferToken ? [transferToken] : [];
}

/**
Expand Down Expand Up @@ -86,81 +80,6 @@ function getTokenTransferToken(
return buildRequiredToken(transaction, to, transferAmount, messenger);
}

/**
* Get the gas fee token required for a transaction.
*
* @param transaction - Transaction metadata.
* @param messenger - Controller messenger.
* @returns The gas fee token or undefined if it could not be determined.
*/
function getGasFeeToken(
transaction: TransactionMeta,
messenger: TransactionPayControllerMessenger,
): TransactionPayRequiredToken | undefined {
const { chainId, txParams } = transaction;
const { gas, maxFeePerGas } = txParams;
const nativeTokenAddress = getNativeToken(chainId);

const maxGasCostRawHex = add0x(
new BigNumber(gas ?? '0x0')
.multipliedBy(new BigNumber(maxFeePerGas ?? '0x0'))
.toString(16),
);

const token = buildRequiredToken(
transaction,
nativeTokenAddress,
maxGasCostRawHex,
messenger,
);

if (!token) {
return undefined;
}

const amountUsdValue = new BigNumber(token.amountUsd);

const hasBalance = new BigNumber(token.balanceRaw).isGreaterThanOrEqualTo(
token.amountRaw,
);

if (hasBalance || amountUsdValue.isGreaterThanOrEqualTo(1)) {
return {
...token,
allowUnderMinimum: true,
skipIfBalance: true,
};
}

const fiatRates = getTokenFiatRate(
messenger,
nativeTokenAddress,
chainId,
) as FiatRates;

const oneDollarRawHex = add0x(
new BigNumber(1).dividedBy(fiatRates.usdRate).shiftedBy(18).toString(16),
);

const oneDollarToken = buildRequiredToken(
transaction,
nativeTokenAddress,
oneDollarRawHex,
messenger,
);

/* istanbul ignore next */
if (!oneDollarToken) {
return undefined;
}

return {
...oneDollarToken,
allowUnderMinimum: true,
skipIfBalance: true,
};
}

/**
* Get the full token properties for a specific token and amount.
*
Expand Down
Loading