"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const bignumber_js_1 = require("bignumber.js");
const contractWrapperBase_1 = require("../contractWrapperBase");
const contractWrapperFactory_1 = require("../contractWrapperFactory");
const iContractWrapperBase_1 = require("../iContractWrapperBase");
const loggingService_1 = require("../loggingService");
const web3EventService_1 = require("../web3EventService");
class Erc20Wrapper extends contractWrapperBase_1.ContractWrapperBase {
    constructor() {
        super(...arguments);
        this.name = "ERC20";
        this.friendlyName = "ERC20 Token";
        this.factory = exports.Erc20Factory;
    }
    /**
     * Approve transfer of tokens by msg.sender (or `onBehalfOf`, if given)
     * from the given "spender".
     * @param options
     */
    approve(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.spender) {
                throw new Error("spender is not defined");
            }
            const amount = new bignumber_js_1.BigNumber(options.amount);
            if (amount.eq(0)) {
                loggingService_1.LoggingService.warn("ERC20.approve: amount is zero.  Doing nothing.");
                return new iContractWrapperBase_1.ArcTransactionResult(null, this.contract);
            }
            this.logContractFunctionCall("ERC20.approve", options);
            return this.wrapTransactionInvocation("ERC20.approve", options, this.contract.approve, [options.spender, options.amount], options.owner ? { from: options.owner } : undefined);
        });
    }
    /**
     * Transfer tokens from the current account to another.
     * @param options
     */
    transfer(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.amount) {
                throw new Error("amount is not defined");
            }
            if (!options.to) {
                throw new Error("to is not defined");
            }
            const amount = new bignumber_js_1.BigNumber(options.amount);
            if (amount.eq(0)) {
                loggingService_1.LoggingService.warn("ERC20.transfer: amount is zero.  Doing nothing.");
                return new iContractWrapperBase_1.ArcTransactionResult(null, this.contract);
            }
            this.logContractFunctionCall("ERC20.transfer", options);
            return this.wrapTransactionInvocation("ERC20.transfer", options, this.contract.transfer, [options.to, options.amount]);
        });
    }
    /**
     * Transfer tokens from one address to another.
     * @param options
     */
    transferFrom(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.amount) {
                throw new Error("amount is not defined");
            }
            if (!options.to) {
                throw new Error("to is not defined");
            }
            if (!options.from) {
                throw new Error("from is not defined");
            }
            const amount = new bignumber_js_1.BigNumber(options.amount);
            if (amount.eq(0)) {
                loggingService_1.LoggingService.warn("ERC20.transferFrom: amount is zero.  Doing nothing.");
                return new iContractWrapperBase_1.ArcTransactionResult(null, this.contract);
            }
            this.logContractFunctionCall("ERC20.transferFrom", options);
            return this.wrapTransactionInvocation("ERC20.transferFrom", options, this.contract.transferFrom, [options.from, options.to, options.amount]);
        });
    }
    /**
     * Returns a promise of the given account's current token balance.
     * @param account
     */
    getBalanceOf(account) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!account) {
                throw new Error("account is not defined");
            }
            this.logContractFunctionCall("ERC20.getBalanceOf", account);
            return this.contract.balanceOf(account);
        });
    }
    /**
     * Returns a promise of the token's total number of tokens.
     */
    getTotalSupply() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.logContractFunctionCall("ERC20.getTotalSupply");
            return this.contract.totalSupply();
        });
    }
    /**
     * Returns a promise of the number of tokens that the given account "spender" is
     * currently allowed to transfer from the given token holder's account.
     * @param options
     */
    getAllowance(options) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!options.owner) {
                throw new Error("owner is not defined");
            }
            if (!options.spender) {
                throw new Error("spender is not defined");
            }
            this.logContractFunctionCall("ERC20.allowance", options);
            return this.contract.allowance(options.owner, options.spender);
        });
    }
    hydrated() {
        /* tslint:disable:max-line-length */
        this.Approval = this.createEventFetcherFactory(this.contract.Approval);
        this.Transfer = this.createEventFetcherFactory(this.contract.Transfer);
        /* tslint:enable:max-line-length */
    }
}
exports.Erc20Wrapper = Erc20Wrapper;
/**
 * defined just to add good type checking
 */
class Erc20FactoryType extends contractWrapperFactory_1.ContractWrapperFactory {
    deployed() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            throw new Error("Erc20 has not been deployed");
        });
    }
}
exports.Erc20FactoryType = Erc20FactoryType;
exports.Erc20Factory = new Erc20FactoryType("ERC20", Erc20Wrapper, new web3EventService_1.Web3EventService());
//# sourceMappingURL=erc20.js.map