"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DogeTransaction = void 0;
const constants_1 = require("../../utils/constants");
const utils_1 = require("../../utils/utils");
const TransactionBase_1 = require("../TransactionBase");
const DogeAddress_1 = require("../addressObjects/DogeAddress");
const UtxoTransaction_1 = require("./UtxoTransaction");
class DogeTransaction extends UtxoTransaction_1.UtxoTransaction {
    isValidPkscript(index) {
        const vout = this.extractVoutAt(index);
        if (!vout.scriptPubKey.address)
            return true; //OP_RETURN
        const address = new DogeAddress_1.DogeAddress(vout.scriptPubKey.address);
        return address.addressToPkscript() == vout.scriptPubKey.hex;
    }
    get currencyName() {
        return constants_1.DOGE_NATIVE_TOKEN_NAME;
    }
    async paymentSummary({ client, inUtxo, outUtxo }) {
        try {
            this.assertValidVinIndex(inUtxo);
        }
        catch (e) {
            return { status: TransactionBase_1.PaymentSummaryStatus.InvalidInUtxo };
        }
        try {
            this.assertValidVoutIndex(outUtxo);
        }
        catch (e) {
            return { status: TransactionBase_1.PaymentSummaryStatus.InvalidOutUtxo };
        }
        // TODO: update
        await this.vinVoutAt(inUtxo, client);
        if (this.type === "coinbase") {
            return { status: TransactionBase_1.PaymentSummaryStatus.Coinbase };
        }
        const spentAmount = this.spentAmounts[inUtxo];
        if (!spentAmount.address) {
            return { status: TransactionBase_1.PaymentSummaryStatus.NoSpentAmountAddress };
        }
        const receiveAmount = this.receivedAmounts[outUtxo];
        if (!receiveAmount.address) {
            return { status: TransactionBase_1.PaymentSummaryStatus.NoReceiveAmountAddress };
        }
        // Extract addresses from input and output fields
        const sourceAddress = spentAmount.address;
        const receivingAddress = receiveAmount.address;
        // We will update this once we iterate over inputs and outputs if we have full transaction
        let oneToOne = true;
        const isFull = this.type === "full_payment";
        if (isFull) {
            let inFunds = (0, utils_1.toBN)(0);
            let returnFunds = (0, utils_1.toBN)(0);
            let outFunds = (0, utils_1.toBN)(0);
            let inFundsOfReceivingAddress = (0, utils_1.toBN)(0);
            for (const vinAmount of this.spentAmounts) {
                if (sourceAddress && vinAmount.address === sourceAddress) {
                    inFunds = inFunds.add(vinAmount.amount);
                }
                if (receivingAddress && vinAmount.address === receivingAddress) {
                    inFundsOfReceivingAddress = inFundsOfReceivingAddress.add(vinAmount.amount);
                }
                if (oneToOne && vinAmount.address != sourceAddress && vinAmount.address != receivingAddress) {
                    oneToOne = false;
                }
            }
            for (const voutAmount of this.receivedAmounts) {
                if (sourceAddress && voutAmount.address === sourceAddress) {
                    returnFunds = returnFunds.add(voutAmount.amount);
                }
                if (receivingAddress && voutAmount.address === receivingAddress) {
                    outFunds = outFunds.add(voutAmount.amount);
                }
                // Outputs without address do not break one-to-one condition
                if (oneToOne && !voutAmount.address && voutAmount.amount.gt((0, utils_1.toBN)(0))) {
                    oneToOne = false;
                }
                if (oneToOne && voutAmount.address && voutAmount.address != sourceAddress && voutAmount.address != receivingAddress) {
                    oneToOne = false;
                }
            }
            return {
                status: TransactionBase_1.PaymentSummaryStatus.Success,
                response: {
                    blockTimestamp: this.unixTimestamp,
                    transactionHash: this.stdTxid,
                    sourceAddressHash: (0, utils_1.standardAddressHash)(sourceAddress),
                    sourceAddress,
                    receivingAddress,
                    receivingAddressHash: (0, utils_1.standardAddressHash)(receivingAddress),
                    spentAmount: inFunds.sub(returnFunds),
                    receivedAmount: outFunds.sub(inFundsOfReceivingAddress),
                    transactionStatus: this.successStatus,
                    paymentReference: this.stdPaymentReference,
                    // Intended and actual amounts are the same for utxo transactions
                    intendedSourceAddressHash: (0, utils_1.standardAddressHash)(sourceAddress),
                    intendedSourceAddress: sourceAddress,
                    intendedSourceAmount: inFunds.sub(returnFunds),
                    intendedReceivingAddressHash: (0, utils_1.standardAddressHash)(receivingAddress),
                    intendedReceivingAddress: receivingAddress,
                    intendedReceivingAmount: outFunds.sub(inFundsOfReceivingAddress),
                    oneToOne,
                    isFull,
                },
            };
        }
        else {
            // Since we don't have all inputs "decoded" we can't be sure that transaction is one-to-one
            oneToOne = false;
            const spentAmount = sourceAddress && inUtxo != null ? this.spentAmounts[inUtxo].amount : (0, utils_1.toBN)(0);
            const receivedAmount = receivingAddress && outUtxo != null ? this.receivedAmounts[outUtxo].amount : (0, utils_1.toBN)(0);
            return {
                status: this.isValidPkscript(outUtxo) ? TransactionBase_1.PaymentSummaryStatus.Success : TransactionBase_1.PaymentSummaryStatus.InvalidPkscript,
                response: {
                    blockTimestamp: this.unixTimestamp,
                    transactionHash: this.stdTxid,
                    sourceAddress,
                    sourceAddressHash: (0, utils_1.standardAddressHash)(sourceAddress),
                    receivingAddress,
                    receivingAddressHash: (0, utils_1.standardAddressHash)(receivingAddress),
                    spentAmount,
                    receivedAmount,
                    paymentReference: this.stdPaymentReference,
                    transactionStatus: this.successStatus,
                    // Intended and actual amounts are the same for utxo transactions
                    intendedSourceAddressHash: (0, utils_1.standardAddressHash)(sourceAddress),
                    intendedSourceAddress: sourceAddress,
                    intendedSourceAmount: spentAmount,
                    intendedReceivingAddressHash: (0, utils_1.standardAddressHash)(receivingAddress),
                    intendedReceivingAddress: receivingAddress,
                    intendedReceivingAmount: receivedAmount,
                    oneToOne,
                    isFull,
                },
            };
        }
    }
}
exports.DogeTransaction = DogeTransaction;
//# sourceMappingURL=DogeTransaction.js.map