backend server

This commit is contained in:
raja.blaze 2019-07-09 14:52:36 +05:30
parent 69a0172ba1
commit a2204c6c40
46 changed files with 4038 additions and 9 deletions

View File

@ -25,11 +25,27 @@
"@angular/platform-server": "~8.0.0", "@angular/platform-server": "~8.0.0",
"@angular/router": "~8.0.0", "@angular/router": "~8.0.0",
"@nguniversal/express-engine": "^7.0.2", "@nguniversal/express-engine": "^7.0.2",
"@nguniversal/module-map-ngfactory-loader": "v7.0.2", "@nguniversal/module-map-ngfactory-loader": "^7.0.2",
"babel-preset-es2015": "^6.24.1",
"body-parser": "^1.19.0",
"class-transformer": "^0.2.3",
"class-validator": "^0.9.1",
"cors": "^2.8.5",
"dotenv": "^8.0.0",
"express": "^4.15.2", "express": "^4.15.2",
"express-static-gzip": "^1.1.3",
"helmet": "^3.18.0",
"moment": "^2.24.0",
"morgan": "^1.9.1",
"pg": "^7.11.0",
"pg-native": "^3.0.0",
"plotly.js": "^1.48.3", "plotly.js": "^1.48.3",
"rxjs": "~6.4.0", "rxjs": "~6.4.0",
"swagger-jsdoc": "^3.2.9",
"tslib": "^1.9.0", "tslib": "^1.9.0",
"typeorm": "^0.2.18",
"webpack-filter-warnings-plugin": "^1.2.1",
"winston": "^3.2.1",
"zone.js": "~0.9.1" "zone.js": "~0.9.1"
}, },
"devDependencies": { "devDependencies": {

View File

@ -7,13 +7,64 @@ import {ngExpressEngine} from '@nguniversal/express-engine';
import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader'; import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';
import * as express from 'express'; import * as express from 'express';
import { Request, Response, NextFunction } from 'express';
import * as bodyParser from 'body-parser';
import morgan from 'morgan';
import cors from 'cors';
import helmet from 'helmet';
import * as path from 'path';
import { logger } from './server/app/utils';
import expressStaticGzip from 'express-static-gzip';
import swaggerJSDoc from 'swagger-jsdoc';
import { errorMiddleware } from './server/app/middlewares';
import { getRepository, In, getConnection, getConnectionManager } from 'typeorm';
var moment = require('moment');
import { resolve } from 'path';
import { dbConfig } from './server/app/ormconfig';
import { config } from 'dotenv';
// import {
// BlockchainBlockController,
// BlockchainInputController,
// BlockchainKernelController,
// BlockchainOutputController,
// } from './server/app/controllers';
import { BlockchainBlockController } from './server/app/controllers/BlockchainBlock';
import {join} from 'path'; import {join} from 'path';
// var controllers =
// [
// new BlockchainBlockController(),
// new BlockchainInputController(),
// new BlockchainKernelController(),
// new BlockchainOutputController(),
// ];
const connectionManager = getConnectionManager();
const connection = connectionManager.create(dbConfig);
// Faster server renders w/ Prod mode (dev mode never needed) // Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode(); enableProdMode();
// Express server // Express server
const app = express(); const app = express();
let controllerblockchain = new BlockchainBlockController();
app.use(helmet());
app.use(cors());
app.use(morgan('combined'));
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use('/api-docs', express.static(path.join(__dirname, 'swagger')));
app.get('/swagger.json', function(req, res) {
res.setHeader('Content-Type', 'application/json');
res.send(
swaggerJSDoc({
swaggerDefinition: require('./server/app/swagger/swagger.json'),
apis: ['**/*.ts'],
}),
);
});
app.use(errorMiddleware);
const PORT = process.env.PORT || 4000; const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser'); const DIST_FOLDER = join(process.cwd(), 'dist/browser');
@ -33,7 +84,18 @@ app.set('view engine', 'html');
app.set('views', DIST_FOLDER); app.set('views', DIST_FOLDER);
// Example Express Rest API endpoints // Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { }); app.get('/api/test/ok', (req, res) => {
res.status(200).json({
status: 200,
message: 'perifsdfsfod of blocks generation per second fetched Successfully',
});
});
// controllers.forEach(controller => {
// app.use('/epic_explorer/v1', controller.router);
// });
// Server static files from /browser // Server static files from /browser
app.get('*.*', express.static(DIST_FOLDER, { app.get('*.*', express.static(DIST_FOLDER, {
maxAge: '1y' maxAge: '1y'
@ -45,6 +107,13 @@ app.get('*', (req, res) => {
}); });
// Start up the Node server // Start up the Node server
connection
.connect()
.then(() => {
app.listen(PORT, () => { app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`); console.log(`Node Express server listening on http://localhost:${PORT}`);
}); });
})
.catch(error => {
console.log('connection failed..', error);
});

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,322 @@
import express from 'express';
import { Request, Response, NextFunction } from 'express';
import { getRepository } from 'typeorm';
import { validationMiddleware } from '../middlewares';
import {
InternalServerErrorException,
NoDataFoundException,
} from '../exceptions';
import { BlockchainInput } from '../entities';
import {
BlockchainInputCreateDto,
BlockchainInputSingleViewDto,
BlockchainInputUpdateDto,
BlockchainInputPaginationDto,
} from '../dtos';
import { Paginate } from '../utils';
export class BlockchainInputController {
public path = '/blockchain_input';
public router = express.Router();
constructor() {
this.IntializeRoutes();
}
public IntializeRoutes() {
/**
* @swagger
* /epic_explorer/v1/blockchain_input:
* post:
* tags:
* - name: BLOCKCHAIN_INPUT | BLOCKCHAIN_INPUT CONTROLLER
* summary: create a blockchain_input
* description: create a blockchain_input
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: BlockchainInput
* description: create a blockchain_input
* in: body
* required: true
* schema:
* $ref: '#/definitions/BlockchainInputDto'
* responses:
* 200:
* description: blockchain_input created successfully
* definitions:
* BlockchainInputDto:
* description: Dto
* properties:
* Id:
* type: integer
* Data:
* type: string
* Block:
* type: string
*/
this.router.post(
`${this.path}`,
validationMiddleware(BlockchainInputCreateDto),
this.BlockchainInputCreate,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_input/list:
* get:
* tags:
* - name: BLOCKCHAIN_INPUT | BLOCKCHAIN_INPUT CONTROLLER
* description: pagination blockchain_input
* summary: pagination blockchain_input
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: current_page
* description: current page specification
* in: query
* type: integer
* required: true
* - name: page_size
* description: page size specification
* in: query
* type: integer
* required: true
* - name: max_pages
* description: max pages specification
* in: query
* type: integer
* required: true
* responses:
* 200:
* description: blockchain_input list fetched successfully
*/
this.router.get(
`${this.path}/list`,
validationMiddleware(BlockchainInputPaginationDto),
this.BlockchainInputPagination,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_input/id:
* get:
* tags:
* - name: BLOCKCHAIN_INPUT | BLOCKCHAIN_INPUT CONTROLLER
* summary: get single blockchain_input
* description: get single blockchain_input
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: Id
* in: path
* description: blockchain_input id
* required: true
* type: string
* responses:
* 200:
* description: blockchain_input successfully fetched for given id..
*/
this.router.get(
`${this.path}/:id`,
validationMiddleware(BlockchainInputSingleViewDto),
this.BlockchainInputFetch,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_input:
* patch:
* tags:
* - name: BLOCKCHAIN_INPUT | BLOCKCHAIN_INPUT CONTROLLER
* summary: update a blockchain_input
* description: update a blockchain_input
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: blockchain_input
* description:
* in: body
* required: true
* schema:
* $ref: '#/definitions/BlockchainInputDto'
* responses:
* 200:
* description: blockchain_input updated successfully
*/
this.router.patch(
`${this.path}`,
validationMiddleware(BlockchainInputUpdateDto),
this.BlockchainInputUpdate,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_input/id:
* delete:
* tags:
* - name: BLOCKCHAIN_INPUT | BLOCKCHAIN_INPUT CONTROLLER
* summary: delete a blockchain_input
* description: delete a blockchain_input
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: Id
* in: path
* description: blockchain_input id
* required: true
* type: string
* responses:
* 200:
* description: blockchain_input successfully deleted for given id..
*/
this.router.delete(
`${this.path}/:id`,
validationMiddleware(BlockchainInputSingleViewDto),
this.BlockchainInputDelete,
);
}
private BlockchainInputCreate = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainInputRequestData: BlockchainInputCreateDto = request.body;
const BlockchainInputCreateQuery = await getRepository(
BlockchainInput,
).save(BlockchainInputRequestData);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_input created successfully',
response: BlockchainInputCreateQuery,
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainInputFetch = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainInputFetchQuery = await getRepository(
BlockchainInput,
).findOne({
where: { id: request.params.id },
});
BlockchainInputFetchQuery
? response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_inputsuccessfully fetched for given id.',
response: { ...BlockchainInputFetchQuery },
})
: next(new NoDataFoundException());
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainInputUpdate = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainInputRequestData: BlockchainInputUpdateDto = request.body;
const BlockchainInputUpdateQuery = await getRepository(
BlockchainInput,
).update(BlockchainInputRequestData.Id, BlockchainInputRequestData);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_input updated succesfully',
response: { ...BlockchainInputUpdateQuery },
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainInputDelete = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainInputDeleteQuery = await getRepository(
BlockchainInput,
).delete(request.params.Id);
BlockchainInputDeleteQuery
? response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_input successfully deleted for given id.',
response: { ...BlockchainInputDeleteQuery },
})
: next(new NoDataFoundException());
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainInputPagination = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainInputRequestData: BlockchainInputPaginationDto =
request.query;
const BlockchainInputCountQuery = await getRepository(
BlockchainInput,
).findAndCount({});
if (BlockchainInputCountQuery[1]) {
const PaginationReponseData = Paginate(
BlockchainInputCountQuery[1],
BlockchainInputRequestData.CurrentPage,
BlockchainInputRequestData.PageSize,
BlockchainInputRequestData.MaxPages,
);
const BlockchainInputPaginationQuery = await getRepository(
BlockchainInput,
).find({
skip: PaginationReponseData.startIndex,
take: PaginationReponseData.pageSize,
order: {
Id: 'DESC',
},
});
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_input list fetched successfully',
response: {
...PaginationReponseData,
...BlockchainInputPaginationQuery,
},
});
} else {
next(new NoDataFoundException());
}
} catch (error) {
next(new InternalServerErrorException(error));
}
};
}

