@metamask/assets-controllers 12.0.0 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [14.0.0]
10
+ ### Changed
11
+ - Update TypeScript to v4.8.x ([#1718](https://github.com/MetaMask/core/pull/1718))
12
+ - Update `@metamask/rpc-errors` to `^6.0.0` ([#1690](https://github.com/MetaMask/core/pull/1690))
13
+
14
+ ### Removed
15
+ - **BREAKING:** Remove AbortController polyfill
16
+ - This package now assumes that the AbortController global exists
17
+
18
+ ## [13.0.0]
19
+ ### Changed
20
+ - **BREAKING**: `TokensController` now expects `getNetworkClientById` in constructor options ([#1676](https://github.com/MetaMask/core/pull/1676))
21
+ - **BREAKING**: `TokensController.addToken` now accepts a single options object ([#1676](https://github.com/MetaMask/core/pull/1676))
22
+ ```
23
+ {
24
+ address: string;
25
+ symbol: string;
26
+ decimals: number;
27
+ name?: string;
28
+ image?: string;
29
+ interactingAddress?: string;
30
+ networkClientId?: NetworkClientId;
31
+ }
32
+ ```
33
+ - **BREAKING**: Bump peer dependency on `@metamask/network-controller` to ^13.0.0 ([#1633](https://github.com/MetaMask/core/pull/1633))
34
+ - **CHANGED**: `TokensController.addToken` will use the chain ID value derived from state for `networkClientId` if provided ([#1676](https://github.com/MetaMask/core/pull/1676))
35
+ - **CHANGED**: `TokensController.addTokens` now accepts an optional `networkClientId` as the last parameter ([#1676](https://github.com/MetaMask/core/pull/1676))
36
+ - **CHANGED**: `TokensController.addTokens` will use the chain ID value derived from state for `networkClientId` if provided ([#1676](https://github.com/MetaMask/core/pull/1676))
37
+ - **CHANGED**: `TokensController.watchAsset` options now accepts optional `networkClientId` which is used to get the ERC-20 token name if provided ([#1676](https://github.com/MetaMask/core/pull/1676))
38
+ - Bump dependency on `@metamask/controller-utils` to ^5.0.0 ([#1633](https://github.com/MetaMask/core/pull/1633))
39
+ - Bump dependency on `@metamask/preferences-controller` to ^4.4.1 ([#1676](https://github.com/MetaMask/core/pull/1676))
40
+
9
41
  ## [12.0.0]
10
42
  ### Added
11
43
  - Add `AssetsContractController` methods `getProvider`, `getChainId`, `getERC721Standard`, and `getERC1155Standard` ([#1638](https://github.com/MetaMask/core/pull/1638))
@@ -78,7 +110,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
78
110
  - The `getERC20TokenName` method is used to get the token name for tokens added via `wallet_watchAsset`
79
111
  - The `onTokenListStateChange` method is used to trigger a name update when the token list changes. On each change, token names are copied from the token list if they're missing from token controller state.
80
112
  - **BREAKING:** The signature of the tokens controller method `addToken` has changed
81
- - The fourth and fifth positional parameters (`image` and `interactingAddress`) have been replaced by an `options` object
113
+ - The fourth and fifth positional parameters (`image` and `interactingAddress`) have been replaced by an `options` object
82
114
  - The new options parameter includes the `image` and `interactingAddress` properties, and a new `name` property
83
115
  - The token detection controller now sets the token name when new tokens are detected ([#1127](https://github.com/MetaMask/core/pull/1127))
84
116
  - The `Token` type now includes an optional `name` field ([#1127](https://github.com/MetaMask/core/pull/1127))
@@ -157,7 +189,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
157
189
  - **BREAKING:** Remove the `networkType` configuration option from the NFT detection controller, NFT controller, and tokens controller ([#1360](https://github.com/MetaMask/core/pull/1360), [#1359](https://github.com/MetaMask/core/pull/1359))
158
190
  - **BREAKING:** Remove the `SuggestedAssetMeta` and `SuggestedAssetMetaBase` types from the token controller ([#1268](https://github.com/MetaMask/core/pull/1268))
159
191
  - **BREAKING:** Remove the `acceptWatchAsset` and `rejectWatchAsset` methods from the token controller ([#1268](https://github.com/MetaMask/core/pull/1268))
160
- - Suggested assets can be accepted or rejected using the approval controller instead
192
+ - Suggested assets can be accepted or rejected using the approval controller instead
161
193
 
162
194
  ## [7.0.0]
163
195
  ### Changed
@@ -248,7 +280,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
248
280
  ### Changed
249
281
  - Use Ethers for AssetsContractController ([#845](https://github.com/MetaMask/core/pull/845))
250
282
 
251
- [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@12.0.0...HEAD
283
+ [Unreleased]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@14.0.0...HEAD
284
+ [14.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@13.0.0...@metamask/assets-controllers@14.0.0
285
+ [13.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@12.0.0...@metamask/assets-controllers@13.0.0
252
286
  [12.0.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@11.1.0...@metamask/assets-controllers@12.0.0
253
287
  [11.1.0]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@11.0.1...@metamask/assets-controllers@11.1.0
254
288
  [11.0.1]: https://github.com/MetaMask/core/compare/@metamask/assets-controllers@11.0.0...@metamask/assets-controllers@11.0.1
@@ -105,9 +105,8 @@ export interface ApiNftCreator {
105
105
  *
106
106
  * NftDetection configuration
107
107
  * @property interval - Polling interval used to fetch new token rates
108
- * @property networkType - Network type ID as per net_version
108
+ * @property chainId - Current chain ID
109
109
  * @property selectedAddress - Vault selected address
110
- * @property tokens - List of tokens associated with the active vault
111
110
  */
112
111
  export interface NftDetectionConfig extends BaseConfig {
113
112
  interval: number;
@@ -1 +1 @@
1
- {"version":3,"file":"NftDetectionController.d.ts","sourceRoot":"","sources":["../src/NftDetectionController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NftDetectionController.d.ts","sourceRoot":"","sources":["../src/NftDetectionController.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"NftDetectionController.js","sourceRoot":"","sources":["../src/NftDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport {\n OPENSEA_PROXY_URL,\n fetchWithErrorHandling,\n toChecksumHexAddress,\n ChainId,\n} from '@metamask/controller-utils';\nimport type { NetworkState } from '@metamask/network-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { Source } from './constants';\nimport type { NftController, NftState, NftMetadata } from './NftController';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * @type ApiNft\n *\n * NFT object coming from OpenSea api\n * @property token_id - The NFT identifier\n * @property num_sales - Number of sales\n * @property background_color - The background color to be displayed with the item\n * @property image_url - URI of an image associated with this NFT\n * @property image_preview_url - URI of a smaller image associated with this NFT\n * @property image_thumbnail_url - URI of a thumbnail image associated with this NFT\n * @property image_original_url - URI of the original image associated with this NFT\n * @property animation_url - URI of a animation associated with this NFT\n * @property animation_original_url - URI of the original animation associated with this NFT\n * @property name - The NFT name\n * @property description - The NFT description\n * @property external_link - External link containing additional information\n * @property assetContract - The NFT contract information object\n * @property creator - The NFT owner information object\n * @property lastSale - When this item was last sold\n */\nexport interface ApiNft {\n token_id: string;\n num_sales: number | null;\n background_color: string | null;\n image_url: string | null;\n image_preview_url: string | null;\n image_thumbnail_url: string | null;\n image_original_url: string | null;\n animation_url: string | null;\n animation_original_url: string | null;\n name: string | null;\n description: string | null;\n external_link: string | null;\n asset_contract: ApiNftContract;\n creator: ApiNftCreator;\n last_sale: ApiNftLastSale | null;\n}\n\n/**\n * @type ApiNftContract\n *\n * NFT contract object coming from OpenSea api\n * @property address - Address of the NFT contract\n * @property asset_contract_type - The NFT type, it could be `semi-fungible` or `non-fungible`\n * @property created_date - Creation date\n * @property collection - Object containing the contract name and URI of an image associated\n * @property schema_name - The schema followed by the contract, it could be `ERC721` or `ERC1155`\n * @property symbol - The NFT contract symbol\n * @property total_supply - Total supply of NFTs\n * @property description - The NFT contract description\n * @property external_link - External link containing additional information\n */\nexport interface ApiNftContract {\n address: string;\n asset_contract_type: string | null;\n created_date: string | null;\n schema_name: string | null;\n symbol: string | null;\n total_supply: string | null;\n description: string | null;\n external_link: string | null;\n collection: {\n name: string | null;\n image_url?: string | null;\n };\n}\n\n/**\n * @type ApiNftLastSale\n *\n * NFT sale object coming from OpenSea api\n * @property event_timestamp - Object containing a `username`\n * @property total_price - URI of NFT image associated with this owner\n * @property transaction - Object containing transaction_hash and block_hash\n */\nexport interface ApiNftLastSale {\n event_timestamp: string;\n total_price: string;\n transaction: { transaction_hash: string; block_hash: string };\n}\n\n/**\n * @type ApiNftCreator\n *\n * NFT creator object coming from OpenSea api\n * @property user - Object containing a `username`\n * @property profile_img_url - URI of NFT image associated with this owner\n * @property address - The owner address\n */\nexport interface ApiNftCreator {\n user: { username: string };\n profile_img_url: string;\n address: string;\n}\n\n/**\n * @type NftDetectionConfig\n *\n * NftDetection configuration\n * @property interval - Polling interval used to fetch new token rates\n * @property networkType - Network type ID as per net_version\n * @property selectedAddress - Vault selected address\n * @property tokens - List of tokens associated with the active vault\n */\nexport interface NftDetectionConfig extends BaseConfig {\n interval: number;\n chainId: Hex;\n selectedAddress: string;\n}\n\n/**\n * Controller that passively polls on a set interval for NFT auto detection\n */\nexport class NftDetectionController extends BaseController<\n NftDetectionConfig,\n BaseState\n> {\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private getOwnerNftApi({\n address,\n offset,\n }: {\n address: string;\n offset: number;\n }) {\n return `${OPENSEA_PROXY_URL}/assets?owner=${address}&offset=${offset}&limit=50`;\n }\n\n private async getOwnerNfts(address: string) {\n let nftApiResponse: { assets: ApiNft[] };\n let nfts: ApiNft[] = [];\n let offset = 0;\n let pagingFinish = false;\n /* istanbul ignore if */\n do {\n nftApiResponse = await fetchWithErrorHandling({\n url: this.getOwnerNftApi({ address, offset }),\n timeout: 15000,\n });\n\n if (!nftApiResponse) {\n return nfts;\n }\n\n nftApiResponse?.assets?.length !== 0\n ? (nfts = [...nfts, ...nftApiResponse.assets])\n : (pagingFinish = true);\n offset += 50;\n } while (!pagingFinish);\n\n return nfts;\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'NftDetectionController';\n\n private readonly getOpenSeaApiKey: () => string | undefined;\n\n private readonly addNft: NftController['addNft'];\n\n private readonly getNftState: () => NftState;\n\n /**\n * Creates an NftDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNftsStateChange - Allows subscribing to assets controller state changes.\n * @param options.onPreferencesStateChange - Allows subscribing to preferences controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param options.getOpenSeaApiKey - Gets the OpenSea API key, if one is set.\n * @param options.addNft - Add an NFT.\n * @param options.getNftState - Gets the current state of the Assets controller.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n chainId: initialChainId,\n onPreferencesStateChange,\n onNetworkStateChange,\n getOpenSeaApiKey,\n addNft,\n getNftState,\n }: {\n chainId: Hex;\n onNftsStateChange: (listener: (nftsState: NftState) => void) => void;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getOpenSeaApiKey: () => string | undefined;\n addNft: NftController['addNft'];\n getNftState: () => NftState;\n },\n config?: Partial<NftDetectionConfig>,\n state?: Partial<BaseState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: DEFAULT_INTERVAL,\n chainId: initialChainId,\n selectedAddress: '',\n disabled: true,\n };\n this.initialize();\n this.getNftState = getNftState;\n onPreferencesStateChange(({ selectedAddress, useNftDetection }) => {\n const { selectedAddress: previouslySelectedAddress, disabled } =\n this.config;\n\n if (\n selectedAddress !== previouslySelectedAddress ||\n !useNftDetection !== disabled\n ) {\n this.configure({ selectedAddress, disabled: !useNftDetection });\n }\n\n if (useNftDetection !== undefined) {\n if (useNftDetection) {\n this.start();\n } else {\n this.stop();\n }\n }\n });\n\n onNetworkStateChange(({ providerConfig }) => {\n this.configure({\n chainId: providerConfig.chainId,\n });\n });\n this.getOpenSeaApiKey = getOpenSeaApiKey;\n this.addNft = addNft;\n }\n\n /**\n * Start polling for the currency rate.\n */\n async start() {\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n\n await this.startPolling();\n }\n\n /**\n * Stop polling for the currency rate.\n */\n stop() {\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - An interval on which to poll.\n */\n private async startPolling(interval?: number): Promise<void> {\n interval && this.configure({ interval }, false, false);\n this.stopPolling();\n await this.detectNfts();\n this.intervalId = setInterval(async () => {\n await this.detectNfts();\n }, this.config.interval);\n }\n\n /**\n * Checks whether network is mainnet or not.\n *\n * @returns Whether current network is mainnet.\n */\n isMainnet = (): boolean => this.config.chainId === ChainId.mainnet;\n\n /**\n * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are\n * added.\n */\n async detectNfts() {\n /* istanbul ignore if */\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n const { selectedAddress, chainId } = this.config;\n\n /* istanbul ignore else */\n if (!selectedAddress) {\n return;\n }\n\n const apiNfts = await this.getOwnerNfts(selectedAddress);\n const addNftPromises = apiNfts.map(async (nft: ApiNft) => {\n const {\n token_id,\n num_sales,\n background_color,\n image_url,\n image_preview_url,\n image_thumbnail_url,\n image_original_url,\n animation_url,\n animation_original_url,\n name,\n description,\n external_link,\n creator,\n asset_contract: { address, schema_name },\n last_sale,\n } = nft;\n\n let ignored;\n /* istanbul ignore else */\n const { ignoredNfts } = this.getNftState();\n if (ignoredNfts.length) {\n ignored = ignoredNfts.find((c) => {\n /* istanbul ignore next */\n return (\n c.address === toChecksumHexAddress(address) &&\n c.tokenId === token_id\n );\n });\n }\n\n /* istanbul ignore else */\n if (!ignored) {\n /* istanbul ignore next */\n const nftMetadata: NftMetadata = Object.assign(\n {},\n { name },\n creator && { creator },\n description && { description },\n image_url && { image: image_url },\n num_sales && { numberOfSales: num_sales },\n background_color && { backgroundColor: background_color },\n image_preview_url && { imagePreview: image_preview_url },\n image_thumbnail_url && { imageThumbnail: image_thumbnail_url },\n image_original_url && { imageOriginal: image_original_url },\n animation_url && { animation: animation_url },\n animation_original_url && {\n animationOriginal: animation_original_url,\n },\n schema_name && { standard: schema_name },\n external_link && { externalLink: external_link },\n last_sale && { lastSale: last_sale },\n );\n\n await this.addNft(\n address,\n token_id,\n nftMetadata,\n {\n userAddress: selectedAddress,\n chainId,\n },\n Source.Detected,\n );\n }\n });\n await Promise.all(addNftPromises);\n }\n}\n\nexport default NftDetectionController;\n"]}
1
+ {"version":3,"file":"NftDetectionController.js","sourceRoot":"","sources":["../src/NftDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BaseConfig, BaseState } from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport {\n OPENSEA_PROXY_URL,\n fetchWithErrorHandling,\n toChecksumHexAddress,\n ChainId,\n} from '@metamask/controller-utils';\nimport type { NetworkState } from '@metamask/network-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport { Source } from './constants';\nimport type { NftController, NftState, NftMetadata } from './NftController';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * @type ApiNft\n *\n * NFT object coming from OpenSea api\n * @property token_id - The NFT identifier\n * @property num_sales - Number of sales\n * @property background_color - The background color to be displayed with the item\n * @property image_url - URI of an image associated with this NFT\n * @property image_preview_url - URI of a smaller image associated with this NFT\n * @property image_thumbnail_url - URI of a thumbnail image associated with this NFT\n * @property image_original_url - URI of the original image associated with this NFT\n * @property animation_url - URI of a animation associated with this NFT\n * @property animation_original_url - URI of the original animation associated with this NFT\n * @property name - The NFT name\n * @property description - The NFT description\n * @property external_link - External link containing additional information\n * @property assetContract - The NFT contract information object\n * @property creator - The NFT owner information object\n * @property lastSale - When this item was last sold\n */\nexport interface ApiNft {\n token_id: string;\n num_sales: number | null;\n background_color: string | null;\n image_url: string | null;\n image_preview_url: string | null;\n image_thumbnail_url: string | null;\n image_original_url: string | null;\n animation_url: string | null;\n animation_original_url: string | null;\n name: string | null;\n description: string | null;\n external_link: string | null;\n asset_contract: ApiNftContract;\n creator: ApiNftCreator;\n last_sale: ApiNftLastSale | null;\n}\n\n/**\n * @type ApiNftContract\n *\n * NFT contract object coming from OpenSea api\n * @property address - Address of the NFT contract\n * @property asset_contract_type - The NFT type, it could be `semi-fungible` or `non-fungible`\n * @property created_date - Creation date\n * @property collection - Object containing the contract name and URI of an image associated\n * @property schema_name - The schema followed by the contract, it could be `ERC721` or `ERC1155`\n * @property symbol - The NFT contract symbol\n * @property total_supply - Total supply of NFTs\n * @property description - The NFT contract description\n * @property external_link - External link containing additional information\n */\nexport interface ApiNftContract {\n address: string;\n asset_contract_type: string | null;\n created_date: string | null;\n schema_name: string | null;\n symbol: string | null;\n total_supply: string | null;\n description: string | null;\n external_link: string | null;\n collection: {\n name: string | null;\n image_url?: string | null;\n };\n}\n\n/**\n * @type ApiNftLastSale\n *\n * NFT sale object coming from OpenSea api\n * @property event_timestamp - Object containing a `username`\n * @property total_price - URI of NFT image associated with this owner\n * @property transaction - Object containing transaction_hash and block_hash\n */\nexport interface ApiNftLastSale {\n event_timestamp: string;\n total_price: string;\n transaction: { transaction_hash: string; block_hash: string };\n}\n\n/**\n * @type ApiNftCreator\n *\n * NFT creator object coming from OpenSea api\n * @property user - Object containing a `username`\n * @property profile_img_url - URI of NFT image associated with this owner\n * @property address - The owner address\n */\nexport interface ApiNftCreator {\n user: { username: string };\n profile_img_url: string;\n address: string;\n}\n\n/**\n * @type NftDetectionConfig\n *\n * NftDetection configuration\n * @property interval - Polling interval used to fetch new token rates\n * @property chainId - Current chain ID\n * @property selectedAddress - Vault selected address\n */\nexport interface NftDetectionConfig extends BaseConfig {\n interval: number;\n chainId: Hex;\n selectedAddress: string;\n}\n\n/**\n * Controller that passively polls on a set interval for NFT auto detection\n */\nexport class NftDetectionController extends BaseController<\n NftDetectionConfig,\n BaseState\n> {\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private getOwnerNftApi({\n address,\n offset,\n }: {\n address: string;\n offset: number;\n }) {\n return `${OPENSEA_PROXY_URL}/assets?owner=${address}&offset=${offset}&limit=50`;\n }\n\n private async getOwnerNfts(address: string) {\n let nftApiResponse: { assets: ApiNft[] };\n let nfts: ApiNft[] = [];\n let offset = 0;\n let pagingFinish = false;\n /* istanbul ignore if */\n do {\n nftApiResponse = await fetchWithErrorHandling({\n url: this.getOwnerNftApi({ address, offset }),\n timeout: 15000,\n });\n\n if (!nftApiResponse) {\n return nfts;\n }\n\n nftApiResponse?.assets?.length !== 0\n ? (nfts = [...nfts, ...nftApiResponse.assets])\n : (pagingFinish = true);\n offset += 50;\n } while (!pagingFinish);\n\n return nfts;\n }\n\n /**\n * Name of this controller used during composition\n */\n override name = 'NftDetectionController';\n\n private readonly getOpenSeaApiKey: () => string | undefined;\n\n private readonly addNft: NftController['addNft'];\n\n private readonly getNftState: () => NftState;\n\n /**\n * Creates an NftDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNftsStateChange - Allows subscribing to assets controller state changes.\n * @param options.onPreferencesStateChange - Allows subscribing to preferences controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param options.getOpenSeaApiKey - Gets the OpenSea API key, if one is set.\n * @param options.addNft - Add an NFT.\n * @param options.getNftState - Gets the current state of the Assets controller.\n * @param config - Initial options used to configure this controller.\n * @param state - Initial state to set on this controller.\n */\n constructor(\n {\n chainId: initialChainId,\n onPreferencesStateChange,\n onNetworkStateChange,\n getOpenSeaApiKey,\n addNft,\n getNftState,\n }: {\n chainId: Hex;\n onNftsStateChange: (listener: (nftsState: NftState) => void) => void;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n getOpenSeaApiKey: () => string | undefined;\n addNft: NftController['addNft'];\n getNftState: () => NftState;\n },\n config?: Partial<NftDetectionConfig>,\n state?: Partial<BaseState>,\n ) {\n super(config, state);\n this.defaultConfig = {\n interval: DEFAULT_INTERVAL,\n chainId: initialChainId,\n selectedAddress: '',\n disabled: true,\n };\n this.initialize();\n this.getNftState = getNftState;\n onPreferencesStateChange(({ selectedAddress, useNftDetection }) => {\n const { selectedAddress: previouslySelectedAddress, disabled } =\n this.config;\n\n if (\n selectedAddress !== previouslySelectedAddress ||\n !useNftDetection !== disabled\n ) {\n this.configure({ selectedAddress, disabled: !useNftDetection });\n }\n\n if (useNftDetection !== undefined) {\n if (useNftDetection) {\n this.start();\n } else {\n this.stop();\n }\n }\n });\n\n onNetworkStateChange(({ providerConfig }) => {\n this.configure({\n chainId: providerConfig.chainId,\n });\n });\n this.getOpenSeaApiKey = getOpenSeaApiKey;\n this.addNft = addNft;\n }\n\n /**\n * Start polling for the currency rate.\n */\n async start() {\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n\n await this.startPolling();\n }\n\n /**\n * Stop polling for the currency rate.\n */\n stop() {\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n *\n * @param interval - An interval on which to poll.\n */\n private async startPolling(interval?: number): Promise<void> {\n interval && this.configure({ interval }, false, false);\n this.stopPolling();\n await this.detectNfts();\n this.intervalId = setInterval(async () => {\n await this.detectNfts();\n }, this.config.interval);\n }\n\n /**\n * Checks whether network is mainnet or not.\n *\n * @returns Whether current network is mainnet.\n */\n isMainnet = (): boolean => this.config.chainId === ChainId.mainnet;\n\n /**\n * Triggers asset ERC721 token auto detection on mainnet. Any newly detected NFTs are\n * added.\n */\n async detectNfts() {\n /* istanbul ignore if */\n if (!this.isMainnet() || this.disabled) {\n return;\n }\n const { selectedAddress, chainId } = this.config;\n\n /* istanbul ignore else */\n if (!selectedAddress) {\n return;\n }\n\n const apiNfts = await this.getOwnerNfts(selectedAddress);\n const addNftPromises = apiNfts.map(async (nft: ApiNft) => {\n const {\n token_id,\n num_sales,\n background_color,\n image_url,\n image_preview_url,\n image_thumbnail_url,\n image_original_url,\n animation_url,\n animation_original_url,\n name,\n description,\n external_link,\n creator,\n asset_contract: { address, schema_name },\n last_sale,\n } = nft;\n\n let ignored;\n /* istanbul ignore else */\n const { ignoredNfts } = this.getNftState();\n if (ignoredNfts.length) {\n ignored = ignoredNfts.find((c) => {\n /* istanbul ignore next */\n return (\n c.address === toChecksumHexAddress(address) &&\n c.tokenId === token_id\n );\n });\n }\n\n /* istanbul ignore else */\n if (!ignored) {\n /* istanbul ignore next */\n const nftMetadata: NftMetadata = Object.assign(\n {},\n { name },\n creator && { creator },\n description && { description },\n image_url && { image: image_url },\n num_sales && { numberOfSales: num_sales },\n background_color && { backgroundColor: background_color },\n image_preview_url && { imagePreview: image_preview_url },\n image_thumbnail_url && { imageThumbnail: image_thumbnail_url },\n image_original_url && { imageOriginal: image_original_url },\n animation_url && { animation: animation_url },\n animation_original_url && {\n animationOriginal: animation_original_url,\n },\n schema_name && { standard: schema_name },\n external_link && { externalLink: external_link },\n last_sale && { lastSale: last_sale },\n );\n\n await this.addNft(\n address,\n token_id,\n nftMetadata,\n {\n userAddress: selectedAddress,\n chainId,\n },\n Source.Detected,\n );\n }\n });\n await Promise.all(addNftPromises);\n }\n}\n\nexport default NftDetectionController;\n"]}
@@ -70,7 +70,7 @@ export declare class ERC1155Standard {
70
70
  * @param tokenId - tokenId of a given token in the contract.
71
71
  * @returns Promise resolving an object containing the standard, tokenURI, symbol and name of the given contract/tokenId pair.
72
72
  */
73
- getDetails: (address: string, ipfsGateway: string, tokenId?: string | undefined) => Promise<{
73
+ getDetails: (address: string, ipfsGateway: string, tokenId?: string) => Promise<{
74
74
  standard: string;
75
75
  tokenURI: string | undefined;
76
76
  image: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"ERC1155Standard.d.ts","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC1155/ERC1155Standard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAS7D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAI1C,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAE5B,QAAQ,EAAE,YAAY;IAIlC;;;;;OAKG;IACH,oCAAoC,YACzB,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,sCAAsC,YAC3B,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,iCAAiC,YACtB,MAAM,KACd,QAAQ,OAAO,CAAC,CAEjB;IAEF;;;;;;OAMG;IACH,WAAW,YAAmB,MAAM,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC,CAGrE;IAEF;;;;;;;OAOG;IACH,YAAY,oBACO,MAAM,WACd,MAAM,WACN,MAAM,KACd,QAAQ,EAAE,CAAC,CAIZ;IAEF;;;;;;;;;;;OAWG;IACH,cAAc,aACF,MAAM,QACV,MAAM,MACR,MAAM,MACN,MAAM,SACH,MAAM,KACZ,QAAQ,IAAI,CAAC,CAmBd;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAMxC;IAEF;;;;;;;OAOG;IACH,UAAU,YACC,MAAM,eACF,MAAM;kBAGT,MAAM;kBACN,MAAM,GAAG,SAAS;eACrB,MAAM,GAAG,SAAS;OAiCzB;CACH"}
1
+ {"version":3,"file":"ERC1155Standard.d.ts","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC1155/ERC1155Standard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAS7D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAI1C,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAE5B,QAAQ,EAAE,YAAY;IAIlC;;;;;OAKG;IACH,oCAAoC,YACzB,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,sCAAsC,YAC3B,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,iCAAiC,YACtB,MAAM,KACd,QAAQ,OAAO,CAAC,CAEjB;IAEF;;;;;;OAMG;IACH,WAAW,YAAmB,MAAM,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC,CAGrE;IAEF;;;;;;;OAOG;IACH,YAAY,oBACO,MAAM,WACd,MAAM,WACN,MAAM,KACd,QAAQ,EAAE,CAAC,CAIZ;IAEF;;;;;;;;;;;OAWG;IACH,cAAc,aACF,MAAM,QACV,MAAM,MACR,MAAM,MACN,MAAM,SACH,MAAM,KACZ,QAAQ,IAAI,CAAC,CAmBd;IAEF;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAMxC;IAEF;;;;;;;OAOG;IACH,UAAU,YACC,MAAM,eACF,MAAM,YACT,MAAM;kBAEN,MAAM;kBACN,MAAM,GAAG,SAAS;eACrB,MAAM,GAAG,SAAS;OAiCzB;CACH"}
@@ -78,7 +78,7 @@ export declare class ERC721Standard {
78
78
  * @param tokenId - tokenId of a given token in the contract.
79
79
  * @returns Promise resolving an object containing the standard, tokenURI, symbol and name of the given contract/tokenId pair.
80
80
  */
81
- getDetails: (address: string, ipfsGateway: string, tokenId?: string | undefined) => Promise<{
81
+ getDetails: (address: string, ipfsGateway: string, tokenId?: string) => Promise<{
82
82
  standard: string;
83
83
  tokenURI: string | undefined;
84
84
  symbol: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"ERC721Standard.d.ts","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC721/ERC721Standard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAY7D,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAE5B,QAAQ,EAAE,YAAY;IAIlC;;;;;OAKG;IACH,iCAAiC,YACtB,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,mCAAmC,YACxB,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,gCAAgC,YACrB,MAAM,KACd,QAAQ,OAAO,CAAC,CAEjB;IAEF;;;;;;;OAOG;IACH,aAAa,YACF,MAAM,mBACE,MAAM,SAChB,MAAM,KACZ,QAAQ,MAAM,CAAC,CAGhB;IAEF;;;;;;OAMG;IACH,WAAW,YAAmB,MAAM,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC,CASrE;IAEF;;;;;OAKG;IACH,YAAY,YAAmB,MAAM,KAAG,QAAQ,MAAM,CAAC,CAGrD;IAEF;;;;;OAKG;IACH,cAAc,YAAmB,MAAM,KAAG,QAAQ,MAAM,CAAC,CAGvD;IAEF;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKnE;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAcxC;IAEF;;;;;;;OAOG;IACH,UAAU,YACC,MAAM,eACF,MAAM;kBAGT,MAAM;kBACN,MAAM,GAAG,SAAS;gBACpB,MAAM,GAAG,SAAS;cACpB,MAAM,GAAG,SAAS;eACjB,MAAM,GAAG,SAAS;OA+CzB;CACH"}
1
+ {"version":3,"file":"ERC721Standard.d.ts","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC721/ERC721Standard.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAY7D,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAE5B,QAAQ,EAAE,YAAY;IAIlC;;;;;OAKG;IACH,iCAAiC,YACtB,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,mCAAmC,YACxB,MAAM,KACd,QAAQ,OAAO,CAAC,CAKjB;IAEF;;;;;OAKG;IACH,gCAAgC,YACrB,MAAM,KACd,QAAQ,OAAO,CAAC,CAEjB;IAEF;;;;;;;OAOG;IACH,aAAa,YACF,MAAM,mBACE,MAAM,SAChB,MAAM,KACZ,QAAQ,MAAM,CAAC,CAGhB;IAEF;;;;;;OAMG;IACH,WAAW,YAAmB,MAAM,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC,CASrE;IAEF;;;;;OAKG;IACH,YAAY,YAAmB,MAAM,KAAG,QAAQ,MAAM,CAAC,CAGrD;IAEF;;;;;OAKG;IACH,cAAc,YAAmB,MAAM,KAAG,QAAQ,MAAM,CAAC,CAGvD;IAEF;;;;;;OAMG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKnE;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAcxC;IAEF;;;;;;;OAOG;IACH,UAAU,YACC,MAAM,eACF,MAAM,YACT,MAAM;kBAEN,MAAM;kBACN,MAAM,GAAG,SAAS;gBACpB,MAAM,GAAG,SAAS;cACpB,MAAM,GAAG,SAAS;eACjB,MAAM,GAAG,SAAS;OA+CzB;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"TokenListController.d.ts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenListController.d.ts","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,KAAK,EACV,iCAAiC,EACjC,YAAY,EACb,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAYnC,QAAA,MAAM,IAAI,wBAAwB,CAAC;AAEnC,oBAAY,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE1D,aAAK,SAAS,GAAG;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AACF,aAAK,iBAAiB,GAAG;IACvB,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,oBAAY,cAAc,GAAG;IAC3B,SAAS,EAAE,YAAY,CAAC;IACxB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,8BAA8B,EAAE,OAAO,CAAC;CACzC,CAAC;AAEF,oBAAY,oBAAoB,GAAG;IACjC,IAAI,EAAE,GAAG,OAAO,IAAI,cAAc,CAAC;IACnC,OAAO,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;CACpC,CAAC;AAEF,oBAAY,iBAAiB,GAAG;IAC9B,IAAI,EAAE,GAAG,OAAO,IAAI,WAAW,CAAC;IAChC,OAAO,EAAE,MAAM,cAAc,CAAC;CAC/B,CAAC;AAEF,aAAK,kBAAkB,GAAG,6BAA6B,CACrD,OAAO,IAAI,EACX,iBAAiB,EACjB,oBAAoB,GAAG,iCAAiC,EACxD,KAAK,EACL,oBAAoB,CAAC,MAAM,CAAC,GAAG,iCAAiC,CAAC,MAAM,CAAC,CACzE,CAAC;AAcF;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,gBAAgB,CACvD,OAAO,IAAI,EACX,cAAc,EACd,kBAAkB,CACnB;;IACC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IAErC,OAAO,CAAC,UAAU,CAAC,CAAgC;IAEnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAS;IAE/C,OAAO,CAAC,OAAO,CAAM;IAErB,OAAO,CAAC,eAAe,CAAkB;IAEzC;;;;;;;;;;;OAWG;gBACS,EACV,OAAO,EACP,8BAAsC,EACtC,oBAAoB,EACpB,QAA2B,EAC3B,qBAAyC,EACzC,SAAS,EACT,KAAK,GACN,EAAE;QACD,OAAO,EAAE,GAAG,CAAC;QACb,8BAA8B,CAAC,EAAE,OAAO,CAAC;QACzC,oBAAoB,CAAC,EAAE,CACrB,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,KAC3C,IAAI,CAAC;QACV,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;QAC/B,SAAS,EAAE,kBAAkB,CAAC;QAC9B,KAAK,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;KACjC;IAoDD;;OAEG;IACG,KAAK;IAOX;;OAEG;IACG,OAAO;IAKb;;OAEG;IACH,IAAI;IAIJ;;;;OAIG;IACM,OAAO;IAKhB,OAAO,CAAC,WAAW;IAMnB;;OAEG;YACW,YAAY;IAO1B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAgFrC;;;;;;OAMG;IACG,cAAc,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAapD;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAU7B;;;;OAIG;IACH,oCAAoC,CAAC,oBAAoB,EAAE,OAAO,GAAG,IAAI;CAQ1E;AAED,eAAe,mBAAmB,CAAC"}
@@ -18,7 +18,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.TokenListController = void 0;
19
19
  const base_controller_1 = require("@metamask/base-controller");
20
20
  const controller_utils_1 = require("@metamask/controller-utils");
21
- const abort_controller_1 = require("abort-controller");
22
21
  const async_mutex_1 = require("async-mutex");
23
22
  const assetsUtil_1 = require("./assetsUtil");
24
23
  const token_service_1 = require("./token-service");
@@ -64,7 +63,7 @@ class TokenListController extends base_controller_1.BaseControllerV2 {
64
63
  this.cacheRefreshThreshold = cacheRefreshThreshold;
65
64
  this.chainId = chainId;
66
65
  this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);
67
- this.abortController = new abort_controller_1.AbortController();
66
+ this.abortController = new AbortController();
68
67
  if (onNetworkStateChange) {
69
68
  onNetworkStateChange((networkControllerState) => __awaiter(this, void 0, void 0, function* () {
70
69
  yield __classPrivateFieldGet(this, _TokenListController_instances, "m", _TokenListController_onNetworkControllerStateChange).call(this, networkControllerState);
@@ -228,7 +227,7 @@ _TokenListController_instances = new WeakSet(), _TokenListController_onNetworkCo
228
227
  return __awaiter(this, void 0, void 0, function* () {
229
228
  if (this.chainId !== networkControllerState.providerConfig.chainId) {
230
229
  this.abortController.abort();
231
- this.abortController = new abort_controller_1.AbortController();
230
+ this.abortController = new AbortController();
232
231
  this.chainId = networkControllerState.providerConfig.chainId;
233
232
  if (this.state.preventPollingOnNetworkRestart) {
234
233
  this.clearingTokenListData();
@@ -1 +1 @@
1
- {"version":3,"file":"TokenListController.js","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport { BaseControllerV2 } from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkControllerStateChangeEvent,\n NetworkState,\n} from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { AbortController as WhatwgAbortController } from 'abort-controller';\nimport { Mutex } from 'async-mutex';\nimport type { Patch } from 'immer';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenList } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\ntype TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = {\n type: `${typeof name}:stateChange`;\n payload: [TokenListState, Patch[]];\n};\n\nexport type GetTokenListState = {\n type: `${typeof name}:getState`;\n handler: () => TokenListState;\n};\n\ntype TokenListMessenger = RestrictedControllerMessenger<\n typeof name,\n GetTokenListState,\n TokenListStateChange | NetworkControllerStateChangeEvent,\n never,\n TokenListStateChange['type'] | NetworkControllerStateChangeEvent['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nconst defaultState: TokenListState = {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends BaseControllerV2<\n typeof name,\n TokenListState,\n TokenListMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: WhatwgAbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new WhatwgAbortController();\n if (onNetworkStateChange) {\n onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n if (this.chainId !== networkControllerState.providerConfig.chainId) {\n this.abortController.abort();\n this.abortController = new WhatwgAbortController();\n this.chainId = networkControllerState.providerConfig.chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n private async startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\n this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n */\n async fetchTokenList(): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens: TokenListMap = await safelyExecute(() =>\n this.fetchFromCache(),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI: TokenListToken[] = await safelyExecute(() =>\n fetchTokenList(this.chainId, this.abortController.signal),\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[this.chainId]?.data || {}) };\n\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n // Filtering out tokens with less than 3 occurrences and native tokens\n const filteredTokenList = tokensFromAPI.filter(\n (token) =>\n token.occurrences &&\n token.occurrences >= 3 &&\n token.address !== '0x0000000000000000000000000000000000000000',\n );\n // Removing the tokens with symbol conflicts\n const symbolsList = filteredTokenList.map((token) => token.symbol);\n const duplicateSymbols = [\n ...new Set(\n symbolsList.filter(\n (symbol, index) => symbolsList.indexOf(symbol) !== index,\n ),\n ),\n ];\n const uniqueTokenList = filteredTokenList.filter(\n (token) => !duplicateSymbols.includes(token.symbol),\n );\n for (const token of uniqueTokenList) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId: this.chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [this.chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n *\n * @returns The cached data, or `null` if the cache was expired.\n */\n async fetchFromCache(): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[this.chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
1
+ {"version":3,"file":"TokenListController.js","sourceRoot":"","sources":["../src/TokenListController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RestrictedControllerMessenger } from '@metamask/base-controller';\nimport { BaseControllerV2 } from '@metamask/base-controller';\nimport { safelyExecute } from '@metamask/controller-utils';\nimport type {\n NetworkControllerStateChangeEvent,\n NetworkState,\n} from '@metamask/network-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport type { Patch } from 'immer';\n\nimport {\n isTokenListSupportedForNetwork,\n formatAggregatorNames,\n formatIconUrlWithProxy,\n} from './assetsUtil';\nimport { fetchTokenList } from './token-service';\n\nconst DEFAULT_INTERVAL = 24 * 60 * 60 * 1000;\nconst DEFAULT_THRESHOLD = 24 * 60 * 60 * 1000;\n\nconst name = 'TokenListController';\n\nexport type TokenListToken = {\n name: string;\n symbol: string;\n decimals: number;\n address: string;\n occurrences: number;\n aggregators: string[];\n iconUrl: string;\n};\n\nexport type TokenListMap = Record<string, TokenListToken>;\n\ntype DataCache = {\n timestamp: number;\n data: TokenListMap;\n};\ntype TokensChainsCache = {\n [chainId: Hex]: DataCache;\n};\n\nexport type TokenListState = {\n tokenList: TokenListMap;\n tokensChainsCache: TokensChainsCache;\n preventPollingOnNetworkRestart: boolean;\n};\n\nexport type TokenListStateChange = {\n type: `${typeof name}:stateChange`;\n payload: [TokenListState, Patch[]];\n};\n\nexport type GetTokenListState = {\n type: `${typeof name}:getState`;\n handler: () => TokenListState;\n};\n\ntype TokenListMessenger = RestrictedControllerMessenger<\n typeof name,\n GetTokenListState,\n TokenListStateChange | NetworkControllerStateChangeEvent,\n never,\n TokenListStateChange['type'] | NetworkControllerStateChangeEvent['type']\n>;\n\nconst metadata = {\n tokenList: { persist: true, anonymous: true },\n tokensChainsCache: { persist: true, anonymous: true },\n preventPollingOnNetworkRestart: { persist: true, anonymous: true },\n};\n\nconst defaultState: TokenListState = {\n tokenList: {},\n tokensChainsCache: {},\n preventPollingOnNetworkRestart: false,\n};\n\n/**\n * Controller that passively polls on a set interval for the list of tokens from metaswaps api\n */\nexport class TokenListController extends BaseControllerV2<\n typeof name,\n TokenListState,\n TokenListMessenger\n> {\n private readonly mutex = new Mutex();\n\n private intervalId?: ReturnType<typeof setTimeout>;\n\n private readonly intervalDelay: number;\n\n private readonly cacheRefreshThreshold: number;\n\n private chainId: Hex;\n\n private abortController: AbortController;\n\n /**\n * Creates a TokenListController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onNetworkStateChange - A function for registering an event handler for network state changes.\n * @param options.interval - The polling interval, in milliseconds.\n * @param options.cacheRefreshThreshold - The token cache expiry time, in milliseconds.\n * @param options.messenger - A restricted controller messenger.\n * @param options.state - Initial state to set on this controller.\n * @param options.preventPollingOnNetworkRestart - Determines whether to prevent poilling on network restart in extension.\n */\n constructor({\n chainId,\n preventPollingOnNetworkRestart = false,\n onNetworkStateChange,\n interval = DEFAULT_INTERVAL,\n cacheRefreshThreshold = DEFAULT_THRESHOLD,\n messenger,\n state,\n }: {\n chainId: Hex;\n preventPollingOnNetworkRestart?: boolean;\n onNetworkStateChange?: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n interval?: number;\n cacheRefreshThreshold?: number;\n messenger: TokenListMessenger;\n state?: Partial<TokenListState>;\n }) {\n super({\n name,\n metadata,\n messenger,\n state: { ...defaultState, ...state },\n });\n this.intervalDelay = interval;\n this.cacheRefreshThreshold = cacheRefreshThreshold;\n this.chainId = chainId;\n this.updatePreventPollingOnNetworkRestart(preventPollingOnNetworkRestart);\n this.abortController = new AbortController();\n if (onNetworkStateChange) {\n onNetworkStateChange(async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n });\n } else {\n this.messagingSystem.subscribe(\n 'NetworkController:stateChange',\n async (networkControllerState) => {\n await this.#onNetworkControllerStateChange(networkControllerState);\n },\n );\n }\n }\n\n /**\n * Updates state and restarts polling on changes to the network controller\n * state.\n *\n * @param networkControllerState - The updated network controller state.\n */\n async #onNetworkControllerStateChange(networkControllerState: NetworkState) {\n if (this.chainId !== networkControllerState.providerConfig.chainId) {\n this.abortController.abort();\n this.abortController = new AbortController();\n this.chainId = networkControllerState.providerConfig.chainId;\n if (this.state.preventPollingOnNetworkRestart) {\n this.clearingTokenListData();\n } else {\n // Ensure tokenList is referencing data from correct network\n this.update(() => {\n return {\n ...this.state,\n tokenList: this.state.tokensChainsCache[this.chainId]?.data || {},\n };\n });\n await this.restart();\n }\n }\n }\n\n /**\n * Start polling for the token list.\n */\n async start() {\n if (!isTokenListSupportedForNetwork(this.chainId)) {\n return;\n }\n await this.startPolling();\n }\n\n /**\n * Restart polling for the token list.\n */\n async restart() {\n this.stopPolling();\n await this.startPolling();\n }\n\n /**\n * Stop polling for the token list.\n */\n stop() {\n this.stopPolling();\n }\n\n /**\n * Prepare to discard this controller.\n *\n * This stops any active polling.\n */\n override destroy() {\n super.destroy();\n this.stopPolling();\n }\n\n private stopPolling() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n private async startPolling(): Promise<void> {\n await safelyExecute(() => this.fetchTokenList());\n this.intervalId = setInterval(async () => {\n await safelyExecute(() => this.fetchTokenList());\n }, this.intervalDelay);\n }\n\n /**\n * Fetching token list from the Token Service API.\n */\n async fetchTokenList(): Promise<void> {\n const releaseLock = await this.mutex.acquire();\n try {\n const { tokensChainsCache } = this.state;\n let tokenList: TokenListMap = {};\n const cachedTokens: TokenListMap = await safelyExecute(() =>\n this.fetchFromCache(),\n );\n if (cachedTokens) {\n // Use non-expired cached tokens\n tokenList = { ...cachedTokens };\n } else {\n // Fetch fresh token list\n const tokensFromAPI: TokenListToken[] = await safelyExecute(() =>\n fetchTokenList(this.chainId, this.abortController.signal),\n );\n\n if (!tokensFromAPI) {\n // Fallback to expired cached tokens\n tokenList = { ...(tokensChainsCache[this.chainId]?.data || {}) };\n\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache,\n };\n });\n return;\n }\n // Filtering out tokens with less than 3 occurrences and native tokens\n const filteredTokenList = tokensFromAPI.filter(\n (token) =>\n token.occurrences &&\n token.occurrences >= 3 &&\n token.address !== '0x0000000000000000000000000000000000000000',\n );\n // Removing the tokens with symbol conflicts\n const symbolsList = filteredTokenList.map((token) => token.symbol);\n const duplicateSymbols = [\n ...new Set(\n symbolsList.filter(\n (symbol, index) => symbolsList.indexOf(symbol) !== index,\n ),\n ),\n ];\n const uniqueTokenList = filteredTokenList.filter(\n (token) => !duplicateSymbols.includes(token.symbol),\n );\n for (const token of uniqueTokenList) {\n const formattedToken: TokenListToken = {\n ...token,\n aggregators: formatAggregatorNames(token.aggregators),\n iconUrl: formatIconUrlWithProxy({\n chainId: this.chainId,\n tokenAddress: token.address,\n }),\n };\n tokenList[token.address] = formattedToken;\n }\n }\n const updatedTokensChainsCache: TokensChainsCache = {\n ...tokensChainsCache,\n [this.chainId]: {\n timestamp: Date.now(),\n data: tokenList,\n },\n };\n this.update(() => {\n return {\n ...this.state,\n tokenList,\n tokensChainsCache: updatedTokensChainsCache,\n };\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Checks if the Cache timestamp is valid,\n * if yes data in cache will be returned\n * otherwise null will be returned.\n *\n * @returns The cached data, or `null` if the cache was expired.\n */\n async fetchFromCache(): Promise<TokenListMap | null> {\n const { tokensChainsCache }: TokenListState = this.state;\n const dataCache = tokensChainsCache[this.chainId];\n const now = Date.now();\n if (\n dataCache?.data &&\n now - dataCache?.timestamp < this.cacheRefreshThreshold\n ) {\n return dataCache.data;\n }\n return null;\n }\n\n /**\n * Clearing tokenList and tokensChainsCache explicitly.\n */\n clearingTokenListData(): void {\n this.update(() => {\n return {\n ...this.state,\n tokenList: {},\n tokensChainsCache: {},\n };\n });\n }\n\n /**\n * Updates preventPollingOnNetworkRestart from extension.\n *\n * @param shouldPreventPolling - Determine whether to prevent polling on network change\n */\n updatePreventPollingOnNetworkRestart(shouldPreventPolling: boolean): void {\n this.update(() => {\n return {\n ...this.state,\n preventPollingOnNetworkRestart: shouldPreventPolling,\n };\n });\n }\n}\n\nexport default TokenListController;\n"]}
@@ -3,7 +3,7 @@ import { Contract } from '@ethersproject/contracts';
3
3
  import type { AddApprovalRequest } from '@metamask/approval-controller';
4
4
  import type { BaseConfig, BaseState, RestrictedControllerMessenger } from '@metamask/base-controller';
5
5
  import { BaseController } from '@metamask/base-controller';
6
- import type { NetworkState } from '@metamask/network-controller';
6
+ import type { NetworkClientId, NetworkController, NetworkState } from '@metamask/network-controller';
7
7
  import type { PreferencesState } from '@metamask/preferences-controller';
8
8
  import type { Hex } from '@metamask/utils';
9
9
  import { EventEmitter } from 'events';
@@ -86,7 +86,6 @@ export declare type TokensControllerMessenger = RestrictedControllerMessenger<ty
86
86
  */
87
87
  export declare class TokensController extends BaseController<TokensConfig, TokensState> {
88
88
  private readonly mutex;
89
- private ethersProvider;
90
89
  private abortController;
91
90
  private readonly messagingSystem;
92
91
  /**
@@ -105,6 +104,7 @@ export declare class TokensController extends BaseController<TokensConfig, Token
105
104
  */
106
105
  name: string;
107
106
  private readonly getERC20TokenName;
107
+ private readonly getNetworkClientById;
108
108
  /**
109
109
  * Creates a TokensController instance.
110
110
  *
@@ -114,44 +114,51 @@ export declare class TokensController extends BaseController<TokensConfig, Token
114
114
  * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
115
115
  * @param options.onTokenListStateChange - Allows subscribing to token list controller state changes.
116
116
  * @param options.getERC20TokenName - Gets the ERC-20 token name.
117
+ * @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.
117
118
  * @param options.config - Initial options used to configure this controller.
118
119
  * @param options.state - Initial state to set on this controller.
119
120
  * @param options.messenger - The controller messenger.
120
121
  */
121
- constructor({ chainId: initialChainId, onPreferencesStateChange, onNetworkStateChange, onTokenListStateChange, getERC20TokenName, config, state, messenger, }: {
122
+ constructor({ chainId: initialChainId, onPreferencesStateChange, onNetworkStateChange, onTokenListStateChange, getERC20TokenName, getNetworkClientById, config, state, messenger, }: {
122
123
  chainId: Hex;
123
124
  onPreferencesStateChange: (listener: (preferencesState: PreferencesState) => void) => void;
124
125
  onNetworkStateChange: (listener: (networkState: NetworkState) => void) => void;
125
126
  onTokenListStateChange: (listener: (tokenListState: TokenListState) => void) => void;
126
127
  getERC20TokenName: AssetsContractController['getERC20TokenName'];
128
+ getNetworkClientById: NetworkController['getNetworkClientById'];
127
129
  config?: Partial<TokensConfig>;
128
130
  state?: Partial<TokensState>;
129
131
  messenger: TokensControllerMessenger;
130
132
  });
131
- _instantiateNewEthersProvider(): any;
132
133
  /**
133
134
  * Adds a token to the stored token list.
134
135
  *
135
- * @param address - Hex address of the token contract.
136
- * @param symbol - Symbol of the token.
137
- * @param decimals - Number of decimals the token uses.
138
- * @param options - Object containing name and image of the token
139
- * @param options.name - Name of the token
140
- * @param options.image - Image of the token
136
+ * @param options - The method argument object.
137
+ * @param options.address - Hex address of the token contract.
138
+ * @param options.symbol - Symbol of the token.
139
+ * @param options.decimals - Number of decimals the token uses.
140
+ * @param options.name - Name of the token.
141
+ * @param options.image - Image of the token.
141
142
  * @param options.interactingAddress - The address of the account to add a token to.
143
+ * @param options.networkClientId - Network Client ID.
142
144
  * @returns Current token list.
143
145
  */
144
- addToken(address: string, symbol: string, decimals: number, { name, image, interactingAddress, }?: {
146
+ addToken({ address, symbol, decimals, name, image, interactingAddress, networkClientId, }: {
147
+ address: string;
148
+ symbol: string;
149
+ decimals: number;
145
150
  name?: string;
146
151
  image?: string;
147
152
  interactingAddress?: string;
153
+ networkClientId?: NetworkClientId;
148
154
  }): Promise<Token[]>;
149
155
  /**
150
156
  * Add a batch of tokens.
151
157
  *
152
158
  * @param tokensToImport - Array of tokens to import.
159
+ * @param networkClientId - Optional network client ID used to determine interacting chain ID.
153
160
  */
154
- addTokens(tokensToImport: Token[]): Promise<void>;
161
+ addTokens(tokensToImport: Token[], networkClientId?: NetworkClientId): Promise<void>;
155
162
  /**
156
163
  * Ignore a batch of tokens.
157
164
  *
@@ -189,22 +196,30 @@ export declare class TokensController extends BaseController<TokensConfig, Token
189
196
  * Detects whether or not a token is ERC-721 compatible.
190
197
  *
191
198
  * @param tokenAddress - The token contract address.
199
+ * @param networkClientId - Optional network client ID to fetch contract info with.
192
200
  * @returns A boolean indicating whether the token address passed in supports the EIP-721
193
201
  * interface.
194
202
  */
195
- _detectIsERC721(tokenAddress: string): Promise<any>;
196
- _createEthersContract(tokenAddress: string, abi: string, ethersProvider: any): Contract;
203
+ _detectIsERC721(tokenAddress: string, networkClientId?: NetworkClientId): Promise<any>;
204
+ _createEthersContract(tokenAddress: string, abi: string, networkClientId?: NetworkClientId): Contract;
197
205
  _generateRandomId(): string;
198
206
  /**
199
207
  * Adds a new suggestedAsset to the list of watched assets.
200
208
  * Parameters will be validated according to the asset type being watched.
201
209
  *
202
- * @param asset - The asset to be watched. For now only ERC20 tokens are accepted.
203
- * @param type - The asset type.
204
- * @param interactingAddress - The address of the account that is requesting to watch the asset.
210
+ * @param options - The method options.
211
+ * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.
212
+ * @param options.type - The asset type.
213
+ * @param options.interactingAddress - The address of the account that is requesting to watch the asset.
214
+ * @param options.networkClientId - Network Client ID.
205
215
  * @returns Object containing a Promise resolving to the suggestedAsset address if accepted.
206
216
  */
207
- watchAsset(asset: Token, type: string, interactingAddress?: string): Promise<void>;
217
+ watchAsset({ asset, type, interactingAddress, networkClientId, }: {
218
+ asset: Token;
219
+ type: string;
220
+ interactingAddress?: string;
221
+ networkClientId?: NetworkClientId;
222
+ }): Promise<void>;
208
223
  /**
209
224
  * Takes a new tokens and ignoredTokens array for the current network/account combination
210
225
  * and returns new allTokens and allIgnoredTokens state to update to.
@@ -1 +1 @@
1
- {"version":3,"file":"TokensController.d.ts","sourceRoot":"","sources":["../src/TokensController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokensController.d.ts","sourceRoot":"","sources":["../src/TokensController.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,6 @@ const base_controller_1 = require("@metamask/base-controller");
19
19
  const contract_metadata_1 = __importDefault(require("@metamask/contract-metadata"));
20
20
  const controller_utils_1 = require("@metamask/controller-utils");
21
21
  const metamask_eth_abis_1 = require("@metamask/metamask-eth-abis");
22
- const abort_controller_1 = require("abort-controller");
23
22
  const async_mutex_1 = require("async-mutex");
24
23
  const events_1 = require("events");
25
24
  const uuid_1 = require("uuid");
@@ -42,11 +41,12 @@ class TokensController extends base_controller_1.BaseController {
42
41
  * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.
43
42
  * @param options.onTokenListStateChange - Allows subscribing to token list controller state changes.
44
43
  * @param options.getERC20TokenName - Gets the ERC-20 token name.
44
+ * @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.
45
45
  * @param options.config - Initial options used to configure this controller.
46
46
  * @param options.state - Initial state to set on this controller.
47
47
  * @param options.messenger - The controller messenger.
48
48
  */
49
- constructor({ chainId: initialChainId, onPreferencesStateChange, onNetworkStateChange, onTokenListStateChange, getERC20TokenName, config, state, messenger, }) {
49
+ constructor({ chainId: initialChainId, onPreferencesStateChange, onNetworkStateChange, onTokenListStateChange, getERC20TokenName, getNetworkClientById, config, state, messenger, }) {
50
50
  super(config, state);
51
51
  this.mutex = new async_mutex_1.Mutex();
52
52
  /**
@@ -60,8 +60,9 @@ class TokensController extends base_controller_1.BaseController {
60
60
  this.defaultConfig = Object.assign({ selectedAddress: '', chainId: initialChainId, provider: undefined }, config);
61
61
  this.defaultState = Object.assign({ tokens: [], ignoredTokens: [], detectedTokens: [], allTokens: {}, allIgnoredTokens: {}, allDetectedTokens: {} }, state);
62
62
  this.initialize();
63
- this.abortController = new abort_controller_1.AbortController();
63
+ this.abortController = new AbortController();
64
64
  this.getERC20TokenName = getERC20TokenName;
65
+ this.getNetworkClientById = getNetworkClientById;
65
66
  this.messagingSystem = messenger;
66
67
  onPreferencesStateChange(({ selectedAddress }) => {
67
68
  var _a, _b, _c;
@@ -80,9 +81,8 @@ class TokensController extends base_controller_1.BaseController {
80
81
  const { selectedAddress } = this.config;
81
82
  const { chainId } = providerConfig;
82
83
  this.abortController.abort();
83
- this.abortController = new abort_controller_1.AbortController();
84
+ this.abortController = new AbortController();
84
85
  this.configure({ chainId });
85
- this.ethersProvider = this._instantiateNewEthersProvider();
86
86
  this.update({
87
87
  tokens: ((_a = allTokens[chainId]) === null || _a === void 0 ? void 0 : _a[selectedAddress]) || [],
88
88
  ignoredTokens: ((_b = allIgnoredTokens[chainId]) === null || _b === void 0 ? void 0 : _b[selectedAddress]) || [],
@@ -117,27 +117,29 @@ class TokensController extends base_controller_1.BaseController {
117
117
  }
118
118
  });
119
119
  }
120
- _instantiateNewEthersProvider() {
121
- var _a;
122
- return new providers_1.Web3Provider((_a = this.config) === null || _a === void 0 ? void 0 : _a.provider);
123
- }
124
120
  /**
125
121
  * Adds a token to the stored token list.
126
122
  *
127
- * @param address - Hex address of the token contract.
128
- * @param symbol - Symbol of the token.
129
- * @param decimals - Number of decimals the token uses.
130
- * @param options - Object containing name and image of the token
131
- * @param options.name - Name of the token
132
- * @param options.image - Image of the token
123
+ * @param options - The method argument object.
124
+ * @param options.address - Hex address of the token contract.
125
+ * @param options.symbol - Symbol of the token.
126
+ * @param options.decimals - Number of decimals the token uses.
127
+ * @param options.name - Name of the token.
128
+ * @param options.image - Image of the token.
133
129
  * @param options.interactingAddress - The address of the account to add a token to.
130
+ * @param options.networkClientId - Network Client ID.
134
131
  * @returns Current token list.
135
132
  */
136
- addToken(address, symbol, decimals, { name, image, interactingAddress, } = {}) {
133
+ addToken({ address, symbol, decimals, name, image, interactingAddress, networkClientId, }) {
137
134
  var _a, _b, _c;
138
135
  return __awaiter(this, void 0, void 0, function* () {
139
136
  const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;
140
- const { chainId: currentChainId, selectedAddress } = this.config;
137
+ const { chainId, selectedAddress } = this.config;
138
+ let currentChainId = chainId;
139
+ if (networkClientId) {
140
+ currentChainId =
141
+ this.getNetworkClientById(networkClientId).configuration.chainId;
142
+ }
141
143
  const accountAddress = interactingAddress || selectedAddress;
142
144
  const isInteractingWithWalletAccount = accountAddress === selectedAddress;
143
145
  const releaseLock = yield this.mutex.acquire();
@@ -148,10 +150,10 @@ class TokensController extends base_controller_1.BaseController {
148
150
  const detectedTokens = ((_c = allDetectedTokens[currentChainId]) === null || _c === void 0 ? void 0 : _c[accountAddress]) || [];
149
151
  const newTokens = [...tokens];
150
152
  const [isERC721, tokenMetadata] = yield Promise.all([
151
- this._detectIsERC721(address),
153
+ this._detectIsERC721(address, networkClientId),
152
154
  this.fetchTokenMetadata(address),
153
155
  ]);
154
- if (currentChainId !== this.config.chainId) {
156
+ if (!networkClientId && currentChainId !== this.config.chainId) {
155
157
  throw new Error('TokensController Error: Switched networks while adding token');
156
158
  }
157
159
  const newEntry = {
@@ -160,7 +162,7 @@ class TokensController extends base_controller_1.BaseController {
160
162
  decimals,
161
163
  image: image ||
162
164
  (0, assetsUtil_1.formatIconUrlWithProxy)({
163
- chainId: this.config.chainId,
165
+ chainId: currentChainId,
164
166
  tokenAddress: address,
165
167
  }),
166
168
  isERC721,
@@ -182,6 +184,7 @@ class TokensController extends base_controller_1.BaseController {
182
184
  newIgnoredTokens,
183
185
  newDetectedTokens,
184
186
  interactingAddress: accountAddress,
187
+ interactingChainId: currentChainId,
185
188
  });
186
189
  let newState = {
187
190
  allTokens: newAllTokens,
@@ -204,8 +207,9 @@ class TokensController extends base_controller_1.BaseController {
204
207
  * Add a batch of tokens.
205
208
  *
206
209
  * @param tokensToImport - Array of tokens to import.
210
+ * @param networkClientId - Optional network client ID used to determine interacting chain ID.
207
211
  */
208
- addTokens(tokensToImport) {
212
+ addTokens(tokensToImport, networkClientId) {
209
213
  return __awaiter(this, void 0, void 0, function* () {
210
214
  const releaseLock = yield this.mutex.acquire();
211
215
  const { tokens, detectedTokens, ignoredTokens } = this.state;
@@ -234,10 +238,16 @@ class TokensController extends base_controller_1.BaseController {
234
238
  const newTokens = Object.values(newTokensMap);
235
239
  const newDetectedTokens = detectedTokens.filter((token) => !importedTokensMap[token.address.toLowerCase()]);
236
240
  const newIgnoredTokens = ignoredTokens.filter((tokenAddress) => !newTokensMap[tokenAddress.toLowerCase()]);
241
+ let interactingChainId;
242
+ if (networkClientId) {
243
+ interactingChainId =
244
+ this.getNetworkClientById(networkClientId).configuration.chainId;
245
+ }
237
246
  const { newAllTokens, newAllDetectedTokens, newAllIgnoredTokens } = this._getNewAllTokensState({
238
247
  newTokens,
239
248
  newDetectedTokens,
240
249
  newIgnoredTokens,
250
+ interactingChainId,
241
251
  });
242
252
  this.update({
243
253
  tokens: newTokens,
@@ -396,10 +406,11 @@ class TokensController extends base_controller_1.BaseController {
396
406
  * Detects whether or not a token is ERC-721 compatible.
397
407
  *
398
408
  * @param tokenAddress - The token contract address.
409
+ * @param networkClientId - Optional network client ID to fetch contract info with.
399
410
  * @returns A boolean indicating whether the token address passed in supports the EIP-721
400
411
  * interface.
401
412
  */
402
- _detectIsERC721(tokenAddress) {
413
+ _detectIsERC721(tokenAddress, networkClientId) {
403
414
  var _a, _b;
404
415
  return __awaiter(this, void 0, void 0, function* () {
405
416
  const checksumAddress = (0, controller_utils_1.toChecksumHexAddress)(tokenAddress);
@@ -411,7 +422,7 @@ class TokensController extends base_controller_1.BaseController {
411
422
  else if (((_b = contract_metadata_1.default[checksumAddress]) === null || _b === void 0 ? void 0 : _b.erc20) === true) {
412
423
  return Promise.resolve(false);
413
424
  }
414
- const tokenContract = this._createEthersContract(tokenAddress, metamask_eth_abis_1.abiERC721, this.ethersProvider);
425
+ const tokenContract = this._createEthersContract(tokenAddress, metamask_eth_abis_1.abiERC721, networkClientId);
415
426
  try {
416
427
  return yield tokenContract.supportsInterface(controller_utils_1.ERC721_INTERFACE_ID);
417
428
  }
@@ -424,8 +435,13 @@ class TokensController extends base_controller_1.BaseController {
424
435
  }
425
436
  });
426
437
  }
427
- _createEthersContract(tokenAddress, abi, ethersProvider) {
428
- const tokenContract = new contracts_1.Contract(tokenAddress, abi, ethersProvider);
438
+ _createEthersContract(tokenAddress, abi, networkClientId) {
439
+ var _a;
440
+ const provider = networkClientId
441
+ ? this.getNetworkClientById(networkClientId).provider
442
+ : (_a = this.config) === null || _a === void 0 ? void 0 : _a.provider;
443
+ const web3provider = new providers_1.Web3Provider(provider);
444
+ const tokenContract = new contracts_1.Contract(tokenAddress, abi, web3provider);
429
445
  return tokenContract;
430
446
  }
431
447
  _generateRandomId() {
@@ -435,12 +451,14 @@ class TokensController extends base_controller_1.BaseController {
435
451
  * Adds a new suggestedAsset to the list of watched assets.
436
452
  * Parameters will be validated according to the asset type being watched.
437
453
  *
438
- * @param asset - The asset to be watched. For now only ERC20 tokens are accepted.
439
- * @param type - The asset type.
440
- * @param interactingAddress - The address of the account that is requesting to watch the asset.
454
+ * @param options - The method options.
455
+ * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.
456
+ * @param options.type - The asset type.
457
+ * @param options.interactingAddress - The address of the account that is requesting to watch the asset.
458
+ * @param options.networkClientId - Network Client ID.
441
459
  * @returns Object containing a Promise resolving to the suggestedAsset address if accepted.
442
460
  */
443
- watchAsset(asset, type, interactingAddress) {
461
+ watchAsset({ asset, type, interactingAddress, networkClientId, }) {
444
462
  return __awaiter(this, void 0, void 0, function* () {
445
463
  if (type !== controller_utils_1.ERC20) {
446
464
  throw new Error(`Asset of type ${type} not supported`);
@@ -457,15 +475,20 @@ class TokensController extends base_controller_1.BaseController {
457
475
  yield this._requestApproval(suggestedAssetMeta);
458
476
  let name;
459
477
  try {
460
- name = yield this.getERC20TokenName(asset.address);
478
+ name = yield this.getERC20TokenName(asset.address, networkClientId);
461
479
  }
462
480
  catch (error) {
463
481
  name = undefined;
464
482
  }
465
- yield this.addToken(asset.address, asset.symbol, asset.decimals, {
483
+ const { address, symbol, decimals, image } = asset;
484
+ yield this.addToken({
485
+ address,
486
+ symbol,
487
+ decimals,
466
488
  name,
467
- image: asset.image,
489
+ image,
468
490
  interactingAddress: suggestedAssetMeta.interactingAddress,
491
+ networkClientId,
469
492
  });
470
493
  });
471
494
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TokensController.js","sourceRoot":"","sources":["../src/TokensController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { AddApprovalRequest } from '@metamask/approval-controller';\nimport type {\n BaseConfig,\n BaseState,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport contractsMap from '@metamask/contract-metadata';\nimport {\n toChecksumHexAddress,\n ERC721_INTERFACE_ID,\n ORIGIN_METAMASK,\n ApprovalType,\n ERC20,\n} from '@metamask/controller-utils';\nimport { abiERC721 } from '@metamask/metamask-eth-abis';\nimport type { NetworkState } from '@metamask/network-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\nimport { AbortController as WhatwgAbortController } from 'abort-controller';\nimport { Mutex } from 'async-mutex';\nimport { EventEmitter } from 'events';\nimport { v1 as random } from 'uuid';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport {\n formatAggregatorNames,\n formatIconUrlWithProxy,\n validateTokenToWatch,\n} from './assetsUtil';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from './token-service';\nimport type {\n TokenListMap,\n TokenListState,\n TokenListToken,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\n\n/**\n * @type TokensConfig\n *\n * Tokens controller configuration\n * @property selectedAddress - Vault selected address\n */\nexport interface TokensConfig extends BaseConfig {\n selectedAddress: string;\n chainId: Hex;\n provider: any;\n}\n\n/**\n * @type SuggestedAssetMeta\n *\n * Suggested asset by EIP747 meta data\n * @property id - Generated UUID associated with this suggested asset\n * @property time - Timestamp associated with this this suggested asset\n * @property type - Type type this suggested asset\n * @property asset - Asset suggested object\n * @property interactingAddress - Account address that requested watch asset\n */\ntype SuggestedAssetMeta = {\n id: string;\n time: number;\n type: string;\n asset: Token;\n interactingAddress: string;\n};\n\n/**\n * @type TokensState\n *\n * Assets controller state\n * @property tokens - List of tokens associated with the active network and address pair\n * @property ignoredTokens - List of ignoredTokens associated with the active network and address pair\n * @property detectedTokens - List of detected tokens associated with the active network and address pair\n * @property allTokens - Object containing tokens by network and account\n * @property allIgnoredTokens - Object containing hidden/ignored tokens by network and account\n * @property allDetectedTokens - Object containing tokens detected with non-zero balances\n */\nexport interface TokensState extends BaseState {\n tokens: Token[];\n ignoredTokens: string[];\n detectedTokens: Token[];\n allTokens: { [chainId: Hex]: { [key: string]: Token[] } };\n allIgnoredTokens: { [chainId: Hex]: { [key: string]: string[] } };\n allDetectedTokens: { [chainId: Hex]: { [key: string]: Token[] } };\n}\n\n/**\n * The name of the {@link TokensController}.\n */\nconst controllerName = 'TokensController';\n\n/**\n * The external actions available to the {@link TokensController}.\n */\ntype AllowedActions = AddApprovalRequest;\n\n/**\n * The messenger of the {@link TokensController}.\n */\nexport type TokensControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AllowedActions,\n never,\n AllowedActions['type'],\n never\n>;\n\n/**\n * Controller that stores assets and exposes convenience methods\n */\nexport class TokensController extends BaseController<\n TokensConfig,\n TokensState\n> {\n private readonly mutex = new Mutex();\n\n private ethersProvider: any;\n\n private abortController: WhatwgAbortController;\n\n private readonly messagingSystem: TokensControllerMessenger;\n\n /**\n * Fetch metadata for a token.\n *\n * @param tokenAddress - The address of the token.\n * @returns The token metadata.\n */\n private async fetchTokenMetadata(\n tokenAddress: string,\n ): Promise<TokenListToken | undefined> {\n try {\n const token = await fetchTokenMetadata<TokenListToken>(\n this.config.chainId,\n tokenAddress,\n this.abortController.signal,\n );\n return token;\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * EventEmitter instance used to listen to specific EIP747 events\n */\n hub = new EventEmitter();\n\n /**\n * Name of this controller used during composition\n */\n override name = 'TokensController';\n\n private readonly getERC20TokenName: AssetsContractController['getERC20TokenName'];\n\n /**\n * Creates a TokensController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param options.onTokenListStateChange - Allows subscribing to token list controller state changes.\n * @param options.getERC20TokenName - Gets the ERC-20 token name.\n * @param options.config - Initial options used to configure this controller.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messenger.\n */\n constructor({\n chainId: initialChainId,\n onPreferencesStateChange,\n onNetworkStateChange,\n onTokenListStateChange,\n getERC20TokenName,\n config,\n state,\n messenger,\n }: {\n chainId: Hex;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n onTokenListStateChange: (\n listener: (tokenListState: TokenListState) => void,\n ) => void;\n getERC20TokenName: AssetsContractController['getERC20TokenName'];\n config?: Partial<TokensConfig>;\n state?: Partial<TokensState>;\n messenger: TokensControllerMessenger;\n }) {\n super(config, state);\n\n this.defaultConfig = {\n selectedAddress: '',\n chainId: initialChainId,\n provider: undefined,\n ...config,\n };\n\n this.defaultState = {\n tokens: [],\n ignoredTokens: [],\n detectedTokens: [],\n allTokens: {},\n allIgnoredTokens: {},\n allDetectedTokens: {},\n ...state,\n };\n\n this.initialize();\n this.abortController = new WhatwgAbortController();\n this.getERC20TokenName = getERC20TokenName;\n\n this.messagingSystem = messenger;\n\n onPreferencesStateChange(({ selectedAddress }) => {\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { chainId } = this.config;\n this.configure({ selectedAddress });\n this.update({\n tokens: allTokens[chainId]?.[selectedAddress] || [],\n ignoredTokens: allIgnoredTokens[chainId]?.[selectedAddress] || [],\n detectedTokens: allDetectedTokens[chainId]?.[selectedAddress] || [],\n });\n });\n\n onNetworkStateChange(({ providerConfig }) => {\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { selectedAddress } = this.config;\n const { chainId } = providerConfig;\n this.abortController.abort();\n this.abortController = new WhatwgAbortController();\n this.configure({ chainId });\n this.ethersProvider = this._instantiateNewEthersProvider();\n this.update({\n tokens: allTokens[chainId]?.[selectedAddress] || [],\n ignoredTokens: allIgnoredTokens[chainId]?.[selectedAddress] || [],\n detectedTokens: allDetectedTokens[chainId]?.[selectedAddress] || [],\n });\n });\n\n onTokenListStateChange(({ tokenList }) => {\n const { tokens } = this.state;\n if (tokens.length && !tokens[0].name) {\n this.updateTokensAttribute(tokenList, 'name');\n }\n });\n }\n\n _instantiateNewEthersProvider(): any {\n return new Web3Provider(this.config?.provider);\n }\n\n /**\n * Adds a token to the stored token list.\n *\n * @param address - Hex address of the token contract.\n * @param symbol - Symbol of the token.\n * @param decimals - Number of decimals the token uses.\n * @param options - Object containing name and image of the token\n * @param options.name - Name of the token\n * @param options.image - Image of the token\n * @param options.interactingAddress - The address of the account to add a token to.\n * @returns Current token list.\n */\n async addToken(\n address: string,\n symbol: string,\n decimals: number,\n {\n name,\n image,\n interactingAddress,\n }: { name?: string; image?: string; interactingAddress?: string } = {},\n ): Promise<Token[]> {\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { chainId: currentChainId, selectedAddress } = this.config;\n const accountAddress = interactingAddress || selectedAddress;\n const isInteractingWithWalletAccount = accountAddress === selectedAddress;\n const releaseLock = await this.mutex.acquire();\n\n try {\n address = toChecksumHexAddress(address);\n const tokens = allTokens[currentChainId]?.[accountAddress] || [];\n const ignoredTokens =\n allIgnoredTokens[currentChainId]?.[accountAddress] || [];\n const detectedTokens =\n allDetectedTokens[currentChainId]?.[accountAddress] || [];\n const newTokens: Token[] = [...tokens];\n const [isERC721, tokenMetadata] = await Promise.all([\n this._detectIsERC721(address),\n this.fetchTokenMetadata(address),\n ]);\n if (currentChainId !== this.config.chainId) {\n throw new Error(\n 'TokensController Error: Switched networks while adding token',\n );\n }\n const newEntry: Token = {\n address,\n symbol,\n decimals,\n image:\n image ||\n formatIconUrlWithProxy({\n chainId: this.config.chainId,\n tokenAddress: address,\n }),\n isERC721,\n aggregators: formatAggregatorNames(tokenMetadata?.aggregators || []),\n name,\n };\n const previousEntry = newTokens.find(\n (token) => token.address.toLowerCase() === address.toLowerCase(),\n );\n if (previousEntry) {\n const previousIndex = newTokens.indexOf(previousEntry);\n newTokens[previousIndex] = newEntry;\n } else {\n newTokens.push(newEntry);\n }\n\n const newIgnoredTokens = ignoredTokens.filter(\n (tokenAddress) => tokenAddress.toLowerCase() !== address.toLowerCase(),\n );\n const newDetectedTokens = detectedTokens.filter(\n (token) => token.address.toLowerCase() !== address.toLowerCase(),\n );\n\n const { newAllTokens, newAllIgnoredTokens, newAllDetectedTokens } =\n this._getNewAllTokensState({\n newTokens,\n newIgnoredTokens,\n newDetectedTokens,\n interactingAddress: accountAddress,\n });\n\n let newState: Partial<TokensState> = {\n allTokens: newAllTokens,\n allIgnoredTokens: newAllIgnoredTokens,\n allDetectedTokens: newAllDetectedTokens,\n };\n\n // Only update active tokens if user is interacting with their active wallet account.\n if (isInteractingWithWalletAccount) {\n newState = {\n ...newState,\n tokens: newTokens,\n ignoredTokens: newIgnoredTokens,\n detectedTokens: newDetectedTokens,\n };\n }\n\n this.update(newState);\n return newTokens;\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Add a batch of tokens.\n *\n * @param tokensToImport - Array of tokens to import.\n */\n async addTokens(tokensToImport: Token[]) {\n const releaseLock = await this.mutex.acquire();\n const { tokens, detectedTokens, ignoredTokens } = this.state;\n const importedTokensMap: { [key: string]: true } = {};\n // Used later to dedupe imported tokens\n const newTokensMap = tokens.reduce((output, current) => {\n output[current.address] = current;\n return output;\n }, {} as { [address: string]: Token });\n try {\n tokensToImport.forEach((tokenToAdd) => {\n const { address, symbol, decimals, image, aggregators, name } =\n tokenToAdd;\n const checksumAddress = toChecksumHexAddress(address);\n const formattedToken: Token = {\n address: checksumAddress,\n symbol,\n decimals,\n image,\n aggregators,\n name,\n };\n newTokensMap[address] = formattedToken;\n importedTokensMap[address.toLowerCase()] = true;\n return formattedToken;\n });\n const newTokens = Object.values(newTokensMap);\n\n const newDetectedTokens = detectedTokens.filter(\n (token) => !importedTokensMap[token.address.toLowerCase()],\n );\n const newIgnoredTokens = ignoredTokens.filter(\n (tokenAddress) => !newTokensMap[tokenAddress.toLowerCase()],\n );\n\n const { newAllTokens, newAllDetectedTokens, newAllIgnoredTokens } =\n this._getNewAllTokensState({\n newTokens,\n newDetectedTokens,\n newIgnoredTokens,\n });\n\n this.update({\n tokens: newTokens,\n allTokens: newAllTokens,\n detectedTokens: newDetectedTokens,\n allDetectedTokens: newAllDetectedTokens,\n ignoredTokens: newIgnoredTokens,\n allIgnoredTokens: newAllIgnoredTokens,\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Ignore a batch of tokens.\n *\n * @param tokenAddressesToIgnore - Array of token addresses to ignore.\n */\n ignoreTokens(tokenAddressesToIgnore: string[]) {\n const { ignoredTokens, detectedTokens, tokens } = this.state;\n const ignoredTokensMap: { [key: string]: true } = {};\n let newIgnoredTokens: string[] = [...ignoredTokens];\n\n const checksummedTokenAddresses = tokenAddressesToIgnore.map((address) => {\n const checksumAddress = toChecksumHexAddress(address);\n ignoredTokensMap[address.toLowerCase()] = true;\n return checksumAddress;\n });\n newIgnoredTokens = [...ignoredTokens, ...checksummedTokenAddresses];\n const newDetectedTokens = detectedTokens.filter(\n (token) => !ignoredTokensMap[token.address.toLowerCase()],\n );\n const newTokens = tokens.filter(\n (token) => !ignoredTokensMap[token.address.toLowerCase()],\n );\n\n const { newAllIgnoredTokens, newAllDetectedTokens, newAllTokens } =\n this._getNewAllTokensState({\n newIgnoredTokens,\n newDetectedTokens,\n newTokens,\n });\n\n this.update({\n ignoredTokens: newIgnoredTokens,\n tokens: newTokens,\n detectedTokens: newDetectedTokens,\n allIgnoredTokens: newAllIgnoredTokens,\n allDetectedTokens: newAllDetectedTokens,\n allTokens: newAllTokens,\n });\n }\n\n /**\n * Adds a batch of detected tokens to the stored token list.\n *\n * @param incomingDetectedTokens - Array of detected tokens to be added or updated.\n * @param detectionDetails - An object containing the chain ID and address of the currently selected network on which the incomingDetectedTokens were detected.\n * @param detectionDetails.selectedAddress - the account address on which the incomingDetectedTokens were detected.\n * @param detectionDetails.chainId - the chainId on which the incomingDetectedTokens were detected.\n */\n async addDetectedTokens(\n incomingDetectedTokens: Token[],\n detectionDetails?: { selectedAddress: string; chainId: Hex },\n ) {\n const releaseLock = await this.mutex.acquire();\n const { tokens, detectedTokens, ignoredTokens } = this.state;\n const newTokens: Token[] = [...tokens];\n let newDetectedTokens: Token[] = [...detectedTokens];\n\n try {\n incomingDetectedTokens.forEach((tokenToAdd) => {\n const {\n address,\n symbol,\n decimals,\n image,\n aggregators,\n isERC721,\n name,\n } = tokenToAdd;\n const checksumAddress = toChecksumHexAddress(address);\n const newEntry: Token = {\n address: checksumAddress,\n symbol,\n decimals,\n image,\n isERC721,\n aggregators,\n name,\n };\n const previousImportedEntry = newTokens.find(\n (token) =>\n token.address.toLowerCase() === checksumAddress.toLowerCase(),\n );\n if (previousImportedEntry) {\n // Update existing data of imported token\n const previousImportedIndex = newTokens.indexOf(\n previousImportedEntry,\n );\n newTokens[previousImportedIndex] = newEntry;\n } else {\n const ignoredTokenIndex = ignoredTokens.indexOf(address);\n if (ignoredTokenIndex === -1) {\n // Add detected token\n const previousDetectedEntry = newDetectedTokens.find(\n (token) =>\n token.address.toLowerCase() === checksumAddress.toLowerCase(),\n );\n if (previousDetectedEntry) {\n const previousDetectedIndex = newDetectedTokens.indexOf(\n previousDetectedEntry,\n );\n newDetectedTokens[previousDetectedIndex] = newEntry;\n } else {\n newDetectedTokens.push(newEntry);\n }\n }\n }\n });\n\n const {\n selectedAddress: interactingAddress,\n chainId: interactingChainId,\n } = detectionDetails || {};\n\n const { newAllTokens, newAllDetectedTokens } = this._getNewAllTokensState(\n {\n newTokens,\n newDetectedTokens,\n interactingAddress,\n interactingChainId,\n },\n );\n\n const { chainId, selectedAddress } = this.config;\n // if the newly added detectedTokens were detected on (and therefore added to) a different chainId/selectedAddress than the currently configured combo\n // the newDetectedTokens (which should contain the detectedTokens on the current chainId/address combo) needs to be repointed to the current chainId/address pair\n // if the detectedTokens were detected on the current chainId/address then this won't change anything.\n newDetectedTokens =\n newAllDetectedTokens?.[chainId]?.[selectedAddress] || [];\n\n this.update({\n tokens: newTokens,\n allTokens: newAllTokens,\n detectedTokens: newDetectedTokens,\n allDetectedTokens: newAllDetectedTokens,\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Adds isERC721 field to token object. This is called when a user attempts to add tokens that\n * were previously added which do not yet had isERC721 field.\n *\n * @param tokenAddress - The contract address of the token requiring the isERC721 field added.\n * @returns The new token object with the added isERC721 field.\n */\n async updateTokenType(tokenAddress: string) {\n const isERC721 = await this._detectIsERC721(tokenAddress);\n const { tokens } = this.state;\n const tokenIndex = tokens.findIndex((token) => {\n return token.address.toLowerCase() === tokenAddress.toLowerCase();\n });\n tokens[tokenIndex].isERC721 = isERC721;\n this.update({ tokens });\n return tokens[tokenIndex];\n }\n\n /**\n * This is a function that updates the tokens name for the tokens name if it is not defined.\n *\n * @param tokenList - Represents the fetched token list from service API\n * @param tokenAttribute - Represents the token attribute that we want to update on the token list\n */\n private updateTokensAttribute(\n tokenList: TokenListMap,\n tokenAttribute: keyof Token & keyof TokenListToken,\n ) {\n const { tokens } = this.state;\n\n const newTokens = tokens.map((token) => {\n const newToken = tokenList[token.address.toLowerCase()];\n\n return !token[tokenAttribute] && newToken?.[tokenAttribute]\n ? { ...token, [tokenAttribute]: newToken[tokenAttribute] }\n : { ...token };\n });\n\n this.update({ tokens: newTokens });\n }\n\n /**\n * Detects whether or not a token is ERC-721 compatible.\n *\n * @param tokenAddress - The token contract address.\n * @returns A boolean indicating whether the token address passed in supports the EIP-721\n * interface.\n */\n async _detectIsERC721(tokenAddress: string) {\n const checksumAddress = toChecksumHexAddress(tokenAddress);\n // if this token is already in our contract metadata map we don't need\n // to check against the contract\n if (contractsMap[checksumAddress]?.erc721 === true) {\n return Promise.resolve(true);\n } else if (contractsMap[checksumAddress]?.erc20 === true) {\n return Promise.resolve(false);\n }\n\n const tokenContract = this._createEthersContract(\n tokenAddress,\n abiERC721,\n this.ethersProvider,\n );\n try {\n return await tokenContract.supportsInterface(ERC721_INTERFACE_ID);\n } catch (error: any) {\n // currently we see a variety of errors across different networks when\n // token contracts are not ERC721 compatible. We need to figure out a better\n // way of differentiating token interface types but for now if we get an error\n // we have to assume the token is not ERC721 compatible.\n return false;\n }\n }\n\n _createEthersContract(\n tokenAddress: string,\n abi: string,\n ethersProvider: any,\n ): Contract {\n const tokenContract = new Contract(tokenAddress, abi, ethersProvider);\n return tokenContract;\n }\n\n _generateRandomId(): string {\n return random();\n }\n\n /**\n * Adds a new suggestedAsset to the list of watched assets.\n * Parameters will be validated according to the asset type being watched.\n *\n * @param asset - The asset to be watched. For now only ERC20 tokens are accepted.\n * @param type - The asset type.\n * @param interactingAddress - The address of the account that is requesting to watch the asset.\n * @returns Object containing a Promise resolving to the suggestedAsset address if accepted.\n */\n async watchAsset(\n asset: Token,\n type: string,\n interactingAddress?: string,\n ): Promise<void> {\n if (type !== ERC20) {\n throw new Error(`Asset of type ${type} not supported`);\n }\n\n const { selectedAddress } = this.config;\n\n const suggestedAssetMeta: SuggestedAssetMeta = {\n asset,\n id: this._generateRandomId(),\n time: Date.now(),\n type,\n interactingAddress: interactingAddress || selectedAddress,\n };\n\n validateTokenToWatch(asset);\n\n await this._requestApproval(suggestedAssetMeta);\n\n let name;\n try {\n name = await this.getERC20TokenName(asset.address);\n } catch (error) {\n name = undefined;\n }\n\n await this.addToken(asset.address, asset.symbol, asset.decimals, {\n name,\n image: asset.image,\n interactingAddress: suggestedAssetMeta.interactingAddress,\n });\n }\n\n /**\n * Takes a new tokens and ignoredTokens array for the current network/account combination\n * and returns new allTokens and allIgnoredTokens state to update to.\n *\n * @param params - Object that holds token params.\n * @param params.newTokens - The new tokens to set for the current network and selected account.\n * @param params.newIgnoredTokens - The new ignored tokens to set for the current network and selected account.\n * @param params.newDetectedTokens - The new detected tokens to set for the current network and selected account.\n * @param params.interactingAddress - The account address to use to store the tokens.\n * @param params.interactingChainId - The chainId to use to store the tokens.\n * @returns The updated `allTokens` and `allIgnoredTokens` state.\n */\n _getNewAllTokensState(params: {\n newTokens?: Token[];\n newIgnoredTokens?: string[];\n newDetectedTokens?: Token[];\n interactingAddress?: string;\n interactingChainId?: Hex;\n }) {\n const {\n newTokens,\n newIgnoredTokens,\n newDetectedTokens,\n interactingAddress,\n interactingChainId,\n } = params;\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { chainId, selectedAddress } = this.config;\n\n const userAddressToAddTokens = interactingAddress ?? selectedAddress;\n const chainIdToAddTokens = interactingChainId ?? chainId;\n\n let newAllTokens = allTokens;\n if (\n newTokens?.length ||\n (newTokens &&\n allTokens &&\n allTokens[chainIdToAddTokens] &&\n allTokens[chainIdToAddTokens][userAddressToAddTokens])\n ) {\n const networkTokens = allTokens[chainIdToAddTokens];\n const newNetworkTokens = {\n ...networkTokens,\n ...{ [userAddressToAddTokens]: newTokens },\n };\n newAllTokens = {\n ...allTokens,\n ...{ [chainIdToAddTokens]: newNetworkTokens },\n };\n }\n\n let newAllIgnoredTokens = allIgnoredTokens;\n if (\n newIgnoredTokens?.length ||\n (newIgnoredTokens &&\n allIgnoredTokens &&\n allIgnoredTokens[chainIdToAddTokens] &&\n allIgnoredTokens[chainIdToAddTokens][userAddressToAddTokens])\n ) {\n const networkIgnoredTokens = allIgnoredTokens[chainIdToAddTokens];\n const newIgnoredNetworkTokens = {\n ...networkIgnoredTokens,\n ...{ [userAddressToAddTokens]: newIgnoredTokens },\n };\n newAllIgnoredTokens = {\n ...allIgnoredTokens,\n ...{ [chainIdToAddTokens]: newIgnoredNetworkTokens },\n };\n }\n\n let newAllDetectedTokens = allDetectedTokens;\n if (\n newDetectedTokens?.length ||\n (newDetectedTokens &&\n allDetectedTokens &&\n allDetectedTokens[chainIdToAddTokens] &&\n allDetectedTokens[chainIdToAddTokens][userAddressToAddTokens])\n ) {\n const networkDetectedTokens = allDetectedTokens[chainIdToAddTokens];\n const newDetectedNetworkTokens = {\n ...networkDetectedTokens,\n ...{ [userAddressToAddTokens]: newDetectedTokens },\n };\n newAllDetectedTokens = {\n ...allDetectedTokens,\n ...{ [chainIdToAddTokens]: newDetectedNetworkTokens },\n };\n }\n return { newAllTokens, newAllIgnoredTokens, newAllDetectedTokens };\n }\n\n /**\n * Removes all tokens from the ignored list.\n */\n clearIgnoredTokens() {\n this.update({ ignoredTokens: [], allIgnoredTokens: {} });\n }\n\n async _requestApproval(suggestedAssetMeta: SuggestedAssetMeta) {\n return this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n id: suggestedAssetMeta.id,\n origin: ORIGIN_METAMASK,\n type: ApprovalType.WatchAsset,\n requestData: {\n id: suggestedAssetMeta.id,\n interactingAddress: suggestedAssetMeta.interactingAddress,\n asset: {\n address: suggestedAssetMeta.asset.address,\n decimals: suggestedAssetMeta.asset.decimals,\n symbol: suggestedAssetMeta.asset.symbol,\n image: suggestedAssetMeta.asset.image || null,\n },\n },\n },\n true,\n );\n }\n}\n\nexport default TokensController;\n"]}
1
+ {"version":3,"file":"TokensController.js","sourceRoot":"","sources":["../src/TokensController.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport { Web3Provider } from '@ethersproject/providers';\nimport type { AddApprovalRequest } from '@metamask/approval-controller';\nimport type {\n BaseConfig,\n BaseState,\n RestrictedControllerMessenger,\n} from '@metamask/base-controller';\nimport { BaseController } from '@metamask/base-controller';\nimport contractsMap from '@metamask/contract-metadata';\nimport {\n toChecksumHexAddress,\n ERC721_INTERFACE_ID,\n ORIGIN_METAMASK,\n ApprovalType,\n ERC20,\n} from '@metamask/controller-utils';\nimport { abiERC721 } from '@metamask/metamask-eth-abis';\nimport type {\n NetworkClientId,\n NetworkController,\n NetworkState,\n} from '@metamask/network-controller';\nimport type { PreferencesState } from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\nimport { Mutex } from 'async-mutex';\nimport { EventEmitter } from 'events';\nimport { v1 as random } from 'uuid';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport {\n formatAggregatorNames,\n formatIconUrlWithProxy,\n validateTokenToWatch,\n} from './assetsUtil';\nimport {\n fetchTokenMetadata,\n TOKEN_METADATA_NO_SUPPORT_ERROR,\n} from './token-service';\nimport type {\n TokenListMap,\n TokenListState,\n TokenListToken,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\n\n/**\n * @type TokensConfig\n *\n * Tokens controller configuration\n * @property selectedAddress - Vault selected address\n */\nexport interface TokensConfig extends BaseConfig {\n selectedAddress: string;\n chainId: Hex;\n provider: any;\n}\n\n/**\n * @type SuggestedAssetMeta\n *\n * Suggested asset by EIP747 meta data\n * @property id - Generated UUID associated with this suggested asset\n * @property time - Timestamp associated with this this suggested asset\n * @property type - Type type this suggested asset\n * @property asset - Asset suggested object\n * @property interactingAddress - Account address that requested watch asset\n */\ntype SuggestedAssetMeta = {\n id: string;\n time: number;\n type: string;\n asset: Token;\n interactingAddress: string;\n};\n\n/**\n * @type TokensState\n *\n * Assets controller state\n * @property tokens - List of tokens associated with the active network and address pair\n * @property ignoredTokens - List of ignoredTokens associated with the active network and address pair\n * @property detectedTokens - List of detected tokens associated with the active network and address pair\n * @property allTokens - Object containing tokens by network and account\n * @property allIgnoredTokens - Object containing hidden/ignored tokens by network and account\n * @property allDetectedTokens - Object containing tokens detected with non-zero balances\n */\nexport interface TokensState extends BaseState {\n tokens: Token[];\n ignoredTokens: string[];\n detectedTokens: Token[];\n allTokens: { [chainId: Hex]: { [key: string]: Token[] } };\n allIgnoredTokens: { [chainId: Hex]: { [key: string]: string[] } };\n allDetectedTokens: { [chainId: Hex]: { [key: string]: Token[] } };\n}\n\n/**\n * The name of the {@link TokensController}.\n */\nconst controllerName = 'TokensController';\n\n/**\n * The external actions available to the {@link TokensController}.\n */\ntype AllowedActions = AddApprovalRequest;\n\n/**\n * The messenger of the {@link TokensController}.\n */\nexport type TokensControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n AllowedActions,\n never,\n AllowedActions['type'],\n never\n>;\n\n/**\n * Controller that stores assets and exposes convenience methods\n */\nexport class TokensController extends BaseController<\n TokensConfig,\n TokensState\n> {\n private readonly mutex = new Mutex();\n\n private abortController: AbortController;\n\n private readonly messagingSystem: TokensControllerMessenger;\n\n /**\n * Fetch metadata for a token.\n *\n * @param tokenAddress - The address of the token.\n * @returns The token metadata.\n */\n private async fetchTokenMetadata(\n tokenAddress: string,\n ): Promise<TokenListToken | undefined> {\n try {\n const token = await fetchTokenMetadata<TokenListToken>(\n this.config.chainId,\n tokenAddress,\n this.abortController.signal,\n );\n return token;\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(TOKEN_METADATA_NO_SUPPORT_ERROR)\n ) {\n return undefined;\n }\n throw error;\n }\n }\n\n /**\n * EventEmitter instance used to listen to specific EIP747 events\n */\n hub = new EventEmitter();\n\n /**\n * Name of this controller used during composition\n */\n override name = 'TokensController';\n\n private readonly getERC20TokenName: AssetsContractController['getERC20TokenName'];\n\n private readonly getNetworkClientById: NetworkController['getNetworkClientById'];\n\n /**\n * Creates a TokensController instance.\n *\n * @param options - The controller options.\n * @param options.chainId - The chain ID of the current network.\n * @param options.onPreferencesStateChange - Allows subscribing to preference controller state changes.\n * @param options.onNetworkStateChange - Allows subscribing to network controller state changes.\n * @param options.onTokenListStateChange - Allows subscribing to token list controller state changes.\n * @param options.getERC20TokenName - Gets the ERC-20 token name.\n * @param options.getNetworkClientById - Gets the network client with the given id from the NetworkController.\n * @param options.config - Initial options used to configure this controller.\n * @param options.state - Initial state to set on this controller.\n * @param options.messenger - The controller messenger.\n */\n constructor({\n chainId: initialChainId,\n onPreferencesStateChange,\n onNetworkStateChange,\n onTokenListStateChange,\n getERC20TokenName,\n getNetworkClientById,\n config,\n state,\n messenger,\n }: {\n chainId: Hex;\n onPreferencesStateChange: (\n listener: (preferencesState: PreferencesState) => void,\n ) => void;\n onNetworkStateChange: (\n listener: (networkState: NetworkState) => void,\n ) => void;\n onTokenListStateChange: (\n listener: (tokenListState: TokenListState) => void,\n ) => void;\n getERC20TokenName: AssetsContractController['getERC20TokenName'];\n getNetworkClientById: NetworkController['getNetworkClientById'];\n config?: Partial<TokensConfig>;\n state?: Partial<TokensState>;\n messenger: TokensControllerMessenger;\n }) {\n super(config, state);\n\n this.defaultConfig = {\n selectedAddress: '',\n chainId: initialChainId,\n provider: undefined,\n ...config,\n };\n\n this.defaultState = {\n tokens: [],\n ignoredTokens: [],\n detectedTokens: [],\n allTokens: {},\n allIgnoredTokens: {},\n allDetectedTokens: {},\n ...state,\n };\n\n this.initialize();\n this.abortController = new AbortController();\n this.getERC20TokenName = getERC20TokenName;\n this.getNetworkClientById = getNetworkClientById;\n\n this.messagingSystem = messenger;\n\n onPreferencesStateChange(({ selectedAddress }) => {\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { chainId } = this.config;\n this.configure({ selectedAddress });\n this.update({\n tokens: allTokens[chainId]?.[selectedAddress] || [],\n ignoredTokens: allIgnoredTokens[chainId]?.[selectedAddress] || [],\n detectedTokens: allDetectedTokens[chainId]?.[selectedAddress] || [],\n });\n });\n\n onNetworkStateChange(({ providerConfig }) => {\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { selectedAddress } = this.config;\n const { chainId } = providerConfig;\n this.abortController.abort();\n this.abortController = new AbortController();\n this.configure({ chainId });\n this.update({\n tokens: allTokens[chainId]?.[selectedAddress] || [],\n ignoredTokens: allIgnoredTokens[chainId]?.[selectedAddress] || [],\n detectedTokens: allDetectedTokens[chainId]?.[selectedAddress] || [],\n });\n });\n\n onTokenListStateChange(({ tokenList }) => {\n const { tokens } = this.state;\n if (tokens.length && !tokens[0].name) {\n this.updateTokensAttribute(tokenList, 'name');\n }\n });\n }\n\n /**\n * Adds a token to the stored token list.\n *\n * @param options - The method argument object.\n * @param options.address - Hex address of the token contract.\n * @param options.symbol - Symbol of the token.\n * @param options.decimals - Number of decimals the token uses.\n * @param options.name - Name of the token.\n * @param options.image - Image of the token.\n * @param options.interactingAddress - The address of the account to add a token to.\n * @param options.networkClientId - Network Client ID.\n * @returns Current token list.\n */\n async addToken({\n address,\n symbol,\n decimals,\n name,\n image,\n interactingAddress,\n networkClientId,\n }: {\n address: string;\n symbol: string;\n decimals: number;\n name?: string;\n image?: string;\n interactingAddress?: string;\n networkClientId?: NetworkClientId;\n }): Promise<Token[]> {\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { chainId, selectedAddress } = this.config;\n let currentChainId = chainId;\n if (networkClientId) {\n currentChainId =\n this.getNetworkClientById(networkClientId).configuration.chainId;\n }\n\n const accountAddress = interactingAddress || selectedAddress;\n const isInteractingWithWalletAccount = accountAddress === selectedAddress;\n const releaseLock = await this.mutex.acquire();\n\n try {\n address = toChecksumHexAddress(address);\n const tokens = allTokens[currentChainId]?.[accountAddress] || [];\n const ignoredTokens =\n allIgnoredTokens[currentChainId]?.[accountAddress] || [];\n const detectedTokens =\n allDetectedTokens[currentChainId]?.[accountAddress] || [];\n const newTokens: Token[] = [...tokens];\n const [isERC721, tokenMetadata] = await Promise.all([\n this._detectIsERC721(address, networkClientId),\n this.fetchTokenMetadata(address),\n ]);\n if (!networkClientId && currentChainId !== this.config.chainId) {\n throw new Error(\n 'TokensController Error: Switched networks while adding token',\n );\n }\n const newEntry: Token = {\n address,\n symbol,\n decimals,\n image:\n image ||\n formatIconUrlWithProxy({\n chainId: currentChainId,\n tokenAddress: address,\n }),\n isERC721,\n aggregators: formatAggregatorNames(tokenMetadata?.aggregators || []),\n name,\n };\n const previousEntry = newTokens.find(\n (token) => token.address.toLowerCase() === address.toLowerCase(),\n );\n if (previousEntry) {\n const previousIndex = newTokens.indexOf(previousEntry);\n newTokens[previousIndex] = newEntry;\n } else {\n newTokens.push(newEntry);\n }\n\n const newIgnoredTokens = ignoredTokens.filter(\n (tokenAddress) => tokenAddress.toLowerCase() !== address.toLowerCase(),\n );\n const newDetectedTokens = detectedTokens.filter(\n (token) => token.address.toLowerCase() !== address.toLowerCase(),\n );\n\n const { newAllTokens, newAllIgnoredTokens, newAllDetectedTokens } =\n this._getNewAllTokensState({\n newTokens,\n newIgnoredTokens,\n newDetectedTokens,\n interactingAddress: accountAddress,\n interactingChainId: currentChainId,\n });\n\n let newState: Partial<TokensState> = {\n allTokens: newAllTokens,\n allIgnoredTokens: newAllIgnoredTokens,\n allDetectedTokens: newAllDetectedTokens,\n };\n\n // Only update active tokens if user is interacting with their active wallet account.\n if (isInteractingWithWalletAccount) {\n newState = {\n ...newState,\n tokens: newTokens,\n ignoredTokens: newIgnoredTokens,\n detectedTokens: newDetectedTokens,\n };\n }\n\n this.update(newState);\n return newTokens;\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Add a batch of tokens.\n *\n * @param tokensToImport - Array of tokens to import.\n * @param networkClientId - Optional network client ID used to determine interacting chain ID.\n */\n async addTokens(tokensToImport: Token[], networkClientId?: NetworkClientId) {\n const releaseLock = await this.mutex.acquire();\n const { tokens, detectedTokens, ignoredTokens } = this.state;\n const importedTokensMap: { [key: string]: true } = {};\n // Used later to dedupe imported tokens\n const newTokensMap = tokens.reduce((output, current) => {\n output[current.address] = current;\n return output;\n }, {} as { [address: string]: Token });\n try {\n tokensToImport.forEach((tokenToAdd) => {\n const { address, symbol, decimals, image, aggregators, name } =\n tokenToAdd;\n const checksumAddress = toChecksumHexAddress(address);\n const formattedToken: Token = {\n address: checksumAddress,\n symbol,\n decimals,\n image,\n aggregators,\n name,\n };\n newTokensMap[address] = formattedToken;\n importedTokensMap[address.toLowerCase()] = true;\n return formattedToken;\n });\n const newTokens = Object.values(newTokensMap);\n\n const newDetectedTokens = detectedTokens.filter(\n (token) => !importedTokensMap[token.address.toLowerCase()],\n );\n const newIgnoredTokens = ignoredTokens.filter(\n (tokenAddress) => !newTokensMap[tokenAddress.toLowerCase()],\n );\n\n let interactingChainId;\n if (networkClientId) {\n interactingChainId =\n this.getNetworkClientById(networkClientId).configuration.chainId;\n }\n\n const { newAllTokens, newAllDetectedTokens, newAllIgnoredTokens } =\n this._getNewAllTokensState({\n newTokens,\n newDetectedTokens,\n newIgnoredTokens,\n interactingChainId,\n });\n\n this.update({\n tokens: newTokens,\n allTokens: newAllTokens,\n detectedTokens: newDetectedTokens,\n allDetectedTokens: newAllDetectedTokens,\n ignoredTokens: newIgnoredTokens,\n allIgnoredTokens: newAllIgnoredTokens,\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Ignore a batch of tokens.\n *\n * @param tokenAddressesToIgnore - Array of token addresses to ignore.\n */\n ignoreTokens(tokenAddressesToIgnore: string[]) {\n const { ignoredTokens, detectedTokens, tokens } = this.state;\n const ignoredTokensMap: { [key: string]: true } = {};\n let newIgnoredTokens: string[] = [...ignoredTokens];\n\n const checksummedTokenAddresses = tokenAddressesToIgnore.map((address) => {\n const checksumAddress = toChecksumHexAddress(address);\n ignoredTokensMap[address.toLowerCase()] = true;\n return checksumAddress;\n });\n newIgnoredTokens = [...ignoredTokens, ...checksummedTokenAddresses];\n const newDetectedTokens = detectedTokens.filter(\n (token) => !ignoredTokensMap[token.address.toLowerCase()],\n );\n const newTokens = tokens.filter(\n (token) => !ignoredTokensMap[token.address.toLowerCase()],\n );\n\n const { newAllIgnoredTokens, newAllDetectedTokens, newAllTokens } =\n this._getNewAllTokensState({\n newIgnoredTokens,\n newDetectedTokens,\n newTokens,\n });\n\n this.update({\n ignoredTokens: newIgnoredTokens,\n tokens: newTokens,\n detectedTokens: newDetectedTokens,\n allIgnoredTokens: newAllIgnoredTokens,\n allDetectedTokens: newAllDetectedTokens,\n allTokens: newAllTokens,\n });\n }\n\n /**\n * Adds a batch of detected tokens to the stored token list.\n *\n * @param incomingDetectedTokens - Array of detected tokens to be added or updated.\n * @param detectionDetails - An object containing the chain ID and address of the currently selected network on which the incomingDetectedTokens were detected.\n * @param detectionDetails.selectedAddress - the account address on which the incomingDetectedTokens were detected.\n * @param detectionDetails.chainId - the chainId on which the incomingDetectedTokens were detected.\n */\n async addDetectedTokens(\n incomingDetectedTokens: Token[],\n detectionDetails?: { selectedAddress: string; chainId: Hex },\n ) {\n const releaseLock = await this.mutex.acquire();\n const { tokens, detectedTokens, ignoredTokens } = this.state;\n const newTokens: Token[] = [...tokens];\n let newDetectedTokens: Token[] = [...detectedTokens];\n\n try {\n incomingDetectedTokens.forEach((tokenToAdd) => {\n const {\n address,\n symbol,\n decimals,\n image,\n aggregators,\n isERC721,\n name,\n } = tokenToAdd;\n const checksumAddress = toChecksumHexAddress(address);\n const newEntry: Token = {\n address: checksumAddress,\n symbol,\n decimals,\n image,\n isERC721,\n aggregators,\n name,\n };\n const previousImportedEntry = newTokens.find(\n (token) =>\n token.address.toLowerCase() === checksumAddress.toLowerCase(),\n );\n if (previousImportedEntry) {\n // Update existing data of imported token\n const previousImportedIndex = newTokens.indexOf(\n previousImportedEntry,\n );\n newTokens[previousImportedIndex] = newEntry;\n } else {\n const ignoredTokenIndex = ignoredTokens.indexOf(address);\n if (ignoredTokenIndex === -1) {\n // Add detected token\n const previousDetectedEntry = newDetectedTokens.find(\n (token) =>\n token.address.toLowerCase() === checksumAddress.toLowerCase(),\n );\n if (previousDetectedEntry) {\n const previousDetectedIndex = newDetectedTokens.indexOf(\n previousDetectedEntry,\n );\n newDetectedTokens[previousDetectedIndex] = newEntry;\n } else {\n newDetectedTokens.push(newEntry);\n }\n }\n }\n });\n\n const {\n selectedAddress: interactingAddress,\n chainId: interactingChainId,\n } = detectionDetails || {};\n\n const { newAllTokens, newAllDetectedTokens } = this._getNewAllTokensState(\n {\n newTokens,\n newDetectedTokens,\n interactingAddress,\n interactingChainId,\n },\n );\n\n const { chainId, selectedAddress } = this.config;\n // if the newly added detectedTokens were detected on (and therefore added to) a different chainId/selectedAddress than the currently configured combo\n // the newDetectedTokens (which should contain the detectedTokens on the current chainId/address combo) needs to be repointed to the current chainId/address pair\n // if the detectedTokens were detected on the current chainId/address then this won't change anything.\n newDetectedTokens =\n newAllDetectedTokens?.[chainId]?.[selectedAddress] || [];\n\n this.update({\n tokens: newTokens,\n allTokens: newAllTokens,\n detectedTokens: newDetectedTokens,\n allDetectedTokens: newAllDetectedTokens,\n });\n } finally {\n releaseLock();\n }\n }\n\n /**\n * Adds isERC721 field to token object. This is called when a user attempts to add tokens that\n * were previously added which do not yet had isERC721 field.\n *\n * @param tokenAddress - The contract address of the token requiring the isERC721 field added.\n * @returns The new token object with the added isERC721 field.\n */\n async updateTokenType(tokenAddress: string) {\n const isERC721 = await this._detectIsERC721(tokenAddress);\n const { tokens } = this.state;\n const tokenIndex = tokens.findIndex((token) => {\n return token.address.toLowerCase() === tokenAddress.toLowerCase();\n });\n tokens[tokenIndex].isERC721 = isERC721;\n this.update({ tokens });\n return tokens[tokenIndex];\n }\n\n /**\n * This is a function that updates the tokens name for the tokens name if it is not defined.\n *\n * @param tokenList - Represents the fetched token list from service API\n * @param tokenAttribute - Represents the token attribute that we want to update on the token list\n */\n private updateTokensAttribute(\n tokenList: TokenListMap,\n tokenAttribute: keyof Token & keyof TokenListToken,\n ) {\n const { tokens } = this.state;\n\n const newTokens = tokens.map((token) => {\n const newToken = tokenList[token.address.toLowerCase()];\n\n return !token[tokenAttribute] && newToken?.[tokenAttribute]\n ? { ...token, [tokenAttribute]: newToken[tokenAttribute] }\n : { ...token };\n });\n\n this.update({ tokens: newTokens });\n }\n\n /**\n * Detects whether or not a token is ERC-721 compatible.\n *\n * @param tokenAddress - The token contract address.\n * @param networkClientId - Optional network client ID to fetch contract info with.\n * @returns A boolean indicating whether the token address passed in supports the EIP-721\n * interface.\n */\n async _detectIsERC721(\n tokenAddress: string,\n networkClientId?: NetworkClientId,\n ) {\n const checksumAddress = toChecksumHexAddress(tokenAddress);\n // if this token is already in our contract metadata map we don't need\n // to check against the contract\n if (contractsMap[checksumAddress]?.erc721 === true) {\n return Promise.resolve(true);\n } else if (contractsMap[checksumAddress]?.erc20 === true) {\n return Promise.resolve(false);\n }\n\n const tokenContract = this._createEthersContract(\n tokenAddress,\n abiERC721,\n networkClientId,\n );\n try {\n return await tokenContract.supportsInterface(ERC721_INTERFACE_ID);\n } catch (error: any) {\n // currently we see a variety of errors across different networks when\n // token contracts are not ERC721 compatible. We need to figure out a better\n // way of differentiating token interface types but for now if we get an error\n // we have to assume the token is not ERC721 compatible.\n return false;\n }\n }\n\n _createEthersContract(\n tokenAddress: string,\n abi: string,\n networkClientId?: NetworkClientId,\n ): Contract {\n const provider = networkClientId\n ? this.getNetworkClientById(networkClientId).provider\n : this.config?.provider;\n\n const web3provider = new Web3Provider(provider);\n const tokenContract = new Contract(tokenAddress, abi, web3provider);\n return tokenContract;\n }\n\n _generateRandomId(): string {\n return random();\n }\n\n /**\n * Adds a new suggestedAsset to the list of watched assets.\n * Parameters will be validated according to the asset type being watched.\n *\n * @param options - The method options.\n * @param options.asset - The asset to be watched. For now only ERC20 tokens are accepted.\n * @param options.type - The asset type.\n * @param options.interactingAddress - The address of the account that is requesting to watch the asset.\n * @param options.networkClientId - Network Client ID.\n * @returns Object containing a Promise resolving to the suggestedAsset address if accepted.\n */\n async watchAsset({\n asset,\n type,\n interactingAddress,\n networkClientId,\n }: {\n asset: Token;\n type: string;\n interactingAddress?: string;\n networkClientId?: NetworkClientId;\n }): Promise<void> {\n if (type !== ERC20) {\n throw new Error(`Asset of type ${type} not supported`);\n }\n\n const { selectedAddress } = this.config;\n\n const suggestedAssetMeta: SuggestedAssetMeta = {\n asset,\n id: this._generateRandomId(),\n time: Date.now(),\n type,\n interactingAddress: interactingAddress || selectedAddress,\n };\n\n validateTokenToWatch(asset);\n\n await this._requestApproval(suggestedAssetMeta);\n\n let name;\n try {\n name = await this.getERC20TokenName(asset.address, networkClientId);\n } catch (error) {\n name = undefined;\n }\n\n const { address, symbol, decimals, image } = asset;\n await this.addToken({\n address,\n symbol,\n decimals,\n name,\n image,\n interactingAddress: suggestedAssetMeta.interactingAddress,\n networkClientId,\n });\n }\n\n /**\n * Takes a new tokens and ignoredTokens array for the current network/account combination\n * and returns new allTokens and allIgnoredTokens state to update to.\n *\n * @param params - Object that holds token params.\n * @param params.newTokens - The new tokens to set for the current network and selected account.\n * @param params.newIgnoredTokens - The new ignored tokens to set for the current network and selected account.\n * @param params.newDetectedTokens - The new detected tokens to set for the current network and selected account.\n * @param params.interactingAddress - The account address to use to store the tokens.\n * @param params.interactingChainId - The chainId to use to store the tokens.\n * @returns The updated `allTokens` and `allIgnoredTokens` state.\n */\n _getNewAllTokensState(params: {\n newTokens?: Token[];\n newIgnoredTokens?: string[];\n newDetectedTokens?: Token[];\n interactingAddress?: string;\n interactingChainId?: Hex;\n }) {\n const {\n newTokens,\n newIgnoredTokens,\n newDetectedTokens,\n interactingAddress,\n interactingChainId,\n } = params;\n const { allTokens, allIgnoredTokens, allDetectedTokens } = this.state;\n const { chainId, selectedAddress } = this.config;\n\n const userAddressToAddTokens = interactingAddress ?? selectedAddress;\n const chainIdToAddTokens = interactingChainId ?? chainId;\n\n let newAllTokens = allTokens;\n if (\n newTokens?.length ||\n (newTokens &&\n allTokens &&\n allTokens[chainIdToAddTokens] &&\n allTokens[chainIdToAddTokens][userAddressToAddTokens])\n ) {\n const networkTokens = allTokens[chainIdToAddTokens];\n const newNetworkTokens = {\n ...networkTokens,\n ...{ [userAddressToAddTokens]: newTokens },\n };\n newAllTokens = {\n ...allTokens,\n ...{ [chainIdToAddTokens]: newNetworkTokens },\n };\n }\n\n let newAllIgnoredTokens = allIgnoredTokens;\n if (\n newIgnoredTokens?.length ||\n (newIgnoredTokens &&\n allIgnoredTokens &&\n allIgnoredTokens[chainIdToAddTokens] &&\n allIgnoredTokens[chainIdToAddTokens][userAddressToAddTokens])\n ) {\n const networkIgnoredTokens = allIgnoredTokens[chainIdToAddTokens];\n const newIgnoredNetworkTokens = {\n ...networkIgnoredTokens,\n ...{ [userAddressToAddTokens]: newIgnoredTokens },\n };\n newAllIgnoredTokens = {\n ...allIgnoredTokens,\n ...{ [chainIdToAddTokens]: newIgnoredNetworkTokens },\n };\n }\n\n let newAllDetectedTokens = allDetectedTokens;\n if (\n newDetectedTokens?.length ||\n (newDetectedTokens &&\n allDetectedTokens &&\n allDetectedTokens[chainIdToAddTokens] &&\n allDetectedTokens[chainIdToAddTokens][userAddressToAddTokens])\n ) {\n const networkDetectedTokens = allDetectedTokens[chainIdToAddTokens];\n const newDetectedNetworkTokens = {\n ...networkDetectedTokens,\n ...{ [userAddressToAddTokens]: newDetectedTokens },\n };\n newAllDetectedTokens = {\n ...allDetectedTokens,\n ...{ [chainIdToAddTokens]: newDetectedNetworkTokens },\n };\n }\n return { newAllTokens, newAllIgnoredTokens, newAllDetectedTokens };\n }\n\n /**\n * Removes all tokens from the ignored list.\n */\n clearIgnoredTokens() {\n this.update({ ignoredTokens: [], allIgnoredTokens: {} });\n }\n\n async _requestApproval(suggestedAssetMeta: SuggestedAssetMeta) {\n return this.messagingSystem.call(\n 'ApprovalController:addRequest',\n {\n id: suggestedAssetMeta.id,\n origin: ORIGIN_METAMASK,\n type: ApprovalType.WatchAsset,\n requestData: {\n id: suggestedAssetMeta.id,\n interactingAddress: suggestedAssetMeta.interactingAddress,\n asset: {\n address: suggestedAssetMeta.asset.address,\n decimals: suggestedAssetMeta.asset.decimals,\n symbol: suggestedAssetMeta.asset.symbol,\n image: suggestedAssetMeta.asset.image || null,\n },\n },\n },\n true,\n );\n }\n}\n\nexport default TokensController;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/assets-controllers",
3
- "version": "12.0.0",
3
+ "version": "14.0.0",
4
4
  "description": "Controllers which manage interactions involving ERC-20, ERC-721, and ERC-1155 tokens (including NFTs)",
5
5
  "keywords": [
6
6
  "MetaMask",
@@ -33,18 +33,17 @@
33
33
  "@ethersproject/contracts": "^5.7.0",
34
34
  "@ethersproject/providers": "^5.7.0",
35
35
  "@metamask/abi-utils": "^2.0.2",
36
- "@metamask/approval-controller": "^3.5.1",
37
- "@metamask/base-controller": "^3.2.1",
36
+ "@metamask/approval-controller": "^3.5.2",
37
+ "@metamask/base-controller": "^3.2.2",
38
38
  "@metamask/contract-metadata": "^2.3.1",
39
- "@metamask/controller-utils": "^4.3.2",
39
+ "@metamask/controller-utils": "^5.0.1",
40
40
  "@metamask/eth-query": "^3.0.1",
41
41
  "@metamask/metamask-eth-abis": "3.0.0",
42
- "@metamask/network-controller": "^12.2.0",
43
- "@metamask/preferences-controller": "^4.4.0",
44
- "@metamask/rpc-errors": "^5.1.1",
42
+ "@metamask/network-controller": "^13.0.1",
43
+ "@metamask/preferences-controller": "^4.4.2",
44
+ "@metamask/rpc-errors": "^6.0.0",
45
45
  "@metamask/utils": "^6.2.0",
46
46
  "@types/uuid": "^8.3.0",
47
- "abort-controller": "^3.0.0",
48
47
  "async-mutex": "^0.2.6",
49
48
  "ethereumjs-util": "^7.0.10",
50
49
  "immer": "^9.0.6",
@@ -63,14 +62,14 @@
63
62
  "nock": "^13.3.1",
64
63
  "sinon": "^9.2.4",
65
64
  "ts-jest": "^27.1.4",
66
- "typedoc": "^0.22.15",
67
- "typedoc-plugin-missing-exports": "^0.22.6",
68
- "typescript": "~4.6.3"
65
+ "typedoc": "^0.23.15",
66
+ "typedoc-plugin-missing-exports": "^0.23.0",
67
+ "typescript": "~4.8.4"
69
68
  },
70
69
  "peerDependencies": {
71
- "@metamask/approval-controller": "^3.5.1",
72
- "@metamask/network-controller": "^12.2.0",
73
- "@metamask/preferences-controller": "^4.4.0"
70
+ "@metamask/approval-controller": "^3.5.2",
71
+ "@metamask/network-controller": "^13.0.1",
72
+ "@metamask/preferences-controller": "^4.4.2"
74
73
  },
75
74
  "engines": {
76
75
  "node": ">=16.0.0"