"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RippleDbWalletTransactions = void 0;
const stream_1 = require("stream");
const coin_1 = require("../../../models/coin");
const walletAddress_1 = require("../../../models/walletAddress");
class RippleDbWalletTransactions extends stream_1.Transform {
    constructor(wallet) {
        super({ objectMode: true });
        this.wallet = wallet;
    }
    async getAddresses() {
        const { chain, network, _id } = this.wallet;
        if (!this.walletAddresses) {
            this.walletAddresses = await walletAddress_1.WalletAddressStorage.collection.find({ chain, network, wallet: _id }).toArray();
        }
        return this.walletAddresses;
    }
    getHistoryEntry(category, value, tx, o) {
        return (JSON.stringify({
            id: tx.txid,
            txid: tx.txid,
            fee: tx.fee,
            size: 0,
            category,
            satoshis: value,
            height: tx.blockHeight,
            blockTime: tx.blockTimeNormalized,
            ...(o && {
                address: o.address,
                outputIndex: o.mintIndex
            })
        }) + '\n');
    }
    async _transform(tx, _, done) {
        const { chain, network } = this.wallet;
        const outputs = await coin_1.CoinStorage.collection
            .find({
            chain,
            network,
            mintTxid: tx.txid
        }, { batchSize: 10000 })
            .project({ address: 1, wallets: 1, value: 1, mintIndex: 1 })
            .addCursorFlag('noCursorTimeout', true)
            .toArray();
        const walletAddressesObjs = await this.getAddresses();
        const walletAddresses = walletAddressesObjs.map(w => w.address);
        const sending = walletAddresses.includes(tx.from);
        for (const o of outputs) {
            const isSend = !walletAddresses.includes(o.address);
            const isMove = o.address != tx.from && walletAddresses.includes(o.address);
            if (sending) {
                const sendValue = -1 * Math.abs(o.value);
                if (isSend) {
                    this.push(this.getHistoryEntry('send', sendValue, tx, o));
                }
                else if (isMove) {
                    this.push(this.getHistoryEntry('move', sendValue, tx, o));
                }
            }
            else {
                const isReceiving = walletAddresses.includes(o.address);
                if (isReceiving) {
                    const receiveValue = Math.abs(o.value);
                    this.push(this.getHistoryEntry('receive', receiveValue, tx, o));
                }
            }
        }
        if (sending && tx.fee > 0) {
            this.push(this.getHistoryEntry('fee', -1 * tx.fee, tx));
        }
        done();
    }
}
exports.RippleDbWalletTransactions = RippleDbWalletTransactions;
//# sourceMappingURL=wallet-tx-transform.js.map