View File

@ -0,0 +1,714 @@
import express from 'express';
import { Request, Response, NextFunction } from 'express';
import { getRepository, getConnection } from 'typeorm';
import { validationMiddleware } from '../middlewares';
import {
InternalServerErrorException,
NoDataFoundException,
} from '../exceptions';
import { BlockchainKernel } from '../entities';
import {
BlockchainKernelCreateDto,
BlockchainKernelSingleViewDto,
BlockchainKernelUpdateDto,
BlockchainKernelPaginationDto,
TransactionFeeDto,
} from '../dtos';
import { Paginate } from '../utils';
var moment = require('moment');
export class BlockchainKernelController {
public path = '/blockchain_kernel';
public router = express.Router();
constructor() {
this.IntializeRoutes();
}
public IntializeRoutes() {
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel:
* post:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: create a blockchain_kernel
* description: create a blockchain_kernel
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: BlockchainKernel
* description: create a blockchain_kernel
* in: body
* required: true
* schema:
* $ref: '#/definitions/BlockchainKernelDto'
* responses:
* 200:
* description: blockchain_kernel created successfully
* definitions:
* BlockchainKernelDto:
* description: Dto
* properties:
* Id:
* type: integer
* Features:
* type: string
* Fee:
* type: integer
* LockHeight:
* type: integer
* Excess:
* type: string
* ExcessSig:
* type: string
* Block:
* type: string
*/
this.router.post(
`${this.path}`,
validationMiddleware(BlockchainKernelCreateDto),
this.BlockchainKernelCreate,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel/transactionfee:
* get:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: create a blockchain_kernel
* description: create a blockchain_kernel
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: FromDate
* description: Enter the From date
* in: query
* type: string
* - name: ToDate
* description: Enter the To date
* in: query
* type: string
* - name: Interval
* description: Try to give Intevals such as 1 week/ 15 days/ 30 days/ 60 days/ 3 months
* in: query
* type: string
* responses:
* 200:
* description: Transaction fee chart fetched successfully
*/
this.router.get(
`${this.path}/transactionfee`,
validationMiddleware(TransactionFeeDto, true),
this.TransactionFee,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel/transactionheatmap:
* get:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: Transaction Heatmap
* description: Transaction Heatmap (Input/output/kernal)
* consumes:
* - application/json
* produces:
* - application/json
* responses:
* 200:
* description: Transaction heatmap chart fetched successfully
*/
this.router.get(
`${this.path}/transactionheatmap`,
validationMiddleware(TransactionFeeDto, true),
this.HeatmapChart,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel/transactionlinechart:
* get:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: Transaction line chart
* description: Transaction line chart
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: FromDate
* description: Enter the From date
* in: query
* type: string
* - name: ToDate
* description: Enter the To date
* in: query
* type: string
* - name: Interval
* description: Try to give Intevals such as 1 week/ 15 days/ 30 days/ 60 days/ 3 months
* in: query
* type: string
* responses:
* 200:
* description: Transaction line chart fetched successfully
*/
this.router.get(
`${this.path}/transactionlinechart`,
validationMiddleware(TransactionFeeDto, true),
this.TransactionChart,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel/list:
* get:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* description: pagination blockchain_kernel
* summary: pagination blockchain_kernel
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: current_page
* description: current page specification
* in: query
* type: integer
* required: true
* - name: page_size
* description: page size specification
* in: query
* type: integer
* required: true
* - name: max_pages
* description: max pages specification
* in: query
* type: integer
* required: true
* responses:
* 200:
* description: blockchain_kernel list fetched successfully
*/
this.router.get(
`${this.path}/list`,
validationMiddleware(BlockchainKernelPaginationDto),
this.BlockchainKernelPagination,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel/id:
* get:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: get single blockchain_kernel
* description: get single blockchain_kernel
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: Id
* in: path
* description: blockchain_kernel id
* required: true
* type: string
* responses:
* 200:
* description: blockchain_kernel successfully fetched for given id..
*/
this.router.get(
`${this.path}/:id`,
validationMiddleware(BlockchainKernelSingleViewDto),
this.BlockchainKernelFetch,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel:
* patch:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: update a blockchain_kernel
* description: update a blockchain_kernel
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: blockchain_kernel
* description:
* in: body
* required: true
* schema:
* $ref: '#/definitions/BlockchainKernelDto'
* responses:
* 200:
* description: blockchain_kernel updated successfully
*/
this.router.patch(
`${this.path}`,
validationMiddleware(BlockchainKernelUpdateDto),
this.BlockchainKernelUpdate,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_kernel/id:
* delete:
* tags:
* - name: BLOCKCHAIN_KERNEL | BLOCKCHAIN_KERNEL CONTROLLER
* summary: delete a blockchain_kernel
* description: delete a blockchain_kernel
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: Id
* in: path
* description: blockchain_kernel id
* required: true
* type: string
* responses:
* 200:
* description: blockchain_kernel successfully deleted for given id..
*/
this.router.delete(
`${this.path}/:id`,
validationMiddleware(BlockchainKernelSingleViewDto),
this.BlockchainKernelDelete,
);
}
private BlockchainKernelCreate = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainKernelRequestData: BlockchainKernelCreateDto =
request.body;
const BlockchainKernelCreateQuery = await getRepository(
BlockchainKernel,
).save(BlockchainKernelRequestData);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_kernel created successfully',
response: BlockchainKernelCreateQuery,
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainKernelFetch = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainKernelFetchQuery = await getRepository(
BlockchainKernel,
).findOne({
where: { id: request.params.id },
});
BlockchainKernelFetchQuery
? response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_kernelsuccessfully fetched for given id.',
response: { ...BlockchainKernelFetchQuery },
})
: next(new NoDataFoundException());
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainKernelUpdate = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainKernelRequestData: BlockchainKernelUpdateDto =
request.body;
const BlockchainKernelUpdateQuery = await getRepository(
BlockchainKernel,
).update(BlockchainKernelRequestData.Id, BlockchainKernelRequestData);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_kernel updated succesfully',
response: { ...BlockchainKernelUpdateQuery },
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainKernelDelete = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainKernelDeleteQuery = await getRepository(
BlockchainKernel,
).delete(request.params.Id);
BlockchainKernelDeleteQuery
? response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_kernel successfully deleted for given id.',
response: { ...BlockchainKernelDeleteQuery },
})
: next(new NoDataFoundException());
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainKernelPagination = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainKernelRequestData: BlockchainKernelPaginationDto =
request.query;
const BlockchainKernelCountQuery = await getRepository(
BlockchainKernel,
).findAndCount({});
if (BlockchainKernelCountQuery[1]) {
const PaginationReponseData = Paginate(
BlockchainKernelCountQuery[1],
BlockchainKernelRequestData.CurrentPage,
BlockchainKernelRequestData.PageSize,
BlockchainKernelRequestData.MaxPages,
);
const BlockchainKernelPaginationQuery = await getRepository(
BlockchainKernel,
).find({
skip: PaginationReponseData.startIndex,
take: PaginationReponseData.pageSize,
order: {
Id: 'DESC',
},
});
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_kernel list fetched successfully',
response: {
...PaginationReponseData,
...BlockchainKernelPaginationQuery,
},
});
} else {
next(new NoDataFoundException());
}
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private TransactionFee = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const TransactionFeeRequestData: TransactionFeeDto = request.query;
if (TransactionFeeRequestData.Interval) {
var timeIntervalQry =
"timestamp > current_date - interval '" +
TransactionFeeRequestData.Interval +
"'";
} else if (
TransactionFeeRequestData.FromDate ||
TransactionFeeRequestData.ToDate
) {
let fromdate = moment(TransactionFeeRequestData.FromDate)
.utc()
.format('YYYY-MM-DD');
let todate = moment(TransactionFeeRequestData.ToDate)
.utc()
.format('YYYY-MM-DD');
var timeIntervalQry =
'timestamp BETWEEN SYMMETRIC ' + fromdate + ' AND ' + todate;
} else {
var timeIntervalQry = "timestamp > current_date - interval '30 days'";
}
const TransactionFeeQuery = await getConnection()
.query(
"select 1 as hash, date(DATE_TRUNC('day', timestamp)) as date, sum(fee)/1000000 as fee \
from blockchain_block t1 join blockchain_kernel t2 on t2.block_id=t1.hash where " +
timeIntervalQry +
"group by DATE_TRUNC('day', timestamp) order by date",
)
.catch(err_msg => {
next(err_msg);
});
let date = [],
Fee = [];
TransactionFeeQuery.forEach(e => {
date.push(moment(e.date).format('YYYY-MM-DD'));
Fee.push(parseInt(e.fee));
});
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'Transaction fee chart fetched successfully',
response: {
Date: date,
Fee: Fee,
},
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private HeatmapChart = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
// const TransactionFeeRequestData: TransactionFeeDto = request.query;
// if (TransactionFeeRequestData.Interval) {
// var timeIntervalQry =
// "timestamp > current_date - interval '" +
// TransactionFeeRequestData.Interval +
// "'";
// } else if (
// TransactionFeeRequestData.FromDate ||
// TransactionFeeRequestData.ToDate
// ) {
let fromdate = moment()
.subtract(7, 'd')
.format('YYYY-MM-DD');
let todate = moment()
.subtract(1, 'd')
.format('YYYY-MM-DD');
// var timeIntervalQry =
// 'timestamp BETWEEN SYMMETRIC ' + fromdate + ' AND ' + todate;
// } else {
// var timeIntervalQry = "timestamp > current_date - interval '30 days'";
// }
const TransactionHeatmapChartQuery = await getConnection()
.query(
"with hours as ( \
SELECT generate_series('" +
fromdate +
" 00:00:00'::timestamp, '" +
todate +
" 23:00:00', '1 hours') as hour ) select hours.hour, t1.totalinput, t1.totalkernal, t1.totaloutput \
from hours left join(select to_char(x.timestamp,'YYYY-MM-DD HH24:00:00') as hour_of_day ,\
SUM(x.input_count) as totalinput, SUM(x.kernal_count) as totalkernal, SUM(x.output_count) as totaloutput\
from ( SELECT blockchain_block.hash, \
blockchain_block.timestamp, \
sum(bi.block_id_count) AS input_count,\
sum(bk.block_id_count) AS kernal_count, \
sum(bo.block_id_count) AS output_count \
FROM blockchain_block \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_input group by block_id) as bi \
ON blockchain_block.hash = \
bi.block_id \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_kernel group by block_id) as bk \
ON blockchain_block.hash = \
bk.block_id \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_output group by block_id) as bo \
ON blockchain_block.hash = \
bo.block_id WHERE blockchain_block.timestamp >= '" +
fromdate +
" 00:00:00' \
AND blockchain_block.timestamp <= '" +
todate +
" 23:59:59' \
GROUP BY blockchain_block.hash \
ORDER BY blockchain_block.timestamp DESC ) as x \
group by to_char(x.timestamp,'YYYY-MM-DD HH24:00:00') \
order by hour_of_day asc) as t1 on to_timestamp(t1.hour_of_day, 'YYYY-MM-DD HH24:00:00') = hours.hour",
)
.catch(err_msg => {
next(err_msg);
});
let date = [],
hour = [],
totalinput = [],
totalkernal = [],
totaloutput = [],
innerhour = [],
innertotalinput = [],
innertotalkernal = [],
innertotaloutput = [],
prev_date = '';
// for(var i=0 ; i < 7 ; i++){
// date.push(moment().subtract(7, 'days').add(i, 'days').format('YYYY-MM-DD'));
// }
TransactionHeatmapChartQuery.forEach(e => {
var dateformat = moment(e.hour)
.format('YYYY-MM-DD HH')
.split(' ');
if (date.indexOf(dateformat[0]) >= 0 && prev_date == dateformat[0]) {
innerhour.push(dateformat[1]);
innertotalinput.push(e.totalinput != null ? e.totalinput : 0);
innertotalkernal.push(e.totalkernal != null ? e.totalkernal : 0);
innertotaloutput.push(e.totaloutput != null ? e.totaloutput : 0);
} else {
date.push(dateformat[0]);
innerhour.length > 0 ? hour.push(innerhour) : '';
innertotalinput.length > 0 ? totalinput.push(innertotalinput) : '';
innertotalkernal.length > 0 ? totalkernal.push(innertotalkernal) : '';
innertotaloutput.length > 0 ? totaloutput.push(innertotaloutput) : '';
(innerhour = []),
(innertotalinput = []),
(innertotalkernal = []),
(innertotaloutput = []);
innerhour.push(dateformat[1]);
innertotalinput.push((e.totalinput! = null ? e.totalinput : 0));
innertotalkernal.push(e.totalkernal != null ? e.totalkernal : 0);
innertotaloutput.push(e.totaloutput != null ? e.totaloutput : 0);
prev_date = dateformat[0];
}
});
hour.push(innerhour);
totalinput.push(innertotalinput);
totalkernal.push(innertotalkernal);
totaloutput.push(innertotaloutput);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'Transaction heatmap chart fetched successfully',
response: {
date,
hour,
totalinput,
totalkernal,
totaloutput,
},
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private TransactionChart = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const TransactionFeeRequestData: TransactionFeeDto = request.query;
if (TransactionFeeRequestData.Interval) {
var timeIntervalQry =
"blockchain_block.timestamp > current_date - interval '" +
TransactionFeeRequestData.Interval +
"'";
var seriesquery =
"now() - interval '" +
TransactionFeeRequestData.Interval +
"', now()";
} else if (
TransactionFeeRequestData.FromDate ||
TransactionFeeRequestData.ToDate
) {
var timeIntervalQry =
'blockchain_block.timestamp BETWEEN SYMMETRIC ' +
TransactionFeeRequestData.FromDate +
' AND ' +
TransactionFeeRequestData.ToDate;
var seriesquery =
"'" +
TransactionFeeRequestData.FromDate +
"'::timestamp, '" +
TransactionFeeRequestData.ToDate +
"'";
} else {
var timeIntervalQry =
"blockchain_block.timestamp > current_date - interval '30 days'";
var seriesquery = "now() - interval '30 days', now()";
}
const TransactionHeatmapChartQuery = await getConnection()
.query(
'with hours as ( SELECT hour::date from generate_series(' +
seriesquery +
", '1 day') as hour) select hours.hour, \
t1.totalinput, \
t1.totalkernal, \
t1.totaloutput \
from hours left join(select to_char(x.timestamp,'YYYY-MM-DD') as hour_of_day , \
SUM(x.input_count) as totalinput, SUM(x.kernal_count) as totalkernal, SUM(x.output_count) as totaloutput \
from ( SELECT blockchain_block.hash, \
blockchain_block.timestamp, \
sum(bi.block_id_count) AS input_count,\
sum(bk.block_id_count) AS kernal_count, \
sum(bo.block_id_count) AS output_count \
FROM blockchain_block \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_input group by block_id) as bi \
ON blockchain_block.hash = \
bi.block_id \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_kernel group by block_id) as bk \
ON blockchain_block.hash = \
bk.block_id \
LEFT JOIN (select block_id, count(block_id) as block_id_count from blockchain_output group by block_id) as bo \
ON blockchain_block.hash = \
bo.block_id WHERE " +
timeIntervalQry +
" \
GROUP BY blockchain_block.hash \
ORDER BY blockchain_block.timestamp DESC) as x \
group by to_char(x.timestamp,'YYYY-MM-DD') \
order by hour_of_day asc) as t1 on to_timestamp(t1.hour_of_day, 'YYYY-MM-DD') = hours.hour",
)
.catch(err_msg => {
next(err_msg);
});
let date = [],
totalinput = [],
totalkernal = [],
totaloutput = [];
TransactionHeatmapChartQuery.forEach(e => {
date.push(moment(e.hour).format('YYYY-MM-DD'));
totalinput.push(e.totalinput != null ? e.totalinput : 0);
totalkernal.push(e.totalkernal != null ? e.totalkernal : 0);
totaloutput.push(e.totaloutput != null ? e.totaloutput : 0);
});
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'Transaction chart fetched successfully',
response: {
date,
totalinput,
totalkernal,
totaloutput,
},
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
}

View File

@ -0,0 +1,338 @@
import express from 'express';
import { Request, Response, NextFunction } from 'express';
import { getRepository } from 'typeorm';
import { validationMiddleware } from '../middlewares';
import {
InternalServerErrorException,
NoDataFoundException,
} from '../exceptions';
import { BlockchainOutput } from '../entities';
import {
BlockchainOutputCreateDto,
BlockchainOutputSingleViewDto,
BlockchainOutputUpdateDto,
BlockchainOutputPaginationDto,
} from '../dtos';
import { Paginate } from '../utils';
export class BlockchainOutputController {
public path = '/public';
public router = express.Router();
constructor() {
this.IntializeRoutes();
}
public IntializeRoutes() {
/**
* @swagger
* /epic_explorer/v1/blockchain_output:
* post:
* tags:
* - name: BLOCKCHAIN_OUTPUT | BLOCKCHAIN_OUTPUT CONTROLLER
* summary: create a blockchain_output
* description: create a blockchain_output
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: BlockchainOutput
* description: create a blockchain_output
* in: body
* required: true
* schema:
* $ref: '#/definitions/BlockchainOutputDto'
* responses:
* 200:
* description: blockchain_output created successfully
* definitions:
* BlockchainOutputDto:
* description: Dto
* properties:
* Id:
* type: integer
* OutputType:
* type: string
* Commit:
* type: string
* Spent:
* type: string
* ProofHash:
* type: string
* Block:
* type: string
* MerkleProof:
* type: string
* Proof:
* type: string
* BlockHeight:
* type: integer
* MmrIndex:
* type: integer
*/
this.router.post(
`${this.path}`,
validationMiddleware(BlockchainOutputCreateDto),
this.BlockchainOutputCreate,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_output/list:
* get:
* tags:
* - name: BLOCKCHAIN_OUTPUT | BLOCKCHAIN_OUTPUT CONTROLLER
* description: pagination blockchain_output
* summary: pagination blockchain_output
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: current_page
* description: current page specification
* in: query
* type: integer
* required: true
* - name: page_size
* description: page size specification
* in: query
* type: integer
* required: true
* - name: max_pages
* description: max pages specification
* in: query
* type: integer
* required: true
* responses:
* 200:
* description: blockchain_output list fetched successfully
*/
this.router.get(
`${this.path}/list`,
validationMiddleware(BlockchainOutputPaginationDto),
this.BlockchainOutputPagination,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_output/id:
* get:
* tags:
* - name: BLOCKCHAIN_OUTPUT | BLOCKCHAIN_OUTPUT CONTROLLER
* summary: get single blockchain_output
* description: get single blockchain_output
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: Id
* in: path
* description: blockchain_output id
* required: true
* type: string
* responses:
* 200:
* description: blockchain_output successfully fetched for given id..
*/
this.router.get(
`${this.path}/:id`,
validationMiddleware(BlockchainOutputSingleViewDto),
this.BlockchainOutputFetch,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_output:
* patch:
* tags:
* - name: BLOCKCHAIN_OUTPUT | BLOCKCHAIN_OUTPUT CONTROLLER
* summary: update a blockchain_output
* description: update a blockchain_output
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: blockchain_output
* description:
* in: body
* required: true
* schema:
* $ref: '#/definitions/BlockchainOutputDto'
* responses:
* 200:
* description: blockchain_output updated successfully
*/
this.router.patch(
`${this.path}`,
validationMiddleware(BlockchainOutputUpdateDto),
this.BlockchainOutputUpdate,
);
/**
* @swagger
* /epic_explorer/v1/blockchain_output/id:
* delete:
* tags:
* - name: BLOCKCHAIN_OUTPUT | BLOCKCHAIN_OUTPUT CONTROLLER
* summary: delete a blockchain_output
* description: delete a blockchain_output
* consumes:
* - application/json
* produces:
* - application/json
* parameters:
* - name: Id
* in: path
* description: blockchain_output id
* required: true
* type: string
* responses:
* 200:
* description: blockchain_output successfully deleted for given id..
*/
this.router.delete(
`${this.path}/:id`,
validationMiddleware(BlockchainOutputSingleViewDto),
this.BlockchainOutputDelete,
);
}
private BlockchainOutputCreate = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainOutputRequestData: BlockchainOutputCreateDto =
request.body;
const BlockchainOutputCreateQuery = await getRepository(
BlockchainOutput,
).save(BlockchainOutputRequestData);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_output created successfully',
response: BlockchainOutputCreateQuery,
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainOutputFetch = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainOutputFetchQuery = await getRepository(
BlockchainOutput,
).findOne({
where: { id: request.params.id },
});
BlockchainOutputFetchQuery
? response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_outputsuccessfully fetched for given id.',
response: { ...BlockchainOutputFetchQuery },
})
: next(new NoDataFoundException());
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainOutputUpdate = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainOutputRequestData: BlockchainOutputUpdateDto =
request.body;
const BlockchainOutputUpdateQuery = await getRepository(
BlockchainOutput,
).update(BlockchainOutputRequestData.Id, BlockchainOutputRequestData);
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_output updated succesfully',
response: { ...BlockchainOutputUpdateQuery },
});
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainOutputDelete = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainOutputDeleteQuery = await getRepository(
BlockchainOutput,
).delete(request.params.Id);
BlockchainOutputDeleteQuery
? response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_output successfully deleted for given id.',
response: { ...BlockchainOutputDeleteQuery },
})
: next(new NoDataFoundException());
} catch (error) {
next(new InternalServerErrorException(error));
}
};
private BlockchainOutputPagination = async (
request: Request,
response: Response,
next: NextFunction,
) => {
try {
const BlockchainOutputRequestData: BlockchainOutputPaginationDto =
request.query;
const BlockchainOutputCountQuery = await getRepository(
BlockchainOutput,
).findAndCount({});
if (BlockchainOutputCountQuery[1]) {
const PaginationReponseData = Paginate(
BlockchainOutputCountQuery[1],
BlockchainOutputRequestData.CurrentPage,
BlockchainOutputRequestData.PageSize,
BlockchainOutputRequestData.MaxPages,
);
const BlockchainOutputPaginationQuery = await getRepository(
BlockchainOutput,
).find({
skip: PaginationReponseData.startIndex,
take: PaginationReponseData.pageSize,
order: {
Id: 'DESC',
},
});
response.status(200).json({
status: 200,
timestamp: Date.now(),
message: 'blockchain_output list fetched successfully',
response: {
...PaginationReponseData,
...BlockchainOutputPaginationQuery,
},
});
} else {
next(new NoDataFoundException());
}
} catch (error) {
next(new InternalServerErrorException(error));
}
};
}

