UNPKG

bitcore-node

Version:

A blockchain indexing node with extended capabilities using bitcore

303 lines 12.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chai_1 = require("chai"); const sinon_1 = __importDefault(require("sinon")); const io = __importStar(require("socket.io-client")); const config_1 = __importDefault(require("../../src/config")); const p2p_1 = require("../../src/modules/bitcoin/p2p"); const rpc_1 = require("../../src/rpc"); const api_1 = require("../../src/services/api"); const event_1 = require("../../src/services/event"); const helpers_1 = require("../helpers"); const { PrivateKey } = require('bitcore-lib'); const chain = 'BTC'; const network = 'regtest'; const chainConfig = config_1.default.chains[chain][network]; const creds = chainConfig.rpc; const rpc = new rpc_1.AsyncRPC(creds.username, creds.password, creds.host, creds.port); const bitcore_client_1 = require("bitcore-client"); const wallet_1 = require("../../src/models/wallet"); const walletAddress_1 = require("../../src/models/walletAddress"); const socket_1 = require("../../src/services/socket"); const utils_1 = require("../../src/utils"); const integration_1 = require("../helpers/integration"); function getSocket() { const socket = io.connect('http://localhost:3000', { transports: ['websocket'] }); return socket; } let p2pWorker; let socket = getSocket(); const bwsPrivKey = new PrivateKey(); const bwsKey = bwsPrivKey.publicKey.toString('hex'); const authKey = new PrivateKey(); const pubKey = authKey.publicKey.toString('hex'); const address = '2MuYKLUaKCenkEpwPkWUwYpBoDBNA2dgY3t'; const sandbox = sinon_1.default.createSandbox(); describe('Websockets', function () { const suite = this; this.timeout(60000); before(async () => { (0, integration_1.intBeforeHelper)(); sandbox.stub(socket_1.Socket.serviceConfig, 'bwsKeys').value([bwsKey]); await (0, helpers_1.resetDatabase)(); await event_1.Event.start(); await api_1.Api.start(); const inserted = await wallet_1.WalletStorage.collection.insertOne({ chain, network, name: 'WalletSocketTest', singleAddress: false, pubKey, path: '' }); await walletAddress_1.WalletAddressStorage.collection.insertOne({ address, chain, network, processed: true, wallet: inserted.insertedId }); }); after(async () => { await event_1.Event.stop(); await api_1.Api.stop(); await (0, helpers_1.resetDatabase)(); await (0, integration_1.intAfterHelper)(suite); }); beforeEach(async () => { socket = getSocket(); const connected = new Promise(r => { socket.on('connect', () => { console.log('Socket connected'); r(); }); }); await connected; p2pWorker = new p2p_1.BitcoinP2PWorker({ chain, network, chainConfig }); console.log('Starting p2p worker'); p2pWorker.start(); if (p2pWorker.isSyncing) { console.log('Worker is syncing. Waiting til done'); await p2pWorker.syncDone(); } console.log('Waiting til p2p done'); await p2pWorker.waitTilSync(); console.log('P2P done'); }); afterEach(async () => { try { console.log('Stopping p2p worker'); await p2pWorker.stop(); console.log('Disconnecting socket'); await socket.disconnect(); } catch (e) { console.log('Error stopping p2p worker'); } }); it('should get websocket events', async () => { socket.emit('room', '/BTC/regtest/inv'); let hasSeenTxEvent = false; let hasSeenBlockEvent = false; let hasSeenCoinEvent = false; const anAddress = await rpc.getnewaddress(''); let sawEvents = new Promise(async (resolve) => { socket.on('block', () => { hasSeenBlockEvent = true; console.log('Block event received'); if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) { resolve(); } }); socket.on('tx', () => { hasSeenTxEvent = true; console.log('Transaction event received'); if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) { resolve(); } }); socket.on('coin', () => { hasSeenCoinEvent = true; console.log('Coin event received'); if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) { resolve(); } }); while (!hasSeenBlockEvent) { console.log('WAITING FOR BLOCK EVENT ON SOCKET'); if (hasSeenTxEvent && hasSeenCoinEvent && hasSeenBlockEvent) { return resolve(); } await (0, utils_1.wait)(1000); } }); console.log('Generating 100 blocks'); await rpc.call('generatetoaddress', [101, anAddress]); await p2pWorker.syncDone(); console.log('Sync done, generating new block'); await rpc.call('generatetoaddress', [1, anAddress]); console.log('Sending bitcoin'); await rpc.sendtoaddress(address, 0.1); await sawEvents; (0, chai_1.expect)(hasSeenBlockEvent).to.equal(true); (0, chai_1.expect)(hasSeenTxEvent).to.equal(true); (0, chai_1.expect)(hasSeenCoinEvent).to.equal(true); }); it('should get wallet events', async () => { const authClient = new bitcore_client_1.Client({ apiUrl: 'http://localhost:3000/api', authKey }); const payload = { method: 'socket', url: 'http://localhost:3000/api' }; const authPayload = { pubKey, message: authClient.getMessage(payload), signature: authClient.sign(payload) }; const chain = 'BTC'; const network = 'regtest'; const roomPrefix = `/${chain}/${network}/`; socket.emit('room', roomPrefix + 'wallet', authPayload); let hasSeenTxEvent = false; let hasSeenCoinEvent = false; let sawEvents = new Promise(async (resolve) => { socket.on('tx', () => { hasSeenTxEvent = true; console.log('Transaction event received'); if (hasSeenTxEvent && hasSeenCoinEvent) { resolve(); } }); socket.on('coin', () => { hasSeenCoinEvent = true; console.log('Coin event received'); if (hasSeenTxEvent && hasSeenCoinEvent) { resolve(); } }); while (!hasSeenTxEvent) { console.log('WAITING FOR TX EVENT ON SOCKET'); if (hasSeenTxEvent && hasSeenCoinEvent) { return resolve(); } await (0, utils_1.wait)(1000); } }); await rpc.sendtoaddress(address, 0.1); await sawEvents; (0, chai_1.expect)(hasSeenTxEvent).to.equal(true); (0, chai_1.expect)(hasSeenCoinEvent).to.equal(true); }); it('should get all wallet events', async () => { const authClient = new bitcore_client_1.Client({ apiUrl: 'http://localhost:3000/api', authKey: bwsPrivKey }); const payload = { method: 'socket', url: 'http://localhost:3000/api' }; const authPayload = { pubKey: bwsKey, message: authClient.getMessage(payload), signature: authClient.sign(payload) }; const chain = 'BTC'; const network = 'regtest'; const roomPrefix = `/${chain}/${network}/`; socket.emit('room', roomPrefix + 'wallets', authPayload); let hasSeenTxEvent = false; let hasSeenCoinEvent = false; let sawEvents = new Promise(async (resolve) => { socket.on('tx', () => { hasSeenTxEvent = true; console.log('Transaction event received'); if (hasSeenTxEvent && hasSeenCoinEvent) { resolve(); } }); socket.on('coin', () => { hasSeenCoinEvent = true; console.log('Coin event received'); if (hasSeenTxEvent && hasSeenCoinEvent) { resolve(); } }); while (!hasSeenTxEvent) { console.log('WAITING FOR Wallet-TX EVENT ON SOCKET'); if (hasSeenTxEvent && hasSeenCoinEvent) { return resolve(); } await (0, utils_1.wait)(1000); } }); await rpc.sendtoaddress(address, 0.1); await sawEvents; (0, chai_1.expect)(hasSeenTxEvent).to.equal(true); (0, chai_1.expect)(hasSeenCoinEvent).to.equal(true); sandbox.restore(); }); it('should get an error when the key does not match the bwsKey', async () => { const pubKey = authKey.publicKey.toString('hex'); const wrongKey = new PrivateKey(); const authClient = new bitcore_client_1.Client({ apiUrl: 'http://localhost:3000/api', authKey: wrongKey }); const payload = { method: 'socket', url: 'http://localhost:3000/api' }; const authPayload = { pubKey, message: authClient.getMessage(payload), signature: authClient.sign(payload) }; const chain = 'BTC'; const network = 'regtest'; const roomPrefix = `/${chain}/${network}/`; let failed = new Promise(resolve => { socket.on('failure', e => { (0, chai_1.expect)(e.message).to.include('Authentication failed'); resolve(); }); }); socket.emit('room', roomPrefix + 'wallets', authPayload); await failed; }); it('should get an error when the signature is invalid', async () => { const wrongKey = new PrivateKey(); const authClient = new bitcore_client_1.Client({ apiUrl: 'http://localhost:3000/api', authKey: wrongKey }); const payload = { method: 'socket', url: 'http://localhost:3000/api' }; const authPayload = { pubKey, message: authClient.getMessage(payload), signature: 'invalid' }; const chain = 'BTC'; const network = 'regtest'; const roomPrefix = `/${chain}/${network}/`; let failed = new Promise(resolve => { socket.on('failure', e => { (0, chai_1.expect)(e.message).to.include('Authentication failed'); resolve(); }); }); socket.emit('room', roomPrefix + 'wallet', authPayload); await failed; }); }); //# sourceMappingURL=websocket.spec.js.map