bitcore-node
Version:
A blockchain indexing node with extended capabilities using bitcore
107 lines (104 loc) • 3.66 kB
text/typescript
import { Transform } from 'stream';
import { ITransaction } from '../../../models/baseTransaction';
import { IWallet } from '../../../models/wallet';
import { IWalletAddress, WalletAddressStorage } from '../../../models/walletAddress';
import { BlockTransaction } from '../types';
import { RippleStateProvider } from './csp';
export class RippleWalletTransactions extends Transform {
walletAddresses?: Array<IWalletAddress>;
constructor(private wallet: IWallet, private csp: RippleStateProvider) {
super({ objectMode: true });
}
async getAddresses() {
const { chain, network, _id } = this.wallet;
if (!this.walletAddresses) {
this.walletAddresses = await WalletAddressStorage.collection.find({ chain, network, wallet: _id }).toArray();
}
return this.walletAddresses;
}
async _transform(tx: BlockTransaction, _, done) {
const { network } = this.wallet;
const transaction = this.csp.transform(tx, network) as ITransaction;
const changes = (tx as any).outcome.balanceChanges;
const changed = Object.keys(changes);
const relevantAddresses = (await this.getAddresses()).filter(w => changed.includes(w.address)).map(w => w.address);
let sending = false;
let receiving = false;
for (let address of relevantAddresses) {
for (const output of changes[address]) {
if (Number(output.value) > 0) {
receiving = true;
}
if (Number(output.value) < 0) {
sending = true;
}
}
for (const output of changes[address]) {
if (sending) {
if (!receiving) {
this.push(
JSON.stringify({
id: tx.hash,
txid: tx.hash,
fee: transaction.fee * 1e6,
size: 0,
category: 'send',
satoshis: -1 * Number(output.value) * 1e6,
height: transaction.blockHeight,
address,
outputIndex: changed.indexOf(address),
blockTime: transaction.blockTimeNormalized
}) + '\n'
);
} else {
this.push(
JSON.stringify({
id: tx.hash,
txid: tx.hash,
fee: transaction.fee * 1e6,
size: 0,
category: 'move',
satoshis: -1 * Number(output.value) * 1e6,
height: transaction.blockHeight,
address,
outputIndex: changed.indexOf(address),
blockTime: transaction.blockTimeNormalized
}) + '\n'
);
}
if (transaction.fee > 0) {
this.push(
JSON.stringify({
id: tx.hash,
txid: tx.hash,
category: 'fee',
satoshis: -1 * Number(transaction.fee) * 1e6,
height: transaction.blockHeight,
blockTime: transaction.blockTimeNormalized
}) + '\n'
);
}
return done();
} else {
if (receiving) {
this.push(
JSON.stringify({
id: tx.hash,
txid: tx.hash,
fee: transaction.fee * 1e6,
size: 0,
category: 'receive',
satoshis: Number(output.value) * 1e6,
height: transaction.blockHeight,
address,
outputIndex: changed.indexOf(address),
blockTime: transaction.blockTimeNormalized
}) + '\n'
);
}
}
}
}
done();
}
}