Source: wallet/act.js

/**
 * Provides smart contract APIs for ACT
 * @module stayge-wallet/act
 */

'use strict'

const utils = require('../icon-js/utils.js');

/**
 * Class representing the ACT smart contract
 */
class ACT {

    /**
     * Create a ACT
     * @param {Wallet} wallet
     * @param {String} scoreAddress contract address of ACT
     */
    constructor(wallet, scoreAddress) {
        this._wallet = wallet;
        this._scoreAddress = scoreAddress;
    }


    /**
     * Returns name
     * @return {Promise<String>}
     */
    async name() {
        const name = await this._wallet.call(
            this._scoreAddress,
            'name',
            {}
        );

        return name;
    }


    /**
     * Returns symbol
     * @return {Promise<String>}
     */
    async symbol() {
        const symbol = await this._wallet.call(
            this._scoreAddress,
            'symbol',
            {}
        );

        return symbol;
    }


    /**
     * Returns decimals
     * @return {Promise<Number>}
     */
    async decimals() {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return utils.toBigNumber(decimals).toNumber();
    }


    /**
     * Returns total supply
     * @return {Promise<Number>}
     */
    async totalSupply() {
        const [totalSupply, decimals] = await Promise.all([
            this._wallet.call(
                this._scoreAddress,
                'totalSupply',
                {}
            ),
            this._wallet.call(
                this._scoreAddress,
                'decimals',
                {}
            )
        ]);

        return utils
            .toBigNumber(totalSupply)
            .dividedBy(10 ** utils.toBigNumber(decimals))
            .toNumber();
    }


    /**
     * Returns balance of ACT for the specified owner
     * @param  {String} owner address of owner
     * @return {Promise<Number>}
     */
    async balanceOf(owner) {
        owner = owner || this._wallet.getAddressString();

        const [balance, decimals] = await Promise.all([
            this._wallet.call(
                this._scoreAddress,
                'balanceOf',
                {_owner: owner}
            ),
            this._wallet.call(
                this._scoreAddress,
                'decimals',
                {}
            )
        ]);

        return utils
            .toBigNumber(balance)
            .dividedBy(10 ** utils.toBigNumber(decimals))
            .toNumber();
    }


