@metamask-previews/assets-controllers 25.0.0-preview.b9f6d86 → 25.0.0-preview.bf56dac

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.
@@ -1 +1 @@
1
- {"version":3,"file":"ERC20Standard.js","sourceRoot":"","sources":["../../src/Standards/ERC20Standard.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport { decodeSingle } from '@metamask/abi-utils';\nimport { ERC20 } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { assertIsStrictHexString } from '@metamask/utils';\nimport { toUtf8 } from 'ethereumjs-util';\nimport type { BN } from 'ethereumjs-util';\n\nimport { ethersBigNumberToBN } from '../assetsUtil';\n\nexport class ERC20Standard {\n private readonly provider: Web3Provider;\n\n constructor(provider: Web3Provider) {\n this.provider = provider;\n }\n\n /**\n * Get balance or count for current account on specific asset contract.\n *\n * @param address - Asset ERC20 contract address.\n * @param selectedAddress - Current account public address.\n * @returns Promise resolving to BN object containing balance for current account on specific asset contract.\n */\n async getBalanceOf(address: string, selectedAddress: string): Promise<BN> {\n const contract = new Contract(address, abiERC20, this.provider);\n const balance = await contract.balanceOf(selectedAddress);\n return ethersBigNumberToBN(balance);\n }\n\n /**\n * Query for the decimals for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract string.\n * @returns Promise resolving to the 'decimals'.\n */\n async getTokenDecimals(address: string): Promise<string> {\n const contract = new Contract(address, abiERC20, this.provider);\n try {\n const decimals = await contract.decimals();\n return decimals.toString();\n } catch (err) {\n // Mirror previous implementation\n if (\n err instanceof Error &&\n err.message.includes('call revert exception')\n ) {\n throw new Error('Failed to parse token decimals');\n }\n throw err;\n }\n }\n\n /**\n * Query for the name for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract string.\n * @returns Promise resolving to the 'name'.\n */\n async getTokenName(address: string): Promise<string> {\n const contract = new Contract(address, abiERC20, this.provider);\n try {\n const name = await contract.name();\n return name.toString();\n } catch (err) {\n // Mirror previous implementation\n if (\n err instanceof Error &&\n err.message.includes('call revert exception')\n ) {\n throw new Error('Failed to parse token name');\n }\n throw err;\n }\n }\n\n /**\n * Query for symbol for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract address.\n * @returns Promise resolving to the 'symbol'.\n */\n async getTokenSymbol(address: string): Promise<string> {\n // Signature for calling `symbol()`\n const payload = { to: address, data: '0x95d89b41' };\n const result = await this.provider.call(payload);\n assertIsStrictHexString(result);\n // Parse as string - treat empty string as failure\n try {\n const decoded = decodeSingle('string', result);\n if (decoded?.length > 0) {\n return decoded;\n }\n } catch {\n // Ignore error\n }\n\n // Parse as bytes - treat empty string as failure\n try {\n const utf8 = toUtf8(result);\n if (utf8.length > 0) {\n return utf8;\n }\n } catch {\n // Ignore error\n }\n\n throw new Error('Failed to parse token symbol');\n }\n\n /**\n * Query if a contract implements an interface.\n *\n * @param address - Asset contract address.\n * @param userAddress - The public address for the currently active user's account.\n * @returns Promise resolving an object containing the standard, decimals, symbol and balance of the given contract/userAddress pair.\n */\n async getDetails(\n address: string,\n userAddress?: string,\n ): Promise<{\n standard: string;\n symbol: string | undefined;\n decimals: string | undefined;\n balance: BN | undefined;\n }> {\n const [decimals, symbol, balance] = await Promise.all([\n this.getTokenDecimals(address),\n this.getTokenSymbol(address),\n userAddress ? this.getBalanceOf(address, userAddress) : undefined,\n ]);\n return {\n decimals,\n symbol,\n balance,\n standard: ERC20,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"ERC20Standard.js","sourceRoot":"","sources":["../../src/Standards/ERC20Standard.ts"],"names":[],"mappings":"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","sourcesContent":["import { toUtf8 } from '@ethereumjs/util';\nimport { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport { decodeSingle } from '@metamask/abi-utils';\nimport { ERC20 } from '@metamask/controller-utils';\nimport { abiERC20 } from '@metamask/metamask-eth-abis';\nimport { assertIsStrictHexString } from '@metamask/utils';\nimport type BN from 'bn.js';\n\nimport { ethersBigNumberToBN } from '../assetsUtil';\n\nexport class ERC20Standard {\n private readonly provider: Web3Provider;\n\n constructor(provider: Web3Provider) {\n this.provider = provider;\n }\n\n /**\n * Get balance or count for current account on specific asset contract.\n *\n * @param address - Asset ERC20 contract address.\n * @param selectedAddress - Current account public address.\n * @returns Promise resolving to BN object containing balance for current account on specific asset contract.\n */\n async getBalanceOf(address: string, selectedAddress: string): Promise<BN> {\n const contract = new Contract(address, abiERC20, this.provider);\n const balance = await contract.balanceOf(selectedAddress);\n return ethersBigNumberToBN(balance);\n }\n\n /**\n * Query for the decimals for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract string.\n * @returns Promise resolving to the 'decimals'.\n */\n async getTokenDecimals(address: string): Promise<string> {\n const contract = new Contract(address, abiERC20, this.provider);\n try {\n const decimals = await contract.decimals();\n return decimals.toString();\n } catch (err) {\n // Mirror previous implementation\n if (\n err instanceof Error &&\n err.message.includes('call revert exception')\n ) {\n throw new Error('Failed to parse token decimals');\n }\n throw err;\n }\n }\n\n /**\n * Query for the name for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract string.\n * @returns Promise resolving to the 'name'.\n */\n async getTokenName(address: string): Promise<string> {\n const contract = new Contract(address, abiERC20, this.provider);\n try {\n const name = await contract.name();\n return name.toString();\n } catch (err) {\n // Mirror previous implementation\n if (\n err instanceof Error &&\n err.message.includes('call revert exception')\n ) {\n throw new Error('Failed to parse token name');\n }\n throw err;\n }\n }\n\n /**\n * Query for symbol for a given ERC20 asset.\n *\n * @param address - ERC20 asset contract address.\n * @returns Promise resolving to the 'symbol'.\n */\n async getTokenSymbol(address: string): Promise<string> {\n // Signature for calling `symbol()`\n const payload = { to: address, data: '0x95d89b41' };\n const result = await this.provider.call(payload);\n assertIsStrictHexString(result);\n // Parse as string - treat empty string as failure\n try {\n const decoded = decodeSingle('string', result);\n if (decoded?.length > 0) {\n return decoded;\n }\n } catch {\n // Ignore error\n }\n\n // Parse as bytes - treat empty string as failure\n try {\n const utf8 = toUtf8(result);\n if (utf8.length > 0) {\n return utf8;\n }\n } catch {\n // Ignore error\n }\n\n throw new Error('Failed to parse token symbol');\n }\n\n /**\n * Query if a contract implements an interface.\n *\n * @param address - Asset contract address.\n * @param userAddress - The public address for the currently active user's account.\n * @returns Promise resolving an object containing the standard, decimals, symbol and balance of the given contract/userAddress pair.\n */\n async getDetails(\n address: string,\n userAddress?: string,\n ): Promise<{\n standard: string;\n symbol: string | undefined;\n decimals: string | undefined;\n balance: BN | undefined;\n }> {\n const [decimals, symbol, balance] = await Promise.all([\n this.getTokenDecimals(address),\n this.getTokenSymbol(address),\n userAddress ? this.getBalanceOf(address, userAddress) : undefined,\n ]);\n return {\n decimals,\n symbol,\n balance,\n standard: ERC20,\n };\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
- /// <reference types="bn.js" />
2
1
  import type { Web3Provider } from '@ethersproject/providers';
3
- import type { BN } from 'ethereumjs-util';
2
+ import type * as BN from 'bn.js';
4
3
  export declare class ERC1155Standard {
5
4
  private readonly provider;
6
5
  constructor(provider: Web3Provider);
@@ -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;AAU7D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAI1C,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAE5B,QAAQ,EAAE,YAAY;IAIlC;;;;;OAKG;IACG,oCAAoC,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;OAKG;IACG,sCAAsC,CAC1C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;OAKG;IACG,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpE;;;;;;;OAOG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,EAAE,CAAC;IAMd;;;;;;;;;;;OAWG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAqBhB;;;;;OAKG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBtD;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBpD;;;;;;OAMG;YACW,yBAAyB;IAQvC;;;;;;;OAOG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;KAC5B,CAAC;CA8CH"}
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;AAU7D,OAAO,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAIjC,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;gBAE5B,QAAQ,EAAE,YAAY;IAIlC;;;;;OAKG;IACG,oCAAoC,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;OAKG;IACG,sCAAsC,CAC1C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC;IAOnB;;;;;OAKG;IACG,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKpE;;;;;;;OAOG;IACG,YAAY,CAChB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,EAAE,CAAC;IAMd;;;;;;;;;;;OAWG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAqBhB;;;;;OAKG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBtD;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBpD;;;;;;OAMG;YACW,yBAAyB;IAQvC;;;;;;;OAOG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAC7B,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;KAC5B,CAAC;CA8CH"}
@@ -1 +1 @@
1
- {"version":3,"file":"ERC1155Standard.js","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC1155/ERC1155Standard.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport {\n ERC1155,\n ERC1155_INTERFACE_ID,\n ERC1155_METADATA_URI_INTERFACE_ID,\n ERC1155_TOKEN_RECEIVER_INTERFACE_ID,\n safelyExecute,\n timeoutFetch,\n} from '@metamask/controller-utils';\nimport { abiERC1155 } from '@metamask/metamask-eth-abis';\nimport type { BN } from 'ethereumjs-util';\n\nimport { getFormattedIpfsUrl, ethersBigNumberToBN } from '../../../assetsUtil';\n\nexport class ERC1155Standard {\n private readonly provider: Web3Provider;\n\n constructor(provider: Web3Provider) {\n this.provider = provider;\n }\n\n /**\n * Query if contract implements ERC1155 URI Metadata interface.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to whether the contract implements ERC1155 URI Metadata interface.\n */\n async contractSupportsURIMetadataInterface(\n address: string,\n ): Promise<boolean> {\n return this.contractSupportsInterface(\n address,\n ERC1155_METADATA_URI_INTERFACE_ID,\n );\n }\n\n /**\n * Query if contract implements ERC1155 Token Receiver interface.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to whether the contract implements ERC1155 Token Receiver interface.\n */\n async contractSupportsTokenReceiverInterface(\n address: string,\n ): Promise<boolean> {\n return this.contractSupportsInterface(\n address,\n ERC1155_TOKEN_RECEIVER_INTERFACE_ID,\n );\n }\n\n /**\n * Query if contract implements ERC1155 interface.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to whether the contract implements the base ERC1155 interface.\n */\n async contractSupportsBase1155Interface(address: string): Promise<boolean> {\n return this.contractSupportsInterface(address, ERC1155_INTERFACE_ID);\n }\n\n /**\n * Query for tokenURI for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @param tokenId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'tokenURI'.\n */\n async getTokenURI(address: string, tokenId: string): Promise<string> {\n const contract = new Contract(address, abiERC1155, this.provider);\n return contract.uri(tokenId);\n }\n\n /**\n * Query for balance of a given ERC1155 token.\n *\n * @param contractAddress - ERC1155 asset contract address.\n * @param address - Wallet public address.\n * @param tokenId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'balanceOf'.\n */\n async getBalanceOf(\n contractAddress: string,\n address: string,\n tokenId: string,\n ): Promise<BN> {\n const contract = new Contract(contractAddress, abiERC1155, this.provider);\n const balance = await contract.balanceOf(address, tokenId);\n return ethersBigNumberToBN(balance);\n }\n\n /**\n * Transfer single ERC1155 token.\n * When minting/creating tokens, the from arg MUST be set to 0x0 (i.e. zero address).\n * When burning/destroying tokens, the to arg MUST be set to 0x0 (i.e. zero address).\n *\n * @param operator - ERC1155 token address.\n * @param from - ERC1155 token holder.\n * @param to - ERC1155 token recipient.\n * @param id - ERC1155 token id.\n * @param value - Number of tokens to be sent.\n * @returns Promise resolving to the 'transferSingle'.\n */\n async transferSingle(\n operator: string,\n from: string,\n to: string,\n id: string,\n value: string,\n ): Promise<void> {\n const contract = new Contract(operator, abiERC1155, this.provider);\n return new Promise<void>((resolve, reject) => {\n contract.transferSingle(\n operator,\n from,\n to,\n id,\n value,\n (error: Error, result: void) => {\n /* istanbul ignore if */\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n },\n );\n });\n }\n\n /**\n * Query for symbol for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to the 'symbol'.\n */\n async getAssetSymbol(address: string): Promise<string> {\n const contract = new Contract(\n address,\n // Contract ABI fragment containing only the symbol method to fetch the symbol of the contract.\n [\n {\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '_symbol', type: 'string' }],\n stateMutability: 'view',\n type: 'function',\n payable: false,\n },\n ],\n this.provider,\n );\n return contract.symbol();\n }\n\n /**\n * Query for name for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to the 'name'.\n */\n async getAssetName(address: string): Promise<string> {\n const contract = new Contract(\n address,\n // Contract ABI fragment containing only the name method to fetch the name of the contract.\n [\n {\n inputs: [],\n name: 'name',\n outputs: [{ name: '_name', type: 'string' }],\n stateMutability: 'view',\n type: 'function',\n payable: false,\n },\n ],\n this.provider,\n );\n return contract.name();\n }\n\n /**\n * Query if a contract implements an interface.\n *\n * @param address - ERC1155 asset contract address.\n * @param interfaceId - Interface identifier.\n * @returns Promise resolving to whether the contract implements `interfaceID`.\n */\n private async contractSupportsInterface(\n address: string,\n interfaceId: string,\n ): Promise<boolean> {\n const contract = new Contract(address, abiERC1155, this.provider);\n return contract.supportsInterface(interfaceId);\n }\n\n /**\n * Query if a contract implements an interface.\n *\n * @param address - Asset contract address.\n * @param ipfsGateway - The user's preferred IPFS gateway.\n * @param tokenId - tokenId of a given token in the contract.\n * @returns Promise resolving an object containing the standard, tokenURI, symbol and name of the given contract/tokenId pair.\n */\n async getDetails(\n address: string,\n ipfsGateway: string,\n tokenId?: string,\n ): Promise<{\n standard: string;\n tokenURI: string | undefined;\n image: string | undefined;\n name: string | undefined;\n symbol: string | undefined;\n }> {\n const isERC1155 = await this.contractSupportsBase1155Interface(address);\n\n if (!isERC1155) {\n throw new Error(\"This isn't a valid ERC1155 contract\");\n }\n\n let image;\n\n const [symbol, name, tokenURI] = await Promise.all([\n safelyExecute(() => this.getAssetSymbol(address)),\n safelyExecute(() => this.getAssetName(address)),\n tokenId\n ? safelyExecute(() =>\n this.getTokenURI(address, tokenId).then((uri) =>\n uri.startsWith('ipfs://')\n ? getFormattedIpfsUrl(ipfsGateway, uri, true)\n : uri,\n ),\n )\n : undefined,\n ]);\n\n if (tokenURI) {\n try {\n const response = await timeoutFetch(tokenURI);\n const object = await response.json();\n image = object?.image;\n if (image?.startsWith('ipfs://')) {\n image = getFormattedIpfsUrl(ipfsGateway, image, true);\n }\n } catch {\n // Catch block should be kept empty to ignore exceptions, and\n // pass as much information as possible to the return statement\n }\n }\n\n // TODO consider querying to the metadata to get name.\n return {\n standard: ERC1155,\n tokenURI,\n image,\n symbol,\n name,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"ERC1155Standard.js","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC1155/ERC1155Standard.ts"],"names":[],"mappings":"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","sourcesContent":["import { Contract } from '@ethersproject/contracts';\nimport type { Web3Provider } from '@ethersproject/providers';\nimport {\n ERC1155,\n ERC1155_INTERFACE_ID,\n ERC1155_METADATA_URI_INTERFACE_ID,\n ERC1155_TOKEN_RECEIVER_INTERFACE_ID,\n safelyExecute,\n timeoutFetch,\n} from '@metamask/controller-utils';\nimport { abiERC1155 } from '@metamask/metamask-eth-abis';\nimport type * as BN from 'bn.js';\n\nimport { getFormattedIpfsUrl, ethersBigNumberToBN } from '../../../assetsUtil';\n\nexport class ERC1155Standard {\n private readonly provider: Web3Provider;\n\n constructor(provider: Web3Provider) {\n this.provider = provider;\n }\n\n /**\n * Query if contract implements ERC1155 URI Metadata interface.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to whether the contract implements ERC1155 URI Metadata interface.\n */\n async contractSupportsURIMetadataInterface(\n address: string,\n ): Promise<boolean> {\n return this.contractSupportsInterface(\n address,\n ERC1155_METADATA_URI_INTERFACE_ID,\n );\n }\n\n /**\n * Query if contract implements ERC1155 Token Receiver interface.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to whether the contract implements ERC1155 Token Receiver interface.\n */\n async contractSupportsTokenReceiverInterface(\n address: string,\n ): Promise<boolean> {\n return this.contractSupportsInterface(\n address,\n ERC1155_TOKEN_RECEIVER_INTERFACE_ID,\n );\n }\n\n /**\n * Query if contract implements ERC1155 interface.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to whether the contract implements the base ERC1155 interface.\n */\n async contractSupportsBase1155Interface(address: string): Promise<boolean> {\n return this.contractSupportsInterface(address, ERC1155_INTERFACE_ID);\n }\n\n /**\n * Query for tokenURI for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @param tokenId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'tokenURI'.\n */\n async getTokenURI(address: string, tokenId: string): Promise<string> {\n const contract = new Contract(address, abiERC1155, this.provider);\n return contract.uri(tokenId);\n }\n\n /**\n * Query for balance of a given ERC1155 token.\n *\n * @param contractAddress - ERC1155 asset contract address.\n * @param address - Wallet public address.\n * @param tokenId - ERC1155 asset identifier.\n * @returns Promise resolving to the 'balanceOf'.\n */\n async getBalanceOf(\n contractAddress: string,\n address: string,\n tokenId: string,\n ): Promise<BN> {\n const contract = new Contract(contractAddress, abiERC1155, this.provider);\n const balance = await contract.balanceOf(address, tokenId);\n return ethersBigNumberToBN(balance);\n }\n\n /**\n * Transfer single ERC1155 token.\n * When minting/creating tokens, the from arg MUST be set to 0x0 (i.e. zero address).\n * When burning/destroying tokens, the to arg MUST be set to 0x0 (i.e. zero address).\n *\n * @param operator - ERC1155 token address.\n * @param from - ERC1155 token holder.\n * @param to - ERC1155 token recipient.\n * @param id - ERC1155 token id.\n * @param value - Number of tokens to be sent.\n * @returns Promise resolving to the 'transferSingle'.\n */\n async transferSingle(\n operator: string,\n from: string,\n to: string,\n id: string,\n value: string,\n ): Promise<void> {\n const contract = new Contract(operator, abiERC1155, this.provider);\n return new Promise<void>((resolve, reject) => {\n contract.transferSingle(\n operator,\n from,\n to,\n id,\n value,\n (error: Error, result: void) => {\n /* istanbul ignore if */\n if (error) {\n reject(error);\n return;\n }\n resolve(result);\n },\n );\n });\n }\n\n /**\n * Query for symbol for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to the 'symbol'.\n */\n async getAssetSymbol(address: string): Promise<string> {\n const contract = new Contract(\n address,\n // Contract ABI fragment containing only the symbol method to fetch the symbol of the contract.\n [\n {\n inputs: [],\n name: 'symbol',\n outputs: [{ name: '_symbol', type: 'string' }],\n stateMutability: 'view',\n type: 'function',\n payable: false,\n },\n ],\n this.provider,\n );\n return contract.symbol();\n }\n\n /**\n * Query for name for a given asset.\n *\n * @param address - ERC1155 asset contract address.\n * @returns Promise resolving to the 'name'.\n */\n async getAssetName(address: string): Promise<string> {\n const contract = new Contract(\n address,\n // Contract ABI fragment containing only the name method to fetch the name of the contract.\n [\n {\n inputs: [],\n name: 'name',\n outputs: [{ name: '_name', type: 'string' }],\n stateMutability: 'view',\n type: 'function',\n payable: false,\n },\n ],\n this.provider,\n );\n return contract.name();\n }\n\n /**\n * Query if a contract implements an interface.\n *\n * @param address - ERC1155 asset contract address.\n * @param interfaceId - Interface identifier.\n * @returns Promise resolving to whether the contract implements `interfaceID`.\n */\n private async contractSupportsInterface(\n address: string,\n interfaceId: string,\n ): Promise<boolean> {\n const contract = new Contract(address, abiERC1155, this.provider);\n return contract.supportsInterface(interfaceId);\n }\n\n /**\n * Query if a contract implements an interface.\n *\n * @param address - Asset contract address.\n * @param ipfsGateway - The user's preferred IPFS gateway.\n * @param tokenId - tokenId of a given token in the contract.\n * @returns Promise resolving an object containing the standard, tokenURI, symbol and name of the given contract/tokenId pair.\n */\n async getDetails(\n address: string,\n ipfsGateway: string,\n tokenId?: string,\n ): Promise<{\n standard: string;\n tokenURI: string | undefined;\n image: string | undefined;\n name: string | undefined;\n symbol: string | undefined;\n }> {\n const isERC1155 = await this.contractSupportsBase1155Interface(address);\n\n if (!isERC1155) {\n throw new Error(\"This isn't a valid ERC1155 contract\");\n }\n\n let image;\n\n const [symbol, name, tokenURI] = await Promise.all([\n safelyExecute(() => this.getAssetSymbol(address)),\n safelyExecute(() => this.getAssetName(address)),\n tokenId\n ? safelyExecute(() =>\n this.getTokenURI(address, tokenId).then((uri) =>\n uri.startsWith('ipfs://')\n ? getFormattedIpfsUrl(ipfsGateway, uri, true)\n : uri,\n ),\n )\n : undefined,\n ]);\n\n if (tokenURI) {\n try {\n const response = await timeoutFetch(tokenURI);\n const object = await response.json();\n image = object?.image;\n if (image?.startsWith('ipfs://')) {\n image = getFormattedIpfsUrl(ipfsGateway, image, true);\n }\n } catch {\n // Catch block should be kept empty to ignore exceptions, and\n // pass as much information as possible to the return statement\n }\n }\n\n // TODO consider querying to the metadata to get name.\n return {\n standard: ERC1155,\n tokenURI,\n image,\n symbol,\n name,\n };\n }\n}\n"]}
@@ -1,19 +1,30 @@
1
- import type { AccountsControllerSelectedAccountChangeEvent } from '@metamask/accounts-controller';
1
+ import type { AccountsControllerGetSelectedAccountAction, AccountsControllerSelectedAccountChangeEvent } from '@metamask/accounts-controller';
2
2
  import type { RestrictedControllerMessenger, ControllerGetStateAction, ControllerStateChangeEvent } from '@metamask/base-controller';
3
3
  import type { KeyringControllerGetStateAction, KeyringControllerLockEvent, KeyringControllerUnlockEvent } from '@metamask/keyring-controller';
4
- import type { NetworkClientId, NetworkControllerNetworkDidChangeEvent, NetworkControllerGetNetworkConfigurationByNetworkClientId } from '@metamask/network-controller';
4
+ import type { NetworkClientId, NetworkControllerFindNetworkClientIdByChainIdAction, NetworkControllerGetNetworkConfigurationByNetworkClientId, NetworkControllerGetProviderConfigAction, NetworkControllerNetworkDidChangeEvent } from '@metamask/network-controller';
5
5
  import { StaticIntervalPollingController } from '@metamask/polling-controller';
6
6
  import type { PreferencesControllerGetStateAction, PreferencesControllerStateChangeEvent } from '@metamask/preferences-controller';
7
7
  import type { AssetsContractController } from './AssetsContractController';
8
8
  import type { GetTokenListState, TokenListStateChange, TokenListToken } from './TokenListController';
9
9
  import type { Token } from './TokenRatesController';
10
10
  import type { TokensControllerAddDetectedTokensAction, TokensControllerGetStateAction } from './TokensController';
11
+ /**
12
+ * Compare 2 given strings and return boolean
13
+ * eg: "foo" and "FOO" => true
14
+ * eg: "foo" and "bar" => false
15
+ * eg: "foo" and 123 => false
16
+ *
17
+ * @param value1 - first string to compare
18
+ * @param value2 - first string to compare
19
+ * @returns true if 2 strings are identical when they are lowercase
20
+ */
21
+ export declare function isEqualCaseInsensitive(value1: string, value2: string): boolean;
11
22
  export declare const STATIC_MAINNET_TOKEN_LIST: Record<string, Partial<TokenListToken> & Pick<Token, "symbol" | "address" | "decimals">>;
12
23
  export declare const controllerName = "TokenDetectionController";
13
24
  export declare type TokenDetectionState = Record<never, never>;
14
25
  export declare type TokenDetectionControllerGetStateAction = ControllerGetStateAction<typeof controllerName, TokenDetectionState>;
15
26
  export declare type TokenDetectionControllerActions = TokenDetectionControllerGetStateAction;
16
- export declare type AllowedActions = NetworkControllerGetNetworkConfigurationByNetworkClientId | GetTokenListState | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction;
27
+ export declare type AllowedActions = AccountsControllerGetSelectedAccountAction | NetworkControllerFindNetworkClientIdByChainIdAction | NetworkControllerGetNetworkConfigurationByNetworkClientId | NetworkControllerGetProviderConfigAction | GetTokenListState | KeyringControllerGetStateAction | PreferencesControllerGetStateAction | TokensControllerGetStateAction | TokensControllerAddDetectedTokensAction;
17
28
  export declare type TokenDetectionControllerStateChangeEvent = ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;
18
29
  export declare type TokenDetectionControllerEvents = TokenDetectionControllerStateChangeEvent;
19
30
  export declare type AllowedEvents = AccountsControllerSelectedAccountChangeEvent | NetworkControllerNetworkDidChangeEvent | TokenListStateChange | KeyringControllerLockEvent | KeyringControllerUnlockEvent | PreferencesControllerStateChangeEvent;
@@ -91,11 +102,11 @@ export declare class TokenDetectionController extends StaticIntervalPollingContr
91
102
  *
92
103
  * @param options - Options for token detection.
93
104
  * @param options.networkClientId - The ID of the network client to use.
94
- * @param options.accountAddress - the selectedAddress against which to detect for token balances.
105
+ * @param options.selectedAddress - the selectedAddress against which to detect for token balances.
95
106
  */
96
- detectTokens({ networkClientId, accountAddress, }?: {
107
+ detectTokens({ networkClientId, selectedAddress, }?: {
97
108
  networkClientId?: NetworkClientId;
98
- accountAddress?: string;
109
+ selectedAddress?: string;
99
110
  }): Promise<void>;
100
111
  }
101
112
  export default TokenDetectionController;
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.d.ts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TokenDetectionController.d.ts","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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"}
@@ -33,23 +33,31 @@ var __rest = (this && this.__rest) || function (s, e) {
33
33
  var __importDefault = (this && this.__importDefault) || function (mod) {
34
34
  return (mod && mod.__esModule) ? mod : { "default": mod };
35
35
  };
36
- var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_chainId, _TokenDetectionController_selectedAddress, _TokenDetectionController_networkClientId, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_getCorrectChainId, _TokenDetectionController_restartTokenDetection;
36
+ var _TokenDetectionController_instances, _TokenDetectionController_intervalId, _TokenDetectionController_chainId, _TokenDetectionController_selectedAddress, _TokenDetectionController_networkClientId, _TokenDetectionController_disabled, _TokenDetectionController_isUnlocked, _TokenDetectionController_isDetectionEnabledFromPreferences, _TokenDetectionController_isDetectionEnabledForNetwork, _TokenDetectionController_getBalancesInSingleCall, _TokenDetectionController_trackMetaMetricsEvent, _TokenDetectionController_registerEventListeners, _TokenDetectionController_stopPolling, _TokenDetectionController_startPolling, _TokenDetectionController_getCorrectChainIdAndNetworkClientId, _TokenDetectionController_restartTokenDetection;
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.TokenDetectionController = exports.controllerName = exports.STATIC_MAINNET_TOKEN_LIST = void 0;
38
+ exports.TokenDetectionController = exports.controllerName = exports.STATIC_MAINNET_TOKEN_LIST = exports.isEqualCaseInsensitive = void 0;
39
39
  const contract_metadata_1 = __importDefault(require("@metamask/contract-metadata"));
40
40
  const controller_utils_1 = require("@metamask/controller-utils");
41
41
  const polling_controller_1 = require("@metamask/polling-controller");
42
42
  const assetsUtil_1 = require("./assetsUtil");
43
43
  const DEFAULT_INTERVAL = 180000;
44
44
  /**
45
- * Finds a case insensitive match in an array of strings
46
- * @param source - An array of strings to search.
47
- * @param target - The target string to search for.
48
- * @returns The first match that is found.
45
+ * Compare 2 given strings and return boolean
46
+ * eg: "foo" and "FOO" => true
47
+ * eg: "foo" and "bar" => false
48
+ * eg: "foo" and 123 => false
49
+ *
50
+ * @param value1 - first string to compare
51
+ * @param value2 - first string to compare
52
+ * @returns true if 2 strings are identical when they are lowercase
49
53
  */
50
- function findCaseInsensitiveMatch(source, target) {
51
- return source.find((e) => e.toLowerCase() === target.toLowerCase());
54
+ function isEqualCaseInsensitive(value1, value2) {
55
+ if (typeof value1 !== 'string' || typeof value2 !== 'string') {
56
+ return false;
57
+ }
58
+ return value1.toLowerCase() === value2.toLowerCase();
52
59
  }
60
+ exports.isEqualCaseInsensitive = isEqualCaseInsensitive;
53
61
  exports.STATIC_MAINNET_TOKEN_LIST = Object.entries(contract_metadata_1.default).reduce((acc, [base, contract]) => {
54
62
  const { logo } = contract, tokenMetadata = __rest(contract, ["logo"]);
55
63
  return Object.assign(Object.assign({}, acc), { [base.toLowerCase()]: Object.assign(Object.assign({}, tokenMetadata), { address: base.toLowerCase(), iconUrl: `images/contract/${logo}`, aggregators: [] }) });
@@ -79,7 +87,7 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin
79
87
  * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.
80
88
  * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.
81
89
  */
82
- constructor({ networkClientId, selectedAddress = '', interval = DEFAULT_INTERVAL, disabled = true, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, }) {
90
+ constructor({ networkClientId, selectedAddress, interval = DEFAULT_INTERVAL, disabled = true, getBalancesInSingleCall, trackMetaMetricsEvent, messenger, }) {
83
91
  super({
84
92
  name: exports.controllerName,
85
93
  messenger,
@@ -100,8 +108,10 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin
100
108
  __classPrivateFieldSet(this, _TokenDetectionController_disabled, disabled, "f");
101
109
  this.setIntervalLength(interval);
102
110
  __classPrivateFieldSet(this, _TokenDetectionController_networkClientId, networkClientId, "f");
103
- __classPrivateFieldSet(this, _TokenDetectionController_selectedAddress, selectedAddress, "f");
104
- __classPrivateFieldSet(this, _TokenDetectionController_chainId, __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainId).call(this, networkClientId), "f");
111
+ __classPrivateFieldSet(this, _TokenDetectionController_selectedAddress, selectedAddress !== null && selectedAddress !== void 0 ? selectedAddress : this.messagingSystem.call('AccountsController:getSelectedAccount')
112
+ .address, "f");
113
+ const { chainId } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainIdAndNetworkClientId).call(this, networkClientId);
114
+ __classPrivateFieldSet(this, _TokenDetectionController_chainId, chainId, "f");
105
115
  const { useTokenDetection: defaultUseTokenDetection } = this.messagingSystem.call('PreferencesController:getState');
106
116
  __classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, defaultUseTokenDetection, "f");
107
117
  __classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledForNetwork, (0, assetsUtil_1.isTokenDetectionSupportedForNetwork)(__classPrivateFieldGet(this, _TokenDetectionController_chainId, "f")), "f");
@@ -154,7 +164,7 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin
154
164
  }
155
165
  yield this.detectTokens({
156
166
  networkClientId,
157
- accountAddress: options.address,
167
+ selectedAddress: options.address,
158
168
  });
159
169
  });
160
170
  }
@@ -164,69 +174,74 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin
164
174
  *
165
175
  * @param options - Options for token detection.
166
176
  * @param options.networkClientId - The ID of the network client to use.
167
- * @param options.accountAddress - the selectedAddress against which to detect for token balances.
177
+ * @param options.selectedAddress - the selectedAddress against which to detect for token balances.
168
178
  */
169
- detectTokens({ networkClientId, accountAddress, } = {}) {
179
+ detectTokens({ networkClientId, selectedAddress, } = {}) {
180
+ var _a, _b;
170
181
  return __awaiter(this, void 0, void 0, function* () {
171
- if (!this.isActive || !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledForNetwork, "f")) {
182
+ if (!this.isActive) {
183
+ return;
184
+ }
185
+ const addressAgainstWhichToDetect = selectedAddress !== null && selectedAddress !== void 0 ? selectedAddress : __classPrivateFieldGet(this, _TokenDetectionController_selectedAddress, "f");
186
+ const { chainId: chainIdAgainstWhichToDetect, networkClientId: networkClientIdAgainstWhichToDetect, } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainIdAndNetworkClientId).call(this, networkClientId);
187
+ if (!(0, assetsUtil_1.isTokenDetectionSupportedForNetwork)(chainIdAgainstWhichToDetect)) {
172
188
  return;
173
189
  }
174
- const selectedAddress = accountAddress !== null && accountAddress !== void 0 ? accountAddress : __classPrivateFieldGet(this, _TokenDetectionController_selectedAddress, "f");
175
- const chainId = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainId).call(this, networkClientId);
176
190
  if (!__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") &&
177
- chainId !== controller_utils_1.ChainId.mainnet) {
191
+ chainIdAgainstWhichToDetect !== controller_utils_1.ChainId.mainnet) {
178
192
  return;
179
193
  }
180
- const isTokenDetectionInactiveInMainnet = !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") && chainId === controller_utils_1.ChainId.mainnet;
181
- const { tokenList } = this.messagingSystem.call('TokenListController:getState');
194
+ const isTokenDetectionInactiveInMainnet = !__classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledFromPreferences, "f") &&
195
+ chainIdAgainstWhichToDetect === controller_utils_1.ChainId.mainnet;
196
+ const { tokensChainsCache } = this.messagingSystem.call('TokenListController:getState');
197
+ const tokenList = (_b = (_a = tokensChainsCache[chainIdAgainstWhichToDetect]) === null || _a === void 0 ? void 0 : _a.data) !== null && _b !== void 0 ? _b : {};
182
198
  const tokenListUsed = isTokenDetectionInactiveInMainnet
183
199
  ? exports.STATIC_MAINNET_TOKEN_LIST
184
200
  : tokenList;
185
- const { tokens, detectedTokens, ignoredTokens } = this.messagingSystem.call('TokensController:getState');
201
+ const { allTokens, allDetectedTokens, allIgnoredTokens } = this.messagingSystem.call('TokensController:getState');
202
+ const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [
203
+ allTokens,
204
+ allDetectedTokens,
205
+ allIgnoredTokens,
206
+ ].map((tokens) => {
207
+ var _a, _b;
208
+ return ((_b = (_a = tokens[chainIdAgainstWhichToDetect]) === null || _a === void 0 ? void 0 : _a[addressAgainstWhichToDetect]) !== null && _b !== void 0 ? _b : []).map((value) => (typeof value === 'string' ? value : value.address));
209
+ });
186
210
  const tokensToDetect = [];
187
211
  for (const tokenAddress of Object.keys(tokenListUsed)) {
188
- if (!findCaseInsensitiveMatch(tokens.map(({ address }) => address), tokenAddress) &&
189
- !findCaseInsensitiveMatch(detectedTokens.map(({ address }) => address), tokenAddress)) {
212
+ if ([
213
+ tokensAddresses,
214
+ detectedTokensAddresses,
215
+ ignoredTokensAddresses,
216
+ ].every((addresses) => !addresses.find((address) => isEqualCaseInsensitive(address, tokenAddress)))) {
190
217
  tokensToDetect.push(tokenAddress);
191
218
  }
192
219
  }
193
- const sliceOfTokensToDetect = [];
194
- sliceOfTokensToDetect[0] = tokensToDetect.slice(0, 1000);
195
- sliceOfTokensToDetect[1] = tokensToDetect.slice(1000, tokensToDetect.length - 1);
196
- /* istanbul ignore else */
197
- if (!selectedAddress) {
198
- return;
199
- }
200
- for (const tokensSlice of sliceOfTokensToDetect) {
220
+ const slicesOfTokensToDetect = [];
221
+ slicesOfTokensToDetect[0] = tokensToDetect.slice(0, 1000);
222
+ slicesOfTokensToDetect[1] = tokensToDetect.slice(1000, tokensToDetect.length - 1);
223
+ for (const tokensSlice of slicesOfTokensToDetect) {
201
224
  if (tokensSlice.length === 0) {
202
225
  break;
203
226
  }
204
227
  yield (0, controller_utils_1.safelyExecute)(() => __awaiter(this, void 0, void 0, function* () {
205
- var _a;
206
- const balances = yield __classPrivateFieldGet(this, _TokenDetectionController_getBalancesInSingleCall, "f").call(this, selectedAddress, tokensSlice);
207
- const tokensToAdd = [];
228
+ const balances = yield __classPrivateFieldGet(this, _TokenDetectionController_getBalancesInSingleCall, "f").call(this, addressAgainstWhichToDetect, tokensSlice, networkClientIdAgainstWhichToDetect);
229
+ const tokensWithBalance = [];
208
230
  const eventTokensDetails = [];
209
- let ignored;
210
- for (const tokenAddress of Object.keys(balances)) {
211
- if (ignoredTokens.length) {
212
- ignored = ignoredTokens.find((ignoredTokenAddress) => ignoredTokenAddress === (0, controller_utils_1.toChecksumHexAddress)(tokenAddress));
213
- }
214
- const caseInsensitiveTokenKey = (_a = findCaseInsensitiveMatch(Object.keys(tokenListUsed), tokenAddress)) !== null && _a !== void 0 ? _a : '';
215
- if (ignored === undefined) {
216
- const { decimals, symbol, aggregators, iconUrl, name } = tokenListUsed[caseInsensitiveTokenKey];
217
- eventTokensDetails.push(`${symbol} - ${tokenAddress}`);
218
- tokensToAdd.push({
219
- address: tokenAddress,
220
- decimals,
221
- symbol,
222
- aggregators,
223
- image: iconUrl,
224
- isERC721: false,
225
- name,
226
- });
227
- }
231
+ for (const nonZeroTokenAddress of Object.keys(balances)) {
232
+ const { decimals, symbol, aggregators, iconUrl, name } = tokenListUsed[nonZeroTokenAddress];
233
+ eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);
234
+ tokensWithBalance.push({
235
+ address: nonZeroTokenAddress,
236
+ decimals,
237
+ symbol,
238
+ aggregators,
239
+ image: iconUrl,
240
+ isERC721: false,
241
+ name,
242
+ });
228
243
  }
229
- if (tokensToAdd.length) {
244
+ if (tokensWithBalance.length) {
230
245
  __classPrivateFieldGet(this, _TokenDetectionController_trackMetaMetricsEvent, "f").call(this, {
231
246
  event: 'Token Detected',
232
247
  category: 'Wallet',
@@ -236,9 +251,9 @@ class TokenDetectionController extends polling_controller_1.StaticIntervalPollin
236
251
  asset_type: 'TOKEN',
237
252
  },
238
253
  });
239
- yield this.messagingSystem.call('TokensController:addDetectedTokens', tokensToAdd, {
240
- selectedAddress,
241
- chainId,
254
+ yield this.messagingSystem.call('TokensController:addDetectedTokens', tokensWithBalance, {
255
+ selectedAddress: addressAgainstWhichToDetect,
256
+ chainId: chainIdAgainstWhichToDetect,
242
257
  });
243
258
  }
244
259
  }));
@@ -286,7 +301,8 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_
286
301
  }));
287
302
  this.messagingSystem.subscribe('NetworkController:networkDidChange', ({ selectedNetworkClientId }) => __awaiter(this, void 0, void 0, function* () {
288
303
  const isNetworkClientIdChanged = __classPrivateFieldGet(this, _TokenDetectionController_networkClientId, "f") !== selectedNetworkClientId;
289
- const newChainId = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainId).call(this, selectedNetworkClientId);
304
+ const { chainId: newChainId } = __classPrivateFieldGet(this, _TokenDetectionController_instances, "m", _TokenDetectionController_getCorrectChainIdAndNetworkClientId).call(this, selectedNetworkClientId);
305
+ __classPrivateFieldSet(this, _TokenDetectionController_chainId, newChainId, "f");
290
306
  __classPrivateFieldSet(this, _TokenDetectionController_isDetectionEnabledForNetwork, (0, assetsUtil_1.isTokenDetectionSupportedForNetwork)(newChainId), "f");
291
307
  if (isNetworkClientIdChanged && __classPrivateFieldGet(this, _TokenDetectionController_isDetectionEnabledForNetwork, "f")) {
292
308
  __classPrivateFieldSet(this, _TokenDetectionController_networkClientId, selectedNetworkClientId, "f");
@@ -310,15 +326,27 @@ _TokenDetectionController_intervalId = new WeakMap(), _TokenDetectionController_
310
326
  yield this.detectTokens();
311
327
  }), this.getIntervalLength()), "f");
312
328
  });
313
- }, _TokenDetectionController_getCorrectChainId = function _TokenDetectionController_getCorrectChainId(networkClientId) {
314
- var _a;
315
- const { chainId } = (_a = this.messagingSystem.call('NetworkController:getNetworkConfigurationByNetworkClientId', networkClientId !== null && networkClientId !== void 0 ? networkClientId : __classPrivateFieldGet(this, _TokenDetectionController_networkClientId, "f"))) !== null && _a !== void 0 ? _a : {};
316
- return chainId !== null && chainId !== void 0 ? chainId : __classPrivateFieldGet(this, _TokenDetectionController_chainId, "f");
329
+ }, _TokenDetectionController_getCorrectChainIdAndNetworkClientId = function _TokenDetectionController_getCorrectChainIdAndNetworkClientId(networkClientId) {
330
+ if (networkClientId) {
331
+ const networkConfiguration = this.messagingSystem.call('NetworkController:getNetworkConfigurationByNetworkClientId', networkClientId);
332
+ if (networkConfiguration) {
333
+ return {
334
+ chainId: networkConfiguration.chainId,
335
+ networkClientId,
336
+ };
337
+ }
338
+ }
339
+ const { chainId } = this.messagingSystem.call('NetworkController:getProviderConfig');
340
+ const newNetworkClientId = this.messagingSystem.call('NetworkController:findNetworkClientIdByChainId', chainId);
341
+ return {
342
+ chainId,
343
+ networkClientId: newNetworkClientId,
344
+ };
317
345
  }, _TokenDetectionController_restartTokenDetection = function _TokenDetectionController_restartTokenDetection({ selectedAddress, networkClientId, } = {}) {
318
346
  return __awaiter(this, void 0, void 0, function* () {
319
347
  yield this.detectTokens({
320
348
  networkClientId,
321
- accountAddress: selectedAddress,
349
+ selectedAddress,
322
350
  });
323
351
  this.setIntervalLength(DEFAULT_INTERVAL);
324
352
  });
@@ -1 +1 @@
1
- {"version":3,"file":"TokenDetectionController.js","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccountsControllerSelectedAccountChangeEvent } from '@metamask/accounts-controller';\nimport type {\n RestrictedControllerMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport contractMap from '@metamask/contract-metadata';\nimport {\n ChainId,\n safelyExecute,\n toChecksumHexAddress,\n} from '@metamask/controller-utils';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type {\n NetworkClientId,\n NetworkControllerNetworkDidChangeEvent,\n NetworkControllerGetNetworkConfigurationByNetworkClientId,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport { isTokenDetectionSupportedForNetwork } from './assetsUtil';\nimport type {\n GetTokenListState,\n TokenListStateChange,\n TokenListToken,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\nimport type {\n TokensControllerAddDetectedTokensAction,\n TokensControllerGetStateAction,\n} from './TokensController';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * Finds a case insensitive match in an array of strings\n * @param source - An array of strings to search.\n * @param target - The target string to search for.\n * @returns The first match that is found.\n */\nfunction findCaseInsensitiveMatch(source: string[], target: string) {\n return source.find((e: string) => e.toLowerCase() === target.toLowerCase());\n}\n\ntype LegacyToken = Omit<\n Token,\n 'aggregators' | 'image' | 'balanceError' | 'isERC721'\n> & {\n name: string;\n logo: string;\n erc20?: boolean;\n erc721?: boolean;\n};\n\nexport const STATIC_MAINNET_TOKEN_LIST = Object.entries<LegacyToken>(\n contractMap,\n).reduce<\n Record<\n string,\n Partial<TokenListToken> & Pick<Token, 'address' | 'symbol' | 'decimals'>\n >\n>((acc, [base, contract]) => {\n const { logo, ...tokenMetadata } = contract;\n return {\n ...acc,\n [base.toLowerCase()]: {\n ...tokenMetadata,\n address: base.toLowerCase(),\n iconUrl: `images/contract/${logo}`,\n aggregators: [],\n },\n };\n}, {});\n\nexport const controllerName = 'TokenDetectionController';\n\nexport type TokenDetectionState = Record<never, never>;\n\nexport type TokenDetectionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenDetectionState\n>;\n\nexport type TokenDetectionControllerActions =\n TokenDetectionControllerGetStateAction;\n\nexport type AllowedActions =\n | NetworkControllerGetNetworkConfigurationByNetworkClientId\n | GetTokenListState\n | KeyringControllerGetStateAction\n | PreferencesControllerGetStateAction\n | TokensControllerGetStateAction\n | TokensControllerAddDetectedTokensAction;\n\nexport type TokenDetectionControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;\n\nexport type TokenDetectionControllerEvents =\n TokenDetectionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedAccountChangeEvent\n | NetworkControllerNetworkDidChangeEvent\n | TokenListStateChange\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent;\n\nexport type TokenDetectionControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n TokenDetectionControllerActions | AllowedActions,\n TokenDetectionControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Controller that passively polls on a set interval for Tokens auto detection\n * @property intervalId - Polling interval used to fetch new token rates\n * @property chainId - The chain ID of the current network\n * @property selectedAddress - Vault selected address\n * @property networkClientId - The network client ID of the current selected network\n * @property disabled - Boolean to track if network requests are blocked\n * @property isUnlocked - Boolean to track if the keyring state is unlocked\n * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network\n */\nexport class TokenDetectionController extends StaticIntervalPollingController<\n typeof controllerName,\n TokenDetectionState,\n TokenDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #chainId: Hex;\n\n #selectedAddress: string;\n\n #networkClientId: NetworkClientId;\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n #isDetectionEnabledForNetwork: boolean;\n\n readonly #getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n\n readonly #trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n token_standard: string;\n asset_type: string;\n };\n }) => void;\n\n /**\n * Creates a TokenDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The controller messaging system.\n * @param options.disabled - If set to true, all network requests are blocked.\n * @param options.interval - Polling interval used to fetch new token rates\n * @param options.networkClientId - The selected network client ID of the current network\n * @param options.selectedAddress - Vault selected address\n * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.\n * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.\n */\n constructor({\n networkClientId,\n selectedAddress = '',\n interval = DEFAULT_INTERVAL,\n disabled = true,\n getBalancesInSingleCall,\n trackMetaMetricsEvent,\n messenger,\n }: {\n networkClientId: NetworkClientId;\n selectedAddress?: string;\n interval?: number;\n disabled?: boolean;\n getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n token_standard: string;\n asset_type: string;\n };\n }) => void;\n messenger: TokenDetectionControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {},\n metadata: {},\n });\n\n this.#disabled = disabled;\n this.setIntervalLength(interval);\n\n this.#networkClientId = networkClientId;\n this.#selectedAddress = selectedAddress;\n this.#chainId = this.#getCorrectChainId(networkClientId);\n\n const { useTokenDetection: defaultUseTokenDetection } =\n this.messagingSystem.call('PreferencesController:getState');\n this.#isDetectionEnabledFromPreferences = defaultUseTokenDetection;\n this.#isDetectionEnabledForNetwork = isTokenDetectionSupportedForNetwork(\n this.#chainId,\n );\n\n this.#getBalancesInSingleCall = getBalancesInSingleCall;\n\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n const { isUnlocked } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n this.#isUnlocked = isUnlocked;\n\n this.#registerEventListeners();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system subscriptions to controller events.\n */\n #registerEventListeners() {\n this.messagingSystem.subscribe('KeyringController:unlock', async () => {\n this.#isUnlocked = true;\n await this.#restartTokenDetection();\n });\n\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n this.#stopPolling();\n });\n\n this.messagingSystem.subscribe(\n 'TokenListController:stateChange',\n async ({ tokenList }) => {\n const hasTokens = Object.keys(tokenList).length;\n\n if (hasTokens) {\n await this.#restartTokenDetection();\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'PreferencesController:stateChange',\n async ({ selectedAddress: newSelectedAddress, useTokenDetection }) => {\n const isSelectedAddressChanged =\n this.#selectedAddress !== newSelectedAddress;\n const isDetectionChangedFromPreferences =\n this.#isDetectionEnabledFromPreferences !== useTokenDetection;\n\n this.#selectedAddress = newSelectedAddress;\n this.#isDetectionEnabledFromPreferences = useTokenDetection;\n\n if (\n useTokenDetection &&\n (isSelectedAddressChanged || isDetectionChangedFromPreferences)\n ) {\n await this.#restartTokenDetection({\n selectedAddress: this.#selectedAddress,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n async ({ address: newSelectedAddress }) => {\n const isSelectedAddressChanged =\n this.#selectedAddress !== newSelectedAddress;\n if (\n isSelectedAddressChanged &&\n this.#isDetectionEnabledFromPreferences\n ) {\n this.#selectedAddress = newSelectedAddress;\n await this.#restartTokenDetection({\n selectedAddress: this.#selectedAddress,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'NetworkController:networkDidChange',\n async ({ selectedNetworkClientId }) => {\n const isNetworkClientIdChanged =\n this.#networkClientId !== selectedNetworkClientId;\n\n const newChainId = this.#getCorrectChainId(selectedNetworkClientId);\n this.#isDetectionEnabledForNetwork =\n isTokenDetectionSupportedForNetwork(newChainId);\n\n if (isNetworkClientIdChanged && this.#isDetectionEnabledForNetwork) {\n this.#networkClientId = selectedNetworkClientId;\n await this.#restartTokenDetection({\n networkClientId: this.#networkClientId,\n });\n }\n },\n );\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable() {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable() {\n this.#disabled = true;\n }\n\n /**\n * Internal isActive state\n *\n * @type {object}\n */\n get isActive() {\n return !this.#disabled && this.#isUnlocked;\n }\n\n /**\n * Start polling for detected tokens.\n */\n async start() {\n this.enable();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for detected tokens.\n */\n stop() {\n this.disable();\n this.#stopPolling();\n }\n\n #stopPolling() {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n if (!this.isActive) {\n return;\n }\n this.#stopPolling();\n await this.detectTokens();\n this.#intervalId = setInterval(async () => {\n await this.detectTokens();\n }, this.getIntervalLength());\n }\n\n #getCorrectChainId(networkClientId?: NetworkClientId) {\n const { chainId } =\n this.messagingSystem.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n networkClientId ?? this.#networkClientId,\n ) ?? {};\n return chainId ?? this.#chainId;\n }\n\n async _executePoll(\n networkClientId: string,\n options: { address: string },\n ): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n networkClientId,\n accountAddress: options.address,\n });\n }\n\n /**\n * Restart token detection polling period and call detectNewTokens\n * in case of address change or user session initialization.\n *\n * @param options - Options for restart token detection.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances\n * @param options.networkClientId - The ID of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n networkClientId,\n }: { selectedAddress?: string; networkClientId?: string } = {}) {\n await this.detectTokens({\n networkClientId,\n accountAddress: selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n /**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.networkClientId - The ID of the network client to use.\n * @param options.accountAddress - the selectedAddress against which to detect for token balances.\n */\n async detectTokens({\n networkClientId,\n accountAddress,\n }: {\n networkClientId?: NetworkClientId;\n accountAddress?: string;\n } = {}): Promise<void> {\n if (!this.isActive || !this.#isDetectionEnabledForNetwork) {\n return;\n }\n const selectedAddress = accountAddress ?? this.#selectedAddress;\n const chainId = this.#getCorrectChainId(networkClientId);\n\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainId !== ChainId.mainnet\n ) {\n return;\n }\n const isTokenDetectionInactiveInMainnet =\n !this.#isDetectionEnabledFromPreferences && chainId === ChainId.mainnet;\n const { tokenList } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n const tokenListUsed = isTokenDetectionInactiveInMainnet\n ? STATIC_MAINNET_TOKEN_LIST\n : tokenList;\n\n const { tokens, detectedTokens, ignoredTokens } = this.messagingSystem.call(\n 'TokensController:getState',\n );\n const tokensToDetect: string[] = [];\n for (const tokenAddress of Object.keys(tokenListUsed)) {\n if (\n !findCaseInsensitiveMatch(\n tokens.map(({ address }) => address),\n tokenAddress,\n ) &&\n !findCaseInsensitiveMatch(\n detectedTokens.map(({ address }) => address),\n tokenAddress,\n )\n ) {\n tokensToDetect.push(tokenAddress);\n }\n }\n const sliceOfTokensToDetect = [];\n sliceOfTokensToDetect[0] = tokensToDetect.slice(0, 1000);\n sliceOfTokensToDetect[1] = tokensToDetect.slice(\n 1000,\n tokensToDetect.length - 1,\n );\n\n /* istanbul ignore else */\n if (!selectedAddress) {\n return;\n }\n\n for (const tokensSlice of sliceOfTokensToDetect) {\n if (tokensSlice.length === 0) {\n break;\n }\n\n await safelyExecute(async () => {\n const balances = await this.#getBalancesInSingleCall(\n selectedAddress,\n tokensSlice,\n );\n const tokensToAdd: Token[] = [];\n const eventTokensDetails: string[] = [];\n let ignored;\n for (const tokenAddress of Object.keys(balances)) {\n if (ignoredTokens.length) {\n ignored = ignoredTokens.find(\n (ignoredTokenAddress) =>\n ignoredTokenAddress === toChecksumHexAddress(tokenAddress),\n );\n }\n const caseInsensitiveTokenKey =\n findCaseInsensitiveMatch(\n Object.keys(tokenListUsed),\n tokenAddress,\n ) ?? '';\n\n if (ignored === undefined) {\n const { decimals, symbol, aggregators, iconUrl, name } =\n tokenListUsed[caseInsensitiveTokenKey];\n eventTokensDetails.push(`${symbol} - ${tokenAddress}`);\n tokensToAdd.push({\n address: tokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n });\n }\n }\n\n if (tokensToAdd.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: 'ERC20',\n asset_type: 'TOKEN',\n },\n });\n await this.messagingSystem.call(\n 'TokensController:addDetectedTokens',\n tokensToAdd,\n {\n selectedAddress,\n chainId,\n },\n );\n }\n });\n }\n }\n}\n\nexport default TokenDetectionController;\n"]}
1
+ {"version":3,"file":"TokenDetectionController.js","sourceRoot":"","sources":["../src/TokenDetectionController.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AccountsControllerGetSelectedAccountAction,\n AccountsControllerSelectedAccountChangeEvent,\n} from '@metamask/accounts-controller';\nimport type {\n RestrictedControllerMessenger,\n ControllerGetStateAction,\n ControllerStateChangeEvent,\n} from '@metamask/base-controller';\nimport contractMap from '@metamask/contract-metadata';\nimport { ChainId, safelyExecute } from '@metamask/controller-utils';\nimport type {\n KeyringControllerGetStateAction,\n KeyringControllerLockEvent,\n KeyringControllerUnlockEvent,\n} from '@metamask/keyring-controller';\nimport type {\n NetworkClientId,\n NetworkControllerFindNetworkClientIdByChainIdAction,\n NetworkControllerGetNetworkConfigurationByNetworkClientId,\n NetworkControllerGetProviderConfigAction,\n NetworkControllerNetworkDidChangeEvent,\n} from '@metamask/network-controller';\nimport { StaticIntervalPollingController } from '@metamask/polling-controller';\nimport type {\n PreferencesControllerGetStateAction,\n PreferencesControllerStateChangeEvent,\n} from '@metamask/preferences-controller';\nimport type { Hex } from '@metamask/utils';\n\nimport type { AssetsContractController } from './AssetsContractController';\nimport { isTokenDetectionSupportedForNetwork } from './assetsUtil';\nimport type {\n GetTokenListState,\n TokenListStateChange,\n TokenListToken,\n} from './TokenListController';\nimport type { Token } from './TokenRatesController';\nimport type {\n TokensControllerAddDetectedTokensAction,\n TokensControllerGetStateAction,\n} from './TokensController';\n\nconst DEFAULT_INTERVAL = 180000;\n\n/**\n * Compare 2 given strings and return boolean\n * eg: \"foo\" and \"FOO\" => true\n * eg: \"foo\" and \"bar\" => false\n * eg: \"foo\" and 123 => false\n *\n * @param value1 - first string to compare\n * @param value2 - first string to compare\n * @returns true if 2 strings are identical when they are lowercase\n */\nexport function isEqualCaseInsensitive(\n value1: string,\n value2: string,\n): boolean {\n if (typeof value1 !== 'string' || typeof value2 !== 'string') {\n return false;\n }\n return value1.toLowerCase() === value2.toLowerCase();\n}\n\ntype LegacyToken = Omit<\n Token,\n 'aggregators' | 'image' | 'balanceError' | 'isERC721'\n> & {\n name: string;\n logo: string;\n erc20?: boolean;\n erc721?: boolean;\n};\n\nexport const STATIC_MAINNET_TOKEN_LIST = Object.entries<LegacyToken>(\n contractMap,\n).reduce<\n Record<\n string,\n Partial<TokenListToken> & Pick<Token, 'address' | 'symbol' | 'decimals'>\n >\n>((acc, [base, contract]) => {\n const { logo, ...tokenMetadata } = contract;\n return {\n ...acc,\n [base.toLowerCase()]: {\n ...tokenMetadata,\n address: base.toLowerCase(),\n iconUrl: `images/contract/${logo}`,\n aggregators: [],\n },\n };\n}, {});\n\nexport const controllerName = 'TokenDetectionController';\n\nexport type TokenDetectionState = Record<never, never>;\n\nexport type TokenDetectionControllerGetStateAction = ControllerGetStateAction<\n typeof controllerName,\n TokenDetectionState\n>;\n\nexport type TokenDetectionControllerActions =\n TokenDetectionControllerGetStateAction;\n\nexport type AllowedActions =\n | AccountsControllerGetSelectedAccountAction\n | NetworkControllerFindNetworkClientIdByChainIdAction\n | NetworkControllerGetNetworkConfigurationByNetworkClientId\n | NetworkControllerGetProviderConfigAction\n | GetTokenListState\n | KeyringControllerGetStateAction\n | PreferencesControllerGetStateAction\n | TokensControllerGetStateAction\n | TokensControllerAddDetectedTokensAction;\n\nexport type TokenDetectionControllerStateChangeEvent =\n ControllerStateChangeEvent<typeof controllerName, TokenDetectionState>;\n\nexport type TokenDetectionControllerEvents =\n TokenDetectionControllerStateChangeEvent;\n\nexport type AllowedEvents =\n | AccountsControllerSelectedAccountChangeEvent\n | NetworkControllerNetworkDidChangeEvent\n | TokenListStateChange\n | KeyringControllerLockEvent\n | KeyringControllerUnlockEvent\n | PreferencesControllerStateChangeEvent;\n\nexport type TokenDetectionControllerMessenger = RestrictedControllerMessenger<\n typeof controllerName,\n TokenDetectionControllerActions | AllowedActions,\n TokenDetectionControllerEvents | AllowedEvents,\n AllowedActions['type'],\n AllowedEvents['type']\n>;\n\n/**\n * Controller that passively polls on a set interval for Tokens auto detection\n * @property intervalId - Polling interval used to fetch new token rates\n * @property chainId - The chain ID of the current network\n * @property selectedAddress - Vault selected address\n * @property networkClientId - The network client ID of the current selected network\n * @property disabled - Boolean to track if network requests are blocked\n * @property isUnlocked - Boolean to track if the keyring state is unlocked\n * @property isDetectionEnabledFromPreferences - Boolean to track if detection is enabled from PreferencesController\n * @property isDetectionEnabledForNetwork - Boolean to track if detected is enabled for current network\n */\nexport class TokenDetectionController extends StaticIntervalPollingController<\n typeof controllerName,\n TokenDetectionState,\n TokenDetectionControllerMessenger\n> {\n #intervalId?: ReturnType<typeof setTimeout>;\n\n #chainId: Hex;\n\n #selectedAddress: string;\n\n #networkClientId: NetworkClientId;\n\n #disabled: boolean;\n\n #isUnlocked: boolean;\n\n #isDetectionEnabledFromPreferences: boolean;\n\n #isDetectionEnabledForNetwork: boolean;\n\n readonly #getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n\n readonly #trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n token_standard: string;\n asset_type: string;\n };\n }) => void;\n\n /**\n * Creates a TokenDetectionController instance.\n *\n * @param options - The controller options.\n * @param options.messenger - The controller messaging system.\n * @param options.disabled - If set to true, all network requests are blocked.\n * @param options.interval - Polling interval used to fetch new token rates\n * @param options.networkClientId - The selected network client ID of the current network\n * @param options.selectedAddress - Vault selected address\n * @param options.getBalancesInSingleCall - Gets the balances of a list of tokens for the given address.\n * @param options.trackMetaMetricsEvent - Sets options for MetaMetrics event tracking.\n */\n constructor({\n networkClientId,\n selectedAddress,\n interval = DEFAULT_INTERVAL,\n disabled = true,\n getBalancesInSingleCall,\n trackMetaMetricsEvent,\n messenger,\n }: {\n networkClientId: NetworkClientId;\n selectedAddress?: string;\n interval?: number;\n disabled?: boolean;\n getBalancesInSingleCall: AssetsContractController['getBalancesInSingleCall'];\n trackMetaMetricsEvent: (options: {\n event: string;\n category: string;\n properties: {\n tokens: string[];\n token_standard: string;\n asset_type: string;\n };\n }) => void;\n messenger: TokenDetectionControllerMessenger;\n }) {\n super({\n name: controllerName,\n messenger,\n state: {},\n metadata: {},\n });\n\n this.#disabled = disabled;\n this.setIntervalLength(interval);\n\n this.#networkClientId = networkClientId;\n this.#selectedAddress =\n selectedAddress ??\n this.messagingSystem.call('AccountsController:getSelectedAccount')\n .address;\n const { chainId } =\n this.#getCorrectChainIdAndNetworkClientId(networkClientId);\n this.#chainId = chainId;\n\n const { useTokenDetection: defaultUseTokenDetection } =\n this.messagingSystem.call('PreferencesController:getState');\n this.#isDetectionEnabledFromPreferences = defaultUseTokenDetection;\n this.#isDetectionEnabledForNetwork = isTokenDetectionSupportedForNetwork(\n this.#chainId,\n );\n\n this.#getBalancesInSingleCall = getBalancesInSingleCall;\n\n this.#trackMetaMetricsEvent = trackMetaMetricsEvent;\n\n const { isUnlocked } = this.messagingSystem.call(\n 'KeyringController:getState',\n );\n this.#isUnlocked = isUnlocked;\n\n this.#registerEventListeners();\n }\n\n /**\n * Constructor helper for registering this controller's messaging system subscriptions to controller events.\n */\n #registerEventListeners() {\n this.messagingSystem.subscribe('KeyringController:unlock', async () => {\n this.#isUnlocked = true;\n await this.#restartTokenDetection();\n });\n\n this.messagingSystem.subscribe('KeyringController:lock', () => {\n this.#isUnlocked = false;\n this.#stopPolling();\n });\n\n this.messagingSystem.subscribe(\n 'TokenListController:stateChange',\n async ({ tokenList }) => {\n const hasTokens = Object.keys(tokenList).length;\n\n if (hasTokens) {\n await this.#restartTokenDetection();\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'PreferencesController:stateChange',\n async ({ selectedAddress: newSelectedAddress, useTokenDetection }) => {\n const isSelectedAddressChanged =\n this.#selectedAddress !== newSelectedAddress;\n const isDetectionChangedFromPreferences =\n this.#isDetectionEnabledFromPreferences !== useTokenDetection;\n\n this.#selectedAddress = newSelectedAddress;\n this.#isDetectionEnabledFromPreferences = useTokenDetection;\n\n if (\n useTokenDetection &&\n (isSelectedAddressChanged || isDetectionChangedFromPreferences)\n ) {\n await this.#restartTokenDetection({\n selectedAddress: this.#selectedAddress,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'AccountsController:selectedAccountChange',\n async ({ address: newSelectedAddress }) => {\n const isSelectedAddressChanged =\n this.#selectedAddress !== newSelectedAddress;\n if (\n isSelectedAddressChanged &&\n this.#isDetectionEnabledFromPreferences\n ) {\n this.#selectedAddress = newSelectedAddress;\n await this.#restartTokenDetection({\n selectedAddress: this.#selectedAddress,\n });\n }\n },\n );\n\n this.messagingSystem.subscribe(\n 'NetworkController:networkDidChange',\n async ({ selectedNetworkClientId }) => {\n const isNetworkClientIdChanged =\n this.#networkClientId !== selectedNetworkClientId;\n\n const { chainId: newChainId } =\n this.#getCorrectChainIdAndNetworkClientId(selectedNetworkClientId);\n this.#chainId = newChainId;\n this.#isDetectionEnabledForNetwork =\n isTokenDetectionSupportedForNetwork(newChainId);\n\n if (isNetworkClientIdChanged && this.#isDetectionEnabledForNetwork) {\n this.#networkClientId = selectedNetworkClientId;\n await this.#restartTokenDetection({\n networkClientId: this.#networkClientId,\n });\n }\n },\n );\n }\n\n /**\n * Allows controller to make active and passive polling requests\n */\n enable() {\n this.#disabled = false;\n }\n\n /**\n * Blocks controller from making network calls\n */\n disable() {\n this.#disabled = true;\n }\n\n /**\n * Internal isActive state\n *\n * @type {object}\n */\n get isActive() {\n return !this.#disabled && this.#isUnlocked;\n }\n\n /**\n * Start polling for detected tokens.\n */\n async start() {\n this.enable();\n await this.#startPolling();\n }\n\n /**\n * Stop polling for detected tokens.\n */\n stop() {\n this.disable();\n this.#stopPolling();\n }\n\n #stopPolling() {\n if (this.#intervalId) {\n clearInterval(this.#intervalId);\n }\n }\n\n /**\n * Starts a new polling interval.\n */\n async #startPolling(): Promise<void> {\n if (!this.isActive) {\n return;\n }\n this.#stopPolling();\n await this.detectTokens();\n this.#intervalId = setInterval(async () => {\n await this.detectTokens();\n }, this.getIntervalLength());\n }\n\n #getCorrectChainIdAndNetworkClientId(networkClientId?: NetworkClientId): {\n chainId: Hex;\n networkClientId: NetworkClientId;\n } {\n if (networkClientId) {\n const networkConfiguration = this.messagingSystem.call(\n 'NetworkController:getNetworkConfigurationByNetworkClientId',\n networkClientId,\n );\n if (networkConfiguration) {\n return {\n chainId: networkConfiguration.chainId,\n networkClientId,\n };\n }\n }\n const { chainId } = this.messagingSystem.call(\n 'NetworkController:getProviderConfig',\n );\n const newNetworkClientId = this.messagingSystem.call(\n 'NetworkController:findNetworkClientIdByChainId',\n chainId,\n );\n return {\n chainId,\n networkClientId: newNetworkClientId,\n };\n }\n\n async _executePoll(\n networkClientId: string,\n options: { address: string },\n ): Promise<void> {\n if (!this.isActive) {\n return;\n }\n await this.detectTokens({\n networkClientId,\n selectedAddress: options.address,\n });\n }\n\n /**\n * Restart token detection polling period and call detectNewTokens\n * in case of address change or user session initialization.\n *\n * @param options - Options for restart token detection.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances\n * @param options.networkClientId - The ID of the network client to use.\n */\n async #restartTokenDetection({\n selectedAddress,\n networkClientId,\n }: { selectedAddress?: string; networkClientId?: string } = {}) {\n await this.detectTokens({\n networkClientId,\n selectedAddress,\n });\n this.setIntervalLength(DEFAULT_INTERVAL);\n }\n\n /**\n * For each token in the token list provided by the TokenListController, checks the token's balance for the selected account address on the active network.\n * On mainnet, if token detection is disabled in preferences, ERC20 token auto detection will be triggered for each contract address in the legacy token list from the @metamask/contract-metadata repo.\n *\n * @param options - Options for token detection.\n * @param options.networkClientId - The ID of the network client to use.\n * @param options.selectedAddress - the selectedAddress against which to detect for token balances.\n */\n async detectTokens({\n networkClientId,\n selectedAddress,\n }: {\n networkClientId?: NetworkClientId;\n selectedAddress?: string;\n } = {}): Promise<void> {\n if (!this.isActive) {\n return;\n }\n\n const addressAgainstWhichToDetect =\n selectedAddress ?? this.#selectedAddress;\n const {\n chainId: chainIdAgainstWhichToDetect,\n networkClientId: networkClientIdAgainstWhichToDetect,\n } = this.#getCorrectChainIdAndNetworkClientId(networkClientId);\n\n if (!isTokenDetectionSupportedForNetwork(chainIdAgainstWhichToDetect)) {\n return;\n }\n\n if (\n !this.#isDetectionEnabledFromPreferences &&\n chainIdAgainstWhichToDetect !== ChainId.mainnet\n ) {\n return;\n }\n const isTokenDetectionInactiveInMainnet =\n !this.#isDetectionEnabledFromPreferences &&\n chainIdAgainstWhichToDetect === ChainId.mainnet;\n const { tokensChainsCache } = this.messagingSystem.call(\n 'TokenListController:getState',\n );\n const tokenList =\n tokensChainsCache[chainIdAgainstWhichToDetect]?.data ?? {};\n const tokenListUsed = isTokenDetectionInactiveInMainnet\n ? STATIC_MAINNET_TOKEN_LIST\n : tokenList;\n\n const { allTokens, allDetectedTokens, allIgnoredTokens } =\n this.messagingSystem.call('TokensController:getState');\n const [tokensAddresses, detectedTokensAddresses, ignoredTokensAddresses] = [\n allTokens,\n allDetectedTokens,\n allIgnoredTokens,\n ].map((tokens) =>\n (\n tokens[chainIdAgainstWhichToDetect]?.[addressAgainstWhichToDetect] ?? []\n ).map((value) => (typeof value === 'string' ? value : value.address)),\n );\n const tokensToDetect: string[] = [];\n for (const tokenAddress of Object.keys(tokenListUsed)) {\n if (\n [\n tokensAddresses,\n detectedTokensAddresses,\n ignoredTokensAddresses,\n ].every(\n (addresses) =>\n !addresses.find((address) =>\n isEqualCaseInsensitive(address, tokenAddress),\n ),\n )\n ) {\n tokensToDetect.push(tokenAddress);\n }\n }\n const slicesOfTokensToDetect = [];\n slicesOfTokensToDetect[0] = tokensToDetect.slice(0, 1000);\n slicesOfTokensToDetect[1] = tokensToDetect.slice(\n 1000,\n tokensToDetect.length - 1,\n );\n for (const tokensSlice of slicesOfTokensToDetect) {\n if (tokensSlice.length === 0) {\n break;\n }\n\n await safelyExecute(async () => {\n const balances = await this.#getBalancesInSingleCall(\n addressAgainstWhichToDetect,\n tokensSlice,\n networkClientIdAgainstWhichToDetect,\n );\n const tokensWithBalance: Token[] = [];\n const eventTokensDetails: string[] = [];\n for (const nonZeroTokenAddress of Object.keys(balances)) {\n const { decimals, symbol, aggregators, iconUrl, name } =\n tokenListUsed[nonZeroTokenAddress];\n eventTokensDetails.push(`${symbol} - ${nonZeroTokenAddress}`);\n tokensWithBalance.push({\n address: nonZeroTokenAddress,\n decimals,\n symbol,\n aggregators,\n image: iconUrl,\n isERC721: false,\n name,\n });\n }\n if (tokensWithBalance.length) {\n this.#trackMetaMetricsEvent({\n event: 'Token Detected',\n category: 'Wallet',\n properties: {\n tokens: eventTokensDetails,\n token_standard: 'ERC20',\n asset_type: 'TOKEN',\n },\n });\n await this.messagingSystem.call(\n 'TokensController:addDetectedTokens',\n tokensWithBalance,\n {\n selectedAddress: addressAgainstWhichToDetect,\n chainId: chainIdAgainstWhichToDetect,\n },\n );\n }\n });\n }\n }\n}\n\nexport default TokenDetectionController;\n"]}
@@ -1,7 +1,6 @@
1
- /// <reference types="bn.js" />
2
1
  import type { BigNumber } from '@ethersproject/bignumber';
3
2
  import type { Hex } from '@metamask/utils';
4
- import { BN } from 'ethereumjs-util';
3
+ import BN from 'bn.js';
5
4
  import type { Nft, NftMetadata, OpenSeaV2Collection, OpenSeaV2Contract, OpenSeaV2DetailedNft, OpenSeaV2Nft } from './NftController';
6
5
  import type { ApiNft, ApiNftContract } from './NftDetectionController';
7
6
  import type { AbstractTokenPricesService } from './token-prices-service';
@@ -1 +1 @@
1
- {"version":3,"file":"assetsUtil.d.ts","sourceRoot":"","sources":["../src/assetsUtil.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assetsUtil.d.ts","sourceRoot":"","sources":["../src/assetsUtil.ts"],"names":[],"mappings":"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"}