UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

71 lines 3.39 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InternalTxRelatedFilterTransform = void 0; const walletAddress_1 = require("../../../../models/walletAddress"); const streamWithEventPipe_1 = require("../../../../utils/streamWithEventPipe"); class InternalTxRelatedFilterTransform extends streamWithEventPipe_1.TransformWithEventPipe { constructor(web3, walletId) { super({ objectMode: true }); this.web3 = web3; this.walletId = walletId; this.walletAddresses = []; } /** * This creates a duplicate transaction object for each relevant * internal tx with the `value` field reset to the internal value. * @param tx Transaction object * @param _ Encoding (discarded) * @param done Callback * @returns */ async _transform(tx, _, done) { const walletAddresses = await this.getWalletAddresses(tx); // TODO: rethink how we handle complex smart contracts. Creating objects w/ dup txid's doesn't seem right. let internalTxsToProcess = []; if (tx.effects && tx.effects.length) { const walletRelatedInternalTxs = tx.effects.filter((internalTx) => walletAddresses.includes(internalTx.to) && !internalTx.contractAddress); const refundTxs = walletRelatedInternalTxs.filter(i => i.to === tx.from); const nonRefundTxs = walletRelatedInternalTxs.filter(i => i.to != tx.from); const refundTotal = refundTxs.reduce((a, b) => a + Number(b.amount), 0); // Only consider it a refund if the amount refunded is less than or equal to tx value const hasRefund = refundTotal <= tx.value; if (hasRefund) { // Subtract refund from tx.value tx.value -= refundTotal; // Handle any remaining internal txs internalTxsToProcess = nonRefundTxs; } else { // Treat all txs normal internalTxsToProcess = refundTxs.concat(nonRefundTxs); } for (let internalTx of internalTxsToProcess) { const _tx = Object.assign({}, tx); _tx.value = Number(internalTx.amount); _tx.to = internalTx.to; if (internalTx.from != tx.from) { _tx.initialFrom = tx.from; _tx.from = internalTx.from; } // This is how a requester can verify uniqueness in light of duplicated txids _tx.callStack = internalTx.callStack; this.push(_tx); } } // Discard original tx if original value is 0 - perhaps after refunds if (internalTxsToProcess.length === 0 || tx.value != 0) { this.push(tx); } return done(); } async getWalletAddresses(tx) { if (!this.walletAddresses.length) { this.walletAddresses = await walletAddress_1.WalletAddressStorage.collection .find({ chain: tx.chain, network: tx.network, wallet: this.walletId }) .toArray(); } return this.walletAddresses.map(walletAddress => this.web3.utils.toChecksumAddress(walletAddress.address)); } } exports.InternalTxRelatedFilterTransform = InternalTxRelatedFilterTransform; //# sourceMappingURL=internalTxTransform.js.map