    /**
     * Transfer ACT to the specified recipient
     * @param  {String} to address of the recipient
     * @param  {Number} value the amount to transfer
     * @param  {String} data optional
     * @return {Promise<String>} txHash
     */
    async transfer(to, value, data='') {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'transfer',
            {
                _to: to,
                _value: utils.toHexString(
                    utils.toBigNumber(value).times(10 ** utils.toBigNumber(decimals))
                ),
                _data: data.length > 0 ? utils.convertToHex(data) : data,
            }
        );
    }


    /**
     * Returns allowance of the spender for the owner balance
     * @param  {String} owner   address of the owner
     * @param  {String} spender address of the spender
     * @return {Promise<Number>}
     */
    async allowance(owner, spender) {
        const [allowance, decimals] = await Promise.all([
            this._wallet.call(
                this._scoreAddress,
                'allowance',
                {_owner: owner, _spender: spender}
            ),
            this._wallet.call(
                this._scoreAddress,
                'decimals',
                {}
            )
        ]);

        return utils
            .toBigNumber(allowance)
            .dividedBy(10 ** utils.toBigNumber(decimals))
            .toNumber();
    }


    /**
     * Approve spender to transfer the specified ACT from the owner's balance
     * @param  {String} spender address of the spender
     * @param  {Number} value   ACT amount to approve
     * @return {Promise<String>} txHash
     */
    async approve(spender, value) {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'approve',
            {
                _spender: spender,
                _value: utils.toHexString(
                    utils.toBigNumber(value).times(10 ** utils.toBigNumber(decimals))
                ),
            }
        );
    }


    /**
     * Increase allowance of the spender for the owner's balance
     * @param  {String} spender address of the spender
     * @param  {Number} value   ACT amount to increase
     * @return {Promise<String>} txHash
     */
    async incAllowance(spender, value) {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'inc_allowance',
            {
                _spender: spender,
                _value: utils.toHexString(
                    utils.toBigNumber(value).times(10 ** utils.toBigNumber(decimals))
                ),
            }
        );
    }

    /**
     * Decrease allowance of the spender for the owner's balance
     * @param  {String} spender address of the spender
     * @param  {Number} value   ACT amount to decrease
     * @return {Promise<String>} txHash
     */
    async decAllowance(spender, value) {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'dec_allowance',
            {
                _spender: spender,
                _value: utils.toHexString(
                    utils.toBigNumber(value).times(10 ** utils.toBigNumber(decimals))
                ),
            }
        );
    }


    /**
     * Tranfer ACT from sender to recipient
     * Only the amount of allowance from sender can be tranferred
     * @param  {String} from  address of the sender
     * @param  {String} to    address of the recipient
     * @param  {Number} value ACT amount to transfer
     * @return {Promise<String>} txHash
     */
    async transferFrom(from, to, value) {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'transfer_from',
            {
                _from: from,
                _to: to,
                _value: utils.toHexString(
                    utils.toBigNumber(value).times(10 ** utils.toBigNumber(decimals))
                ),
            }
        );
    }


    /**
     * Mint tokens and allocate to the specified recipient
     * @param  {String} to     address of the recipient
     * @param  {Number} amount amount to mint
     * @return {Promise<String>} txHash
     */
    async mint(to, amount) {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'mint',
            {
                _to: to,
                _amount: utils.toHexString(
                    utils.toBigNumber(amount).times(10 ** utils.toBigNumber(decimals))
                ),
            }
        );
    }


    /**
     * Burn tokens
     * @param  {Number} amount amount to burn
     * @return {Promise<String>} txHash
     */
    async burn(amount) {
        const decimals = await this._wallet.call(
            this._scoreAddress,
            'decimals',
            {}
        );

        return this._wallet.callContractTx(
            this._scoreAddress,
            'burn',
            {
                _amount: utils.toHexString(
                    utils.toBigNumber(amount).times(10 ** utils.toBigNumber(decimals))
                ),
            }
        );
    }


    /**
     * Pause contract to disable it's functionalities
     * @return {Promise<String>} txHash
     */
    async pause() {
        return this._wallet.callContractTx(
            this._scoreAddress,
            'pause',
        );
    }


    /**
     * Unpause contract to enable it's functionalities
     * @return {Promise<String>} txHash
     */
    async unpause() {
        return this._wallet.callContractTx(
            this._scoreAddress,
            'unpause',
        );
    }

    /**
     * Returns whether the contract is paused or not
     * @return {Promise<Bool>} true: paused, false: unpaused
     */
    async paused() {
        const paused = await this._wallet.call(
            this._scoreAddress,
            'paused',
            {}
        );

        if (paused === '0x1') {
            return true;
        } else {
            return false;
        }
    }

    /**
     * set/unset blacklist
     * @param  {String} account address to be set/unset as blacklist
     * @param  {Bool} flag true:set, false:unset
     * @return {Promise<String>} txHash
     */
    async setBlacklist(account, flag) {
        return this._wallet.callContractTx(
            this._scoreAddress,
            'set_blacklist',
            {
                _account: account,
                _value:utils.toHexString(flag ? 1 : 0)
            }
        );
    }

    /**
     * set/unset whitelist
     * @param  {String} account address to be set/unset as whitelist
     * @param  {Bool} flag true:set, false:unset
     * @return {Promise<String>} txHash
     */
    async setWhitelist(account, flag) {
        return this._wallet.callContractTx(
            this._scoreAddress,
            'set_whitelist',
            {
                _account: account,
                _value:utils.toHexString(flag ? 1 : 0)
            }
        );
    }


    /**
     * Returns fee sharing proportion of the address
     * @param  {String} address
     * @return {Promise<Number>}
     */
    async getProportion(address) {
        const proportion = await this._wallet.call(
            this._scoreAddress,
            'get_proportion',
            {_address: address}
        )

        return utils.toBigNumber(proportion);
    }


    /**
     * add to whitelist for fee sharing
     * @param  {String} address
     * @param  {Number} proportion
     * @return {Promise<String>} txHash
     */
    async addFeeWhitelist(address, proportion) {
        return this._wallet.callContractTx(
            this._scoreAddress,
            'add_fee_whitelist',
            {
                _address: address,
                _proportion:utils.toHexString(proportion)
            }
        );
    }

}

/** @type {ACT} */
module.exports = ACT;