Skip to content
Open
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
2 changes: 1 addition & 1 deletion packages/bitcoin-wallet-snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/internal-snaps.git"
},
"source": {
"shasum": "9IkalnyxHKA+stXZw1ye2aW15JgXKtLhwfTUujztrHs=",
"shasum": "ye8FAG8Punj6snX/zr6AwKJCidDHdim1FUHqKwjTQog=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
1 change: 1 addition & 0 deletions packages/snap-networks-utils/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `AssetsProvider` ([#82](https://github.com/MetaMask/internal-snaps/pull/82))
- Add package scaffold with an example `logger` module for shared network-snap utilities ([#79](https://github.com/MetaMask/internal-snaps/pull/79))

[Unreleased]: https://github.com/MetaMask/internal-snaps/
31 changes: 30 additions & 1 deletion packages/snap-networks-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ yarn workspace @metamask/tron-wallet-snap add @metamask/snap-networks-utils@work

## Usage

Import the example logger from the package root or the dedicated subpath:
### Logger

```typescript
import { logger, createPrefixedLogger } from '@metamask/snap-networks-utils';
Expand All @@ -28,6 +28,35 @@ const snapLogger = createPrefixedLogger(logger, '[tron-wallet-snap]');
snapLogger.info('account synced');
```

### Core AssetsController reads

Wire the Snap messenger endowment, then pass it to `AssetsProvider`:

```typescript
import type { Messenger } from '@metamask/messenger';
import { getMessenger } from '@metamask/snaps-sdk';
import type {
AssetsControllerGetAccountAssetByIDAction,
AssetsControllerGetAccountAssetsByIDsAction,
AssetsControllerGetAccountAssetsByScopeAction,
} from '@metamask/assets-controller';
import { AssetsProvider } from '@metamask/snap-networks-utils';
import type { AccountId, Caip19AssetId } from '@metamask/assets-controller';

type CoreMessengerActions =
| AssetsControllerGetAccountAssetByIDAction
| AssetsControllerGetAccountAssetsByIDsAction
| AssetsControllerGetAccountAssetsByScopeAction;

const messenger = getMessenger<Messenger<string, CoreMessengerActions>>();
const assetsProvider = new AssetsProvider({ messenger });

const asset = await assetsProvider.getAccountAssetByID(
accountId as AccountId,
assetId as Caip19AssetId,
);
```

## Contributing

This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/internal-snaps#readme).
6 changes: 6 additions & 0 deletions packages/snap-networks-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
},
"dependencies": {
"@metamask/assets-controller": "^13.0.0",
"@metamask/messenger": "^2.0.0",
"@metamask/snaps-sdk": "^11.2.0",
"@metamask/utils": "^11.9.0"
},
"devDependencies": {
"@metamask/auto-changelog": "^6.1.1",
"@ts-bridge/cli": "^0.6.4",
Expand Down
5 changes: 5 additions & 0 deletions packages/snap-networks-utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
export type { Logger } from './logger';
export { createPrefixedLogger, logger, noOpLogger } from './logger';
export {
ASSETS_PROVIDER_NAME,
AssetsProvider,
type AssetsProviderMessenger,
} from './providers/assets/AssetsProvider';
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { AccountId, Caip19AssetId } from '@metamask/assets-controller';
import type { CaipChainId } from '@metamask/utils';

import type { AssetsProviderMessenger } from './AssetsProvider';
import { AssetsProvider } from './AssetsProvider';

const ACCOUNT_ID = '550e8400-e29b-41d4-a716-446655440000' as AccountId;
const ASSET_ID = 'tron:728126428/slip44:195' as Caip19AssetId;
const CHAIN_ID = 'tron:728126428' as CaipChainId;

type WithAssetsProviderCallback<ReturnValue> = (payload: {
assetsProvider: AssetsProvider;
mockMessenger: jest.Mocked<AssetsProviderMessenger>;
}) => Promise<ReturnValue> | ReturnValue;

/**
* Wraps tests for AssetsProvider by creating a fresh provider with a mock
* messenger. The callback receives the provider and mock for test configuration.
*
* @param testFunction - The test body receiving the provider and mocks.
* @returns The return value of the callback.
*/
async function withAssetsProvider<ReturnValue>(
testFunction: WithAssetsProviderCallback<ReturnValue>,
): Promise<ReturnValue> {
const mockMessenger: jest.Mocked<AssetsProviderMessenger> = {
call: jest.fn(),
};

const assetsProvider = new AssetsProvider({
messenger: mockMessenger,
});

return await testFunction({
assetsProvider,
mockMessenger,
});
}

describe('AssetsProvider', () => {
describe('getAccountAssetByID', () => {
it('calls AssetsController:getAccountAssetByID', async () => {
await withAssetsProvider(async ({ assetsProvider, mockMessenger }) => {
await assetsProvider.getAccountAssetByID(ACCOUNT_ID, ASSET_ID);

expect(mockMessenger.call).toHaveBeenCalledWith(
'AssetsController:getAccountAssetByID',
ACCOUNT_ID,
ASSET_ID,
);
});
});
});

describe('getAccountAssetsByIDs', () => {
it('calls AssetsController:getAccountAssetsByIDs', async () => {
const assetIds = [ASSET_ID];

await withAssetsProvider(async ({ assetsProvider, mockMessenger }) => {
await assetsProvider.getAccountAssetsByIDs(ACCOUNT_ID, assetIds);

expect(mockMessenger.call).toHaveBeenCalledWith(
'AssetsController:getAccountAssetsByIDs',
ACCOUNT_ID,
assetIds,
);
});
});
});

describe('getAccountAssetsByScope', () => {
it('calls AssetsController:getAccountAssetsByScope', async () => {
await withAssetsProvider(async ({ assetsProvider, mockMessenger }) => {
await assetsProvider.getAccountAssetsByScope(CHAIN_ID, ACCOUNT_ID);

expect(mockMessenger.call).toHaveBeenCalledWith(
'AssetsController:getAccountAssetsByScope',
ACCOUNT_ID,
CHAIN_ID,
);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import type {
AccountId,
AssetsControllerGetAccountAssetByIDAction,
AssetsControllerGetAccountAssetsByIDsAction,
AssetsControllerGetAccountAssetsByScopeAction,
Caip19AssetId,
} from '@metamask/assets-controller';
import type { Messenger } from '@metamask/messenger';
import { AsyncMessenger } from '@metamask/snaps-sdk';
import type { CaipChainId } from '@metamask/utils';

/**
* Namespace for the {@link AssetsProvider} messenger.
*/
export const ASSETS_PROVIDER_NAME = 'AssetsProvider' as const;

/**
* Actions from other messengers that {@link AssetsProvider} calls.
*/
export type AssetsProviderAllowedActions =
| AssetsControllerGetAccountAssetByIDAction
| AssetsControllerGetAccountAssetsByIDsAction
| AssetsControllerGetAccountAssetsByScopeAction;

/**
* Messenger restricted to actions consumed by {@link AssetsProvider}.
*/
export type AssetsProviderMessenger = AsyncMessenger<
Messenger<typeof ASSETS_PROVIDER_NAME, AssetsProviderAllowedActions>
>;

export class AssetsProvider {
readonly #messenger: AssetsProviderMessenger;

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

/**
* Returns a single account asset by CAIP-19 ID, or `undefined` if missing.
*
* @param accountId - Keyring account ID.
* @param assetId - CAIP-19 asset ID.
* @returns Controller asset, or `undefined`.
*/
async getAccountAssetByID(
accountId: AccountId,
assetId: Caip19AssetId,
): Promise<ReturnType<AssetsControllerGetAccountAssetByIDAction['handler']>> {
return this.#messenger.call(
'AssetsController:getAccountAssetByID',
accountId,
assetId,
);
}

/**
* Returns account assets for the given CAIP-19 IDs, keyed by asset ID.
*
* @param accountId - Keyring account ID.
* @param assetIds - CAIP-19 asset IDs to resolve.
* @returns Map of asset ID → controller asset.
*/
async getAccountAssetsByIDs(
accountId: AccountId,
assetIds: Caip19AssetId[],
): Promise<
ReturnType<AssetsControllerGetAccountAssetsByIDsAction['handler']>
> {
return this.#messenger.call(
'AssetsController:getAccountAssetsByIDs',
accountId,
assetIds,
);
}

/**
* Returns controller-backed assets for an account on a chain.
*
* @param scope - CAIP-2 chain ID to filter controller results.
* @param accountId - Keyring account ID.
* @returns Controller assets keyed by CAIP-19 asset ID.
*/
async getAccountAssetsByScope(
scope: CaipChainId,
accountId: AccountId,
): Promise<
ReturnType<AssetsControllerGetAccountAssetsByScopeAction['handler']>
> {
return this.#messenger.call(
'AssetsController:getAccountAssetsByScope',
accountId,
scope,
);
}
}
3 changes: 2 additions & 1 deletion packages/snap-networks-utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": "../../tsconfig.packages.json",
"compilerOptions": {
"baseUrl": "./"
"baseUrl": "./",
"types": ["jest"]
},
"references": [],
"include": ["../../types", "./src"]
Expand Down
4 changes: 4 additions & 0 deletions packages/tron-wallet-snap/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Update `snap.manifest.json` bundle shasum ([#82](https://github.com/MetaMask/internal-snaps/pull/82))

## [2.0.0]

### Changed
Expand Down
2 changes: 1 addition & 1 deletion packages/tron-wallet-snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/internal-snaps.git"
},
"source": {
"shasum": "0TZh63x04Gncx8UgHBoWnQ4RmX6kmTL6RmJTyqgJ7G8=",
"shasum": "xQEloRiq1TZIyQM1F+rtfw4PGQDMakX2jIOlGtDt6ks=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
Loading
Loading