Skip to content

fix(card): missing tokens when revoking using external tools#30209

Merged
Brunonascdev merged 1 commit into
mainfrom
fix/mm-card-missing-not-enabled-assets
May 15, 2026
Merged

fix(card): missing tokens when revoking using external tools#30209
Brunonascdev merged 1 commit into
mainfrom
fix/mm-card-missing-not-enabled-assets

Conversation

@Brunonascdev
Copy link
Copy Markdown
Contributor

@Brunonascdev Brunonascdev commented May 14, 2026

Description

This branch fixes MetaMask Card available funding assets so that after a user revokes a token allowance (e.g. via revoke.cash) or when another linked wallet still holds an active delegation, the currently selected wallet still gets a correct Inactive / not enabled row for supported tokens from Baanx delegation settings—instead of the token disappearing or being incorrectly deduplicated across wallets.

What changed (high level):

  1. BaanxProvider.buildSupportedTokens — Replaces wallet-blind deduplication (address + chainId only) with hasPlaceholderForCurrentWallet: an existing row only blocks adding an Inactive placeholder for the same wallet (or legacy empty walletAddress). Another wallet’s Active/Limited row no longer suppresses the current wallet’s placeholder. New Inactive placeholders are stamped with walletAddress: currentWalletAddress (passed from getCardHomeData).
  2. selectCardAvailableTokensActive and Limited assets from any linked wallet stay visible; Inactive rows are shown only when they belong to the selected EVM account (or have no walletAddress), avoiding duplicate “not enabled” noise for other accounts.
  3. TestsBaanxProvider.test.ts covers buildSupportedTokens (empty funding list, same-wallet dedup, multi-wallet core case, null / empty delegationSettings, contract enrichment). cardController.test.ts covers the selector filtering behaviour with mocked selected account.

Intentionally not included: A feature-flag fallback that synthesizes tokens without delegationSettings (would lack jurisdiction-correct delegationContract). When delegationSettings is missing or has no networks, behaviour stays return fundingAssets as-is (no synthetic list).

Why

  • /v1/wallet/external can be empty after revocation while /v1/delegation/chain/config still lists supported networks/tokens. Placeholders must be built from delegation settings per selected wallet, not deduplicated globally across wallets.
  • UI reads availableFundingAssets via selectCardAvailableTokens; filtering Inactive by account keeps the asset list accurate for account switching and multi-wallet Baanx linkage.

What changed (scoped paths)

Area Files / behaviour
Baanx provider BaanxProvider.ts: getCardHomeData(address, …) passes address into buildSupportedTokens; wallet-aware placeholder dedup; Inactive walletAddress set to current address.
Selectors cardController.ts: selectCardAvailableTokens uses selectSelectedEvmAccount and filters Inactive by current address.
Tests BaanxProvider.test.ts, cardController.test.ts.

Out of scope (intentional)

  • Feature-flag–only token list without delegationSettings / delegationContract.
  • Changes to unauthenticated getOnChainAssets (still bypasses buildSupportedTokens).

Changelog

CHANGELOG entry: Fixed Card available asset list so supported tokens show per-wallet “not enabled” state after revocation or when another linked wallet still has an active delegation; inactive rows are scoped to the selected account in the token picker.

Related issues

Fixes:

Manual testing steps

Feature: Card available tokens after revocation / multi-wallet

  Background:
    Given I am authenticated with the MetaMask Card (Baanx) backend
    And delegation chain config returns supported networks (e.g. Linea USDC)
    And I may have more than one EVM wallet linked to the same card account

  Scenario: revoke on external tool then open Card
    Given I had delegated USDC on Linea from wallet A
    When I revoke the allowance (e.g. revoke.cash) so wallet external API returns no rows for that delegation
    And I select wallet A in MetaMask
    When I open Card home / spending limit asset list
    Then USDC on Linea still appears as not enabled (Inactive) for wallet A when delegation settings still list the token
    And I can re-enable delegation from that row (contract comes from delegation settings)

  Scenario: another wallet still delegated
    Given wallet B still has an active USDC Linea delegation in Baanx wallet external data
    When I select wallet A (revoked or never delegated)
    Then I still see a not-enabled / Inactive row for USDC Linea for wallet A
    And I still see wallet B’s Active (or Limited) row for awareness

  Scenario: account switch
    Given both wallets have their own Inactive placeholders for the same token
    When I switch the selected EVM account in the app
    Then the available token list shows Inactive rows only for the selected account (plus all Active/Limited from any wallet)