View File

@ -0,0 +1,4 @@
export * from './BlockchainBlock';
export * from './BlockchainInput';
export * from './BlockchainOutput';
export * from './BlockchainKernel';

View File

@ -0,0 +1,138 @@
import { IsInt, IsNotEmpty, IsString } from 'class-validator';
export class BlockchainBlockCreateDto {
@IsInt()
@IsNotEmpty()
public Version: number;
@IsInt()
@IsNotEmpty()
public Height: number;
@IsString()
@IsNotEmpty()
public Timestamp: Date;
@IsString()
@IsNotEmpty()
public OutputRoot: string;
@IsString()
@IsNotEmpty()
public RangeProofRoot: string;
@IsString()
@IsNotEmpty()
public KernelRoot: string;
@IsString()
@IsNotEmpty()
public Nonce: string;
@IsString()
@IsNotEmpty()
public TotalDifficulty: string;
@IsString()
@IsNotEmpty()
public Previous: any;
@IsString()
@IsNotEmpty()
public TotalKernelOffset: string;
@IsInt()
@IsNotEmpty()
public EdgeBits: number;
@IsString()
@IsNotEmpty()
public CuckooSolution: number[];
@IsString()
@IsNotEmpty()
public PrevRoot: string;
@IsInt()
@IsNotEmpty()
public SecondaryScaling: number;
}
export class BlockchainBlockUpdateDto {
@IsString()
@IsNotEmpty()
public Hash: string;
@IsInt()
public Version: number;
@IsInt()
public Height: number;
@IsString()
public Timestamp: Date;
@IsString()
public OutputRoot: string;
@IsString()
public RangeProofRoot: string;
@IsString()
public KernelRoot: string;
@IsString()
public Nonce: string;
@IsString()
public TotalDifficulty: string;
@IsString()
public Previous: any;
@IsString()
public TotalKernelOffset: string;
@IsInt()
public EdgeBits: number;
@IsString()
public CuckooSolution: number[];
@IsString()
public PrevRoot: string;
@IsInt()
public SecondaryScaling: number;
}
export class BlockchainBlockSingleViewDto {
@IsString()
@IsNotEmpty()
Hash: string;
}
export class BlockchainBlockPaginationDto {
@IsString()
@IsNotEmpty()
public CurrentPage: string;
@IsString()
@IsNotEmpty()
public PageSize: string;
// @IsString()
// @IsNotEmpty()
// public MaxPages: string;
}
export class TotalDifficultyNBlockDto {
@IsString()
public FromDate: string;
@IsString()
public ToDate: string;
@IsString()
public Interval: string;
}

View File

@ -0,0 +1,43 @@
import { IsInt, IsNotEmpty, IsString } from 'class-validator';
export class BlockchainInputCreateDto {
@IsString()
@IsNotEmpty()
public Data: string;
@IsString()
@IsNotEmpty()
public Block: any;
}
export class BlockchainInputUpdateDto {
@IsInt()
@IsNotEmpty()
public Id: number;
@IsString()
public Data: string;
@IsString()
public Block: any;
}
export class BlockchainInputSingleViewDto {
@IsString()
@IsNotEmpty()
Id: string;
}
export class BlockchainInputPaginationDto {
@IsInt()
@IsNotEmpty()
public CurrentPage: number;
@IsInt()
@IsNotEmpty()
public PageSize: number;
@IsInt()
@IsNotEmpty()
public MaxPages: number;
}

View File

@ -0,0 +1,82 @@
import { IsInt, IsNotEmpty, IsString } from 'class-validator';
export class BlockchainKernelCreateDto {
@IsString()
@IsNotEmpty()
public Features: string;
@IsInt()
@IsNotEmpty()
public Fee: number;
@IsInt()
@IsNotEmpty()
public LockHeight: number;
@IsString()
@IsNotEmpty()
public Excess: string;
@IsString()
@IsNotEmpty()
public ExcessSig: string;
@IsString()
@IsNotEmpty()
public Block: any;
}
export class BlockchainKernelUpdateDto {
@IsInt()
@IsNotEmpty()
public Id: number;
@IsString()
public Features: string;
@IsInt()
public Fee: number;
@IsInt()
public LockHeight: number;
@IsString()
public Excess: string;
@IsString()
public ExcessSig: string;
@IsString()
public Block: any;
}
export class BlockchainKernelSingleViewDto {
@IsString()
@IsNotEmpty()
Id: string;
}
export class BlockchainKernelPaginationDto {
@IsInt()
@IsNotEmpty()
public CurrentPage: number;
@IsInt()
@IsNotEmpty()
public PageSize: number;
@IsInt()
@IsNotEmpty()
public MaxPages: number;
}
export class TransactionFeeDto {
@IsString()
public FromDate: string;
@IsString()
public ToDate: string;
@IsString()
public Interval: string;
}

