"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultTokensAPI = void 0;
const utils_1 = require("../utils");
const types_1 = require("../types");
class DefaultTokensAPI {
    constructor(api, transactionAPI) {
        this.api = api;
        this.transactionAPI = transactionAPI;
    }
    total(currency) {
        return __awaiter(this, void 0, void 0, function* () {
            const currencyId = utils_1.newCurrencyId(this.api, currency);
            const rawAmount = yield this.api.query.tokens.totalIssuance(currencyId);
            return utils_1.newMonetaryAmount(rawAmount.toString(), currency);
        });
    }
    getAccountData(currency, id) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.api.query.tokens.accounts(id, utils_1.newCurrencyId(this.api, currency));
        });
    }
    balance(currency, id) {
        return __awaiter(this, void 0, void 0, function* () {
            const accountData = yield this.getAccountData(currency, id);
            return types_1.parseOrmlTokensAccountData(accountData, currency);
        });
    }
    subscribeToBalance(currency, account, callback) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const accountId = utils_1.newAccountId(this.api, account);
                const unsubscribe = yield this.api.query.tokens.accounts(accountId, utils_1.newCurrencyId(this.api, currency), (accountData) => {
                    callback(account, types_1.parseOrmlTokensAccountData(accountData, currency));
                });
                return unsubscribe;
            }
            catch (error) {
                Promise.reject(error);
            }
            // as a fallback, return an empty void function
            return () => {
                return;
            };
        });
    }
    buildTransferExtrinsic(destination, amount) {
        const amountAtomicUnit = this.api.createType("Balance", amount.toString(true));
        return this.api.tx.tokens.transfer(destination, utils_1.newCurrencyId(this.api, amount.currency), amountAtomicUnit);
    }
    transfer(destination, amount) {
        return __awaiter(this, void 0, void 0, function* () {
            const amountAtomicUnit = this.api.createType("Balance", amount.toString(true));
            const transferTransaction = this.api.tx.tokens.transfer(destination, utils_1.newCurrencyId(this.api, amount.currency), amountAtomicUnit);
            yield this.transactionAPI.sendLogged(transferTransaction, this.api.events.tokens.Transfer, true);
        });
    }
    setBalance(accountId, freeBalance, lockedBalance) {
        return __awaiter(this, void 0, void 0, function* () {
            lockedBalance = lockedBalance ? lockedBalance : utils_1.newMonetaryAmount(0, freeBalance.currency);
            const tx = this.api.tx.sudo.sudo(this.api.tx.tokens.setBalance(accountId, utils_1.newCurrencyId(this.api, freeBalance.currency), freeBalance.toString(true), lockedBalance.toString(true)));
            yield this.transactionAPI.sendLogged(tx, this.api.events.tokens.BalanceSet, true);
        });
    }
}
exports.DefaultTokensAPI = DefaultTokensAPI;
//# sourceMappingURL=tokens.js.map