bitcore-node
Version:
A blockchain indexing node with extended capabilities using bitcore
161 lines • 7.52 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Socket = exports.SocketService = void 0;
const mongodb_1 = require("mongodb");
const socket_io_1 = __importDefault(require("socket.io"));
const Loggify_1 = require("../decorators/Loggify");
const logger_1 = __importDefault(require("../logger"));
const events_1 = require("../models/events");
const wallet_1 = require("../models/wallet");
const auth_1 = require("../utils/auth");
const config_1 = require("./config");
const event_1 = require("./event");
function SanitizeWallet(x) {
const sanitized = Object.assign({}, x, { wallets: new Array() });
if (sanitized.wallets && sanitized.wallets.length > 0) {
delete sanitized.wallets;
}
return sanitized;
}
let SocketService = class SocketService {
constructor({ eventService = event_1.Event, eventModel = events_1.EventStorage, configService = config_1.Config } = {}) {
this.id = Math.random();
this.stopped = true;
this.eventService = eventService;
this.configService = configService;
this.serviceConfig = this.configService.for('socket');
this.eventModel = eventModel;
this.wireup = this.wireup.bind(this);
this.start = this.start.bind(this);
this.signalTx = this.signalTx.bind(this);
this.signalBlock = this.signalBlock.bind(this);
this.signalAddressCoin = this.signalAddressCoin.bind(this);
}
validateRequest(payload) {
try {
const valid = auth_1.Auth.verifyRequestSignature(payload);
return valid;
}
catch (e) {
return false;
}
}
start({ server }) {
const bwsKeys = this.serviceConfig.bwsKeys;
if (this.configService.isDisabled('socket')) {
logger_1.default.info('Disabled Socket Service');
return;
}
if (this.stopped) {
this.stopped = false;
logger_1.default.info('Starting Socket Service');
this.httpServer = server;
this.io = new socket_io_1.default.Server(server);
this.io.sockets.on('connection', socket => {
socket.on('room', (room, payload) => {
const chainNetwork = room.slice(0, room.lastIndexOf('/') + 1);
const roomName = room.slice(room.lastIndexOf('/') + 1);
switch (roomName) {
case 'wallets':
if (bwsKeys.includes(payload.pubKey) && this.validateRequest(payload)) {
socket.join(room);
}
else {
socket.emit('failure', { message: 'Authentication failed' });
}
break;
case 'wallet':
if (this.validateRequest(payload)) {
socket.join(chainNetwork + payload.pubKey);
}
else {
socket.emit('failure', { message: 'Authentication failed' });
}
break;
case 'inv':
case 'address':
socket.join(room);
break;
}
});
});
}
this.wireup();
logger_1.default.info('Started Socket Service');
}
async stop() {
logger_1.default.info('Stopping Socket Service');
this.stopped = true;
this.eventService.txEvent.removeAllListeners();
this.eventService.blockEvent.removeAllListeners();
this.eventService.addressCoinEvent.removeAllListeners();
}
async wireup() {
this.eventService.txEvent.on('tx', async (tx) => {
if (!this.stopped && this.io) {
const { chain, network } = tx;
const sanitizedTx = SanitizeWallet(tx);
this.io.sockets.in(`/${chain}/${network}/inv`).emit('tx', sanitizedTx);
if (tx.wallets && tx.wallets.length) {
const objectIds = tx.wallets.map(w => new mongodb_1.ObjectID(w));
const wallets = await wallet_1.WalletStorage.collection.find({ _id: { $in: objectIds } }).toArray();
for (let wallet of wallets) {
this.io.sockets.in(`/${chain}/${network}/wallets`).emit('tx', { pubKey: wallet.pubKey, tx });
this.io.sockets
.in(`/${chain}/${network}/${wallet.pubKey}`)
.emit('tx', { pubKey: wallet.pubKey, tx: sanitizedTx });
}
}
}
});
this.eventService.blockEvent.on('block', (block) => {
if (!this.stopped && this.io) {
const { chain, network } = block;
this.io.sockets.in(`/${chain}/${network}/inv`).emit('block', block);
}
});
this.eventService.addressCoinEvent.on('coin', async (addressCoin) => {
if (!this.stopped && this.io) {
const { coin, address } = addressCoin;
const { chain, network } = coin;
const sanitizedCoin = SanitizeWallet(coin);
this.io.sockets.in(`/${chain}/${network}/address`).emit(address, sanitizedCoin);
this.io.sockets.in(`/${chain}/${network}/inv`).emit('coin', sanitizedCoin);
if (coin.wallets && coin.wallets.length) {
const objectIds = coin.wallets.map(w => new mongodb_1.ObjectID(w));
const wallets = await wallet_1.WalletStorage.collection.find({ _id: { $in: objectIds } }).toArray();
for (let wallet of wallets) {
this.io.sockets.in(`/${chain}/${network}/wallets`).emit('coin', { pubKey: wallet.pubKey, coin });
this.io.sockets
.in(`/${chain}/${network}/${wallet.pubKey}`)
.emit('coin', { pubKey: wallet.pubKey, coin: sanitizedCoin });
}
}
}
});
}
async signalBlock(block) {
await events_1.EventStorage.signalBlock(block);
}
async signalTx(tx) {
await events_1.EventStorage.signalTx(tx);
}
async signalAddressCoin(payload) {
await events_1.EventStorage.signalAddressCoin(payload);
}
};
exports.SocketService = SocketService;
exports.SocketService = SocketService = __decorate([
Loggify_1.LoggifyClass
], SocketService);
exports.Socket = new SocketService();
//# sourceMappingURL=socket.js.map