View File

@ -0,0 +1,92 @@
import { IsInt, IsNotEmpty, IsString } from 'class-validator';
export class BlockchainOutputCreateDto {
@IsString()
@IsNotEmpty()
public OutputType: string;
@IsString()
@IsNotEmpty()
public Commit: string;
@IsString()
@IsNotEmpty()
public Spent: boolean;
@IsString()
@IsNotEmpty()
public ProofHash: string;
@IsString()
@IsNotEmpty()
public Block: any;
@IsString()
@IsNotEmpty()
public MerkleProof: string;
@IsString()
@IsNotEmpty()
public Proof: string;
@IsInt()
@IsNotEmpty()
public BlockHeight: number;
@IsInt()
@IsNotEmpty()
public MmrIndex: number;
}
export class BlockchainOutputUpdateDto {
@IsInt()
@IsNotEmpty()
public Id: number;
@IsString()
public OutputType: string;
@IsString()
public Commit: string;
@IsString()
public Spent: boolean;
@IsString()
public ProofHash: string;
@IsString()
public Block: any;
@IsString()
public MerkleProof: string;
@IsString()
public Proof: string;
@IsInt()
public BlockHeight: number;
@IsInt()
public MmrIndex: number;
}
export class BlockchainOutputSingleViewDto {
@IsString()
@IsNotEmpty()
Id: string;
}
export class BlockchainOutputPaginationDto {
@IsInt()
@IsNotEmpty()
public CurrentPage: number;
@IsInt()
@IsNotEmpty()
public PageSize: number;
@IsInt()
@IsNotEmpty()
public MaxPages: number;
}

4
server/app/dtos/index.ts Normal file
View File

@ -0,0 +1,4 @@
export * from './BlockchainBlock';
export * from './BlockchainInput';
export * from './BlockchainOutput';
export * from './BlockchainKernel';

View File

@ -0,0 +1,125 @@
import { Column, Entity, Index, OneToMany } from 'typeorm';
import { BlockchainInput } from './BlockchainInput';
import { BlockchainKernel } from './BlockchainKernel';
import { BlockchainOutput } from './BlockchainOutput';
@Entity('blockchain_block', { schema: 'public' })
export class BlockchainBlock {
@Index()
@Column('character varying', {
nullable: false,
primary: true,
length: 64,
name: 'hash',
})
Hash: string;
@Column('integer', {
nullable: false,
name: 'version',
})
Version: number;
@Column('integer', {
nullable: false,
name: 'height',
})
Height: number;
@Column('timestamp with time zone', {
nullable: false,
name: 'timestamp',
})
Timestamp: Date;
@Column('character varying', {
nullable: false,
length: 64,
name: 'output_root',
})
OutputRoot: string;
@Column('character varying', {
nullable: false,
length: 64,
name: 'range_proof_root',
})
RangeProofRoot: string;
@Column('character varying', {
nullable: false,
length: 64,
name: 'kernel_root',
})
KernelRoot: string;
@Column('text', {
nullable: false,
name: 'nonce',
})
Nonce: string;
@Column('bigint', {
nullable: false,
name: 'total_difficulty',
})
TotalDifficulty: string;
@Column('character varying', {
nullable: false,
length: 64,
name: 'previous_id',
})
PreviousId: string;
@Column('character varying', {
nullable: false,
length: 64,
name: 'total_kernel_offset',
})
TotalKernelOffset: string;
@Column('integer', {
nullable: false,
name: 'edge_bits',
})
EdgeBits: number;
@Column('int4', {
nullable: false,
array: true,
name: 'cuckoo_solution',
})
CuckooSolution: number[];
@Column('character varying', {
nullable: false,
length: 64,
name: 'prev_root',
})
PrevRoot: string;
@Column('integer', {
nullable: false,
name: 'secondary_scaling',
})
SecondaryScaling: number;
@OneToMany(
type => BlockchainInput,
blockchain_input => blockchain_input.Block,
)
BlockchainInputs: BlockchainInput[];
@OneToMany(
type => BlockchainKernel,
blockchain_kernel => blockchain_kernel.Block,
)
BlockchainKernels: BlockchainKernel[];
@OneToMany(
type => BlockchainOutput,
blockchain_output => blockchain_output.Block,
)
BlockchainOutputs: BlockchainOutput[];
}

View File

@ -0,0 +1,40 @@
import {
Column,
Entity,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { BlockchainBlock } from './BlockchainBlock';
@Entity('blockchain_input', { schema: 'public' })
export class BlockchainInput {
@PrimaryGeneratedColumn({
type: 'integer',
name: 'id',
})
Id: number;
@Column('character varying', {
nullable: false,
length: 66,
name: 'data',
})
Data: string;
@Column('character varying', {
nullable: false,
primary: true,
length: 64,
name: 'block_id',
})
BlockId: string;
@ManyToOne(
type => BlockchainBlock,
blockchain_block => blockchain_block.BlockchainInputs,
{ nullable: false },
)
@JoinColumn({ name: 'block_id' })
Block: BlockchainBlock | null;
}

View File

@ -0,0 +1,67 @@
import {
BaseEntity,
Column,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import { BlockchainBlock } from './BlockchainBlock';
@Entity('blockchain_kernel', { schema: 'public' })
export class BlockchainKernel {
@PrimaryGeneratedColumn({
type: 'integer',
name: 'id',
})
Id: number;
@Column('text', {
nullable: false,
name: 'features',
})
Features: string;
@Column('integer', {
nullable: false,
name: 'fee',
})
Fee: number;
@Column('integer', {
nullable: false,
name: 'lock_height',
})
LockHeight: number;
@Column('character varying', {
nullable: false,
length: 66,
name: 'excess',
})
Excess: string;
@Column('character varying', {
nullable: false,
length: 142,
name: 'excess_sig',
})
ExcessSig: string;
@Column('character varying', {
nullable: false,
primary: true,
length: 64,
name: 'block_id',
})
BlockId: string;
@ManyToOne(
type => BlockchainBlock,
blockchain_block => blockchain_block.BlockchainKernels,
{ nullable: false },
)
@JoinColumn({ name: 'block_id' })
Block: BlockchainBlock | null;
}

View File

@ -0,0 +1,91 @@
import {
BaseEntity,
Column,
Entity,
Index,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
OneToOne,
PrimaryColumn,
PrimaryGeneratedColumn,
RelationId,
} from 'typeorm';
import { BlockchainBlock } from './BlockchainBlock';
@Entity('blockchain_output', { schema: 'public' })
export class BlockchainOutput {
@PrimaryGeneratedColumn({
type: 'integer',
name: 'id',
})
Id: number;
@Column('text', {
nullable: false,
name: 'output_type',
})
OutputType: string;
@Column('character varying', {
nullable: false,
length: 66,
name: 'commit',
})
Commit: string;
@Column('boolean', {
nullable: false,
name: 'spent',
})
Spent: boolean;
@Column('character varying', {
nullable: false,
length: 64,
name: 'proof_hash',
})
ProofHash: string;
@Column('text', {
nullable: true,
name: 'merkle_proof',
})
MerkleProof: string | null;
@Column('text', {
nullable: true,
name: 'proof',
})
Proof: string | null;
@Column('integer', {
nullable: true,
name: 'block_height',
})
BlockHeight: number | null;
@Column('integer', {
nullable: true,
name: 'mmr_index',
})
MmrIndex: number | null;
@Column('character varying', {
nullable: false,
primary: true,
length: 64,
name: 'block_id',
})
BlockId: string;
@ManyToOne(
type => BlockchainBlock,
blockchain_block => blockchain_block.BlockchainOutputs,
{ nullable: false },
)
@JoinColumn({ name: 'block_id' })
Block: BlockchainBlock | null;
}

View File

@ -0,0 +1,4 @@
export * from './BlockchainBlock';
export * from './BlockchainInput';
export * from './BlockchainOutput';
export * from './BlockchainKernel';

View File

@ -0,0 +1,11 @@
export class HttpException extends Error {
public status: number;
public message: any;
public error: any;
constructor(status: number, message: any, error?: any) {
super(message);
this.status = status;
this.message = message;
this.error = error;
}
}

View File

@ -0,0 +1,4 @@
export * from './http';
export * from './internalServerError';
export * from './noDataFound';
export * from './integerValidation.exception';

View File

@ -0,0 +1,7 @@
import { HttpException } from './index';
export class IntegerValidationException extends HttpException {
constructor(fieldName: String) {
super(400, `${fieldName} must be an integer`);
}
}

View File

@ -0,0 +1,7 @@
import { HttpException } from './index';
export class InternalServerErrorException extends HttpException {
constructor(error: any) {
super(500, 'Internal Server Error!!', error);
}
}

View File

@ -0,0 +1,7 @@
import { HttpException } from './index';
export class NoDataFoundException extends HttpException {
constructor() {
super(404, 'No Data Found');
}
}

View File

@ -0,0 +1,19 @@
import { NextFunction, Request, Response } from 'express';
import { HttpException } from '../exceptions/index';
export function errorMiddleware(
error: HttpException,
request: Request,
response: Response,
next: NextFunction,
) {
const status = error.status || 500;
const message = error.message || 'Internal Server Error';
const timestamp = Date.now();
response.status(status).send({
status,
timestamp,
message,
error: error.error || {},
});
}

View File

@ -0,0 +1,2 @@
export * from './error.middleware';
export * from './validator.middleware';

View File

@ -0,0 +1,32 @@
import { plainToClass } from 'class-transformer';
import { validate, ValidationError } from 'class-validator';
import * as express from 'express';
import { NextFunction, Request, Response } from 'express';
import { HttpException } from '../exceptions/index';
export function validationMiddleware<T>(
type: any,
skipMissingProperties = false,
): express.RequestHandler {
return (request: Request, response: Response, next: NextFunction) => {
validate(
plainToClass(type, {
...request.body,
...request.query,
...request.params,
}),
{
skipMissingProperties,
},
).then((errors: ValidationError[]) => {
if (errors.length > 0) {
const message = errors.map((error: ValidationError) =>
Object.values(error.constraints),
);
next(new HttpException(400, message));
} else {
next();
}
});
};
}

16
server/app/ormconfig.ts Normal file
View File

@ -0,0 +1,16 @@
import { ConnectionOptions } from 'typeorm';
import { resolve } from 'path';
import { config } from 'dotenv';
config({ path: resolve('.env') });
export const dbConfig: ConnectionOptions = {
type: 'postgres',
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
synchronize: false,
logging: false,
entities: [__dirname + '/entities/*{.ts,.js}'],
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View File

@ -0,0 +1,63 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Epic Explorer</title>
<link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
<link
rel="icon"
type="image/png"
href="./favicon-32x32.png"
sizes="32x32"
/>
<link
rel="icon"
type="image/png"
href="./favicon-16x16.png"
sizes="16x16"
/>
<style>
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}
</style>
</head>
<body>
<div id="swagger-ui"></div>
<script src="./swagger-ui-bundle.js"></script>
<script src="./swagger-ui-standalone-preset.js"></script>
<script>
window.onload = function() {
// Begin Swagger UI call region
const ui = SwaggerUIBundle({
url: 'http://localhost:3000/swagger.json',
dom_id: '#swagger-ui',
docExpansion: 'none',
deepLinking: true,
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
plugins: [SwaggerUIBundle.plugins.DownloadUrl],
layout: 'StandaloneLayout',
});
// End Swagger UI call region
window.ui = ui;
};
</script>
</body>
</html>

View File

@ -0,0 +1,67 @@
<!doctype html>
<html lang="en-US">
<body onload="run()">
</body>
</html>
<script>
'use strict';
function run () {
var oauth2 = window.opener.swaggerUIRedirectOauth2;
var sentState = oauth2.state;
var redirectUrl = oauth2.redirectUrl;
var isValid, qp, arr;
if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
} else {
qp = location.search.substring(1);
}
arr = qp.split("&")
arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';})
qp = qp ? JSON.parse('{' + arr.join() + '}',
function (key, value) {
return key === "" ? value : decodeURIComponent(value)
}
) : {}
isValid = qp.state === sentState
if ((
oauth2.auth.schema.get("flow") === "accessCode"||
oauth2.auth.schema.get("flow") === "authorizationCode"
) && !oauth2.auth.code) {
if (!isValid) {
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
});
}
if (qp.code) {
delete oauth2.state;
oauth2.auth.code = qp.code;
oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
} else {
let oauthErrorMsg
if (qp.error) {
oauthErrorMsg = "["+qp.error+"]: " +
(qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
(qp.error_uri ? "More info: "+qp.error_uri : "");
}
oauth2.errCb({
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
});
}
} else {
oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
}
window.close();
}
</script>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":3,"sources":[],"names":[],"mappings":"","file":"swagger-ui.css","sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,25 @@
{
"info": {
"title": "Epic Explorer- API DOCUMENTATION",
"version": "1.0.0",
"description": "Epic Explorer Dashing",
"termsOfService": "",
"contact": {
"email": "dhivakar.blaze@gmail.com"
},
"license": {
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0"
}
},
"host": "localhost:3000",
"basePath": "/",
"schemes": ["http", "https"],
"securityDefinitions": {
"JWT": {
"type": "apiKey",
"name": "authorization",
"in": "header"
}
}
}

