diff --git a/package.json b/package.json index d7a92f54..39b2d255 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ ], "files": [], "scripts": { - "build": "yarn workspaces foreach --all --no-private --parallel --interlaced --verbose run build", + "build": "yarn workspaces foreach --all --no-private --parallel --topological-dev --interlaced --verbose run build", "build:clean": "yarn build:only-clean && yarn build", "build:docs": "yarn workspaces foreach --all --no-private --parallel --interlaced --verbose run build:docs", "build:only-clean": "rimraf -g 'packages/*/dist'", diff --git a/packages/solana-wallet-snap/CHANGELOG.md b/packages/solana-wallet-snap/CHANGELOG.md index 53933ffa..71412fb9 100644 --- a/packages/solana-wallet-snap/CHANGELOG.md +++ b/packages/solana-wallet-snap/CHANGELOG.md @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Extract Snap-owned balance fetch/persist/read logic into `SnapAssetsAdapter`; `AssetsService` delegates account asset reads and saves through the adapter (no Core routing yet). +- Wire Core messenger plumbing (`endowment:messenger`, `AssetsProvider`, `RemoteFeatureFlagsProvider`) into the Solana snap. Providers are constructed and injected into `AssetsService` but Snap-owned reads remain the sole production path. +- Extract Snap-owned balance fetch/persist/read logic into `SnapAssetsAdapter`; `AssetsService` delegates account asset reads and saves through the adapter (no Core routing yet). ([#121](https://github.com/MetaMask/internal-snaps/pull/121)) - Align `AssetsService` read API with `snap-networks-utils` / AssetsController shapes by adding `getAccountAssetByID`, `getAccountAssetsByIDs`, `getAccountAssetsByScope`, and `getAccountAssetsForAllActiveScopes`, and routing Keyring, Send, send render, and `refreshSend` through them (still Snap-owned storage). ([#120](https://github.com/MetaMask/internal-snaps/pull/120)) - This package was migrated from [snap-solana-wallet](https://github.com/MetaMask/snap-solana-wallet). See the source repository for the original [changelog](https://github.com/MetaMask/snap-solana-wallet/blob/main/packages/snap/CHANGELOG.md). ([#72](https://github.com/MetaMask/internal-snaps/pull/72)) diff --git a/packages/solana-wallet-snap/package.json b/packages/solana-wallet-snap/package.json index 642f2ecc..51f74c9f 100644 --- a/packages/solana-wallet-snap/package.json +++ b/packages/solana-wallet-snap/package.json @@ -52,10 +52,14 @@ }, "devDependencies": { "@jest/globals": "^29.5.0", + "@metamask/assets-controller": "^13.0.0", "@metamask/auto-changelog": "^6.1.1", "@metamask/key-tree": "9.1.2", "@metamask/keyring-api": "^23.7.0", "@metamask/keyring-snap-sdk": "^9.2.1", + "@metamask/messenger": "^2.0.0", + "@metamask/remote-feature-flag-controller": "^5.0.0", + "@metamask/snap-networks-utils": "workspace:^", "@metamask/snaps-cli": "^8.4.1", "@metamask/snaps-jest": "^10.2.0", "@metamask/snaps-sdk": "^11.2.0", diff --git a/packages/solana-wallet-snap/snap.manifest.json b/packages/solana-wallet-snap/snap.manifest.json index 84e85f44..c6da0ee6 100644 --- a/packages/solana-wallet-snap/snap.manifest.json +++ b/packages/solana-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "j3n+ylk6thi2g8W+qqmF7S56WcW2d9Kq5AhjCkqZSAk=", + "shasum": "8xioVFo7Tpep5rVLoWUqeg+bvogIihY9EY6YxFTelDY=", "location": { "npm": { "filePath": "dist/bundle.js", @@ -88,7 +88,15 @@ "snap_manageAccounts": {}, "snap_manageState": {}, "snap_dialog": {}, - "snap_getPreferences": {} + "snap_getPreferences": {}, + "endowment:messenger": { + "actions": [ + "RemoteFeatureFlagController:getState", + "AssetsController:getAccountAssetByID", + "AssetsController:getAccountAssetsByIDs", + "AssetsController:getAccountAssetsByScope" + ] + } }, "platformVersion": "11.2.0", "manifestVersion": "0.1" diff --git a/packages/solana-wallet-snap/src/core/services/assets/AssetsService.test.ts b/packages/solana-wallet-snap/src/core/services/assets/AssetsService.test.ts index e0b161b8..15185af7 100644 --- a/packages/solana-wallet-snap/src/core/services/assets/AssetsService.test.ts +++ b/packages/solana-wallet-snap/src/core/services/assets/AssetsService.test.ts @@ -107,6 +107,14 @@ describe('AssetsService', () => { tokenApiClient: mockTokenApiClient, tokenPricesService: mockTokenPricesService, nftApiClient: mockNftApiClient, + remoteFeatureFlagsProvider: { + getFeatureFlags: jest.fn(), + } as unknown as import('@metamask/snap-networks-utils').RemoteFeatureFlagsProvider, + assetsProvider: { + getAccountAssetByID: jest.fn(), + getAccountAssetsByIDs: jest.fn(), + getAccountAssetsByScope: jest.fn(), + } as unknown as import('@metamask/snap-networks-utils').AssetsProvider, }); }); diff --git a/packages/solana-wallet-snap/src/core/services/assets/AssetsService.ts b/packages/solana-wallet-snap/src/core/services/assets/AssetsService.ts index 152caf53..92f0d77b 100644 --- a/packages/solana-wallet-snap/src/core/services/assets/AssetsService.ts +++ b/packages/solana-wallet-snap/src/core/services/assets/AssetsService.ts @@ -1,4 +1,8 @@ /* eslint-disable jsdoc/require-returns */ +import type { + AssetsProvider, + RemoteFeatureFlagsProvider, +} from '@metamask/snap-networks-utils'; import type { FungibleAssetMarketData, FungibleAssetMetadata, @@ -50,6 +54,13 @@ export class AssetsService { tokenApiClient: TokenApiClient; tokenPricesService: TokenPricesService; nftApiClient: NftApiClient; + /** + * Core plumbing for a follow-up PR that routes fungible reads via + * AssetsController. Required in the constructor options so DI is wired + * without changing callers again when routing lands. + */ + remoteFeatureFlagsProvider: RemoteFeatureFlagsProvider; + assetsProvider: AssetsProvider; }) { this.#logger = createPrefixedLogger(logger, '[🪙 AssetsService]'); this.#configProvider = configProvider; diff --git a/packages/solana-wallet-snap/src/snapContext.ts b/packages/solana-wallet-snap/src/snapContext.ts index 488250df..6d012d1d 100644 --- a/packages/solana-wallet-snap/src/snapContext.ts +++ b/packages/solana-wallet-snap/src/snapContext.ts @@ -1,3 +1,13 @@ +import { + AssetsProvider, + RemoteFeatureFlagsProvider, +} from '@metamask/snap-networks-utils'; +import type { + AssetsProviderMessenger, + RemoteFeatureFlagsProviderMessenger, +} from '@metamask/snap-networks-utils'; +import { getMessenger } from '@metamask/snaps-sdk'; + import type { ICache } from './core/caching/ICache'; import { InMemoryCache } from './core/caching/InMemoryCache'; import { StateCache } from './core/caching/StateCache'; @@ -47,6 +57,7 @@ import { TransactionScanService } from './core/services/transaction-scan/Transac import { WalletService } from './core/services/wallet/WalletService'; import logger, { noOpLogger } from './core/utils/logger'; import { EventEmitter } from './infrastructure'; +import type { CoreMessenger } from './types/core-messenger'; /** * Initializes all the services using dependency injection. @@ -78,6 +89,12 @@ export type SnapExecutionContext = { accountsService: AccountsService; accountsSynchronizer: AccountsSynchronizer; tokenHelper: TokenHelper; + /** + * Core messenger plumbing (routing wired in a follow-up PR). + */ + coreMessenger: CoreMessenger; + remoteFeatureFlagsProvider: RemoteFeatureFlagsProvider; + assetsProvider: AssetsProvider; }; const configProvider = new ConfigProvider(); @@ -160,6 +177,17 @@ const snapAssetsAdapter = new SnapAssetsAdapter({ nftApiClient, }); +/** + * Core controllers plumbing + */ +const coreMessenger = getMessenger(); +const remoteFeatureFlagsProvider = new RemoteFeatureFlagsProvider({ + messenger: coreMessenger as RemoteFeatureFlagsProviderMessenger, +}); +const assetsProvider = new AssetsProvider({ + messenger: coreMessenger as AssetsProviderMessenger, +}); + const assetsService = new AssetsService({ logger, configProvider, @@ -167,6 +195,8 @@ const assetsService = new AssetsService({ tokenApiClient, tokenPricesService, nftApiClient, + remoteFeatureFlagsProvider, + assetsProvider, }); const transactionsRepository = new TransactionsRepository(state); @@ -299,22 +329,28 @@ const snapContext: SnapExecutionContext = { accountsService, accountsSynchronizer, tokenHelper, + coreMessenger, + remoteFeatureFlagsProvider, + assetsProvider, }; export { accountsService, accountsSynchronizer, analyticsService, + assetsProvider, assetsService, clientRequestHandler, configProvider, confirmationHandler, connection, + coreMessenger, eventEmitter, keyring, nameResolutionService, nftService, priceApiClient, + remoteFeatureFlagsProvider, sendSolBuilder, sendSplTokenBuilder, signer, diff --git a/packages/solana-wallet-snap/src/types/core-messenger.ts b/packages/solana-wallet-snap/src/types/core-messenger.ts new file mode 100644 index 00000000..a430bbd9 --- /dev/null +++ b/packages/solana-wallet-snap/src/types/core-messenger.ts @@ -0,0 +1,27 @@ +import type { + AssetsControllerGetAccountAssetByIDAction, + AssetsControllerGetAccountAssetsByIDsAction, + AssetsControllerGetAccountAssetsByScopeAction, +} from '@metamask/assets-controller'; +import type { Messenger } from '@metamask/messenger'; +import type { RemoteFeatureFlagControllerGetStateAction } from '@metamask/remote-feature-flag-controller'; + +/** + * Namespace for this Snap's Core messenger endowment. + */ +export const SOLANA_WALLET_SNAP_MESSENGER_NAMESPACE = + 'SolanaWalletSnap' as const; + +export type CoreMessengerActions = + | RemoteFeatureFlagControllerGetStateAction + | AssetsControllerGetAccountAssetByIDAction + | AssetsControllerGetAccountAssetsByIDsAction + | AssetsControllerGetAccountAssetsByScopeAction; + +/** + * Messenger type passed to `getMessenger` for Core controller actions. + */ +export type CoreMessenger = Messenger< + typeof SOLANA_WALLET_SNAP_MESSENGER_NAMESPACE, + CoreMessengerActions +>; diff --git a/yarn.lock b/yarn.lock index 14ac741c..d9e3043e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3312,7 +3312,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snap-networks-utils@workspace:packages/snap-networks-utils": +"@metamask/snap-networks-utils@workspace:^, @metamask/snap-networks-utils@workspace:packages/snap-networks-utils": version: 0.0.0-use.local resolution: "@metamask/snap-networks-utils@workspace:packages/snap-networks-utils" dependencies: @@ -3677,10 +3677,14 @@ __metadata: resolution: "@metamask/solana-wallet-snap@workspace:packages/solana-wallet-snap" dependencies: "@jest/globals": "npm:^29.5.0" + "@metamask/assets-controller": "npm:^13.0.0" "@metamask/auto-changelog": "npm:^6.1.1" "@metamask/key-tree": "npm:9.1.2" "@metamask/keyring-api": "npm:^23.7.0" "@metamask/keyring-snap-sdk": "npm:^9.2.1" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/remote-feature-flag-controller": "npm:^5.0.0" + "@metamask/snap-networks-utils": "workspace:^" "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" "@metamask/snaps-sdk": "npm:^11.2.0"