diff --git a/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.test.ts b/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.test.ts index d479d5af1e5..9e3f08f5eec 100644 --- a/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.test.ts +++ b/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.test.ts @@ -773,4 +773,49 @@ describe('MultichainAssetsController', () => { }); }); }); + + describe('getAssetMetadata', () => { + it('returns the metadata for a given asset', async () => { + const { messenger } = setupController({ + state: { + accountsAssets: { + [mockSolanaAccount.id]: mockHandleRequestOnAssetsLookupReturnValue, + }, + assetsMetadata: mockGetMetadataReturnValue.assets, + } as MultichainAssetsControllerState, + }); + + const assetId = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1/slip44:501'; + + const metadata = messenger.call( + 'MultichainAssetsController:getAssetMetadata', + assetId, + ); + + expect(metadata).toStrictEqual( + mockGetMetadataReturnValue.assets[assetId], + ); + }); + + it('returns undefined if the asset metadata is not found', async () => { + const { messenger } = setupController({ + state: { + accountsAssets: { + [mockSolanaAccount.id]: mockHandleRequestOnAssetsLookupReturnValue, + }, + assetsMetadata: mockGetMetadataReturnValue.assets, + } as MultichainAssetsControllerState, + }); + + const assetId = + 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; + + const metadata = messenger.call( + 'MultichainAssetsController:getAssetMetadata', + assetId, + ); + + expect(metadata).toBeUndefined(); + }); + }); }); diff --git a/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.ts b/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.ts index 288a65472f6..bc40d803ae5 100644 --- a/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.ts +++ b/packages/assets-controllers/src/MultichainAssetsController/MultichainAssetsController.ts @@ -69,6 +69,11 @@ export function getDefaultMultichainAssetsControllerState(): MultichainAssetsCon return { accountsAssets: {}, assetsMetadata: {} }; } +export type MultichainAssetsControllerGetAssetMetadataAction = { + type: `${typeof controllerName}:getAssetMetadata`; + handler: MultichainAssetsController['getAssetMetadata']; +}; + /** * Returns the state of the {@link MultichainAssetsController}. */ @@ -90,7 +95,8 @@ export type MultichainAssetsControllerStateChangeEvent = * Actions exposed by the {@link MultichainAssetsController}. */ export type MultichainAssetsControllerActions = - MultichainAssetsControllerGetStateAction; + | MultichainAssetsControllerGetStateAction + | MultichainAssetsControllerGetAssetMetadataAction; /** * Events emitted by {@link MultichainAssetsController}. @@ -199,6 +205,8 @@ export class MultichainAssetsController extends BaseController< 'AccountsController:accountAssetListUpdated', async (event) => await this.#handleAccountAssetListUpdatedEvent(event), ); + + this.#registerMessageHandlers(); } async #handleAccountAssetListUpdatedEvent( @@ -215,6 +223,27 @@ export class MultichainAssetsController extends BaseController< ); } + /** + * Constructor helper for registering the controller's messaging system + * actions. + */ + #registerMessageHandlers() { + this.messagingSystem.registerActionHandler( + 'MultichainAssetsController:getAssetMetadata', + this.getAssetMetadata.bind(this), + ); + } + + /** + * Returns the metadata for the given asset + * + * @param asset - The asset to get metadata for + * @returns The metadata for the asset or undefined if not found. + */ + getAssetMetadata(asset: CaipAssetType): FungibleAssetMetadata | undefined { + return this.state.assetsMetadata[asset]; + } + /** * Function to update the assets list for an account *