Skip to content
Merged
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
5 changes: 0 additions & 5 deletions packages/snap-networks-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@ export { createPrefixedLogger, logger, noOpLogger } from './logger';
export { AssetsService } from './services/assets/AssetsService';
export {
ASSETS_SERVICE_NAME,
type AssetsControllerGetAccountAssetByIDAction,
type AssetsControllerGetAccountAssetsByIDsAction,
type AssetsControllerGetAccountAssetsByScopeAction,
type AssetsServiceMessenger,
type AssetsServiceMessengerCaller,
} from './services/assets/messenger';
export type { AssetEntity, AssetScope } from './services/assets/types';
export { mapControllerAsset } from './services/assets/utils/mapControllerAsset';
export {
CORE_MESSENGER_NAMESPACE,
type CoreMessenger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
import type { CaipChainId } from '@metamask/utils';

import { AssetsService } from './AssetsService';
import type { AssetsServiceMessengerCaller } from './messenger';
import { AssetsServiceMessenger } from './messenger';

const ACCOUNT_ID = '550e8400-e29b-41d4-a716-446655440000' as AccountId;
const ASSET_ID = 'tron:728126428/slip44:195' as Caip19AssetId;
Expand Down Expand Up @@ -34,7 +34,7 @@ const mappedAsset = {

type WithAssetsServiceCallback<ReturnValue> = (payload: {
assetsService: AssetsService;
mockMessenger: jest.Mocked<Pick<AssetsServiceMessengerCaller, 'call'>>;
mockMessenger: jest.Mocked<AssetsServiceMessenger>;
}) => Promise<ReturnValue> | ReturnValue;

/**
Expand All @@ -47,10 +47,9 @@ type WithAssetsServiceCallback<ReturnValue> = (payload: {
async function withAssetsService<ReturnValue>(
testFunction: WithAssetsServiceCallback<ReturnValue>,
): Promise<ReturnValue> {
const mockMessenger: jest.Mocked<Pick<AssetsServiceMessengerCaller, 'call'>> =
{
call: jest.fn(),
};
const mockMessenger: jest.Mocked<AssetsServiceMessenger> = {
call: jest.fn(),
};

const assetsService = new AssetsService({
messenger: mockMessenger,
Expand Down
50 changes: 16 additions & 34 deletions packages/snap-networks-utils/src/services/assets/AssetsService.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import type {
AccountId,
Asset,
AssetsControllerGetAccountAssetByIDAction,
AssetsControllerGetAccountAssetsByIDsAction,
AssetsControllerGetAccountAssetsByScopeAction,
Caip19AssetId,
} from '@metamask/assets-controller';
import type { CaipChainId } from '@metamask/utils';

import type { AssetsServiceMessengerCaller } from './messenger';
import type { AssetEntity } from './types';
import { mapControllerAsset } from './utils/mapControllerAsset';
import { AssetsServiceMessenger } from './messenger';

/**
* Thin service that reads account assets from Core AssetsController via a
Expand All @@ -16,9 +16,9 @@ import { mapControllerAsset } from './utils/mapControllerAsset';
* Does not handle snap-owned / protocol-specific assets.
*/
export class AssetsService {
readonly #messenger: AssetsServiceMessengerCaller;
readonly #messenger: AssetsServiceMessenger;

constructor({ messenger }: { messenger: AssetsServiceMessengerCaller }) {
constructor({ messenger }: { messenger: AssetsServiceMessenger }) {
this.#messenger = messenger;
}

Expand All @@ -32,18 +32,12 @@ export class AssetsService {
async getAccountAssetByID(
accountId: AccountId,
assetId: Caip19AssetId,
): Promise<AssetEntity | null> {
const result = await this.#messenger.call(
): Promise<ReturnType<AssetsControllerGetAccountAssetByIDAction['handler']>> {
return this.#messenger.call(
'AssetsController:getAccountAssetByID',
accountId,
assetId,
);

if (!result) {
return null;
}

return mapControllerAsset(accountId, assetId, result);
}

/**
Expand All @@ -57,28 +51,18 @@ export class AssetsService {
async getAccountAssetsByIDs(
accountId: AccountId,
assetIds: Caip19AssetId[],
): Promise<Record<Caip19AssetId, AssetEntity | null>> {
): Promise<
ReturnType<AssetsControllerGetAccountAssetsByIDsAction['handler']>
> {
if (assetIds.length === 0) {
return {};
}

const controllerAssets = await this.#messenger.call(
return this.#messenger.call(
'AssetsController:getAccountAssetsByIDs',
accountId,
assetIds,
);

return Object.fromEntries(
assetIds.map((assetId) => {
const controllerAsset = controllerAssets[assetId];
return [
assetId,
controllerAsset
? mapControllerAsset(accountId, assetId, controllerAsset)
: null,
];
}),
) as Record<Caip19AssetId, AssetEntity | null>;
}

/**
Expand All @@ -91,15 +75,13 @@ export class AssetsService {
async getAccountAssetsByScope(
scope: CaipChainId,
accountId: AccountId,
): Promise<AssetEntity[]> {
const controllerAssets = await this.#messenger.call(
): Promise<
ReturnType<AssetsControllerGetAccountAssetsByScopeAction['handler']>
> {
return this.#messenger.call(
'AssetsController:getAccountAssetsByScope',
accountId,
scope,
);

return (Object.entries(controllerAssets) as [Caip19AssetId, Asset][]).map(
([assetId, asset]) => mapControllerAsset(accountId, assetId, asset),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { CoreMessengerCaller } from '../../types/core-messenger';
import { CORE_MESSENGER_NAMESPACE } from '../../types/core-messenger';
import type { AssetsServiceAllowedActions } from './messenger';
import type { AssetsServiceMessengerCaller } from './messenger';
import type {
AssetsServiceAllowedActions,
AssetsServiceMessenger,
} from './messenger';
import { ASSETS_SERVICE_NAME } from './messenger';

describe('messenger types', () => {
Expand All @@ -23,7 +25,7 @@ describe('messenger types', () => {
it('keeps core and assets service callers compatible', () => {
const assertCompatible = (
caller: CoreMessengerCaller,
): AssetsServiceMessengerCaller => caller;
): AssetsServiceMessenger => caller;

expect(assertCompatible).toBeDefined();
});
Expand Down
23 changes: 3 additions & 20 deletions packages/snap-networks-utils/src/services/assets/messenger.ts

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@ulissesferreira given this file is now just a couple of type declarations, we could consider merging it with AssetsService.ts - wdyt?

@ulissesferreira ulissesferreira Jul 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah that seems fair so we can maintain less files. Sounds good.

Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@ import type {
AssetsControllerGetAccountAssetsByScopeAction,
} from '@metamask/assets-controller';
import type { Messenger } from '@metamask/messenger';

import type { MessengerCaller } from '../../types/messenger-caller';

export type {
AssetsControllerGetAccountAssetByIDAction,
AssetsControllerGetAccountAssetsByIDsAction,
AssetsControllerGetAccountAssetsByScopeAction,
};
Comment on lines -10 to -14

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Better not to re-export these types from another package, because any breaking change on these types from @metamask/assets-controller would turn into a breaking change for @metamask/snap-networks-utils as well.

Consumers can simply import them from @metamask/assets-controller instead

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

100%

import { AsyncMessenger } from '@metamask/snaps-sdk';

/**
* Namespace for the {@link AssetsService} messenger.
Expand All @@ -29,16 +22,6 @@ export type AssetsServiceAllowedActions =
/**
* Messenger restricted to actions consumed by {@link AssetsService}.
*/
export type AssetsServiceMessenger = Messenger<
typeof ASSETS_SERVICE_NAME,
AssetsServiceAllowedActions
export type AssetsServiceMessenger = AsyncMessenger<
Messenger<typeof ASSETS_SERVICE_NAME, AssetsServiceAllowedActions>
>;

/**
* Caller type for {@link AssetsService}.
*
* Matches {@link CoreMessengerCaller} while `CoreMessenger` only delegates
* assets-controller actions.
*/
export type AssetsServiceMessengerCaller =
MessengerCaller<AssetsServiceAllowedActions>;

This file was deleted.

This file was deleted.

Loading