Skip to content

Conversation

@GuillaumeRx
Copy link
Contributor

@GuillaumeRx GuillaumeRx commented Jan 30, 2026

Explanation

A few changes made by AI that don't follow the standards of the repo to test the bugbot behaviors.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Adds new state fields and new APIs/events in AssetsController, which may affect consumers that assume the previous state shape or rely on messenger-based events. Test changes also introduce a focused it.only, which could inadvertently skip the rest of the suite if merged.

Overview
AssetsController now exposes additional state and update hooks. The controller state gains assetsDetails, assetCount, and internalCache (with updated default state and metadata), and the constructor optionally accepts onStateChange to receive AssetsController:stateChange updates.

Adds a manual price update API and a local refresh signal. New setAssetPrice mutates assetsPrice and emits a dataRefreshed signal via a new internal hub (SimpleEventEmitter), plus getActiveAssetIds to list assets from assetsMetadata. The PR also tweaks typing in middleware execution (state as unknown as AssetsControllerStateInternal) and marks newly added custom assets in assetsDetails.

Tests and tooling: updates AssetsController tests for the new state shape and adds coverage for setAssetPrice/getActiveAssetIds, and introduces .cursor/BUGBOT.md PR review guidelines.

Written by Cursor Bugbot for commit 82dc3bf. This will update automatically on new commits. Configure here.

@GuillaumeRx GuillaumeRx requested a review from a team as a code owner January 30, 2026 11:56
@GuillaumeRx GuillaumeRx changed the base branch from main to gr/bugbot-rules January 30, 2026 11:56
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 8 potential issues.

describe('addCustomAsset', () => {
it('adds a custom asset to an account', async () => {
// eslint-disable-next-line jest/no-focused-tests
it.only('adds a custom asset to an account', async () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Focused test will skip all other tests

High Severity

The it.only() modifier on the test case will cause Jest to skip all other tests in this file. This is typically used during local development and debugging but was accidentally committed. The eslint-disable comment jest/no-focused-tests confirms this was intentionally bypassed, which is dangerous in a PR.

Fix in Cursor Fix in Web

}
});

this.state.assetsDetails[normalizedAssetId] = 'custom';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Direct state mutation outside update callback

High Severity

The line this.state.assetsDetails[normalizedAssetId] = 'custom' directly mutates state outside the update() callback. In BaseController, state modifications must go through update() to trigger state change events and maintain immutability. This assignment occurs after the update() call completes, bypassing proper state management.

Fix in Cursor Fix in Web

emit(event: string): void {
this.#listeners.get(event)?.forEach((fn) => fn());
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Controller uses EventEmitter instead of messenger pattern

Low Severity · Bugbot Rules

Please review the controller guidelines and follow the recommendations. The SimpleEventEmitter class and hub property violate the guideline "Use the messenger instead of event emitters" (section in controller-guidelines.md). The dataRefreshed event should be published via the messenger instead.

Additional Locations (1)

Fix in Cursor Fix in Web

@@ -1,3 +1,5 @@
export * from './logger';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Barrel export violates coding guidelines

Low Severity · Bugbot Rules

Please review the controller guidelines and follow the recommendations. The line export * from './logger' is a barrel export which violates the guideline "Avoid barrel exports...Instead, explicitly name each export."

Fix in Cursor Fix in Web

await withController(async ({ controller }) => {
controller.getActiveAssetIds();
});
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test missing assertions and misplaced in wrong describe block

Low Severity · Bugbot Rules

Please review the unit testing guidelines and follow the recommendations. The test 'getActiveAssetIds returns keys from assetsMetadata' has no assertions (suppressed via jest/expect-expect) and is incorrectly nested under the describe('setAssetPrice') block despite testing getActiveAssetIds. Tests without assertions provide no value.

Fix in Cursor Fix in Web

state.assetsPrice[assetId] = price;
});
this.hub.emit('dataRefreshed');
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing asset ID normalization causes lookup inconsistency

Medium Severity

The setAssetPrice method stores prices using the raw assetId parameter without calling normalizeAssetId(). Other methods like addCustomAsset, removeCustomAsset, and normalizeResponse all normalize asset IDs to ensure checksummed EVM addresses. If a price is stored with a lowercase address like eip155:1/erc20:0xa0b86991..., but metadata uses the checksummed form 0xA0b86991..., the price lookup in #getAssetsFromState will fail to match.

Fix in Cursor Fix in Web

emit(event: string): void {
this.#listeners.get(event)?.forEach((fn) => fn());
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused SimpleEventEmitter class and hub property

Medium Severity

The SimpleEventEmitter class is defined and instantiated as hub, and hub.emit('dataRefreshed') is called in setAssetPrice, but there are no subscribers anywhere in the codebase (hub.on(...) is never called for this controller). This creates dead code that adds unnecessary complexity. If event emission is needed, either add the corresponding subscriptions or remove this infrastructure entirely.

Additional Locations (1)

Fix in Cursor Fix in Web

customAssets: { [accountId: string]: string[] };
assetsDetails: { [assetId: string]: string };
assetCount: number;
internalCache: { [key: string]: Json };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused state properties assetCount and internalCache

Low Severity

The state properties assetCount and internalCache are defined in the state type, initialized in getDefaultAssetsControllerState, and have metadata configured, but they are never read from or written to anywhere in the codebase. This is dead code that clutters the state structure. Similarly, assetsDetails is only written to (via a buggy direct mutation) but never read.

Additional Locations (2)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants