How to subscribe to `newBlockHeaders` on local RSK node over websockets? - websocket

I'm connecting to RSKj using the following endpoint:
ws://localhost:4444/
... However, I am unable to connect.
Note that the equivalent HTTP endpoint http://localhost:4444/
work for me, so I know that my RSKj node is running properly.
I need to listen for newBlockHeaders, so I prefer to use WebSockets (instead of HTTP).
How can I do this?

RSKj by default uses 4444 as the port for the HTTP transport;
and 4445 as the port for the Websockets transport.
Also note that the websockets endpoint is not at /,
but rather at websocket.
Therefore use ws://localhost:4445/websocket as your endpoint.
If you're using web3.js,
you can create a web3 instance that connects over Websockets
using the following:
const Web3 = require('web3');
const wsEndpoint = 'ws://localhost:4445/websocket';
const wsProvider =
new Web3.providers.WebsocketProvider(wsEndpoint);
const web3 = new Web3(wsProvider);
The second part of your question can be done
using eth_subscribe on newBlockHeaders.
Using the web3 instance from above like so:
// eth_subscribe newBlockHeaders
web3.eth.subscribe('newBlockHeaders', function(error, blockHeader) {
if (!error) {
// TODO something with blockHeader
} else {
// TODO something with error
}
});

Related

Listen to XRPL payments: Google Cloud Run container failed to start and listen to the port

I have an XRP wallet and I'm trying to monitor incoming payments to this address with WebSockets.
My code works fine locally.
After I subscribed to the wallet address, I simply listen to "transaction" events and get the details about the payments made to that address.
But, I need it to run 24/7 on the cloud. Nothing heavy is here. It is simply a single connection running forever.
The problem is, when I deploy my code to Google Cloud Run, I get the following error:
The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable.
So here is my question:
Given that I'm listening to "transactions" via wss://xrplcluster.com/ (with no ports), how should I modify my code to resolve the Cloud Run complain.
Here you are my code and thanks in advance.
import { Client } from 'xrpl';
const client = new Client("wss://xrplcluster.com/");
async function main() {
await client.connect();
const response = await client.request({
command: "subscribe",
accounts: ["my-wallet-address"]
})
client.on("transaction", tx => {
if (tx.validated) {
const transaction = {
amount: tx.transaction.Amount,
from: tx.transaction.Account,
};
console.log(transaction);
}
});
client.on("disconnected", async code => {
console.log(`The wss client is disconnected with code: ${code}`);
await client.connect();
});
}
main();

How to obtain client MAC, ip and other information in the 'ws.on('connection')' callback function?

This is the ws module, what I want to ask is how to get the client's MAC, ip and other information when connecting
const WebSocket = require('ws');
const WebSocketServer = WebSocket.Server;
const wss = new WebSocketServer({
//...
}, () => {
});
wss.on('connection', function (ws, req) {}); //How to get client MAC, ip and other information?
I don't know what you mean by "other information", but req is an http.IncomingMessage, so the documentation would be a good starting point.
For example, the IP address is accessible as req.socket.localAddress.
You won't be able to get the MAC address.

How to enable trust proxy in express. Nestjs app

I am learning nestjs and, building an app but my ip is behind the proxy,
Nestjs documentation says enable the trust proxy in express,
https://docs.nestjs.com/security/rate-limiting
I am getting trouble how to do that and then how to find the IP.
Try this
import { NestExpressApplication } from "#nestjs/platform-express"
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.set('trust proxy', 1);
Credit:
Nestjs Docs Offical
Nestjs Docs But Not Offical
Express behind proxies
for Fastify adapter trustProxy accept true, number, array of CIDRs, and string of comma separated CIDRs and should be passed like that:
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter({
// #see https://www.fastify.io/docs/latest/Reference/Server/#trustproxy
trustProxy: process.env.TRUST_PROXY?.match(/\d/)
? +process.env.TRUST_PROXY
: process.env.TRUST_PROXY,
}),
);
await app.listen(port, process.env.ADDRESS); // ADDRES = "undefined" or "0.0.0.0"

Is there analog of express's app.set( 'something', something ) in koa?

I need socket.io instance in several places in my app. To achieve this in express i can do this:
app.set('io', io);
In koa right now i have this:
app.use( async ( ctx, next ) => {
ctx.io = io;
await next();
});
This works, but this middleware executes every time my server recieves request. Is there a better way to do this?
I don't know how you are fully implementing but there are a couple things that you can do is you can either pass an addition argument and upgrade the connection to a websocket that will bypass the rest of the middlewares. Or, what I do personally is just have any websocket connection go to a different end point. This will help with any future scalability issues. for example, if you need to create clusters of your server then you will have more control as well will help you testing your backend easier. That's what I would do atleast. My socket.io back end looks like this:
server.ts
oh yea I'm using typescript in the back end
require('dotenv').config({ path: __dirname + '/.env' });
import Koa from 'koa';
const koa = new Koa();
import cors from '#koa/cors';
const PORT = process.env.CHAT_PORT || 3000;
const ENV = process.env.NODE_ENV || 'development';
const server = require('http').createServer(app, { origins: 'http://server.ip' });
const io = (module.exports.io = require('socket.io')(server));
import SocketManager from './lib/SocketManager';
app.use(
cors({
origin: '*',
optionsSuccessStatus: 200,
}),
);
// server setup
server.listen(PORT, (err: ErrorEvent): void => {
if (err) console.error('❌ Unable to connect the server: ', err);
console.log(`💻 Chat server listening on port ${PORT} - ${ENV} environment`);
});
io.on('connection', SocketManager);
then just create a socket manager that imports the io instance and you can then go ahead and handle all the connections.
I hope this is the answer you were looking for/gave you some better insight.

Connect to a sails.js instance via websockets

Is it possible to connect any external application to my sails.js application via WebSockets?
I can use the underlying socket.io embedded in sails.js to talk between the client and server, that's not a problem.
But, I would like to connect another, separate, application to the sails.js server via websockets, and have those two communicate with each other that way, and I am wondering if this is possible?
If so, how can we do this?
Thanks.
Based on SailsJS documentation, we have access to the io object of socket.io, via sails.io.
From that, I just adjusted boostrap.js:
module.exports.bootstrap = function (cb) {
sails.io.on('connection', function (socket) {
socket.on('helloFromClient', function (data) {
console.log('helloFromClient', data);
socket.emit('helloFromServer', {server: 'says hello'});
});
});
cb();
};
Then, in my other nodejs application, which could also be another SailsJS application and I will test that later on, I simply connected and sent a message:
var io = require('socket.io-client');
var socket = io.connect('http://localhost:3000');
socket.emit('helloFromClient', {client: 'says hello'});
socket.on('helloFromServer', function (data) {
console.log('helloFromServer', data);
});
And here are the outputs.
In SailsJS I see:
helloFromClient { client: 'says hello' }
In my client nodejs app I see:
helloFromServer { server: 'says hello' }
So, it seems to be working just fine.

Resources