Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -1434,6 +1434,37 @@ describe('useTransactionCustomAmount', () => {
expect(result.current.amountFiat).toBe('750.50');
});

it('sets isMaxAmount for Max when payment override is MoneyAccount (e.g. Send to Perps)', async () => {
// With TPC MoneyAccount max support (MetaMask/core#9707), isMaxAmount=true
// uses the typed required amount (full withdrawable) rather than the pay
// token's bare on-chain mUSD balance, enabling EXACT_INPUT Max quotes.
useMoneyAccountBalanceMock.mockReturnValue({
withdrawableFiatRaw: '4.70',
} as ReturnType<typeof useMoneyAccountBalance>);

const { result } = runHook({
transactionMeta: {
type: TransactionType.perpsDeposit,
id: transactionIdMock,
chainId: '0x1' as Hex,
txParams: { from: '0xabc' },
} as unknown as Partial<TransactionMeta>,
stateOverrides: moneyAccountStateOverrides,
});

await act(async () => {
result.current.updatePendingAmountPercentage(100);
});

// Full withdrawable balance is shown, not the reduced bare-mUSD figure.
expect(result.current.amountFiat).toBe('4.70');
expect(setTransactionConfigMock).toHaveBeenCalledTimes(1);

const config = { isMaxAmount: false };
setTransactionConfigMock.mock.calls[0][1](config);
expect(config.isMaxAmount).toBe(true);
});

it('returns 0 when payment override is MoneyAccount but withdrawableFiatRaw is undefined', async () => {
useMoneyAccountBalanceMock.mockReturnValue({
withdrawableFiatRaw: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,16 @@ export function useTransactionCustomAmount({
},
});

// Do NOT set isMaxAmount=true for perps or money-account withdraw. TPC's
// calculatePostQuoteSourceAmounts substitutes `token.balanceRaw` when
// isMaxAmount is true: wrong for HyperLiquid (wallet USDC vs typed HL
// balance) and wrong for money account (on-chain mUSD only vs mUSD +
// vmUSD fiat total). Keeping isMaxAmount false routes the typed
// amount through as token.amountRaw.
// Do NOT set isMaxAmount=true for perps/money-account withdraw or money
// account deposit flows. For those, TPC would substitute an on-chain
// balanceRaw that does not match the typed balance (HyperLiquid wallet
// USDC vs HL balance; money-account on-chain mUSD vs mUSD + vmUSD).
//
// Deposits funded from the money account (e.g. Send to Perps) DO set
// isMaxAmount=true so quotes use EXACT_INPUT. That is safe once TPC uses
// the typed required amount for MoneyAccount max instead of the pay
// token's bare mUSD balance (MetaMask/core#9707). Mobile still types the
// full withdrawableFiatRaw amount into the required token.
const shouldSetMax =
percentage === 100 &&
!isPerpsWithdraw &&
Expand Down
Loading