Screenshots/Recordings

Before

After

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Changes multi-wallet token placeholder and filtering logic for Card funding assets, which can affect what users see and can re-enable funding; risk is mitigated by added unit coverage but may impact edge cases around wallet selection and legacy empty walletAddress rows.

Overview
Fixes Card availableFundingAssets generation and display for multi-wallet scenarios so a supported token can still appear as Inactive/not enabled for the currently selected wallet even if another linked wallet has an Active/Limited entry or the external-wallet API returns no rows.

BaanxProvider.getCardHomeData now passes the current address into buildSupportedTokens, which dedupes placeholders by address + chainId + walletAddress (with a legacy fallback for empty wallet) and stamps new inactive placeholders with the current wallet’s address while still enriching existing assets with the network delegationContract.

selectCardAvailableTokens now filters Inactive rows to the selected EVM account (or empty walletAddress) while always showing Active/Limited rows from any linked wallet, reducing duplicate “not enabled” entries; new tests cover the wallet-aware placeholder and selector filtering behavior.

Reviewed by Cursor Bugbot for commit 730da51. Bugbot is set up for automated code reviews on this repo. Configure here.

@Brunonascdev Brunonascdev self-assigned this May 14, 2026
@Brunonascdev Brunonascdev requested a review from a team as a code owner May 14, 2026 20:51
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbotv2 metamaskbotv2 Bot added the team-card Card Team label May 14, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeMoney, SmokeSwap, SmokeConfirmations
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are focused on the MetaMask Card feature:

  1. BaanxProvider.ts: Modified buildSupportedTokens to be wallet-address-aware. Previously tokens were deduplicated by address + chainId; now they're deduplicated by address + chainId + walletAddress. This means each linked wallet gets its own placeholder entry for inactive tokens. The getCardHomeData method now passes the wallet address through to this logic.

  2. cardController.ts (selector): Updated selectCardAvailableTokens to filter the available funding assets based on the currently selected EVM account. Active/Limited tokens are always shown, but Inactive tokens are only shown for the current wallet to prevent duplicate "not enabled" rows in multi-wallet scenarios.

  3. Both test files are unit tests covering the new logic — no E2E test infrastructure changes.

Tag selection rationale:

  • SmokeMoney: Directly covers Card home screen, Add Funds flows, and card analytics — the primary area affected by these changes.
  • SmokeSwap: Per SmokeMoney tag description, "When selecting SmokeMoney for Card Add Funds or similar flows that execute swaps, also select SmokeSwap." The Add Funds flow in Card involves swap paths.
  • SmokeConfirmations: Per SmokeMoney tag description, "also select SmokeConfirmations" when Card Add Funds flows execute swaps. Transaction confirmations are part of the Add Funds flow.

No other tags are needed — changes are isolated to the card controller provider and card selectors, with no impact on accounts, identity, network, browser, snaps, or other wallet features.

Performance Test Selection:
The changes are logic/filtering changes in the card controller provider and selectors. They don't affect UI rendering performance, list rendering, animations, data loading patterns, or any performance-critical paths. The buildSupportedTokens change is a deduplication logic fix, and the selector change adds a simple filter operation. No performance tests are warranted.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

@Brunonascdev Brunonascdev added this pull request to the merge queue May 15, 2026
Merged via the queue into main with commit 7274b18 May 15, 2026
193 of 196 checks passed
@Brunonascdev Brunonascdev deleted the fix/mm-card-missing-not-enabled-assets branch May 15, 2026 14:05
@github-actions github-actions Bot locked and limited conversation to collaborators May 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants