Skip to content

Commit

Permalink
Merge pull request #21 from AbdulAhadArain/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
AbdulAhadArain authored Aug 19, 2024
2 parents dcdf6a4 + e3d928d commit 4192e1b
Show file tree
Hide file tree
Showing 23 changed files with 9,492 additions and 73 deletions.
9,210 changes: 9,210 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
"typescript": "^5.0.2"
},
"dependencies": {
"ethers": "^5.7.2",
"axios": "^1.5.0",
"cors": "^2.8.5",
"cron": "^3.1.7",
"crypto-js": "^4.1.1",
"dotenv": "^16.0.3",
"ethers": "^5.7.2",
"express": "^4.18.2",
"helmet": "^6.0.1",
"http-status": "^1.6.2",
Expand Down
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import express, { Request, Response, Application, NextFunction } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import router from './routes';
import crons from './crons';
import httpStatus from 'http-status';
import ApiError from './utils/ApiError';
import { successHandler, errorHandler } from './config/morgan';
Expand All @@ -26,6 +27,7 @@ app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.options('*', cors());

app.use(crons);
app.use('/v1/api', router);

// send back a 404 error for any unknown api request
Expand Down
2 changes: 2 additions & 0 deletions src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const envVarsSchema = Joi.object()
.required(),
PORT: Joi.number().default(3000),
MONGODB_URL: Joi.string().required().description('Mongo DB url'),
RPC_URL: Joi.string().required().description('RPC URL'),
})
.unknown();

Expand All @@ -26,6 +27,7 @@ if (error) {
const config = {
env: envVars.NODE_ENV,
port: envVars.PORT,
rpcUrl: envVars.RPC_URL,
mongoose: {
url: envVars.MONGODB_URL + (envVars.NODE_ENV === 'test' ? '-test' : ''),
options: {
Expand Down
16 changes: 15 additions & 1 deletion src/controllers/blocks.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ export const getBlocks = async (
}
};

export const getBlockByNumber = async (
req: Request,
res: Response,
next: NextFunction,
): Promise<void> => {
try {
const block = await blockService.getBlockByQuery({
number: parseInt(req.params.blockNumber as any),
});
res.send(block);
} catch (error) {
next(error);
}
};

export const getBlockByHash = async (
req: Request,
res: Response,
Expand All @@ -25,7 +40,6 @@ export const getBlockByHash = async (
try {
const block = await blockService.getBlockByBlockHash(
req.query.blockHash as any,
req.query.networkId as any,
);
res.send(block);
} catch (error) {
Expand Down
1 change: 1 addition & 0 deletions src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export * as contractController from './contract.controller';
export * as methodController from './method.controller';
export * as explorerController from './explorer.controller';
export * as infoController from './info.controller';
export * as nodeController from './node.controller';
26 changes: 26 additions & 0 deletions src/controllers/node.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Request, Response, NextFunction } from 'express';
import { nodeService, blockService } from '../services';

import { ethers } from 'ethers';
import config from '../config/config';

export const syncNode = async (
req: Request,
res: Response,
next: NextFunction,
): Promise<void> => {
try {
const rpc = config.rpcUrl;
const provider = new ethers.providers.JsonRpcProvider(rpc);
const currentBlock = await provider.getBlockNumber();
const lastVisitedBlock = await blockService.getLastBlockNumber();
await nodeService.processBlockAndTransaction(
lastVisitedBlock,
currentBlock,
);

res.send({ status: 'ok' });
} catch (error) {
next(error);
}
};
8 changes: 2 additions & 6 deletions src/controllers/transactions.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { transactionsService } from '../services';
import { NextFunction, Request, Response } from 'express';
import config from '../config/config';
import Web3 from 'web3';

export const getTransactions = async (
Expand All @@ -26,12 +27,7 @@ export const getTransaction = async (
): Promise<void> => {
try {
const tx = await transactionsService.getTransaction(req.params.txId);
const myNetwork = (global as any).networks;
const matchedItem = myNetwork?.find((item: any) => {
return tx.networkId === item.name || tx.remoteNetworkId === item.name;
});
const rpcUrl = matchedItem.rpcUrl;
const web3 = new Web3(rpcUrl);
const web3 = new Web3(config.rpcUrl);
const response = await web3.eth.getTransactionReceipt(
req.params.txId as string,
);
Expand Down
16 changes: 16 additions & 0 deletions src/crons/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { CronJob } from 'cron';
import nodeSync from './nodeSync';

const nodeSyncJob = new CronJob(
'*/10 * * * *',
function () {
nodeSync();
},
null,
true,
);

const startJobs = () => {
nodeSyncJob.start();
};
export default startJobs;
12 changes: 12 additions & 0 deletions src/crons/nodeSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { nodeService, blockService } from '../services';
import { ethers } from 'ethers';
import config from '../config/config';

const nodeSyncJob = async () => {
const rpc = config.rpcUrl;
const provider = new ethers.providers.JsonRpcProvider(rpc);
const currentBlock = await provider.getBlockNumber();
const lastVisitedBlock = await blockService.getLastBlockNumber();
await nodeService.processBlockAndTransaction(lastVisitedBlock, currentBlock);
};
export default nodeSyncJob;
2 changes: 2 additions & 0 deletions src/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export { QuantumPortalContractObjectModel } from './quantumPortalContract.model'
export { QuantumPortalMinedBlockModel } from './quantumPortalMinedBlock.model';
export { QuantumPortalRemoteTransactionModel } from './quantumPortalRemoteTransaction.model';
export { QuantumPortalNetworkModel } from './quantumPortalNetwork.model';
export { QuantumPortalBlockModel } from './quantumPortalBlock.model';
export { QuantumPortalTransactionModel } from './quantumPortalTransaction.model';
23 changes: 23 additions & 0 deletions src/models/quantumPortalBlock.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import mongoose, { Schema } from 'mongoose';
import { quantumPortalBlockFinalizationSchema } from './quantumPortalBlockFinalization.model';

const quantumPortalBlockSchema = new Schema({
hash: String,
parentHash: String,
number: Number,
nonce: String,
timestamp: Number,
difficulty: Number,
gasLimit: String,
gasUsed: String,
miner: String,
extraData: String,
transactions: [Object],
baseFeePerGas: String,
_difficulty: String,
});

export const QuantumPortalBlockModel = mongoose.model(
'quantumPortalBlock',
quantumPortalBlockSchema,
);
33 changes: 33 additions & 0 deletions src/models/quantumPortalTransaction.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import mongoose, { Schema } from 'mongoose';

const quantumPortalTransactionSchema = new Schema({
hash: String,
type: Number,
accessList: [Object],
networkId: String,
blockHash: String,
blockNumber: Number,
transactionIndex: Number,
confirmations: Number,
from: String,
gasPrice: String,
maxPriorityFeePerGas: String,
maxFeePerGas: String,
gasLimit: String,
to: String,
value: String,
valueToDisplay: String,
nonce: Number,
data: String,
r: String,
s: String,
v: Number,
creates: String,
chainId: Number,
wait: String,
});

export const QuantumPortalTransactionModel = mongoose.model(
'quantumPortalTransaction',
quantumPortalTransactionSchema,
);
5 changes: 5 additions & 0 deletions src/routes/block.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ router.get(
validate(blockValidation.getBlockByHash),
blockController.getBlockByHash,
);
router.get(
'/:blockNumber',
validate(blockValidation.getBlock),
blockController.getBlockByNumber,
);
router.get(
'/hash/txs',
validate(blockValidation.getBlockTxs),
Expand Down
5 changes: 5 additions & 0 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import contractRoute from './contract.route';
import methodRoute from './method.route';
import explorerRoute from './explorer.route';
import infoRoute from './info.route';
import nodeRoute from './node.route';

const router = express.Router();

Expand Down Expand Up @@ -43,6 +44,10 @@ const defaultRoute = [
path: '/info',
route: infoRoute,
},
{
path: '/node',
route: nodeRoute,
},
];

defaultRoute.forEach(route => {
Expand Down
8 changes: 8 additions & 0 deletions src/routes/node.route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express';
import { nodeController } from '.././controllers';

const router = express.Router();

router.route('/sync').post(nodeController.syncNode);

export default router;
66 changes: 33 additions & 33 deletions src/services/block.service.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,38 @@
import {
QuantumPortalMinedBlockModel,
QuantumPortalRemoteTransactionModel,
QuantumPortalBlockModel,
QuantumPortalTransactionModel,
} from '../models';
import {
IBlockListResponse,
ITransactionListResponse,
QuantumPortalMinedBlockDocument,
} from '../interfaces';

export const getBlockByBlockHash = async (
blockHash: string,
networkId?: string,
): Promise<QuantumPortalMinedBlockDocument> => {
const filter: { networkId?: string; blockHash: string } = {
blockHash: blockHash,
export const saveBlock = async (block: any) => {
return await QuantumPortalBlockModel.create(block);
};

export const getBlockByBlockHash = async (blockHash: string): Promise<any> => {
const filter: { hash: string } = {
hash: blockHash,
};
if (networkId) {
filter.networkId = networkId;
}
const block = await QuantumPortalMinedBlockModel.findOne(filter);

const block = await QuantumPortalBlockModel.findOne(filter);
return block;
};

export const getBlockByQuery = async (
query: Object,
): Promise<QuantumPortalMinedBlockDocument> => {
const block = await QuantumPortalMinedBlockModel.findOne(query);
export const getBlockByQuery = async (query: Object): Promise<any> => {
const block = await QuantumPortalBlockModel.findOne(query);
return block;
};

export const getBlockTxsByBlockHash = async (
blockHash: string,
page: number,
limit: number,
): Promise<ITransactionListResponse> => {
const docsPromise = await QuantumPortalRemoteTransactionModel.find({
): Promise<any> => {
const docsPromise = await QuantumPortalTransactionModel.find({
blockHash,
})
.sort({ timestamp: -1 })
.skip((page - 1) * limit)
.limit(limit);
const countPromise =
QuantumPortalRemoteTransactionModel.countDocuments().exec();
const countPromise = QuantumPortalTransactionModel.countDocuments().exec();

const [totalResults, results] = await Promise.all([
countPromise,
Expand All @@ -61,13 +52,12 @@ export const getBlockTxsByBlockHash = async (
export const getRecentBlocks = async (
page: number,
limit: number,
): Promise<IBlockListResponse> => {
const docsPromise = await QuantumPortalMinedBlockModel.find()
): Promise<any> => {
const docsPromise = await QuantumPortalBlockModel.find()
.sort({ timestamp: -1 })
.skip((page - 1) * limit)
.limit(limit);
const countPromise =
QuantumPortalRemoteTransactionModel.countDocuments().exec();
const countPromise = QuantumPortalTransactionModel.countDocuments().exec();

const [totalResults, results] = await Promise.all([
countPromise,
Expand All @@ -88,14 +78,13 @@ export const getAllBlocks = async (
page: number,
limit: number,
queryData: any,
): Promise<IBlockListResponse> => {
const docsPromise = await QuantumPortalMinedBlockModel.find(queryData)
): Promise<any> => {
const docsPromise = await QuantumPortalBlockModel.find(queryData)
.sort({ timestamp: -1 })
.skip((page - 1) * limit)
.limit(limit);

const countPromise =
QuantumPortalMinedBlockModel.countDocuments(queryData).exec();
const countPromise = QuantumPortalBlockModel.countDocuments(queryData).exec();

const [totalResults, results] = await Promise.all([
countPromise,
Expand All @@ -111,3 +100,14 @@ export const getAllBlocks = async (
};
return result;
};

export const getLastBlockNumber = async (): Promise<number | undefined> => {
const lastBlock = await QuantumPortalBlockModel.find()
.sort({ nonce: -1 })
.limit(1)
.exec();
if (!lastBlock.length) {
return;
}
return lastBlock[0].number;
};
1 change: 1 addition & 0 deletions src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * as accountService from './account.service';
export * as networkService from './network.service';
export * as contractService from './contract.service';
export * as methodService from './method.service';
export * as nodeService from './node.service';
Loading

0 comments on commit 4192e1b

Please sign in to comment.