View File

@ -0,0 +1,3 @@
// export * from './imagecompressor';
export * from './logger';
export * from './pagination';

View File

@ -0,0 +1,31 @@
import * as winston from 'winston';
export function logger() {
return winston.createLogger({
transports: [
new winston.transports.File({
level: 'info',
filename: './log/all-logs.log',
handleExceptions: true,
maxsize: 5242880, //5MB
maxFiles: 5,
}),
new winston.transports.Console({
format: winston.format.combine(
winston.format.colorize(),
winston.format.timestamp(),
winston.format.align(),
winston.format.printf(info => {
const { timestamp, level, message, ...args } = info;
const ts = timestamp.slice(0, 19).replace('T', ' ');
return `${ts} [${level}]: ${message} ${
Object.keys(args).length ? JSON.stringify(args, null, 2) : ''
}`;
}),
),
}),
],
exitOnError: false,
});
}

View File

@ -0,0 +1,47 @@
export function Paginate(
totalItems: number,
currentPage: number = 1,
pageSize: number = 10,
maxPages: number = 10,
) {
let totalPages = Math.ceil(totalItems / pageSize);
if (currentPage < 1) {
currentPage = 1;
} else if (currentPage > totalPages) {
currentPage = totalPages;
}
let startPage: number, endPage: number;
if (totalPages <= maxPages) {
startPage = 1;
endPage = totalPages;
} else {
let maxPagesBeforeCurrentPage = Math.floor(maxPages / 2);
let maxPagesAfterCurrentPage = Math.ceil(maxPages / 2) - 1;
if (currentPage <= maxPagesBeforeCurrentPage) {
startPage = 1;
endPage = maxPages;
} else if (currentPage + maxPagesAfterCurrentPage >= totalPages) {
startPage = totalPages - maxPages + 1;
endPage = totalPages;
} else {
startPage = currentPage - maxPagesBeforeCurrentPage;
endPage = currentPage + maxPagesAfterCurrentPage;
}
}
let startIndex = (currentPage - 1) * pageSize;
let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);
let pages = Array.from(Array(endPage + 1 - startPage).keys()).map(
i => startPage + i,
);
return {
totalItems: totalItems,
currentPage: currentPage,
pageSize: pageSize,
totalPages: totalPages,
startPage: startPage,
endPage: endPage,
startIndex: startIndex,
endIndex: endIndex,
pages: pages,
};
}

View File

@ -1,6 +1,6 @@
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
@ -14,11 +14,10 @@ import { NotFoundComponent } from './view/home/not-found/not-found.component';
BrowserModule.withServerTransition({ appId: 'serverApp' }), BrowserModule.withServerTransition({ appId: 'serverApp' }),
HttpClientModule, HttpClientModule,
AppRoutingModule, AppRoutingModule,
BrowserAnimationsModule,
], ],
providers: [], providers: [],
bootstrap: [AppComponent,NotFoundComponent] bootstrap: [AppComponent,NotFoundComponent]
}) })
export class AppModule { } export class AppModule { }

View File

@ -1,5 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server'; import { ServerModule } from '@angular/platform-server';
import {ModuleMapLoaderModule} from '@nguniversal/module-map-ngfactory-loader';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
@ -8,6 +9,7 @@ import { AppComponent } from './app.component';
imports: [ imports: [
AppModule, AppModule,
ServerModule, ServerModule,
ModuleMapLoaderModule,
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
}) })

View File

@ -1,7 +1,11 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ChartService } from '../../../shared/services/chart.service'; import { ChartService } from '../../../shared/services/chart.service';
import { HttpParams } from '@angular/common/http'; import { HttpParams } from '@angular/common/http';
import {
HttpClient,
HttpErrorResponse,
HttpHeaders,
} from '@angular/common/http';
@Component({ @Component({
selector: 'app-block-detail-list', selector: 'app-block-detail-list',
templateUrl: './block-detail-list.component.html', templateUrl: './block-detail-list.component.html',
@ -10,10 +14,18 @@ import { HttpParams } from '@angular/common/http';
export class BlockDetailListComponent implements OnInit { export class BlockDetailListComponent implements OnInit {
public latestblockdetail: any = []; public latestblockdetail: any = [];
constructor(private chartService: ChartService) {} constructor(private chartService: ChartService, private http: HttpClient) {}
ngOnInit() { ngOnInit() {
this.gettinglatesthashList(); this.gettinglatesthashList();
this.http
.get('http://localhost:4000/api/test/ok')
// .get('/api/courses/01.json')
.subscribe(data => {
console.log(data);
});
} }
public gettinglatesthashList() { public gettinglatesthashList() {

View File

@ -2,6 +2,7 @@
const path = require('path'); const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');
module.exports = { module.exports = {
mode: 'none', mode: 'none',
@ -21,7 +22,9 @@ module.exports = {
}, },
module: { module: {
rules: [ rules: [
{ test: /\.ts$/, loader: 'ts-loader' }, { test: /\.ts$/,
exclude: [ /node_modules/,],
loader: 'ts-loader' },
{ {
// Mark files inside `@angular/core` as using SystemJS style dynamic imports. // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
// Removing this will cause deprecation warnings to appear. // Removing this will cause deprecation warnings to appear.
@ -42,6 +45,9 @@ module.exports = {
/(.+)?express(\\|\/)(.+)?/, /(.+)?express(\\|\/)(.+)?/,
path.join(__dirname, 'src'), path.join(__dirname, 'src'),
{} {}
) ),
new FilterWarningsPlugin({
exclude: [/mongodb/, /mssql/, /mysql/, /mysql2/, /react-native-sqlite-storage/, /sql/, /oracledb/, /pg/, /pg-native/, /pg-query-stream/, /redis/, /sqlite3/]
})
] ]
}; };