{"version":3,"file":"ERC20Standard.cjs","sourceRoot":"","sources":["../../src/Standards/ERC20Standard.ts"],"names":[],"mappings":"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","sourcesContent":["import { bytesToUtf8 } 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, hexToBytes } 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      // Not done in bytesToUtf8 in ethereumjs/util.\n      const regexPreceedingAndTrailingZeroes = /^(00)+|(00)+$/gu;\n\n      const resultTrimmed = result?.replace(\n        regexPreceedingAndTrailingZeroes,\n        '',\n      );\n\n      const utf8 = bytesToUtf8(hexToBytes(resultTrimmed));\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"]}