"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.Settlements = void 0;
const utils_1 = require("../../procedures/utils");
const internal_1 = require("../../../internal");
const constants_1 = require("../../../utils/constants");
const conversion_1 = require("../../../utils/conversion");
/**
 * Handles all Asset Settlements related functionality
 */
class Settlements extends internal_1.Namespace {
    /**
     * Check whether it is possible to create a settlement Instruction to transfer a certain amount of this Asset's tokens between two Portfolios.
     *
     * @note this takes locked tokens into account. For example, if portfolio A has 1000 tokens and this function is called to check if 700 of them can be
     *   transferred to portfolio B (assuming everything else checks out) the result will be success. If an instruction is created and authorized to transfer those 700 tokens,
     *   they would become locked. From that point, further calls to this function would yield failed results because of the funds being locked, even though they haven't been
     *   transferred yet
     *
     * @param args.from - sender Portfolio (optional, defaults to the current Identity's Default Portfolio)
     * @param args.to - receiver Portfolio
     * @param args.amount - amount of tokens to transfer
     *
     * @deprecated in favor of [[canTransfer]]
     */
    canSettle(args) {
        var _a;
        return __awaiter(this, void 0, void 0, function* () {
            const { parent: { ticker }, context: { polymeshApi: { rpc }, }, context, parent, } = this;
            const { to, amount } = args;
            let { from } = args;
            let isDivisible;
            if (!from) {
                [{ isDivisible }, from] = yield Promise.all([parent.details(), context.getCurrentIdentity()]);
            }
            else {
                ({ isDivisible } = yield parent.details());
            }
            /*
             * The RPC requires a sender account ID (although it's not being used at the moment). We use the current account
             * or a dummy Account (Alice's in testnet) if the SDK was instanced without one
             */
            const senderAddress = ((_a = context.currentPair) === null || _a === void 0 ? void 0 : _a.address) || constants_1.DUMMY_ACCOUNT_ID;
            const fromPortfolioId = conversion_1.portfolioLikeToPortfolioId(from);
            const toPortfolioId = conversion_1.portfolioLikeToPortfolioId(to);
            const fromPortfolio = conversion_1.portfolioIdToPortfolio(fromPortfolioId, context);
            const toPortfolio = conversion_1.portfolioIdToPortfolio(toPortfolioId, context);
            const [, , fromCustodian, toCustodian] = yield Promise.all([
                utils_1.assertPortfolioExists(fromPortfolioId, context),
                utils_1.assertPortfolioExists(toPortfolioId, context),
                fromPortfolio.getCustodian(),
                toPortfolio.getCustodian(),
            ]);
            const res = yield rpc.asset.canTransfer(conversion_1.stringToAccountId(senderAddress, context), conversion_1.stringToIdentityId(fromCustodian.did, context), conversion_1.portfolioIdToMeshPortfolioId(fromPortfolioId, context), conversion_1.stringToIdentityId(toCustodian.did, context), conversion_1.portfolioIdToMeshPortfolioId(toPortfolioId, context), conversion_1.stringToTicker(ticker, context), conversion_1.bigNumberToBalance(amount, context, isDivisible));
            return conversion_1.canTransferResultToTransferStatus(res);
        });
    }
    /**
     * Check whether it is possible to create a settlement instruction to transfer a certain amount of this asset between two Portfolios. Returns a breakdown of
     *   the transaction containing general errors (such as insufficient balance or invalid receiver), any broken transfer restrictions, and any compliance
     *   failures
     *
     * @note this takes locked tokens into account. For example, if portfolio A has 1000 tokens and this function is called to check if 700 of them can be
     *   transferred to portfolio B (assuming everything else checks out) the result will be success. If an instruction is created and authorized to transfer those 700 tokens,
     *   they would become locked. From that point, further calls to this function would yield failed results because of the funds being locked, even though they haven't been
     *   transferred yet
     *
     * @param args.from - sender Portfolio (optional, defaults to the current Identity's Default Portfolio)
     * @param args.to - receiver Portfolio
     * @param args.amount - amount of tokens to transfer
     *
     */
    canTransfer(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const { parent: { ticker }, context: { polymeshApi: { rpc }, }, context, parent, } = this;
            const { to, amount } = args;
            let { from } = args;
            let isDivisible;
            if (!from) {
                [{ isDivisible }, from] = yield Promise.all([parent.details(), context.getCurrentIdentity()]);
            }
            else {
                ({ isDivisible } = yield parent.details());
            }
            const fromPortfolioId = conversion_1.portfolioLikeToPortfolioId(from);
            const toPortfolioId = conversion_1.portfolioLikeToPortfolioId(to);
            const fromPortfolio = conversion_1.portfolioIdToPortfolio(fromPortfolioId, context);
            const toPortfolio = conversion_1.portfolioIdToPortfolio(toPortfolioId, context);
            const [, , fromCustodian, toCustodian] = yield Promise.all([
                utils_1.assertPortfolioExists(fromPortfolioId, context),
                utils_1.assertPortfolioExists(toPortfolioId, context),
                fromPortfolio.getCustodian(),
                toPortfolio.getCustodian(),
            ]);
            const res = yield rpc.asset.canTransferGranular(conversion_1.stringToIdentityId(fromCustodian.did, context), conversion_1.portfolioIdToMeshPortfolioId(fromPortfolioId, context), conversion_1.stringToIdentityId(toCustodian.did, context), conversion_1.portfolioIdToMeshPortfolioId(toPortfolioId, context), conversion_1.stringToTicker(ticker, context), conversion_1.bigNumberToBalance(amount, context, isDivisible));
            return conversion_1.granularCanTransferResultToTransferBreakdown(res, context);
        });
    }
}
exports.Settlements = Settlements;
//# sourceMappingURL=Settlements.js.map