'use strict';

var ethers = require('ethers');
var index = require('./index-5adc67b5.cjs.prod.js');

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n["default"] = e;
  return Object.freeze(n);
}

/**
 * Encodes and decodes Contract functions
 * @contract
 * @public
 */
class ContractEncoder {
  constructor(contractWrapper) {
    this.contractWrapper = contractWrapper;
  }

  /**
   * Encodes the given contract function with argument
   * @returns The encoded data
   */
  encode(fn, args) {
    return this.contractWrapper.readContract.interface.encodeFunctionData(fn, args);
  }

  /**
   * Decode encoded call data for a given function
   * @param fn - the function to decode
   * @param encodedArgs - the encoded arguments
   */
  decode(fn, encodedArgs) {
    return this.contractWrapper.readContract.interface.decodeFunctionData(fn, encodedArgs);
  }
  decodeResult(fn, encodedArgs) {
    return this.contractWrapper.readContract.interface.decodeFunctionResult(fn, encodedArgs);
  }
}

function isNativeToken(tokenAddress) {
  return tokenAddress.toLowerCase() === index.NATIVE_TOKEN_ADDRESS || tokenAddress.toLowerCase() === ethers.constants.AddressZero;
}

/**
 *
 * @param provider - The provider to use
 * @param asset - The asset to fetch the metadata for
 * @returns
 * @internal
 */
async function fetchCurrencyMetadata(provider, asset) {
  if (isNativeToken(asset)) {
    const network = await provider.getNetwork();
    const nativeToken = index.getNativeTokenByChainId(network.chainId);
    return {
      name: nativeToken.name,
      symbol: nativeToken.symbol,
      decimals: nativeToken.decimals
    };
  } else {
    const ERC20MetadataAbi = (await Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@thirdweb-dev/contracts-js/dist/abis/IERC20Metadata.json')); })).default;
    const erc20 = new ethers.Contract(asset, ERC20MetadataAbi, provider);
    const [name, symbol, decimals] = await Promise.all([erc20.name(), erc20.symbol(), erc20.decimals()]);
    return {
      name,
      symbol,
      decimals
    };
  }
}

/**
 *
 * @param providerOrSigner - The provider or signer to use
 * @param asset - The asset to fetch the value for
 * @param price - The price to fetch the value for
 * @returns
 * @internal
 */
async function fetchCurrencyValue(providerOrSigner, asset, price) {
  const metadata = await fetchCurrencyMetadata(providerOrSigner, asset);
  return {
    ...metadata,
    value: ethers.BigNumber.from(price),
    displayValue: ethers.utils.formatUnits(price, metadata.decimals)
  };
}

exports.ContractEncoder = ContractEncoder;
exports.fetchCurrencyMetadata = fetchCurrencyMetadata;
exports.fetchCurrencyValue = fetchCurrencyValue;
exports.isNativeToken = isNativeToken;
