bitcore-node
Version:
A blockchain indexing node with extended capabilities using bitcore
71 lines • 3.39 kB
JavaScript
;
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