This commit is contained in:
Ben
2023-06-09 22:40:35 -04:00
commit 4ce2a59519
20 changed files with 9438 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});
+12
View File
@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
+16
View File
@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { BitcoinStratumProvider } from './bitcoin-stratum.provider';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService, BitcoinStratumProvider],
})
export class AppModule {
constructor(private readonly bitcoinStratumProvider: BitcoinStratumProvider) {
this.bitcoinStratumProvider.listen(3333);
}
}
+8
View File
@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!@';
}
}
+90
View File
@@ -0,0 +1,90 @@
import { Injectable } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate, ValidatorOptions } from 'class-validator';
import { Server, Socket } from 'net';
import { eMethod } from './models/enums/eMethod';
import { SubscriptionMessage } from './models/SubscriptionMessage';
@Injectable()
export class BitcoinStratumProvider {
private server: Server;
constructor() {
this.server = new Server((socket: Socket) => {
console.log('New client connected:', socket.remoteAddress);
socket.on('data', this.handleData.bind(this, socket));
socket.on('end', () => {
// Handle socket disconnection
console.log('Client disconnected:', socket.remoteAddress);
});
socket.on('error', (error: Error) => {
// Handle socket error
console.error('Socket error:', error);
});
});
}
private async handleData(socket: Socket, data: Buffer) {
const message = data.toString();
console.log('Received:', message);
// Parse the message and check if it's the initial subscription message
const parsedMessage = JSON.parse(message);
if (parsedMessage.method === eMethod.SUBSCRIBE) {
const subscriptionMessage = plainToInstance(
SubscriptionMessage,
parsedMessage,
);
const validatorOptions: ValidatorOptions = {
whitelist: true,
forbidNonWhitelisted: true,
};
const errors = await validate(subscriptionMessage, validatorOptions);
if (errors.length === 0) {
const response = this.buildSubscriptionResponse(subscriptionMessage.id);
socket.write(JSON.stringify(response) + '\n');
}
}
}
private buildSubscriptionResponse(requestId: number): any {
const subscriptionResponse = {
id: requestId,
result: [
[
[
'mining.set_difficulty',
'0000000c9c7a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9',
],
[
'mining.notify',
'0000000c9c7a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9',
],
],
'a843cfc2',
4,
],
};
return subscriptionResponse;
}
listen(port: number) {
this.server.listen(port, () => {
console.log(`Bitcoin Stratum server is listening on port ${port}`);
});
}
}
+10
View File
@@ -0,0 +1,10 @@
import { NestFactory } from '@nestjs/core';
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(AppModule, new FastifyAdapter());
await app.listen(3000, '0.0.0.0');
}
bootstrap();
+7
View File
@@ -0,0 +1,7 @@
import { eMethod } from './enums/eMethod';
export class SubscriptionMessage {
id: number;
method: eMethod.SUBSCRIBE;
params: string[];
}
+3
View File
@@ -0,0 +1,3 @@
export enum eMethod {
SUBSCRIBE = 'mining.subscribe'
}