{"version":3,"file":"ERC1155Standard.mjs","sourceRoot":"","sources":["../../../../src/Standards/NftStandards/ERC1155/ERC1155Standard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AAEpD,OAAO,EACL,OAAO,EACP,oBAAoB,EACpB,iCAAiC,EACjC,mCAAmC,EACnC,aAAa,EACb,YAAY,EACb,mCAAmC;AACpC,OAAO,EAAE,UAAU,EAAE,oCAAoC;AAGzD,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,gCAA4B;AAE/E,MAAM,OAAO,eAAe;IAG1B,YAAY,QAAsB;QAChC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,oCAAoC,CACxC,OAAe;QAEf,OAAO,IAAI,CAAC,yBAAyB,CACnC,OAAO,EACP,iCAAiC,CAClC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,sCAAsC,CAC1C,OAAe;QAEf,OAAO,IAAI,CAAC,yBAAyB,CACnC,OAAO,EACP,mCAAmC,CACpC,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,iCAAiC,CAAC,OAAe;QACrD,OAAO,IAAI,CAAC,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;IACvE,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,OAAe,EAAE,OAAe;QAChD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,YAAY,CAChB,eAAuB,EACvB,OAAe,EACf,OAAe;QAEf,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,eAAe,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,cAAc,CAClB,QAAgB,EAChB,IAAY,EACZ,EAAU,EACV,EAAU,EACV,KAAa;QAEb,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,QAAQ,CAAC,cAAc,CACrB,QAAQ,EACR,IAAI,EACJ,EAAE,EACF,EAAE,EACF,KAAK,EACL,CAAC,KAAY,EAAE,MAAY,EAAE,EAAE;gBAC7B,wBAAwB;gBACxB,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,CAAC,KAAK,CAAC,CAAC;oBACd,OAAO;gBACT,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,OAAe;QAClC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,OAAO;QACP,+FAA+F;QAC/F;YACE;gBACE,MAAM,EAAE,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;gBAC9C,eAAe,EAAE,MAAM;gBACvB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,KAAK;aACf;SACF,EACD,IAAI,CAAC,QAAQ,CACd,CAAC;QACF,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,YAAY,CAAC,OAAe;QAChC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,OAAO;QACP,2FAA2F;QAC3F;YACE;gBACE,MAAM,EAAE,EAAE;gBACV,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;gBAC5C,eAAe,EAAE,MAAM;gBACvB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,KAAK;aACf;SACF,EACD,IAAI,CAAC,QAAQ,CACd,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,yBAAyB,CACrC,OAAe,EACf,WAAmB;QAEnB,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClE,OAAO,QAAQ,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,UAAU,CACd,OAAe,EACf,WAAmB,EACnB,OAAgB;QAQhB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iCAAiC,CAAC,OAAO,CAAC,CAAC;QAExE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,KAAK,CAAC;QAEV,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACjD,aAAa,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACjD,aAAa,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO;gBACL,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,CACjB,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAC9C,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;oBACvB,CAAC,CAAC,mBAAmB,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC;oBAC7C,CAAC,CAAC,GAAG,CACR,CACF;gBACH,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;QAEH,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC9C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACrC,KAAK,GAAG,MAAM,EAAE,KAAK,CAAC;gBACtB,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBACjC,KAAK,GAAG,mBAAmB,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;gBAC7D,+DAA+D;YACjE,CAAC;QACH,CAAC;QAED,sDAAsD;QACtD,OAAO;YACL,QAAQ,EAAE,OAAO;YACjB,QAAQ;YACR,KAAK;YACL,MAAM;YACN,IAAI;SACL,CAAC;IACJ,CAAC;CACF","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"]}