├── App ├── chain.log ├── index.js ├── index.ts ├── nodes.js ├── nodes.ts ├── root.js └── root.ts ├── Bin ├── dpx ├── dpx.js └── dpx.ts ├── Dockerfile ├── README.md ├── Scripts ├── mine.js └── work.js ├── Src ├── Addon │ ├── hash-creator.js │ ├── hash-creator.ts │ ├── sign.js │ └── sign.ts ├── classes │ ├── Blockchain │ │ ├── Block.js │ │ ├── Block.ts │ │ ├── Blockchain.js │ │ ├── Blockchain.ts │ │ ├── Transaction.js │ │ ├── Transaction.ts │ │ ├── TransactionMiner.js │ │ ├── TransactionMiner.ts │ │ ├── TransactionPool.js │ │ ├── TransactionPool.ts │ │ ├── Wallet.js │ │ └── Wallet.ts │ └── Network │ │ ├── Nodes.js │ │ ├── Nodes.ts │ │ ├── Root.js │ │ └── Root.ts ├── interfaces │ ├── Blockchain │ │ ├── _Block.js │ │ ├── _Block.ts │ │ ├── _Blockchain.js │ │ ├── _Blockchain.ts │ │ ├── _Errors.js │ │ ├── _Errors.ts │ │ ├── _Transaction.js │ │ ├── _Transaction.ts │ │ ├── _TransactionMiner.js │ │ ├── _TransactionMiner.ts │ │ ├── _TransactionPool.js │ │ ├── _TransactionPool.ts │ │ ├── _Wallet.js │ │ └── _Wallet.ts │ └── Network │ │ ├── _Nodes.js │ │ ├── _Nodes.ts │ │ ├── _Root.js │ │ └── _Root.ts └── types │ ├── errors_interface.js │ ├── errors_interface.ts │ ├── inputMap_types.js │ └── inputMap_types.ts ├── code.txt ├── config.js ├── config.ts ├── package-lock.json ├── package.json └── tsconfig.json /App/chain.log: -------------------------------------------------------------------------------- 1 | [{"hash":"DEFAULT-DPX-GENESIS-HASH","lastHash":"DEFAULT-DPX-LAST-HASH","nonce":0,"difficulty":10,"timestamp":0,"data":{}}] -------------------------------------------------------------------------------- /App/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | const Blockchain_1 = require("../Src/classes/Blockchain/Blockchain"); 16 | const Nodes_1 = require("../Src/classes/Network/Nodes"); 17 | const Wallet_1 = require("../Src/classes/Blockchain/Wallet"); 18 | const TransactionPool_1 = require("../Src/classes/Blockchain/TransactionPool"); 19 | const cluster_1 = __importDefault(require("cluster")); 20 | const root_1 = __importDefault(require("./root")); 21 | const nodes_1 = __importDefault(require("./nodes")); 22 | const config_1 = require("../config"); 23 | const sign_1 = require("../Src/Addon/sign"); 24 | const Transaction_1 = require("../Src/classes/Blockchain/Transaction"); 25 | const fs_1 = __importDefault(require("fs")); 26 | const express_1 = __importDefault(require("express")); 27 | (() => __awaiter(void 0, void 0, void 0, function* () { 28 | // console.log = () => {}; 29 | if (cluster_1.default.isPrimary) { 30 | try { 31 | process.stdout.write("Developix Blockchain is running..."); 32 | const app = (0, express_1.default)(); 33 | let blockchain; 34 | let nodes; 35 | let admin; 36 | // let workers: any[] = []; 37 | let transactionPool; 38 | // let transactionMiner: _TransactionMiner; 39 | let start = false; 40 | // let interval : any; 41 | // --- node api 42 | app.use((req, res, next) => { 43 | if (req.connection.localAddress === req.connection.remoteAddress) { 44 | next(); 45 | } 46 | else { 47 | res.status(403).send("forbidden"); 48 | } 49 | }); 50 | app.use(express_1.default.json()); 51 | app.post("/start", (req, res) => { 52 | try { 53 | blockchain = new Blockchain_1.Blockchain(); 54 | nodes = new Nodes_1.Nodes(config_1.config.NODE_PORT); 55 | admin = new Wallet_1.Wallet(); 56 | transactionPool = new TransactionPool_1.TransactionPool(); 57 | if (fs_1.default.existsSync("./chain.log")) { 58 | blockchain.chain = JSON.parse(fs_1.default.readFileSync("./chain.log").toString()); 59 | } 60 | setInterval(() => { 61 | fs_1.default.writeFileSync("./chain.log", JSON.stringify(blockchain.chain)); 62 | }, 1000 * 60 * 60); 63 | (0, root_1.default)(blockchain, nodes, transactionPool, config_1.config.NODE_PORT + 2); 64 | (0, nodes_1.default)(nodes, blockchain, transactionPool, admin, cluster_1.default); 65 | start = true; 66 | res.status(200).json({ 67 | message: "node started", 68 | status: true, 69 | mainWallet: { 70 | publicKey: admin.publicKey, 71 | privateKey: admin.privateKey, 72 | }, 73 | }); 74 | } 75 | catch (err) { 76 | if (err) { 77 | res.status(500).json({ 78 | message: err.message, 79 | status: false, 80 | }); 81 | } 82 | else { 83 | res.status(500).json({ 84 | message: "unknown error", 85 | status: false, 86 | }); 87 | } 88 | } 89 | }); 90 | app.post("/wallet/create", (req, res) => { 91 | try { 92 | if (!start) { 93 | return res.status(400).json({ 94 | message: "node not started", 95 | status: false, 96 | }); 97 | } 98 | const wallet = new Wallet_1.Wallet(); 99 | res.status(200).json({ 100 | message: "wallet created", 101 | status: true, 102 | wallet: { 103 | publicKey: wallet.publicKey, 104 | privateKey: wallet.privateKey, 105 | }, 106 | }); 107 | } 108 | catch (err) { 109 | res.status(500).json({ 110 | message: "wallet not created", 111 | status: false, 112 | }); 113 | } 114 | }); 115 | app.post("/wallet/balance/:publicKey", (req, res) => { 116 | try { 117 | if (!start) { 118 | return res.status(400).json({ 119 | message: "node not started", 120 | status: false, 121 | }); 122 | } 123 | const { publicKey } = req.params; 124 | const balance = Wallet_1.Wallet.calculateBalance(blockchain.chain, publicKey); 125 | res.status(200).json({ 126 | message: "wallet balance", 127 | status: true, 128 | wallet: { 129 | publicKey, 130 | balance, 131 | }, 132 | }); 133 | } 134 | catch (err) { 135 | res.status(500).json({ 136 | message: "wallet balance not found", 137 | status: false, 138 | }); 139 | } 140 | }); 141 | app.post("/mine/stop", (req, res) => { 142 | try { 143 | if (!start) { 144 | return res.status(400).json({ 145 | message: "node not started", 146 | status: false, 147 | }); 148 | } 149 | for (const worker of Object.values(cluster_1.default.workers)) { 150 | // worker?.send("end"); 151 | worker === null || worker === void 0 ? void 0 : worker.kill(); 152 | } 153 | res.status(200).json({ 154 | message: "mining stopped", 155 | status: true, 156 | }); 157 | } 158 | catch (err) { 159 | res.status(500).json({ 160 | message: "error mining", 161 | status: false, 162 | }); 163 | } 164 | }); 165 | app.post("/mine/start/:core", (req, res) => { 166 | try { 167 | if (!start) { 168 | return res.status(400).json({ 169 | message: "node not started", 170 | status: false, 171 | }); 172 | } 173 | const { core } = req.params; 174 | res.status(200).json({ 175 | message: "mining started", 176 | status: true, 177 | }); 178 | for (let i = 0; i < core; i++) { 179 | let worker = cluster_1.default.fork(); 180 | worker === null || worker === void 0 ? void 0 : worker.send({ 181 | chain: blockchain.chain, 182 | transactions: [ 183 | Transaction_1.Transaction.reward(admin), 184 | ...Object.values(transactionPool.transactionMap).filter((v) => { 185 | Transaction_1.Transaction.isValid(v) === true; 186 | }), 187 | ], 188 | }); 189 | worker.on("error", () => { }); 190 | cluster_1.default.on("message", (worker, message, handle) => __awaiter(void 0, void 0, void 0, function* () { 191 | worker === null || worker === void 0 ? void 0 : worker.send({ 192 | chain: blockchain.chain, 193 | transactions: [ 194 | Transaction_1.Transaction.reward(admin), 195 | ...Object.values(transactionPool.transactionMap), 196 | ], 197 | }); 198 | if (message.chain) { 199 | if (blockchain.replaceChain(message.chain) === true) { 200 | yield nodes.broadcast("chain", blockchain.chain); 201 | transactionPool.clear(); 202 | } 203 | } 204 | })); 205 | } 206 | //interval = setInterval(()=>{}) 207 | } 208 | catch (err) { 209 | res.status(500).json({ 210 | message: "error mining", 211 | status: false, 212 | }); 213 | } 214 | }); 215 | app.post("/transaction", (req, res) => { 216 | try { 217 | if (!start) { 218 | return res.status(400).json({ 219 | message: "node not started", 220 | status: false, 221 | }); 222 | } 223 | const { fromPublicKey, fromPrivateKey, toPublic, amount } = req.body; 224 | const wallet = new Wallet_1.Wallet(); 225 | wallet.keyPair = (0, sign_1.recoveryKeyPair)(fromPrivateKey, fromPublicKey); 226 | wallet.privateKey = fromPrivateKey; 227 | wallet.publicKey = fromPublicKey; 228 | let hasTransaction = transactionPool.isHave(wallet); 229 | console.log(hasTransaction == true); 230 | if (hasTransaction) { 231 | hasTransaction = hasTransaction.update(toPublic, amount, wallet); 232 | if (hasTransaction === null || hasTransaction === void 0 ? void 0 : hasTransaction.code) { 233 | return res.status(hasTransaction.code).json({ 234 | message: hasTransaction.message, 235 | status: false, 236 | }); 237 | } 238 | return res.status(200).json({ 239 | message: "transaction updated", 240 | status: true, 241 | hasTransaction, 242 | }); 243 | } 244 | let transaction = wallet.createTransaction(toPublic, Number(amount), blockchain.chain); 245 | if (transaction === null || transaction === void 0 ? void 0 : transaction.code) { 246 | return res.status(transaction.code).json({ 247 | message: transaction.message, 248 | status: false, 249 | }); 250 | } 251 | transactionPool.add(transaction); 252 | nodes.broadcast("transaction", transaction); 253 | res.status(200).json({ 254 | message: "transaction created", 255 | status: true, 256 | transaction, 257 | }); 258 | } 259 | catch (err) { 260 | console.dir(err, { depth: null }); 261 | res.status(500).json({ 262 | message: "transaction not created", 263 | status: false, 264 | }); 265 | } 266 | }); 267 | app.post("/chain/log", (req, res) => { 268 | try { 269 | if (!start) { 270 | return res.status(400).json({ 271 | message: "node not started", 272 | status: false, 273 | }); 274 | } 275 | const { location } = req.body; 276 | if (fs_1.default.existsSync(location)) { 277 | fs_1.default.unlinkSync(location); 278 | fs_1.default.writeFileSync(location, JSON.stringify(blockchain.chain)); 279 | } 280 | else { 281 | fs_1.default.writeFileSync(location, JSON.stringify(blockchain.chain)); 282 | } 283 | res.status(200).json({ 284 | message: "chain loged", 285 | status: true, 286 | location, 287 | }); 288 | } 289 | catch (err) { 290 | res.status(500).json({ 291 | message: "chain log not saved", 292 | status: false, 293 | }); 294 | } 295 | }); 296 | app.get("/pool", (req, res) => { 297 | res.json(transactionPool.transactionMap); 298 | }); 299 | app.post("/chain/restart", (req, res) => { 300 | try { 301 | if (!start) { 302 | return res.status(400).json({ 303 | message: "node not started", 304 | status: false, 305 | }); 306 | } 307 | blockchain = new Blockchain_1.Blockchain(); 308 | transactionPool.clear(); 309 | res.status(200).json({ 310 | message: "chain restarted", 311 | status: true, 312 | }); 313 | } 314 | catch (error) { 315 | res.status(500).json({ 316 | message: "chain not restarted", 317 | status: false, 318 | }); 319 | } 320 | }); 321 | app.listen(7612, () => { 322 | console.log("node api run in port 7612"); 323 | }); 324 | } 325 | catch (error) { 326 | console.error(error); 327 | } 328 | } 329 | else { 330 | process.on("message", (data) => { 331 | // if (data === "end") { 332 | // return process.exit(0); 333 | // } 334 | let blockchain = new Blockchain_1.Blockchain(); 335 | blockchain.chain = data.chain; 336 | let transactions = data.transactions; 337 | blockchain.addBlock({ transaction: transactions }); 338 | process.send({ chain: blockchain.chain }); 339 | }); 340 | } 341 | }))(); 342 | -------------------------------------------------------------------------------- /App/index.ts: -------------------------------------------------------------------------------- 1 | import { Blockchain } from "../Src/classes/Blockchain/Blockchain"; 2 | import { _Blockchain } from "../Src/interfaces/Blockchain/_Blockchain"; 3 | import { _Block } from "../Src/interfaces/Blockchain/_Block"; 4 | import { Nodes } from "../Src/classes/Network/Nodes"; 5 | import { _Nodes } from "../Src/interfaces/Network/_Nodes"; 6 | import { Wallet } from "../Src/classes/Blockchain/Wallet"; 7 | import { _Wallet } from "../Src/interfaces/Blockchain/_Wallet"; 8 | import { TransactionPool } from "../Src/classes/Blockchain/TransactionPool"; 9 | import { _TransactionPool } from "../Src/interfaces/Blockchain/_TransactionPool"; 10 | import { _Transaction } from "../Src/interfaces/Blockchain/_Transaction"; 11 | import cluster from "cluster"; 12 | import rootFunction from "./root"; 13 | import nodesFunction from "./nodes"; 14 | import { config } from "../config"; 15 | import { recoveryKeyPair } from "../Src/Addon/sign"; 16 | import { _Errors } from "../Src/types/errors_interface"; 17 | import { Transaction } from "../Src/classes/Blockchain/Transaction"; 18 | import fs from "fs"; 19 | import express from "express"; 20 | (async () => { 21 | // console.log = () => {}; 22 | if (cluster.isPrimary) { 23 | try { 24 | process.stdout.write("Developix Blockchain is running..."); 25 | const app = express(); 26 | let blockchain: _Blockchain; 27 | let nodes: _Nodes; 28 | let admin: _Wallet; 29 | // let workers: any[] = []; 30 | let transactionPool: _TransactionPool; 31 | // let transactionMiner: _TransactionMiner; 32 | let start = false; 33 | // let interval : any; 34 | // --- node api 35 | app.use((req, res, next) => { 36 | if (req.connection.localAddress === req.connection.remoteAddress) { 37 | next(); 38 | } else { 39 | res.status(403).send("forbidden"); 40 | } 41 | }); 42 | app.use(express.json()); 43 | app.post("/start", (req, res) => { 44 | try { 45 | blockchain = new Blockchain(); 46 | nodes = new Nodes(config.NODE_PORT); 47 | admin = new Wallet(); 48 | transactionPool = new TransactionPool(); 49 | if (fs.existsSync("./chain.log")) { 50 | blockchain.chain = JSON.parse( 51 | fs.readFileSync("./chain.log").toString() 52 | ); 53 | } 54 | setInterval(() => { 55 | fs.writeFileSync("./chain.log", JSON.stringify(blockchain.chain)); 56 | }, 1000 * 60 * 60); 57 | rootFunction( 58 | blockchain, 59 | nodes, 60 | transactionPool, 61 | config.NODE_PORT + 2 62 | ); 63 | nodesFunction(nodes, blockchain, transactionPool, admin, cluster); 64 | start = true; 65 | res.status(200).json({ 66 | message: "node started", 67 | status: true, 68 | mainWallet: { 69 | publicKey: admin.publicKey, 70 | privateKey: admin.privateKey, 71 | }, 72 | }); 73 | } catch (err: any) { 74 | if (err) { 75 | res.status(500).json({ 76 | message: err.message, 77 | status: false, 78 | }); 79 | } else { 80 | res.status(500).json({ 81 | message: "unknown error", 82 | status: false, 83 | }); 84 | } 85 | } 86 | }); 87 | app.post("/wallet/create", (req, res) => { 88 | try { 89 | if (!start) { 90 | return res.status(400).json({ 91 | message: "node not started", 92 | status: false, 93 | }); 94 | } 95 | const wallet = new Wallet(); 96 | res.status(200).json({ 97 | message: "wallet created", 98 | status: true, 99 | wallet: { 100 | publicKey: wallet.publicKey, 101 | privateKey: wallet.privateKey, 102 | }, 103 | }); 104 | } catch (err) { 105 | res.status(500).json({ 106 | message: "wallet not created", 107 | status: false, 108 | }); 109 | } 110 | }); 111 | app.post("/wallet/balance/:publicKey", (req, res) => { 112 | try { 113 | if (!start) { 114 | return res.status(400).json({ 115 | message: "node not started", 116 | status: false, 117 | }); 118 | } 119 | const { publicKey }: any = req.params; 120 | const balance = Wallet.calculateBalance(blockchain.chain, publicKey); 121 | res.status(200).json({ 122 | message: "wallet balance", 123 | status: true, 124 | wallet: { 125 | publicKey, 126 | balance, 127 | }, 128 | }); 129 | } catch (err) { 130 | res.status(500).json({ 131 | message: "wallet balance not found", 132 | status: false, 133 | }); 134 | } 135 | }); 136 | app.post("/mine/stop", (req, res) => { 137 | try { 138 | if (!start) { 139 | return res.status(400).json({ 140 | message: "node not started", 141 | status: false, 142 | }); 143 | } 144 | for (const worker of Object.values(cluster.workers!)) { 145 | // worker?.send("end"); 146 | worker?.kill(); 147 | } 148 | res.status(200).json({ 149 | message: "mining stopped", 150 | status: true, 151 | }); 152 | } catch (err) { 153 | res.status(500).json({ 154 | message: "error mining", 155 | status: false, 156 | }); 157 | } 158 | }); 159 | app.post("/mine/start/:core", (req, res) => { 160 | try { 161 | if (!start) { 162 | return res.status(400).json({ 163 | message: "node not started", 164 | status: false, 165 | }); 166 | } 167 | const { core }: any = req.params; 168 | res.status(200).json({ 169 | message: "mining started", 170 | status: true, 171 | }); 172 | for (let i = 0; i < core; i++) { 173 | let worker = cluster.fork(); 174 | worker?.send({ 175 | chain: blockchain.chain, 176 | transactions: [ 177 | Transaction.reward(admin), 178 | ...Object.values(transactionPool.transactionMap).filter((v) => { 179 | Transaction.isValid(v as any) === true; 180 | }), 181 | ], 182 | }); 183 | worker.on("error", () => {}); 184 | cluster.on("message", async (worker, message, handle) => { 185 | worker?.send({ 186 | chain: blockchain.chain, 187 | transactions: [ 188 | Transaction.reward(admin), 189 | ...Object.values(transactionPool.transactionMap), 190 | ], 191 | }); 192 | if (message.chain) { 193 | if (blockchain.replaceChain(message.chain) === true) { 194 | await nodes.broadcast("chain", blockchain.chain); 195 | transactionPool.clear(); 196 | } 197 | } 198 | }); 199 | } 200 | //interval = setInterval(()=>{}) 201 | } catch (err) { 202 | res.status(500).json({ 203 | message: "error mining", 204 | status: false, 205 | }); 206 | } 207 | }); 208 | app.post("/transaction", (req, res) => { 209 | try { 210 | if (!start) { 211 | return res.status(400).json({ 212 | message: "node not started", 213 | status: false, 214 | }); 215 | } 216 | 217 | const { fromPublicKey, fromPrivateKey, toPublic, amount }: any = 218 | req.body; 219 | 220 | const wallet = new Wallet(); 221 | 222 | wallet.keyPair = recoveryKeyPair(fromPrivateKey, fromPublicKey); 223 | wallet.privateKey = fromPrivateKey; 224 | wallet.publicKey = fromPublicKey; 225 | 226 | let hasTransaction: any = transactionPool.isHave(wallet); 227 | console.log(hasTransaction == true); 228 | if (hasTransaction) { 229 | hasTransaction = hasTransaction.update(toPublic, amount, wallet); 230 | if (hasTransaction?.code) { 231 | return res.status(hasTransaction.code).json({ 232 | message: hasTransaction.message, 233 | status: false, 234 | }); 235 | } 236 | return res.status(200).json({ 237 | message: "transaction updated", 238 | status: true, 239 | hasTransaction, 240 | }); 241 | } 242 | 243 | let transaction = wallet.createTransaction( 244 | toPublic, 245 | Number(amount), 246 | blockchain.chain 247 | ); 248 | 249 | if ((transaction as _Errors)?.code) { 250 | return res.status((transaction as _Errors).code).json({ 251 | message: (transaction as _Errors).message, 252 | status: false, 253 | }); 254 | } 255 | transactionPool.add(transaction as _Transaction); 256 | nodes.broadcast("transaction", transaction); 257 | res.status(200).json({ 258 | message: "transaction created", 259 | status: true, 260 | transaction, 261 | }); 262 | } catch (err) { 263 | console.dir(err, { depth: null }); 264 | res.status(500).json({ 265 | message: "transaction not created", 266 | status: false, 267 | }); 268 | } 269 | }); 270 | 271 | app.post("/chain/log", (req, res) => { 272 | try { 273 | if (!start) { 274 | return res.status(400).json({ 275 | message: "node not started", 276 | status: false, 277 | }); 278 | } 279 | const { location }: any = req.body; 280 | if (fs.existsSync(location)) { 281 | fs.unlinkSync(location); 282 | fs.writeFileSync(location, JSON.stringify(blockchain.chain)); 283 | } else { 284 | fs.writeFileSync(location, JSON.stringify(blockchain.chain)); 285 | } 286 | res.status(200).json({ 287 | message: "chain loged", 288 | status: true, 289 | location, 290 | }); 291 | } catch (err) { 292 | res.status(500).json({ 293 | message: "chain log not saved", 294 | status: false, 295 | }); 296 | } 297 | }); 298 | 299 | app.get("/pool", (req, res) => { 300 | res.json(transactionPool.transactionMap); 301 | }); 302 | 303 | app.post("/chain/restart", (req, res) => { 304 | try { 305 | if (!start) { 306 | return res.status(400).json({ 307 | message: "node not started", 308 | status: false, 309 | }); 310 | } 311 | blockchain = new Blockchain(); 312 | transactionPool.clear(); 313 | res.status(200).json({ 314 | message: "chain restarted", 315 | status: true, 316 | }); 317 | } catch (error) { 318 | res.status(500).json({ 319 | message: "chain not restarted", 320 | status: false, 321 | }); 322 | } 323 | }); 324 | 325 | app.listen(7612, () => { 326 | console.log("node api run in port 7612"); 327 | }); 328 | } catch (error) { 329 | console.error(error); 330 | } 331 | } else { 332 | process.on("message", (data: any) => { 333 | // if (data === "end") { 334 | // return process.exit(0); 335 | // } 336 | let blockchain = new Blockchain(); 337 | blockchain.chain = data.chain; 338 | let transactions: [_Transaction] = data.transactions; 339 | blockchain.addBlock({ transaction: transactions }); 340 | (process.send as any)({ chain: blockchain.chain }); 341 | }); 342 | } 343 | })(); 344 | -------------------------------------------------------------------------------- /App/nodes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const Transaction_1 = require("../Src/classes/Blockchain/Transaction"); 4 | function default_1(nodes, blockchain, transactionPool, admin, cluster) { 5 | nodes.bet("chain", (data) => { 6 | console.log('new chain : \n', data); 7 | if (blockchain.validTransactionData(data) === true && blockchain.replaceChain(data) === true) { 8 | transactionPool.clearBlockchainTransactions(data); 9 | } 10 | ; 11 | }); 12 | nodes.bet("transaction", (data) => { 13 | const check = Transaction_1.Transaction.isValid(data); 14 | if (check !== true) { 15 | return; 16 | } 17 | transactionPool.add(data); 18 | }); 19 | } 20 | exports.default = default_1; 21 | -------------------------------------------------------------------------------- /App/nodes.ts: -------------------------------------------------------------------------------- 1 | import { _Block } from "../Src/interfaces/Blockchain/_Block"; 2 | import { _Blockchain } from "../Src/interfaces/Blockchain/_Blockchain"; 3 | import { _Nodes } from "../Src/interfaces/Network/_Nodes"; 4 | import { _TransactionPool } from "../Src/interfaces/Blockchain/_TransactionPool"; 5 | import { _Transaction } from "../Src/interfaces/Blockchain/_Transaction"; 6 | import { Transaction } from "../Src/classes/Blockchain/Transaction"; 7 | import { _Wallet } from "../Src/interfaces/Blockchain/_Wallet"; 8 | import { Cluster } from "cluster"; 9 | export default function ( 10 | nodes: _Nodes, 11 | blockchain: _Blockchain, 12 | transactionPool: _TransactionPool, 13 | admin : _Wallet, 14 | cluster : Cluster 15 | ) { 16 | 17 | nodes.bet("chain", (data: Array<_Block>) => { 18 | console.log('new chain : \n',data) 19 | if(blockchain.validTransactionData(data) === true && blockchain.replaceChain(data) === true) { 20 | transactionPool.clearBlockchainTransactions(data); 21 | }; 22 | }); 23 | 24 | nodes.bet("transaction", (data: _Transaction) => { 25 | const check = Transaction.isValid(data); 26 | if (check !== true) { 27 | return; 28 | } 29 | transactionPool.add(data); 30 | }); 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /App/root.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const Root_1 = require("../Src/classes/Network/Root"); 4 | function default_1(blockChain, nodes, transactionPool, port) { 5 | const root = new Root_1.Root(port); 6 | root.start(); 7 | //@ts-ignore 8 | root.send("addMe", { data: { hash: root.hash, port } }); 9 | nodes.start(); 10 | root.bet("welcome", (data) => { 11 | console.log(data); 12 | nodes.list = data.nodes || nodes.list; 13 | blockChain.chain = data.chain || blockChain.chain; 14 | transactionPool.transactionMap = data.transaction || transactionPool.transactionMap; 15 | }); 16 | root.bet("sliceChain", (data) => { 17 | blockChain.chain = blockChain.chain.filter((x, i) => { 18 | return i < data; 19 | }); 20 | }); 21 | root.bet("reaplceChain", (data) => { 22 | blockChain.chain = data; 23 | }); 24 | root.bet("replaceNodes", (data) => { 25 | nodes.list = data.nodes; 26 | }); 27 | root.bet("newNode", (data) => { 28 | nodes.list.push(data); 29 | }); 30 | // root.bet("giveMeData", () => { 31 | // root.send("giveMeData", { 32 | // data: { chain: blockChain.chain, node: nodes.list }, 33 | // }); 34 | // }); 35 | } 36 | exports.default = default_1; 37 | -------------------------------------------------------------------------------- /App/root.ts: -------------------------------------------------------------------------------- 1 | import { Root } from "../Src/classes/Network/Root"; 2 | import { _Blockchain } from "../Src/interfaces/Blockchain/_Blockchain"; 3 | import { _Nodes } from "../Src/interfaces/Network/_Nodes"; 4 | import { _Root } from "../Src/interfaces/Network/_Root"; 5 | import { _Block } from "../Src/interfaces/Blockchain/_Block"; 6 | import { _TransactionPool } from "../Src/interfaces/Blockchain/_TransactionPool"; 7 | export default function ( 8 | blockChain: _Blockchain, 9 | nodes: _Nodes, 10 | transactionPool: _TransactionPool, 11 | port: number 12 | ): void { 13 | const root: _Root = new Root(port); 14 | root.start(); 15 | //@ts-ignore 16 | root.send("addMe", { data: {hash : root.hash, port} }); 17 | nodes.start(); 18 | root.bet("welcome", (data: any) => { 19 | console.log(data) 20 | nodes.list = data.nodes || nodes.list; 21 | blockChain.chain = data.chain || blockChain.chain; 22 | transactionPool.transactionMap = data.transaction || transactionPool.transactionMap; 23 | }); 24 | 25 | root.bet("sliceChain", (data: number) => { 26 | blockChain.chain = blockChain.chain.filter((x, i) => { 27 | return i < data; 28 | }); 29 | }); 30 | 31 | root.bet("reaplceChain", (data: Array<_Block>) => { 32 | blockChain.chain = data; 33 | }); 34 | 35 | root.bet("replaceNodes", (data: {nodes : Array}) => { 36 | nodes.list = data.nodes; 37 | }); 38 | 39 | root.bet("newNode", (data: string) => { 40 | nodes.list.push(data); 41 | }); 42 | 43 | // root.bet("giveMeData", () => { 44 | // root.send("giveMeData", { 45 | // data: { chain: blockChain.chain, node: nodes.list }, 46 | // }); 47 | // }); 48 | } 49 | -------------------------------------------------------------------------------- /Bin/dpx: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | var __importDefault = (this && this.__importDefault) || function (mod) { 4 | return (mod && mod.__esModule) ? mod : { "default": mod }; 5 | }; 6 | Object.defineProperty(exports, "__esModule", { value: true }); 7 | const commander_1 = require("commander"); 8 | const axios_1 = __importDefault(require("axios")); 9 | const ansicolor_1 = __importDefault(require("ansicolor")); 10 | const cli = new commander_1.Command(); 11 | const line = ansicolor_1.default.red("\n" + "-".repeat(process.stdout.columns) + "\n"); 12 | cli.version("1.0.0"); 13 | cli 14 | .command("start") 15 | .description("start node") 16 | .option("-a, --api", "enable api response") 17 | .action((option) => { 18 | axios_1.default 19 | .post("http://127.0.0.1:7612/start") 20 | .then((res) => { 21 | if (option.api) { 22 | return console.log(JSON.stringify(res.data)); 23 | } 24 | console.log(`${line} ${ansicolor_1.default.bright.green("node started")}\n Admin Wallet :\n Public Key : ${ansicolor_1.default.blue(res.data.mainWallet.publicKey)}\n Private Key : ${ansicolor_1.default.red(res.data.mainWallet.privateKey)}${line}`); 25 | }) 26 | .catch(() => { }); 27 | }); 28 | cli 29 | .command("chain") 30 | .description("manage your node chain") 31 | .option("-a, --api", "enable api response") 32 | .option("-l, --log", "save chain log") 33 | .option("-r, --restart", "restart chain") 34 | .action((option) => { 35 | if (option.restart) { 36 | axios_1.default 37 | .post("http://127.0.0.1:7612/restart") 38 | .then((res) => { 39 | if (option.api) { 40 | return console.log(JSON.stringify(res.data)); 41 | } 42 | else if (!res.data.status) { 43 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 44 | } 45 | return console.log(`${line} ${ansicolor_1.default.bright.green("chain restarted")}\n${line}`); 46 | }) 47 | .catch(() => { }); 48 | } 49 | else if (option.log) { 50 | axios_1.default 51 | .post("http://127.0.0.1:7612/chain/log", { 52 | location: process.cwd() + "/chain.log", 53 | }) 54 | .then((res) => { 55 | if (option.api) { 56 | return console.log(JSON.stringify(res.data)); 57 | } 58 | else if (!res.data.status) { 59 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 60 | } 61 | console.log(`${line} ${ansicolor_1.default.bright.green("chain log saved")}\n Location : ${ansicolor_1.default.blue(process.cwd() + "/chain.log")}${line}`); 62 | }) 63 | .catch(() => { }); 64 | } 65 | }); 66 | cli 67 | .command("wallet") 68 | .description("manage your node wallets") 69 | .option("-a, --api", "enable api response") 70 | .option("-c, --create", "create a wallet") 71 | .option("-b, --balance ", "balance of wallet with address") 72 | .action((option) => { 73 | if (option.create) { 74 | axios_1.default 75 | .post("http://127.0.0.1:7612/wallet/create") 76 | .then((res) => { 77 | if (option.api) { 78 | return console.log(JSON.stringify(res.data)); 79 | } 80 | else if (!res.data.status) { 81 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 82 | } 83 | console.log(`${line} ${ansicolor_1.default.bright.green("wallet created")}\n Wallet :\n Public Key : ${ansicolor_1.default.blue(res.data.wallet.publicKey)}\n Private Key : ${ansicolor_1.default.red(res.data.wallet.privateKey)}${line}`); 84 | }) 85 | .catch(() => { }); 86 | } 87 | else if (option.balance) { 88 | axios_1.default 89 | .post("http://127.0.0.1:7612/wallet/balance/" + option.balance) 90 | .then((res) => { 91 | if (option.api) { 92 | return console.log(JSON.stringify(res.data)); 93 | } 94 | else if (!res.data.status) { 95 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 96 | } 97 | console.log(`${line} ${ansicolor_1.default.bright.green("wallet balance")}\n Balance : ${ansicolor_1.default.blue(res.data.wallet.balance)}${line}`); 98 | }) 99 | .then(() => { }); 100 | } 101 | }); 102 | cli 103 | .command("mine") 104 | .description("node mining manege") 105 | .option("-a, --api", "enable api response") 106 | .option("-c, --core ", "select cpu core for mining") 107 | .option("-s, --stop", "stop mining") 108 | .action((option) => { 109 | if (option.stop) { 110 | axios_1.default 111 | .post("http://127.0.0.1:7612/mine/stop") 112 | .then((res) => { 113 | if (option.api) { 114 | return console.log(JSON.stringify(res.data)); 115 | } 116 | else if (!res.data.status) { 117 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 118 | } 119 | console.log(`${line} ${ansicolor_1.default.bright.green("mining stopped")}${line}`); 120 | }) 121 | .catch((err) => { 122 | }); 123 | } 124 | else if (option.core) { 125 | axios_1.default 126 | .post("http://127.0.0.1:7612/mine/start/" + option.core) 127 | .then((res) => { 128 | if (option.api) { 129 | return console.log(JSON.stringify(res.data)); 130 | } 131 | console.log(`${line} ${ansicolor_1.default.bright.green("mining started")}${line}`); 132 | }) 133 | .catch(() => { }); 134 | } 135 | else { 136 | axios_1.default 137 | .post("http://127.0.0.1:7612/mine/start/1") 138 | .then((res) => { 139 | if (option.api) { 140 | return console.log(JSON.stringify(res.data)); 141 | } 142 | console.log(`${line} ${ansicolor_1.default.bright.green("mining started")}${line}`); 143 | }) 144 | .catch(() => { }); 145 | } 146 | }); 147 | cli 148 | .command("transaction") 149 | .description("manage your node transactions") 150 | .option("-a, --api", "enable api response") 151 | .option("-fpub,--fromPublic ", "from public address") 152 | .option("-fpri,--fromPrivate ", "from private address") 153 | .option("-tpub,--toPublic ", "to public address") 154 | .option("-v,--value ", "Transfer Value") 155 | .action((option) => { 156 | if (option.fromPublic && 157 | option.toPublic && 158 | option.fromPrivate && 159 | option.value) { 160 | axios_1.default 161 | .post("http://127.0.0.1:7612/transaction", { 162 | fromPublicKey: option.fromPublic, 163 | fromPrivateKey: option.fromPrivate, 164 | toPublic: option.toPublic, 165 | amount: option.value, 166 | }) 167 | .then((res) => { 168 | if (option.api) { 169 | return console.log(JSON.stringify(res.data)); 170 | } 171 | else if (!res.data.status) { 172 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 173 | } 174 | console.log(`${line} ${ansicolor_1.default.bright.green("transaction created")}${line}`); 175 | }) 176 | .catch((err) => { console.log(err); }); 177 | } 178 | }); 179 | cli.parse(process.argv); 180 | -------------------------------------------------------------------------------- /Bin/dpx.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | var __importDefault = (this && this.__importDefault) || function (mod) { 4 | return (mod && mod.__esModule) ? mod : { "default": mod }; 5 | }; 6 | Object.defineProperty(exports, "__esModule", { value: true }); 7 | const commander_1 = require("commander"); 8 | const axios_1 = __importDefault(require("axios")); 9 | const ansicolor_1 = __importDefault(require("ansicolor")); 10 | const cli = new commander_1.Command(); 11 | const line = ansicolor_1.default.red("\n" + "-".repeat(process.stdout.columns) + "\n"); 12 | cli.version("1.0.0"); 13 | cli 14 | .command("start") 15 | .description("start node") 16 | .option("-a, --api", "enable api response") 17 | .action((option) => { 18 | axios_1.default 19 | .post("http://127.0.0.1:7612/start") 20 | .then((res) => { 21 | if (option.api) { 22 | return console.log(JSON.stringify(res.data)); 23 | } 24 | console.log(`${line} ${ansicolor_1.default.bright.green("node started")}\n Admin Wallet :\n Public Key : ${ansicolor_1.default.blue(res.data.mainWallet.publicKey)}\n Private Key : ${ansicolor_1.default.red(res.data.mainWallet.privateKey)}${line}`); 25 | }) 26 | .catch(() => { }); 27 | }); 28 | cli 29 | .command("chain") 30 | .description("manage your node chain") 31 | .option("-a, --api", "enable api response") 32 | .option("-l, --log", "save chain log") 33 | .option("-r, --restart", "restart chain") 34 | .action((option) => { 35 | if (option.restart) { 36 | axios_1.default 37 | .post("http://127.0.0.1:7612/restart") 38 | .then((res) => { 39 | if (option.api) { 40 | return console.log(JSON.stringify(res.data)); 41 | } 42 | else if (!res.data.status) { 43 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 44 | } 45 | return console.log(`${line} ${ansicolor_1.default.bright.green("chain restarted")}\n${line}`); 46 | }) 47 | .catch(() => { }); 48 | } 49 | else if (option.log) { 50 | axios_1.default 51 | .post("http://127.0.0.1:7612/chain/log", { 52 | location: process.cwd() + "/chain.log", 53 | }) 54 | .then((res) => { 55 | if (option.api) { 56 | return console.log(JSON.stringify(res.data)); 57 | } 58 | else if (!res.data.status) { 59 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 60 | } 61 | console.log(`${line} ${ansicolor_1.default.bright.green("chain log saved")}\n Location : ${ansicolor_1.default.blue(process.cwd() + "/chain.log")}${line}`); 62 | }) 63 | .catch(() => { }); 64 | } 65 | }); 66 | cli 67 | .command("wallet") 68 | .description("manage your node wallets") 69 | .option("-a, --api", "enable api response") 70 | .option("-c, --create", "create a wallet") 71 | .option("-b, --balance ", "balance of wallet with address") 72 | .action((option) => { 73 | if (option.create) { 74 | axios_1.default 75 | .post("http://127.0.0.1:7612/wallet/create") 76 | .then((res) => { 77 | if (option.api) { 78 | return console.log(JSON.stringify(res.data)); 79 | } 80 | else if (!res.data.status) { 81 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 82 | } 83 | console.log(`${line} ${ansicolor_1.default.bright.green("wallet created")}\n Wallet :\n Public Key : ${ansicolor_1.default.blue(res.data.wallet.publicKey)}\n Private Key : ${ansicolor_1.default.red(res.data.wallet.privateKey)}${line}`); 84 | }) 85 | .catch(() => { }); 86 | } 87 | else if (option.balance) { 88 | axios_1.default 89 | .post("http://127.0.0.1:7612/wallet/balance/" + option.balance) 90 | .then((res) => { 91 | if (option.api) { 92 | return console.log(JSON.stringify(res.data)); 93 | } 94 | else if (!res.data.status) { 95 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 96 | } 97 | console.log(`${line} ${ansicolor_1.default.bright.green("wallet balance")}\n Balance : ${ansicolor_1.default.blue(res.data.wallet.balance)}${line}`); 98 | }) 99 | .then(() => { }); 100 | } 101 | }); 102 | cli 103 | .command("mine") 104 | .description("node mining manege") 105 | .option("-a, --api", "enable api response") 106 | .option("-c, --core ", "select cpu core for mining") 107 | .option("-s, --stop", "stop mining") 108 | .action((option) => { 109 | if (option.stop) { 110 | axios_1.default 111 | .post("http://127.0.0.1:7612/mine/stop") 112 | .then((res) => { 113 | if (option.api) { 114 | return console.log(JSON.stringify(res.data)); 115 | } 116 | else if (!res.data.status) { 117 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 118 | } 119 | console.log(`${line} ${ansicolor_1.default.bright.green("mining stopped")}${line}`); 120 | }) 121 | .catch((err) => { 122 | }); 123 | } 124 | else if (option.core) { 125 | axios_1.default 126 | .post("http://127.0.0.1:7612/mine/start/" + option.core) 127 | .then((res) => { 128 | if (option.api) { 129 | return console.log(JSON.stringify(res.data)); 130 | } 131 | console.log(`${line} ${ansicolor_1.default.bright.green("mining started")}${line}`); 132 | }) 133 | .catch(() => { }); 134 | } 135 | else { 136 | axios_1.default 137 | .post("http://127.0.0.1:7612/mine/start/1") 138 | .then((res) => { 139 | if (option.api) { 140 | return console.log(JSON.stringify(res.data)); 141 | } 142 | console.log(`${line} ${ansicolor_1.default.bright.green("mining started")}${line}`); 143 | }) 144 | .catch(() => { }); 145 | } 146 | }); 147 | cli 148 | .command("transaction") 149 | .description("manage your node transactions") 150 | .option("-a, --api", "enable api response") 151 | .option("-fpub,--fromPublic ", "from public address") 152 | .option("-fpri,--fromPrivate ", "from private address") 153 | .option("-tpub,--toPublic ", "to public address") 154 | .option("-v,--value ", "Transfer Value") 155 | .action((option) => { 156 | if (option.fromPublic && 157 | option.toPublic && 158 | option.fromPrivate && 159 | option.value) { 160 | axios_1.default 161 | .post("http://127.0.0.1:7612/transaction", { 162 | fromPublicKey: option.fromPublic, 163 | fromPrivateKey: option.fromPrivate, 164 | toPublic: option.toPublic, 165 | amount: option.value, 166 | }) 167 | .then((res) => { 168 | if (option.api) { 169 | return console.log(JSON.stringify(res.data)); 170 | } 171 | else if (!res.data.status) { 172 | return console.log(`${line} ${ansicolor_1.default.bright.green(res.data.message)}${line}`); 173 | } 174 | console.log(`${line} ${ansicolor_1.default.bright.green("transaction created")}${line}`); 175 | }) 176 | .catch((err) => { console.log(err); }); 177 | } 178 | }); 179 | cli.parse(process.argv); 180 | -------------------------------------------------------------------------------- /Bin/dpx.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Command } from "commander"; 3 | import axios from "axios"; 4 | import color from "ansicolor"; 5 | 6 | const cli = new Command(); 7 | 8 | const line = color.red("\n" + "-".repeat(process.stdout.columns) + "\n"); 9 | cli.version("1.0.0"); 10 | 11 | cli 12 | .command("start") 13 | .description("start node") 14 | .option("-a, --api", "enable api response") 15 | .action((option) => { 16 | axios 17 | .post("http://127.0.0.1:7612/start") 18 | .then((res) => { 19 | if (option.api) { 20 | return console.log(JSON.stringify(res.data)); 21 | } 22 | console.log( 23 | `${line} ${color.bright.green( 24 | "node started" 25 | )}\n Admin Wallet :\n Public Key : ${color.blue( 26 | res.data.mainWallet.publicKey 27 | )}\n Private Key : ${color.red( 28 | res.data.mainWallet.privateKey 29 | )}${line}` 30 | ); 31 | }) 32 | .catch(() => {}); 33 | }); 34 | cli 35 | .command("chain") 36 | .description("manage your node chain") 37 | .option("-a, --api", "enable api response") 38 | .option("-l, --log", "save chain log") 39 | .option("-r, --restart", "restart chain") 40 | .action((option) => { 41 | if (option.restart) { 42 | axios 43 | .post("http://127.0.0.1:7612/restart") 44 | .then((res) => { 45 | if (option.api) { 46 | return console.log(JSON.stringify(res.data)); 47 | } 48 | else if(!res.data.status){ 49 | return console.log(`${line} ${color.bright.green(res.data.message)}${line}`); 50 | } 51 | return console.log( 52 | `${line} ${color.bright.green("chain restarted")}\n${line}` 53 | ); 54 | }) 55 | .catch(() => {}); 56 | } else if (option.log) { 57 | axios 58 | .post("http://127.0.0.1:7612/chain/log", { 59 | location: process.cwd() + "/chain.log", 60 | }) 61 | .then((res) => { 62 | if (option.api) { 63 | return console.log(JSON.stringify(res.data)); 64 | } 65 | else if(!res.data.status){ 66 | return console.log(`${line} ${color.bright.green(res.data.message)}${line}`); 67 | } 68 | console.log( 69 | `${line} ${color.bright.green( 70 | "chain log saved" 71 | )}\n Location : ${color.blue(process.cwd() + "/chain.log")}${line}` 72 | ); 73 | }) 74 | .catch(() => {}); 75 | } 76 | }); 77 | 78 | cli 79 | .command("wallet") 80 | .description("manage your node wallets") 81 | .option("-a, --api", "enable api response") 82 | .option("-c, --create", "create a wallet") 83 | .option("-b, --balance ", "balance of wallet with address") 84 | .action((option) => { 85 | if (option.create) { 86 | axios 87 | .post("http://127.0.0.1:7612/wallet/create") 88 | .then((res) => { 89 | if (option.api) { 90 | return console.log(JSON.stringify(res.data)); 91 | } 92 | else if(!res.data.status){ 93 | return console.log(`${line} ${color.bright.green(res.data.message)}${line}`); 94 | } 95 | console.log( 96 | `${line} ${color.bright.green( 97 | "wallet created" 98 | )}\n Wallet :\n Public Key : ${color.blue( 99 | res.data.wallet.publicKey 100 | )}\n Private Key : ${color.red( 101 | res.data.wallet.privateKey 102 | )}${line}` 103 | ); 104 | }) 105 | .catch(() => {}); 106 | } else if (option.balance) { 107 | axios 108 | .post("http://127.0.0.1:7612/wallet/balance/" + option.balance) 109 | .then((res) => { 110 | if (option.api) { 111 | return console.log(JSON.stringify(res.data)); 112 | } 113 | else if(!res.data.status){ 114 | return console.log(`${line} ${color.bright.green(res.data.message)}${line}`); 115 | } 116 | console.log( 117 | `${line} ${color.bright.green( 118 | "wallet balance" 119 | )}\n Balance : ${color.blue(res.data.wallet.balance)}${line}` 120 | ); 121 | }) 122 | .then(() => {}); 123 | } 124 | }); 125 | 126 | cli 127 | .command("mine") 128 | .description("node mining manege") 129 | .option("-a, --api", "enable api response") 130 | .option("-c, --core ", "select cpu core for mining") 131 | .option("-s, --stop", "stop mining") 132 | .action((option) => { 133 | if (option.stop) { 134 | axios 135 | .post("http://127.0.0.1:7612/mine/stop") 136 | .then((res) => { 137 | if (option.api) { 138 | return console.log(JSON.stringify(res.data)); 139 | } 140 | else if(!res.data.status){ 141 | return console.log(`${line} ${color.bright.green(res.data.message)}${line}`); 142 | } 143 | console.log(`${line} ${color.bright.green("mining stopped")}${line}`); 144 | }) 145 | .catch((err) => { 146 | }); 147 | } else if (option.core) { 148 | axios 149 | .post("http://127.0.0.1:7612/mine/start/" + option.core) 150 | .then((res) => { 151 | if (option.api) { 152 | return console.log(JSON.stringify(res.data)); 153 | } 154 | console.log(`${line} ${color.bright.green("mining started")}${line}`); 155 | }) 156 | .catch(() => {}); 157 | } else { 158 | axios 159 | .post("http://127.0.0.1:7612/mine/start/1") 160 | .then((res) => { 161 | if (option.api) { 162 | return console.log(JSON.stringify(res.data)); 163 | } 164 | console.log(`${line} ${color.bright.green("mining started")}${line}`); 165 | }) 166 | .catch(() => {}); 167 | } 168 | }); 169 | 170 | cli 171 | .command("transaction") 172 | .description("manage your node transactions") 173 | .option("-a, --api", "enable api response") 174 | .option("-fpub,--fromPublic ", "from public address") 175 | .option("-fpri,--fromPrivate ", "from private address") 176 | .option("-tpub,--toPublic ", "to public address") 177 | .option("-v,--value ", "Transfer Value") 178 | .action((option) => { 179 | if ( 180 | option.fromPublic && 181 | option.toPublic && 182 | option.fromPrivate && 183 | option.value 184 | ) { 185 | axios 186 | .post("http://127.0.0.1:7612/transaction", { 187 | fromPublicKey: option.fromPublic, 188 | fromPrivateKey : option.fromPrivate, 189 | toPublic: option.toPublic, 190 | amount: option.value, 191 | }) 192 | .then((res) => { 193 | if (option.api) { 194 | return console.log(JSON.stringify(res.data)); 195 | } 196 | else if(!res.data.status){ 197 | return console.log(`${line} ${color.bright.green(res.data.message)}${line}`); 198 | } 199 | console.log(`${line} ${color.bright.green("transaction created")}${line}`); 200 | }) 201 | .catch((err) => {console.log(err)}); 202 | } 203 | }); 204 | 205 | cli.parse(process.argv); 206 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:alpine 2 | USER root 3 | COPY . /NODE 4 | WORKDIR /NODE 5 | RUN npm install 6 | RUN npm link 7 | CMD ["node", "./App/index.js"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blockchain-client 2 | A blockchain built using Node js/Go 3 | The blockchain was supposed to reach the commercial stage in collaboration with one of the programming groups, which was canceled. 4 | I decided to make the source public, so that if anyone wanted to use it. 5 | 6 | Blockchain-Server-JS source -> [Blockchain-server-js](https://github.com/hamidreza01/Blockchain-Server-JS) 7 | 8 | Blockchain-Server-GO source -> [Blockchain-server-go](https://github.com/hamidreza01/Blockchain-Server-GO) 9 | -------------------------------------------------------------------------------- /Scripts/mine.js: -------------------------------------------------------------------------------- 1 | const {Blockchain : BlockChain} = require("../Src/classes/Blockchain/Blockchain") 2 | const { style } = require("cls.js"); 3 | const cluster = require("cluster"); 4 | const numCPUs = 2; 5 | 6 | if (cluster.isPrimary) { 7 | console.log(`Primary ${process.pid} is running`); 8 | 9 | for (let i = 0; i < numCPUs; i++) { 10 | cluster.fork(); 11 | }; 12 | 13 | 14 | cluster.on("exit", (worker, code, signal) => { 15 | console.log(`worker ${worker.process.pid} died`); 16 | }); 17 | } else { 18 | console.log(`Worker ${process.pid} started`); 19 | const blockChain = new BlockChain(); 20 | blockChain.addBlock("initial"); 21 | let pt, nt, nb, td, average; 22 | const times = []; 23 | for (let i = 0; i < 10000; i++) { 24 | pt = blockChain.chain[blockChain.chain.length - 1].timestamp; 25 | blockChain.addBlock(`block${i}`); 26 | nb = blockChain.chain[blockChain.chain.length - 1]; 27 | nt = nb.timestamp; 28 | td = nt - pt; 29 | times.push(td); 30 | average = 31 | times.reduce((total, num) => { 32 | return total + num; 33 | }) / times.length; 34 | 35 | style({ 36 | text: `time to mine block : ${td}ms`, 37 | color: "blue", 38 | }); 39 | style({ 40 | text: `Difficulity : ${nb.difficulty}`, 41 | color: "red", 42 | }); 43 | 44 | style({ 45 | text: `average time : ${Math.floor(average)}ms`, 46 | color: "yellow", 47 | }); 48 | style({ 49 | text: `-----------------------`, 50 | color: "white", 51 | }) 52 | console.log(BlockChain.isValid(blockChain.chain)) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Scripts/work.js: -------------------------------------------------------------------------------- 1 | const BlockChain = require("../BlockChain/BlockChain"); 2 | const { style } = require("cls.js"); 3 | const cluster = require("cluster"); 4 | const numCPUs = 0; 5 | 6 | if (cluster.isPrimary) { 7 | console.log(`Primary ${process.pid} is running`); 8 | 9 | for (let i = 0; i < numCPUs; i++) { 10 | cluster.fork(); 11 | }; 12 | 13 | 14 | cluster.on("exit", (worker, code, signal) => { 15 | console.log(`worker ${worker.process.pid} died`); 16 | }); 17 | } else { 18 | console.log(`Worker ${process.pid} started`); 19 | const blockChain = new BlockChain(); 20 | blockChain.addBlock({ data: "initial" }); 21 | let pt, nt, nb, td, average; 22 | const times = []; 23 | for (let i = 0; i < 10000; i++) { 24 | pt = blockChain.chain[blockChain.chain.length - 1].timeStamp; 25 | blockChain.addBlock({ data: `block${i}` }); 26 | nb = blockChain.chain[blockChain.chain.length - 1]; 27 | nt = nb.timeStamp; 28 | td = nt - pt; 29 | times.push(td); 30 | average = 31 | times.reduce((total, num) => { 32 | return total + num; 33 | }) / times.length; 34 | 35 | style({ 36 | text: `time to mine block : ${td}ms`, 37 | color: "blue", 38 | }); 39 | style({ 40 | text: `Difficulity : ${nb.difficulty}`, 41 | color: "red", 42 | }); 43 | 44 | style({ 45 | text: `average time : ${Math.floor(average)}ms`, 46 | color: "yellow", 47 | }); 48 | style({ 49 | text: `-----------------------`, 50 | color: "white", 51 | }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Src/Addon/hash-creator.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.hashCreator = void 0; 27 | const crypto = __importStar(require("crypto")); 28 | const hashCreator = (...data) => { 29 | const hash = crypto.createHash("sha256"); 30 | return hash.update(data.join("")).digest("hex"); 31 | }; 32 | exports.hashCreator = hashCreator; 33 | // import * as crypto from "crypto"; 34 | // export const hashCreator = (...data: Array): string => { 35 | // const hash = crypto.createHash("sha256"); 36 | // return hash 37 | // .update( 38 | // data 39 | // .sort() 40 | // .map((x) => { 41 | // return JSON.stringify(x); 42 | // }) 43 | // .join(" ") 44 | // ) 45 | // .digest("hex"); 46 | // }; 47 | -------------------------------------------------------------------------------- /Src/Addon/hash-creator.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from "crypto"; 2 | export const hashCreator = (...data : string[]) => { 3 | const hash = crypto.createHash("sha256"); 4 | return hash.update(data.join("")).digest("hex"); 5 | }; 6 | // import * as crypto from "crypto"; 7 | // export const hashCreator = (...data: Array): string => { 8 | // const hash = crypto.createHash("sha256"); 9 | // return hash 10 | // .update( 11 | // data 12 | // .sort() 13 | // .map((x) => { 14 | // return JSON.stringify(x); 15 | // }) 16 | // .join(" ") 17 | // ) 18 | // .digest("hex"); 19 | // }; 20 | -------------------------------------------------------------------------------- /Src/Addon/sign.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.recoveryKeyPair = exports.verify = exports.ec = void 0; 7 | const elliptic_1 = __importDefault(require("elliptic")); 8 | const hash_creator_1 = require("./hash-creator"); 9 | exports.ec = new elliptic_1.default.ec("ed25519"); 10 | const verify = (data, sign, publicKey) => { 11 | const vrf = exports.ec.keyFromPublic(publicKey, "hex"); 12 | try { 13 | return vrf.verify((0, hash_creator_1.hashCreator)(JSON.stringify(data)), sign); 14 | } 15 | catch (error) { 16 | return false; 17 | } 18 | }; 19 | exports.verify = verify; 20 | const recoveryKeyPair = (privateKey, publicKey) => { 21 | return exports.ec.keyPair({ 22 | "priv": Buffer.from(privateKey, 'base64').toString(), 23 | "pubEnc": publicKey, 24 | }); 25 | }; 26 | exports.recoveryKeyPair = recoveryKeyPair; 27 | -------------------------------------------------------------------------------- /Src/Addon/sign.ts: -------------------------------------------------------------------------------- 1 | import elliptic, { SignatureInput } from "elliptic"; 2 | import { hashCreator } from "./hash-creator"; 3 | 4 | export const ec = new elliptic.ec("ed25519"); 5 | export const verify = ( 6 | data: any, 7 | sign: SignatureInput, 8 | publicKey: string 9 | ): boolean => { 10 | const vrf = ec.keyFromPublic(publicKey, "hex"); 11 | try { 12 | return vrf.verify(hashCreator(JSON.stringify(data)), sign); 13 | } catch (error) { 14 | return false; 15 | } 16 | }; 17 | export const recoveryKeyPair = (privateKey: string, publicKey : string) => { 18 | return ec.keyPair({ 19 | "priv" : Buffer.from(privateKey,'base64').toString() as any, 20 | "pubEnc" : publicKey, 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/Block.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.Block = void 0; 7 | const config_1 = require("../../../config"); 8 | const hash_creator_1 = require("../../Addon/hash-creator"); 9 | const hex_to_bin_1 = __importDefault(require("hex-to-bin")); 10 | class Block { 11 | constructor(timestamp, data, hash, lastHash, nonce, difficulty) { 12 | this.timestamp = timestamp; 13 | this.data = data; 14 | this.hash = hash; 15 | this.lastHash = lastHash; 16 | this.nonce = nonce; 17 | this.difficulty = difficulty; 18 | } 19 | static genesis() { 20 | return config_1.config.GENESIS_DATA; 21 | } 22 | static mineBlock(lastBlock, data) { 23 | const { hash: lastHash } = lastBlock; 24 | let difficulty = lastBlock.difficulty; 25 | let nonce = 0; 26 | let hash, timestamp; 27 | do { 28 | nonce++; 29 | timestamp = Date.now(); 30 | difficulty = Block.adJustDifficulty(lastBlock, timestamp); 31 | hash = (0, hash_creator_1.hashCreator)(lastHash, nonce.toString(), timestamp.toString(), difficulty.toString(), JSON.stringify(data)); 32 | } while ((0, hex_to_bin_1.default)(hash).slice(0, difficulty) !== "0".repeat(difficulty)); 33 | { 34 | return new Block(timestamp, data, hash, lastHash, nonce, difficulty); 35 | } 36 | } 37 | static adJustDifficulty(lastBlock, timestamp) { 38 | if (lastBlock.difficulty < 1) 39 | return 1; 40 | if (timestamp - lastBlock.timestamp > config_1.config.MINE_RATE) 41 | return lastBlock.difficulty - 1; 42 | return lastBlock.difficulty + 1; 43 | } 44 | } 45 | exports.Block = Block; 46 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/Block.ts: -------------------------------------------------------------------------------- 1 | import { config } from "../../../config"; 2 | import { hashCreator } from "../../Addon/hash-creator"; 3 | import { _Block } from "../../interfaces/Blockchain/_Block"; 4 | 5 | import hexToBin from "hex-to-bin"; 6 | import { _Transaction } from "../../interfaces/Blockchain/_Transaction"; 7 | 8 | export class Block implements _Block { 9 | constructor( 10 | public timestamp: number, 11 | public data: {transaction ?: [_Transaction]}, 12 | public hash: string, 13 | public lastHash: string, 14 | public nonce: number, 15 | public difficulty: number 16 | ) {} 17 | static genesis(): _Block { 18 | return config.GENESIS_DATA; 19 | } 20 | static mineBlock(lastBlock: _Block, data: {transaction ?: [_Transaction]}): _Block { 21 | const { hash: lastHash } = lastBlock; 22 | let difficulty = lastBlock.difficulty; 23 | let nonce = 0; 24 | let hash: string, timestamp: number; 25 | do { 26 | nonce++; 27 | timestamp = Date.now(); 28 | difficulty = Block.adJustDifficulty(lastBlock, timestamp); 29 | hash = hashCreator( 30 | lastHash, 31 | nonce.toString(), 32 | timestamp.toString(), 33 | difficulty.toString(), 34 | JSON.stringify(data) 35 | ); 36 | } while (hexToBin(hash).slice(0, difficulty) !== "0".repeat(difficulty)); 37 | { 38 | return new Block(timestamp, data, hash, lastHash, nonce, difficulty); 39 | } 40 | } 41 | static adJustDifficulty(lastBlock: _Block, timestamp: number) { 42 | if (lastBlock.difficulty < 1) return 1; 43 | if (timestamp - lastBlock.timestamp > config.MINE_RATE) 44 | return lastBlock.difficulty - 1; 45 | return lastBlock.difficulty + 1; 46 | } 47 | } -------------------------------------------------------------------------------- /Src/classes/Blockchain/Blockchain.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Blockchain = void 0; 4 | const hash_creator_1 = require("../../Addon/hash-creator"); 5 | const Block_1 = require("./Block"); 6 | const config_1 = require("../../../config"); 7 | const Transaction_1 = require("./Transaction"); 8 | const Wallet_1 = require("./Wallet"); 9 | class Blockchain { 10 | constructor() { 11 | this.chain = [Block_1.Block.genesis()]; 12 | } 13 | addBlock(data) { 14 | const block = Block_1.Block.mineBlock(this.chain[this.chain.length - 1], data); 15 | this.chain.push(block); 16 | } 17 | static isValid(chain) { 18 | if (JSON.stringify(chain[0]) !== JSON.stringify(Block_1.Block.genesis())) 19 | return false; 20 | for (let i = 1; i < chain.length; i++) { 21 | if (chain[i].hash !== 22 | (0, hash_creator_1.hashCreator)(chain[i].lastHash, chain[i].nonce.toString(), chain[i].timestamp.toString(), chain[i].difficulty.toString(), JSON.stringify(chain[i].data))) { 23 | return false; 24 | } 25 | if (chain[i].lastHash !== chain[i - 1].hash) { 26 | return false; 27 | } 28 | if (Math.abs(chain[i - 1].difficulty - chain[i].difficulty) > 1) { 29 | return false; 30 | } 31 | } 32 | return true; 33 | } 34 | replaceChain(chain) { 35 | if (chain.length < this.chain.length) { 36 | return { message: "chain is short", code: 101 }; 37 | } 38 | if (!Blockchain.isValid(chain)) { 39 | return { message: "chain is not valid", code: 102 }; 40 | } 41 | this.chain = chain; 42 | return true; 43 | } 44 | validTransactionData(chain) { 45 | var _a, _b, _c, _d, _e, _f; 46 | for (let i = 1; i < (chain === null || chain === void 0 ? void 0 : chain.length); i++) { 47 | if (((_c = (_b = (_a = chain[i]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.transaction) === null || _c === void 0 ? void 0 : _c.length) < 1) 48 | return { message: "chain data is empty", code: 120 }; 49 | for (let transaction of (_e = (_d = chain[i]) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.transaction) { 50 | let rewardNumber = 0; 51 | if (((_f = transaction === null || transaction === void 0 ? void 0 : transaction.inputMap) === null || _f === void 0 ? void 0 : _f.address) === config_1.config.REWARD_TRANSACTION.address) { 52 | rewardNumber++; 53 | if (rewardNumber > 1) { 54 | return { 55 | message: "reward transaction length is ivalid", 56 | code: 122, 57 | }; 58 | } 59 | if (Object.values(transaction.outputMap).reduce((all, val) => (all + val)) > config_1.config.REWARD) { 60 | return { message: "reward transaction is invalid", code: 121 }; 61 | } 62 | } 63 | else { 64 | let transactionResualt = Transaction_1.Transaction.isValid(transaction); 65 | if (transactionResualt !== true) { 66 | return transactionResualt; 67 | } 68 | else { 69 | const trueValue = Wallet_1.Wallet.calculateBalance(this.chain, transaction.inputMap.address); 70 | if (trueValue !== transaction.inputMap.amount) { 71 | return { message: "transaction amount is invalid", code: 123 }; 72 | } 73 | } 74 | } 75 | } 76 | } 77 | return true; 78 | } 79 | } 80 | exports.Blockchain = Blockchain; 81 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/Blockchain.ts: -------------------------------------------------------------------------------- 1 | import { hashCreator } from "../../Addon/hash-creator"; 2 | import { _Blockchain } from "../../interfaces/Blockchain/_Blockchain"; 3 | import { _Errors } from "../../types/errors_interface"; 4 | import { _Block } from "../../interfaces/Blockchain/_Block"; 5 | import { Block } from "./Block"; 6 | import { _Transaction } from "../../interfaces/Blockchain/_Transaction"; 7 | import { config } from "../../../config"; 8 | import { Transaction } from "./Transaction"; 9 | import { Wallet } from "./Wallet"; 10 | export class Blockchain implements _Blockchain { 11 | chain = [Block.genesis()]; 12 | 13 | addBlock(data: { transaction: [_Transaction] }): void { 14 | const block = Block.mineBlock(this.chain[this.chain.length - 1], data); 15 | this.chain.push(block); 16 | } 17 | 18 | static isValid(chain: Array<_Block>): boolean { 19 | if (JSON.stringify(chain[0]) !== JSON.stringify(Block.genesis())) 20 | return false; 21 | for (let i = 1; i < chain.length; i++) { 22 | if ( 23 | chain[i].hash !== 24 | hashCreator( 25 | chain[i].lastHash, 26 | chain[i].nonce.toString(), 27 | chain[i].timestamp.toString(), 28 | chain[i].difficulty.toString(), 29 | JSON.stringify(chain[i].data) 30 | ) 31 | ) { 32 | return false; 33 | } 34 | 35 | if (chain[i].lastHash !== chain[i - 1].hash) { 36 | return false; 37 | } 38 | if (Math.abs(chain[i - 1].difficulty - chain[i].difficulty) > 1) { 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | replaceChain(chain: Array<_Block>): _Errors | boolean { 45 | if (chain.length < this.chain.length) { 46 | return { message: "chain is short", code: 101 }; 47 | } 48 | if (!Blockchain.isValid(chain)) { 49 | return { message: "chain is not valid", code: 102 }; 50 | } 51 | this.chain = chain; 52 | return true; 53 | } 54 | validTransactionData(chain: Array<_Block>): boolean | _Errors { 55 | for (let i = 1; i < chain?.length; i++) { 56 | if (chain[i]?.data?.transaction?.length! < 1) 57 | return { message: "chain data is empty", code: 120 }; 58 | for (let transaction of chain[i]?.data?.transaction!) { 59 | let rewardNumber = 0; 60 | if ( 61 | transaction?.inputMap?.address === config.REWARD_TRANSACTION.address 62 | ) { 63 | rewardNumber++; 64 | if (rewardNumber > 1) { 65 | return { 66 | message: "reward transaction length is ivalid", 67 | code: 122, 68 | }; 69 | } 70 | if ( 71 | (Object.values(transaction.outputMap).reduce( 72 | (all, val) => ((all as any) + val) as any 73 | ) as number) > config.REWARD 74 | ) { 75 | return { message: "reward transaction is invalid", code: 121 }; 76 | } 77 | } else { 78 | let transactionResualt = Transaction.isValid(transaction); 79 | if (transactionResualt !== true) { 80 | return transactionResualt; 81 | } else { 82 | const trueValue = Wallet.calculateBalance( 83 | this.chain, 84 | transaction.inputMap.address 85 | ); 86 | if (trueValue !== transaction.inputMap.amount) { 87 | return { message: "transaction amount is invalid", code: 123 }; 88 | } 89 | } 90 | } 91 | } 92 | } 93 | return true; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/Transaction.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.Transaction = void 0; 7 | const uniqid_1 = __importDefault(require("uniqid")); 8 | const sign_1 = require("../../Addon/sign"); 9 | const config_1 = require("../../../config"); 10 | class Transaction { 11 | constructor(senderWallet, amount, recpient, inputMap, outputMap) { 12 | this.id = (0, uniqid_1.default)(); 13 | this.outputMap = {}; 14 | this.inputMap = { 15 | timestamp: 0, 16 | address: "", 17 | amount: 0, 18 | signature: { s: "", r: "" }, 19 | }; 20 | (this.outputMap = outputMap || this.outputMapCreator(senderWallet, amount, recpient)), 21 | (this.inputMap = inputMap || this.inputMapCreator(senderWallet, this.outputMap)); 22 | } 23 | inputMapCreator(senderWallet, outputMap) { 24 | return { 25 | timestamp: Date.now(), 26 | address: senderWallet.publicKey, 27 | amount: senderWallet.balance, 28 | signature: senderWallet.sign(outputMap), 29 | }; 30 | } 31 | outputMapCreator(senderWallet, amount, recipient) { 32 | let outputMap = {}; 33 | outputMap[senderWallet.publicKey] = senderWallet.balance - amount; 34 | outputMap[recipient] = amount; 35 | return outputMap; 36 | } 37 | update(recpient, amount, senderWallet) { 38 | if (this.outputMap[senderWallet.publicKey] < amount) { 39 | return { message: "amount exceeds balance", code: 112 }; 40 | } 41 | if (this.outputMap[recpient]) { 42 | this.outputMap[recpient] += amount; 43 | } 44 | else { 45 | this.outputMap[recpient] = amount; 46 | } 47 | this.inputMap = this.inputMapCreator(senderWallet, this.outputMap); 48 | } 49 | static isValid(transaction) { 50 | let total = Object.values(transaction.outputMap).reduce((all, val) => { 51 | return all + val; 52 | }); 53 | if (total !== transaction.inputMap.amount) { 54 | return { 55 | message: `invalid transaction from ${transaction.inputMap.address}`, 56 | code: 111, 57 | }; 58 | } 59 | if (!(0, sign_1.verify)(transaction.outputMap, transaction.inputMap.signature, transaction.inputMap.address)) { 60 | return { 61 | message: `invalid transaction from ${transaction.inputMap.address}`, 62 | code: 112, 63 | }; 64 | } 65 | return true; 66 | } 67 | static reward(minerWallet) { 68 | return new Transaction(minerWallet, 0, minerWallet.publicKey, config_1.config.REWARD_TRANSACTION, { [minerWallet.publicKey]: config_1.config.REWARD }); 69 | } 70 | } 71 | exports.Transaction = Transaction; 72 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/Transaction.ts: -------------------------------------------------------------------------------- 1 | import { _Transaction } from "../../interfaces/Blockchain/_Transaction"; 2 | import { _Wallet } from "../../interfaces/Blockchain/_Wallet"; 3 | import uniqid from "uniqid"; 4 | import { _Errors } from "../../types/errors_interface"; 5 | import { verify } from "../../Addon/sign"; 6 | import { inputMap_type } from "../../types/inputMap_types"; 7 | import { config } from "../../../config"; 8 | export class Transaction implements _Transaction { 9 | id: string = uniqid(); 10 | public outputMap: any = {}; 11 | public inputMap: inputMap_type = { 12 | timestamp: 0, 13 | address: "", 14 | amount: 0, 15 | signature: { s: "", r: "" }, 16 | }; 17 | constructor(senderWallet: _Wallet, amount: number, recpient: string, inputMap?: inputMap_type, outputMap?: {}) { 18 | (this.outputMap = outputMap || this.outputMapCreator(senderWallet, amount, recpient)), 19 | (this.inputMap = inputMap || this.inputMapCreator(senderWallet, this.outputMap)); 20 | } 21 | inputMapCreator(senderWallet: _Wallet, outputMap: {}): inputMap_type { 22 | return { 23 | timestamp: Date.now(), 24 | address: senderWallet.publicKey, 25 | amount: senderWallet.balance, 26 | signature: senderWallet.sign(outputMap), 27 | }; 28 | } 29 | outputMapCreator( 30 | senderWallet: _Wallet, 31 | amount: number, 32 | recipient: string 33 | ): {} { 34 | let outputMap: any = {}; 35 | outputMap[senderWallet.publicKey] = senderWallet.balance - amount; 36 | outputMap[recipient] = amount; 37 | return outputMap; 38 | } 39 | update( 40 | recpient: string, 41 | amount: number, 42 | senderWallet: _Wallet 43 | ): void | _Errors { 44 | if (this.outputMap[senderWallet.publicKey] < amount) { 45 | return { message: "amount exceeds balance", code: 112 }; 46 | } 47 | if(this.outputMap[recpient]){ 48 | this.outputMap[recpient] += amount 49 | }else{ 50 | this.outputMap[recpient] = amount; 51 | } 52 | this.inputMap = this.inputMapCreator(senderWallet,this.outputMap) 53 | } 54 | static isValid(transaction: _Transaction): _Errors | boolean { 55 | let total = Object.values(transaction.outputMap).reduce((all, val: any) => { 56 | return (all as number) + val; 57 | }); 58 | if (total !== transaction.inputMap.amount) { 59 | return { 60 | message: `invalid transaction from ${transaction.inputMap.address}`, 61 | code: 111, 62 | }; 63 | } 64 | if ( 65 | !verify( 66 | transaction.outputMap, 67 | transaction.inputMap.signature, 68 | transaction.inputMap.address 69 | ) 70 | ) { 71 | return { 72 | message: `invalid transaction from ${transaction.inputMap.address}`, 73 | code: 112, 74 | }; 75 | } 76 | return true; 77 | } 78 | static reward(minerWallet: _Wallet): _Transaction { 79 | return new Transaction( 80 | minerWallet, 81 | 0, 82 | minerWallet.publicKey, 83 | config.REWARD_TRANSACTION as any, 84 | {[minerWallet.publicKey]: config.REWARD} 85 | ); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/TransactionMiner.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.TransactionMiner = void 0; 4 | const Transaction_1 = require("./Transaction"); 5 | class TransactionMiner { 6 | constructor(transactionPool, blockchain, wallet, nodes) { 7 | this.transactionPool = transactionPool; 8 | this.blockchain = blockchain; 9 | this.wallet = wallet; 10 | this.nodes = nodes; 11 | } 12 | mineTransaction() { 13 | return new Promise((res) => { 14 | const transactions = [Transaction_1.Transaction.reward(this.wallet), ...Object.values(this.transactionPool.transactionMap)]; 15 | this.blockchain.addBlock({ transaction: transactions }); 16 | this.nodes.broadcast("chain", this.blockchain.chain); 17 | this.transactionPool.clear(); 18 | res(); 19 | }); 20 | } 21 | } 22 | exports.TransactionMiner = TransactionMiner; 23 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/TransactionMiner.ts: -------------------------------------------------------------------------------- 1 | import { _Nodes } from "../../interfaces/Network/_Nodes"; 2 | import { _Block } from "../../interfaces/Blockchain/_Block"; 3 | import { _Wallet } from "../../interfaces/Blockchain/_Wallet"; 4 | import { _Blockchain } from "../../interfaces/Blockchain/_Blockchain"; 5 | import { Transaction } from "./Transaction"; 6 | import { _TransactionPool } from "../../interfaces/Blockchain/_TransactionPool"; 7 | import { _Transaction } from "../../interfaces/Blockchain/_Transaction"; 8 | import { _TransactionMiner } from "../../interfaces/Blockchain/_TransactionMiner"; 9 | export class TransactionMiner implements _TransactionMiner{ 10 | constructor(private transactionPool : _TransactionPool, private blockchain : _Blockchain, private wallet : _Wallet, private nodes : _Nodes ){ 11 | } 12 | mineTransaction() : Promise { 13 | return new Promise((res)=>{ 14 | const transactions =[Transaction.reward(this.wallet),...Object.values(this.transactionPool.transactionMap)]; 15 | this.blockchain.addBlock({transaction : transactions as any}); 16 | this.nodes.broadcast("chain",this.blockchain.chain); 17 | this.transactionPool.clear(); 18 | res() 19 | }) 20 | } 21 | } -------------------------------------------------------------------------------- /Src/classes/Blockchain/TransactionPool.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.TransactionPool = void 0; 4 | class TransactionPool { 5 | constructor() { 6 | this.transactionMap = {}; 7 | } 8 | add(transaction) { 9 | this.transactionMap[transaction.id] = transaction; 10 | } 11 | isHave(wallet) { 12 | let val = Object.values(this.transactionMap); 13 | return val.find(x => { 14 | return x.inputMap.address === wallet.publicKey; 15 | }); 16 | } 17 | clear() { 18 | this.transactionMap = {}; 19 | } 20 | clearBlockchainTransactions(chain) { 21 | for (let i = 1; i < chain.length; i++) { 22 | const block = chain[i]; 23 | for (let j = 1; j < block.data.transaction.length; j++) { 24 | const tx = block.data.transaction[j]; 25 | delete this.transactionMap[tx.id]; 26 | } 27 | } 28 | } 29 | } 30 | exports.TransactionPool = TransactionPool; 31 | ; 32 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/TransactionPool.ts: -------------------------------------------------------------------------------- 1 | import { _Transaction } from "../../interfaces/Blockchain/_Transaction"; 2 | import { _TransactionPool } from "../../interfaces/Blockchain/_TransactionPool"; 3 | import { _Wallet } from "../../interfaces/Blockchain/_Wallet"; 4 | import { _Errors } from "../../types/errors_interface"; 5 | import { Transaction } from "./Transaction"; 6 | import {_Block} from "../../interfaces/Blockchain/_Block"; 7 | export class TransactionPool implements _TransactionPool { 8 | transactionMap : any = {}; 9 | constructor(){ 10 | } 11 | add(transaction : _Transaction) : void | _Errors { 12 | this.transactionMap[transaction.id] = transaction; 13 | } 14 | isHave(wallet : _Wallet) : _Transaction | undefined { 15 | let val = Object.values(this.transactionMap) as Array<_Transaction> 16 | return val.find(x=>{ 17 | return x.inputMap.address === wallet.publicKey 18 | }); 19 | } 20 | clear(){ 21 | this.transactionMap = {} 22 | } 23 | clearBlockchainTransactions(chain : Array<_Block>) : void { 24 | for(let i = 1 ; i < chain.length ; i++){ 25 | const block = chain[i]; 26 | for(let j = 1 ; j < block.data.transaction!.length ; j++){ 27 | const tx = block.data.transaction![j]; 28 | delete this.transactionMap[tx.id]; 29 | } 30 | } 31 | } 32 | }; -------------------------------------------------------------------------------- /Src/classes/Blockchain/Wallet.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.Wallet = void 0; 4 | const sign_1 = require("../../Addon/sign"); 5 | const config_1 = require("../../../config"); 6 | const hash_creator_1 = require("../../Addon/hash-creator"); 7 | const Transaction_1 = require("./Transaction"); 8 | class Wallet { 9 | constructor() { 10 | this.balance = config_1.config.DEFUALT_BALANCE; 11 | this.keyPair = sign_1.ec.genKeyPair(); 12 | this.publicKey = this.keyPair.getPublic().encode("hex"); 13 | this.privateKey = Buffer.from(JSON.stringify(this.keyPair.getPrivate()).replace(/\"/g, '')).toString("base64"); 14 | } 15 | // privateKey: string = this.keyPair.getPrivate(); 16 | sign(data) { 17 | return this.keyPair.sign((0, hash_creator_1.hashCreator)(JSON.stringify(data))); 18 | } 19 | createTransaction(recipient, amount, chain) { 20 | this.balance = Wallet.calculateBalance(chain, this.publicKey); 21 | // console.log(amount , this.balance) 22 | if (amount > this.balance) { 23 | return { message: "amount exceeds balance", code: 112 }; 24 | } 25 | return new Transaction_1.Transaction(this, amount, recipient); 26 | } 27 | static calculateBalance(chain, address) { 28 | var _a, _b, _c; 29 | let value = 0; 30 | let hasTransaction = false; 31 | for (let i = (chain === null || chain === void 0 ? void 0 : chain.length) - 1; i > 0; i--) { 32 | for (let transaction of Object.values((_b = (_a = chain[i]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.transaction)) { 33 | if (((_c = transaction === null || transaction === void 0 ? void 0 : transaction.inputMap) === null || _c === void 0 ? void 0 : _c.address) === address) { 34 | hasTransaction = true; 35 | // break; 36 | } 37 | let outputValue; 38 | try { 39 | outputValue = transaction === null || transaction === void 0 ? void 0 : transaction.outputMap[address]; 40 | } 41 | catch (error) { 42 | outputValue = 0; 43 | } 44 | if (outputValue) { 45 | value += outputValue; 46 | } 47 | } 48 | if (hasTransaction) { 49 | break; 50 | } 51 | } 52 | return value; 53 | } 54 | } 55 | exports.Wallet = Wallet; 56 | -------------------------------------------------------------------------------- /Src/classes/Blockchain/Wallet.ts: -------------------------------------------------------------------------------- 1 | import { _Wallet } from "../../interfaces/Blockchain/_Wallet"; 2 | import { ec } from "../../Addon/sign"; 3 | import { config } from "../../../config"; 4 | import { hashCreator } from "../../Addon/hash-creator"; 5 | import { _Errors } from "../../types/errors_interface"; 6 | import { _Transaction } from "../../interfaces/Blockchain/_Transaction"; 7 | import { Transaction } from "./Transaction"; 8 | import { _Block } from "../../interfaces/Blockchain/_Block"; 9 | 10 | export class Wallet implements _Wallet { 11 | balance: number = config.DEFUALT_BALANCE; 12 | keyPair: any = ec.genKeyPair(); 13 | publicKey: string = this.keyPair.getPublic().encode("hex"); 14 | privateKey: string = Buffer.from(JSON.stringify(this.keyPair.getPrivate()).replace(/\"/g,'')).toString("base64"); 15 | // privateKey: string = this.keyPair.getPrivate(); 16 | sign(data: any): string { 17 | return this.keyPair.sign(hashCreator(JSON.stringify(data))); 18 | } 19 | createTransaction( 20 | recipient: string, 21 | amount: number, 22 | chain: Array<_Block> 23 | ): _Errors | _Transaction { 24 | this.balance = Wallet.calculateBalance(chain, this.publicKey)!; 25 | // console.log(amount , this.balance) 26 | if (amount > this.balance) { 27 | return { message: "amount exceeds balance", code: 112 }; 28 | } 29 | return new Transaction(this, amount, recipient); 30 | } 31 | static calculateBalance(chain: Array<_Block>, address: string) { 32 | let value = 0; 33 | let hasTransaction = false; 34 | for (let i = chain?.length - 1; i > 0; i--) { 35 | for (let transaction of Object.values(chain[i]?.data?.transaction!)) { 36 | if(transaction?.inputMap?.address === address){ 37 | hasTransaction = true; 38 | // break; 39 | } 40 | let outputValue; 41 | try { 42 | outputValue = transaction?.outputMap[address]; 43 | } catch (error) { 44 | outputValue = 0; 45 | } 46 | if (outputValue) { 47 | value += outputValue; 48 | } 49 | 50 | } 51 | if (hasTransaction) { 52 | break; 53 | } 54 | } 55 | return value; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Src/classes/Network/Nodes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 3 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 4 | return new (P || (P = Promise))(function (resolve, reject) { 5 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 6 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 7 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 8 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 9 | }); 10 | }; 11 | var __importDefault = (this && this.__importDefault) || function (mod) { 12 | return (mod && mod.__esModule) ? mod : { "default": mod }; 13 | }; 14 | Object.defineProperty(exports, "__esModule", { value: true }); 15 | exports.Nodes = void 0; 16 | const express_1 = __importDefault(require("express")); 17 | const axios_1 = __importDefault(require("axios")); 18 | class Nodes { 19 | constructor(port) { 20 | this.port = port; 21 | this.list = [""]; 22 | this.app = (0, express_1.default)(); 23 | } 24 | start() { 25 | this.app.use(express_1.default.json()); 26 | this.app.listen(this.port /*,"0.0.0.0"*/); 27 | } 28 | broadcast(name, data) { 29 | return __awaiter(this, void 0, void 0, function* () { 30 | return new Promise((res) => __awaiter(this, void 0, void 0, function* () { 31 | for (let i = 0; i < this.list.length; i++) { 32 | try { 33 | yield axios_1.default.post(`http://${this.list[i]}/${name}`, data); 34 | console.log(`success send ${this.list[i]} with ${name} channel`); 35 | } 36 | catch (error) { 37 | console.log(`Error brodcast to ${this.list[i]} with ${name} channel`); 38 | } 39 | } 40 | res; 41 | })); 42 | }); 43 | } 44 | bet(name, callback) { 45 | this.app.use(express_1.default.json()); 46 | this.app.post("/" + name, (req, res) => { 47 | callback(req.body); 48 | res.send("ok"); 49 | }); 50 | } 51 | } 52 | exports.Nodes = Nodes; 53 | -------------------------------------------------------------------------------- /Src/classes/Network/Nodes.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { _Block } from "../../interfaces/Blockchain/_Block"; 3 | import { _Blockchain } from "../../interfaces/Blockchain/_Blockchain"; 4 | import axios from "axios"; 5 | import { _Nodes } from "../../interfaces/Network/_Nodes"; 6 | export class Nodes implements _Nodes { 7 | list: Array = [""]; 8 | private app = express(); 9 | private blockChain: any; 10 | constructor(private port: number) {} 11 | start(): void { 12 | this.app.use(express.json()); 13 | this.app.listen(this.port/*,"0.0.0.0"*/); 14 | } 15 | async broadcast(name: string, data: any): Promise { 16 | return new Promise(async (res) => { 17 | for (let i = 0; i < this.list.length; i++) { 18 | try { 19 | await axios.post(`http://${this.list[i]}/${name}`, data); 20 | console.log(`success send ${this.list[i]} with ${name} channel`); 21 | } catch (error) { 22 | console.log(`Error brodcast to ${this.list[i]} with ${name} channel`); 23 | } 24 | } 25 | res; 26 | }); 27 | } 28 | bet(name: string, callback: Function): void { 29 | this.app.use(express.json()); 30 | this.app.post("/" + name, (req, res) => { 31 | callback(req.body); 32 | res.send("ok"); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Src/classes/Network/Root.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.Root = void 0; 7 | const config_1 = require("../../../config"); 8 | const express_1 = __importDefault(require("express")); 9 | const axios_1 = __importDefault(require("axios")); 10 | const uniqid_1 = __importDefault(require("uniqid")); 11 | class Root { 12 | constructor(port) { 13 | this.port = port; 14 | this.app = (0, express_1.default)(); 15 | this.hash = (0, uniqid_1.default)(); 16 | } 17 | start() { 18 | this.app.use(express_1.default.json()); 19 | this.app.use((req, res, next) => { 20 | console.log("\nip: %s\npath: %s\nmethod: %s\nbody: %s\n", req.ip, req.path, req.method, JSON.parse(Buffer.from(req.body.data, "base64").toString("ascii"))); 21 | req.body.data = JSON.parse(Buffer.from(req.body.data, "base64").toString("ascii")); 22 | next(); 23 | }); 24 | this.app.use((req, res, next) => { 25 | if (req.body.data.hash !== this.hash) { 26 | console.log("403"); 27 | return res.send("403"); 28 | } 29 | next(); 30 | }); 31 | this.app.listen(this.port /*,"0.0.0.0"*/); 32 | } 33 | bet(channel, callback) { 34 | this.app.post("/" + channel, (req, res) => { 35 | callback(req.body.data); 36 | res.send("ok"); 37 | }); 38 | } 39 | send(channel, data) { 40 | try { 41 | data.hash = this.hash; 42 | axios_1.default.post(`http://${config_1.config.ROOT_URL}/${channel}`, data); 43 | } 44 | catch (err) { 45 | console.log(`error send data to root server with ${channel} channel`); 46 | } 47 | } 48 | } 49 | exports.Root = Root; 50 | -------------------------------------------------------------------------------- /Src/classes/Network/Root.ts: -------------------------------------------------------------------------------- 1 | import { _Root } from "../../interfaces/Network/_Root"; 2 | import { _Errors } from "../../types/errors_interface"; 3 | import { config } from "../../../config"; 4 | import express from "express"; 5 | import axios from "axios"; 6 | import { _Block } from "../../interfaces/Blockchain/_Block"; 7 | import uniqid from "uniqid"; 8 | export class Root implements _Root { 9 | readonly app = express(); 10 | private hash = uniqid(); 11 | constructor(private port: number) {} 12 | start(): void { 13 | this.app.use(express.json()); 14 | this.app.use((req, res, next) => { 15 | console.log( 16 | "\nip: %s\npath: %s\nmethod: %s\nbody: %s\n", 17 | req.ip, 18 | req.path, 19 | req.method, 20 | JSON.parse(Buffer.from(req.body.data, "base64").toString("ascii")) 21 | ); 22 | req.body.data = JSON.parse( 23 | Buffer.from(req.body.data, "base64").toString("ascii") 24 | ); 25 | next(); 26 | }); 27 | this.app.use((req, res, next) => { 28 | if (req.body.data.hash !== this.hash) { 29 | console.log("403") 30 | return res.send("403"); 31 | } 32 | next(); 33 | }); 34 | this.app.listen(this.port/*,"0.0.0.0"*/); 35 | } 36 | bet(channel: string, callback: Function): void { 37 | this.app.post("/" + channel, (req, res) => { 38 | callback(req.body.data); 39 | res.send("ok"); 40 | }); 41 | } 42 | send(channel: string, data: any) { 43 | try { 44 | data.hash = this.hash; 45 | axios.post(`http://${config.ROOT_URL}/${channel}`, data); 46 | } catch (err) { 47 | console.log(`error send data to root server with ${channel} channel`); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Block.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Block.ts: -------------------------------------------------------------------------------- 1 | import { _Transaction } from "./_Transaction"; 2 | 3 | export interface _Block { 4 | timestamp: number; 5 | data: {transaction ?: [_Transaction]}; 6 | hash: string; 7 | lastHash: string; 8 | nonce: number; 9 | difficulty: number; 10 | } 11 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Blockchain.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Blockchain.ts: -------------------------------------------------------------------------------- 1 | import { _Block } from "./_Block"; 2 | import { _Errors } from "../../types/errors_interface"; 3 | import { _Transaction } from "./_Transaction"; 4 | export interface _Blockchain { 5 | chain: Array<_Block>; 6 | addBlock : (data: { transaction : [_Transaction] }) => void 7 | replaceChain: (chain : Array<_Block>) => _Errors | boolean 8 | validTransactionData : (chain: Array<_Block>) => boolean | _Errors 9 | } -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Errors.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | exports.__esModule = true; 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Errors.ts: -------------------------------------------------------------------------------- 1 | export interface _Errors { 2 | message: string; 3 | code: number; 4 | } 5 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Transaction.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Transaction.ts: -------------------------------------------------------------------------------- 1 | import { _Errors } from "../../types/errors_interface"; 2 | import { inputMap_type } from "../../types/inputMap_types"; 3 | import { _Wallet } from "./_Wallet"; 4 | 5 | export interface _Transaction { 6 | id: string; 7 | inputMap: inputMap_type; 8 | outputMap: any; 9 | inputMapCreator: (senderWallet: _Wallet, outputMap: {}) => {}; 10 | outputMapCreator: ( 11 | senderWallet: _Wallet, 12 | amount: number, 13 | recipient: string 14 | ) => {}; 15 | update : (recipient: string,amount : number,senderWallet : _Wallet) => void | _Errors ; 16 | } 17 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_TransactionMiner.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_TransactionMiner.ts: -------------------------------------------------------------------------------- 1 | export interface _TransactionMiner{ 2 | mineTransaction() : Promise; 3 | } -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_TransactionPool.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_TransactionPool.ts: -------------------------------------------------------------------------------- 1 | import { _Transaction } from "./_Transaction"; 2 | import {_Wallet} from "./_Wallet"; 3 | import { _Block } from "./_Block"; 4 | export interface _TransactionPool { 5 | transactionMap : any, 6 | add : (transaction : _Transaction) => void ; 7 | isHave : (wallet : _Wallet) => _Transaction | undefined; 8 | clear : () => void; 9 | clearBlockchainTransactions : (chain : Array<_Block>) => void; 10 | } -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Wallet.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Blockchain/_Wallet.ts: -------------------------------------------------------------------------------- 1 | import { _Transaction } from "./_Transaction"; 2 | import { _Errors } from "../../types/errors_interface"; 3 | import { _Block } from "./_Block"; 4 | export interface _Wallet { 5 | balance : number, 6 | keyPair : any, 7 | publicKey : string, 8 | privateKey : string, 9 | sign : (data : any) => string; 10 | createTransaction : ( recipient : string, amount : number, chain : Array<_Block>) => (_Errors | _Transaction) 11 | } -------------------------------------------------------------------------------- /Src/interfaces/Network/_Nodes.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Network/_Nodes.ts: -------------------------------------------------------------------------------- 1 | import { _Block } from "../Blockchain/_Block"; 2 | import { _Blockchain } from "../Blockchain/_Blockchain"; 3 | 4 | export interface _Nodes { 5 | list : Array, 6 | start : () => void, 7 | broadcast : (name : string , data : any) => Promise, 8 | bet : (name : string , callback : Function) => void 9 | } -------------------------------------------------------------------------------- /Src/interfaces/Network/_Root.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/interfaces/Network/_Root.ts: -------------------------------------------------------------------------------- 1 | import { _Errors } from "../../types/errors_interface"; 2 | import { _Block } from "../Blockchain/_Block"; 3 | 4 | export interface _Root { 5 | start(): void; 6 | bet(channel: string, callback: Function): void; 7 | send(channel: string, data: any): void; 8 | } 9 | -------------------------------------------------------------------------------- /Src/types/errors_interface.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/types/errors_interface.ts: -------------------------------------------------------------------------------- 1 | export interface _Errors { 2 | message: string; 3 | code: number; 4 | } 5 | -------------------------------------------------------------------------------- /Src/types/inputMap_types.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /Src/types/inputMap_types.ts: -------------------------------------------------------------------------------- 1 | import { SignatureInput } from "elliptic"; 2 | 3 | export type inputMap_type = { 4 | timestamp: number; 5 | address: string; 6 | amount: number; 7 | signature: SignatureInput; 8 | }; 9 | -------------------------------------------------------------------------------- /code.txt: -------------------------------------------------------------------------------- 1 | - code list 2 | 3 | -- 100-199 - validation 4 | 5 | --- 101 - chain is short 6 | --- 102 - chain is invalid 7 | --- 111 - invalid transaction 8 | --- 112 - amount exceeds balance 9 | --- 120 - chain data is empty 10 | --- 121 - reward transaction is invalid 11 | --- 122 - reward transaction length is invalid 12 | --- 123 - transaction amount is invalid 13 | 14 | -- 200-299 - connection 15 | 16 | --- 200 - success 17 | --- 250 - port is already in use 18 | 19 | -- 500-599 - server 20 | 21 | --- 500 - server error 22 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.config = void 0; 4 | const DEFUALT_DIFFICULTY = 10; 5 | const ADMIN = { 6 | httpIP: `localhost:45451`, 7 | }; 8 | const REWARD_TRANSACTION = { 9 | address: "**DPX Blockchain**", 10 | }; 11 | const REWARD = 10; 12 | exports.config = { 13 | NODE_PORT: 1414, 14 | ADMIN, 15 | MINE_RATE: 1000 * 60 * 10, 16 | ROOT_URL: "127.0.0.1:1000", 17 | GENESIS_DATA: { 18 | hash: "DEFAULT-DPX-GENESIS-HASH", 19 | lastHash: "DEFAULT-DPX-LAST-HASH", 20 | nonce: 0, 21 | difficulty: DEFUALT_DIFFICULTY, 22 | timestamp: 0, 23 | data: {}, 24 | }, 25 | DEFUALT_BALANCE: 0, 26 | REWARD_TRANSACTION, 27 | REWARD, 28 | }; 29 | -------------------------------------------------------------------------------- /config.ts: -------------------------------------------------------------------------------- 1 | const DEFUALT_DIFFICULTY = 10; 2 | import { _Block } from "./Src/interfaces/Blockchain/_Block"; 3 | import { _Transaction } from "./Src/interfaces/Blockchain/_Transaction"; 4 | const ADMIN = { 5 | httpIP: `localhost:45451`, 6 | }; 7 | const REWARD_TRANSACTION = { 8 | address: "**DPX Blockchain**", 9 | }; 10 | const REWARD = 10; 11 | export const config = { 12 | NODE_PORT: 1414, 13 | ADMIN, 14 | MINE_RATE: 1000 * 60 * 10, 15 | ROOT_URL: "127.0.0.1:1000", 16 | GENESIS_DATA: { 17 | hash: "DEFAULT-DPX-GENESIS-HASH", 18 | lastHash: "DEFAULT-DPX-LAST-HASH", 19 | nonce: 0, 20 | difficulty: DEFUALT_DIFFICULTY, 21 | timestamp: 0, 22 | data: {}, 23 | }, 24 | DEFUALT_BALANCE: 0, 25 | REWARD_TRANSACTION, 26 | REWARD, 27 | }; 28 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "developix-blockchain", 3 | "version": "1.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "developix-blockchain", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "ansicolor": "^1.1.100", 13 | "axios": "^0.26.1", 14 | "chalk": "^5.0.1", 15 | "commander": "^9.2.0", 16 | "elliptic": "^6.5.4", 17 | "express": "^4.17.3", 18 | "hex-to-bin": "^1.0.1", 19 | "hex-to-binary": "^1.0.1", 20 | "uniqid": "^5.4.0" 21 | }, 22 | "bin": { 23 | "dpx": "Bin/dpx" 24 | }, 25 | "devDependencies": { 26 | "@types/elliptic": "^6.4.14", 27 | "@types/express": "^4.17.13", 28 | "@types/node": "^17.0.23", 29 | "@types/uniqid": "^5.3.2", 30 | "@types/uuid": "^8.3.4" 31 | } 32 | }, 33 | "node_modules/@types/bn.js": { 34 | "version": "5.1.0", 35 | "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", 36 | "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", 37 | "dev": true, 38 | "dependencies": { 39 | "@types/node": "*" 40 | } 41 | }, 42 | "node_modules/@types/body-parser": { 43 | "version": "1.19.2", 44 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", 45 | "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", 46 | "dev": true, 47 | "dependencies": { 48 | "@types/connect": "*", 49 | "@types/node": "*" 50 | } 51 | }, 52 | "node_modules/@types/connect": { 53 | "version": "3.4.35", 54 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", 55 | "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", 56 | "dev": true, 57 | "dependencies": { 58 | "@types/node": "*" 59 | } 60 | }, 61 | "node_modules/@types/elliptic": { 62 | "version": "6.4.14", 63 | "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.14.tgz", 64 | "integrity": "sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ==", 65 | "dev": true, 66 | "dependencies": { 67 | "@types/bn.js": "*" 68 | } 69 | }, 70 | "node_modules/@types/express": { 71 | "version": "4.17.13", 72 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", 73 | "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", 74 | "dev": true, 75 | "dependencies": { 76 | "@types/body-parser": "*", 77 | "@types/express-serve-static-core": "^4.17.18", 78 | "@types/qs": "*", 79 | "@types/serve-static": "*" 80 | } 81 | }, 82 | "node_modules/@types/express-serve-static-core": { 83 | "version": "4.17.28", 84 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", 85 | "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", 86 | "dev": true, 87 | "dependencies": { 88 | "@types/node": "*", 89 | "@types/qs": "*", 90 | "@types/range-parser": "*" 91 | } 92 | }, 93 | "node_modules/@types/mime": { 94 | "version": "1.3.2", 95 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 96 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 97 | "dev": true 98 | }, 99 | "node_modules/@types/node": { 100 | "version": "17.0.23", 101 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", 102 | "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", 103 | "dev": true 104 | }, 105 | "node_modules/@types/qs": { 106 | "version": "6.9.7", 107 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", 108 | "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", 109 | "dev": true 110 | }, 111 | "node_modules/@types/range-parser": { 112 | "version": "1.2.4", 113 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", 114 | "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", 115 | "dev": true 116 | }, 117 | "node_modules/@types/serve-static": { 118 | "version": "1.13.10", 119 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", 120 | "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", 121 | "dev": true, 122 | "dependencies": { 123 | "@types/mime": "^1", 124 | "@types/node": "*" 125 | } 126 | }, 127 | "node_modules/@types/uniqid": { 128 | "version": "5.3.2", 129 | "resolved": "https://registry.npmjs.org/@types/uniqid/-/uniqid-5.3.2.tgz", 130 | "integrity": "sha512-/NYoaZpWsnAJDsGYeMNDeG3p3fuUb4AiC7MfKxi5VSu18tXd08w6Ch0fKW94T4FeLXXZwZPoFgHA1O0rDYKyMQ==", 131 | "dev": true 132 | }, 133 | "node_modules/@types/uuid": { 134 | "version": "8.3.4", 135 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", 136 | "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", 137 | "dev": true 138 | }, 139 | "node_modules/accepts": { 140 | "version": "1.3.8", 141 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 142 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 143 | "dependencies": { 144 | "mime-types": "~2.1.34", 145 | "negotiator": "0.6.3" 146 | }, 147 | "engines": { 148 | "node": ">= 0.6" 149 | } 150 | }, 151 | "node_modules/ansicolor": { 152 | "version": "1.1.100", 153 | "resolved": "https://registry.npmjs.org/ansicolor/-/ansicolor-1.1.100.tgz", 154 | "integrity": "sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==" 155 | }, 156 | "node_modules/array-flatten": { 157 | "version": "1.1.1", 158 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 159 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 160 | }, 161 | "node_modules/axios": { 162 | "version": "0.26.1", 163 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", 164 | "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", 165 | "dependencies": { 166 | "follow-redirects": "^1.14.8" 167 | } 168 | }, 169 | "node_modules/bn.js": { 170 | "version": "4.12.0", 171 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 172 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" 173 | }, 174 | "node_modules/body-parser": { 175 | "version": "1.19.2", 176 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", 177 | "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", 178 | "dependencies": { 179 | "bytes": "3.1.2", 180 | "content-type": "~1.0.4", 181 | "debug": "2.6.9", 182 | "depd": "~1.1.2", 183 | "http-errors": "1.8.1", 184 | "iconv-lite": "0.4.24", 185 | "on-finished": "~2.3.0", 186 | "qs": "6.9.7", 187 | "raw-body": "2.4.3", 188 | "type-is": "~1.6.18" 189 | }, 190 | "engines": { 191 | "node": ">= 0.8" 192 | } 193 | }, 194 | "node_modules/brorand": { 195 | "version": "1.1.0", 196 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 197 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 198 | }, 199 | "node_modules/bytes": { 200 | "version": "3.1.2", 201 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 202 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 203 | "engines": { 204 | "node": ">= 0.8" 205 | } 206 | }, 207 | "node_modules/chalk": { 208 | "version": "5.0.1", 209 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", 210 | "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", 211 | "engines": { 212 | "node": "^12.17.0 || ^14.13 || >=16.0.0" 213 | }, 214 | "funding": { 215 | "url": "https://github.com/chalk/chalk?sponsor=1" 216 | } 217 | }, 218 | "node_modules/commander": { 219 | "version": "9.2.0", 220 | "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", 221 | "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==", 222 | "engines": { 223 | "node": "^12.20.0 || >=14" 224 | } 225 | }, 226 | "node_modules/content-disposition": { 227 | "version": "0.5.4", 228 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 229 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 230 | "dependencies": { 231 | "safe-buffer": "5.2.1" 232 | }, 233 | "engines": { 234 | "node": ">= 0.6" 235 | } 236 | }, 237 | "node_modules/content-type": { 238 | "version": "1.0.4", 239 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 240 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 241 | "engines": { 242 | "node": ">= 0.6" 243 | } 244 | }, 245 | "node_modules/cookie": { 246 | "version": "0.4.2", 247 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", 248 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", 249 | "engines": { 250 | "node": ">= 0.6" 251 | } 252 | }, 253 | "node_modules/cookie-signature": { 254 | "version": "1.0.6", 255 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 256 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 257 | }, 258 | "node_modules/debug": { 259 | "version": "2.6.9", 260 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 261 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 262 | "dependencies": { 263 | "ms": "2.0.0" 264 | } 265 | }, 266 | "node_modules/depd": { 267 | "version": "1.1.2", 268 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 269 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 270 | "engines": { 271 | "node": ">= 0.6" 272 | } 273 | }, 274 | "node_modules/destroy": { 275 | "version": "1.0.4", 276 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 277 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 278 | }, 279 | "node_modules/ee-first": { 280 | "version": "1.1.1", 281 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 282 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 283 | }, 284 | "node_modules/elliptic": { 285 | "version": "6.5.4", 286 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", 287 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", 288 | "dependencies": { 289 | "bn.js": "^4.11.9", 290 | "brorand": "^1.1.0", 291 | "hash.js": "^1.0.0", 292 | "hmac-drbg": "^1.0.1", 293 | "inherits": "^2.0.4", 294 | "minimalistic-assert": "^1.0.1", 295 | "minimalistic-crypto-utils": "^1.0.1" 296 | } 297 | }, 298 | "node_modules/encodeurl": { 299 | "version": "1.0.2", 300 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 301 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 302 | "engines": { 303 | "node": ">= 0.8" 304 | } 305 | }, 306 | "node_modules/escape-html": { 307 | "version": "1.0.3", 308 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 309 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 310 | }, 311 | "node_modules/etag": { 312 | "version": "1.8.1", 313 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 314 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 315 | "engines": { 316 | "node": ">= 0.6" 317 | } 318 | }, 319 | "node_modules/express": { 320 | "version": "4.17.3", 321 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", 322 | "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", 323 | "dependencies": { 324 | "accepts": "~1.3.8", 325 | "array-flatten": "1.1.1", 326 | "body-parser": "1.19.2", 327 | "content-disposition": "0.5.4", 328 | "content-type": "~1.0.4", 329 | "cookie": "0.4.2", 330 | "cookie-signature": "1.0.6", 331 | "debug": "2.6.9", 332 | "depd": "~1.1.2", 333 | "encodeurl": "~1.0.2", 334 | "escape-html": "~1.0.3", 335 | "etag": "~1.8.1", 336 | "finalhandler": "~1.1.2", 337 | "fresh": "0.5.2", 338 | "merge-descriptors": "1.0.1", 339 | "methods": "~1.1.2", 340 | "on-finished": "~2.3.0", 341 | "parseurl": "~1.3.3", 342 | "path-to-regexp": "0.1.7", 343 | "proxy-addr": "~2.0.7", 344 | "qs": "6.9.7", 345 | "range-parser": "~1.2.1", 346 | "safe-buffer": "5.2.1", 347 | "send": "0.17.2", 348 | "serve-static": "1.14.2", 349 | "setprototypeof": "1.2.0", 350 | "statuses": "~1.5.0", 351 | "type-is": "~1.6.18", 352 | "utils-merge": "1.0.1", 353 | "vary": "~1.1.2" 354 | }, 355 | "engines": { 356 | "node": ">= 0.10.0" 357 | } 358 | }, 359 | "node_modules/finalhandler": { 360 | "version": "1.1.2", 361 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 362 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 363 | "dependencies": { 364 | "debug": "2.6.9", 365 | "encodeurl": "~1.0.2", 366 | "escape-html": "~1.0.3", 367 | "on-finished": "~2.3.0", 368 | "parseurl": "~1.3.3", 369 | "statuses": "~1.5.0", 370 | "unpipe": "~1.0.0" 371 | }, 372 | "engines": { 373 | "node": ">= 0.8" 374 | } 375 | }, 376 | "node_modules/follow-redirects": { 377 | "version": "1.14.9", 378 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", 379 | "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", 380 | "funding": [ 381 | { 382 | "type": "individual", 383 | "url": "https://github.com/sponsors/RubenVerborgh" 384 | } 385 | ], 386 | "engines": { 387 | "node": ">=4.0" 388 | }, 389 | "peerDependenciesMeta": { 390 | "debug": { 391 | "optional": true 392 | } 393 | } 394 | }, 395 | "node_modules/forwarded": { 396 | "version": "0.2.0", 397 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 398 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 399 | "engines": { 400 | "node": ">= 0.6" 401 | } 402 | }, 403 | "node_modules/fresh": { 404 | "version": "0.5.2", 405 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 406 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 407 | "engines": { 408 | "node": ">= 0.6" 409 | } 410 | }, 411 | "node_modules/hash.js": { 412 | "version": "1.1.7", 413 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 414 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 415 | "dependencies": { 416 | "inherits": "^2.0.3", 417 | "minimalistic-assert": "^1.0.1" 418 | } 419 | }, 420 | "node_modules/hex-to-bin": { 421 | "version": "1.0.1", 422 | "resolved": "https://registry.npmjs.org/hex-to-bin/-/hex-to-bin-1.0.1.tgz", 423 | "integrity": "sha512-qKdiDve+8NxdC3w/bINXfKMiv2oPK0T7RHowDEwrzEbdebKjEZqiMz1aMMXbuULjq6Qo9Yg8jLVnlpYRUKMFPQ==" 424 | }, 425 | "node_modules/hex-to-binary": { 426 | "version": "1.0.1", 427 | "resolved": "https://registry.npmjs.org/hex-to-binary/-/hex-to-binary-1.0.1.tgz", 428 | "integrity": "sha1-YcevAW/CK86pcE2fLpo46MfbuFQ=" 429 | }, 430 | "node_modules/hmac-drbg": { 431 | "version": "1.0.1", 432 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 433 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 434 | "dependencies": { 435 | "hash.js": "^1.0.3", 436 | "minimalistic-assert": "^1.0.0", 437 | "minimalistic-crypto-utils": "^1.0.1" 438 | } 439 | }, 440 | "node_modules/http-errors": { 441 | "version": "1.8.1", 442 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 443 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 444 | "dependencies": { 445 | "depd": "~1.1.2", 446 | "inherits": "2.0.4", 447 | "setprototypeof": "1.2.0", 448 | "statuses": ">= 1.5.0 < 2", 449 | "toidentifier": "1.0.1" 450 | }, 451 | "engines": { 452 | "node": ">= 0.6" 453 | } 454 | }, 455 | "node_modules/iconv-lite": { 456 | "version": "0.4.24", 457 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 458 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 459 | "dependencies": { 460 | "safer-buffer": ">= 2.1.2 < 3" 461 | }, 462 | "engines": { 463 | "node": ">=0.10.0" 464 | } 465 | }, 466 | "node_modules/inherits": { 467 | "version": "2.0.4", 468 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 469 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 470 | }, 471 | "node_modules/ipaddr.js": { 472 | "version": "1.9.1", 473 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 474 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 475 | "engines": { 476 | "node": ">= 0.10" 477 | } 478 | }, 479 | "node_modules/media-typer": { 480 | "version": "0.3.0", 481 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 482 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 483 | "engines": { 484 | "node": ">= 0.6" 485 | } 486 | }, 487 | "node_modules/merge-descriptors": { 488 | "version": "1.0.1", 489 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 490 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 491 | }, 492 | "node_modules/methods": { 493 | "version": "1.1.2", 494 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 495 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 496 | "engines": { 497 | "node": ">= 0.6" 498 | } 499 | }, 500 | "node_modules/mime": { 501 | "version": "1.6.0", 502 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 503 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 504 | "bin": { 505 | "mime": "cli.js" 506 | }, 507 | "engines": { 508 | "node": ">=4" 509 | } 510 | }, 511 | "node_modules/mime-db": { 512 | "version": "1.52.0", 513 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 514 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 515 | "engines": { 516 | "node": ">= 0.6" 517 | } 518 | }, 519 | "node_modules/mime-types": { 520 | "version": "2.1.35", 521 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 522 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 523 | "dependencies": { 524 | "mime-db": "1.52.0" 525 | }, 526 | "engines": { 527 | "node": ">= 0.6" 528 | } 529 | }, 530 | "node_modules/minimalistic-assert": { 531 | "version": "1.0.1", 532 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 533 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 534 | }, 535 | "node_modules/minimalistic-crypto-utils": { 536 | "version": "1.0.1", 537 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 538 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 539 | }, 540 | "node_modules/ms": { 541 | "version": "2.0.0", 542 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 543 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 544 | }, 545 | "node_modules/negotiator": { 546 | "version": "0.6.3", 547 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 548 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 549 | "engines": { 550 | "node": ">= 0.6" 551 | } 552 | }, 553 | "node_modules/on-finished": { 554 | "version": "2.3.0", 555 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 556 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 557 | "dependencies": { 558 | "ee-first": "1.1.1" 559 | }, 560 | "engines": { 561 | "node": ">= 0.8" 562 | } 563 | }, 564 | "node_modules/parseurl": { 565 | "version": "1.3.3", 566 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 567 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 568 | "engines": { 569 | "node": ">= 0.8" 570 | } 571 | }, 572 | "node_modules/path-to-regexp": { 573 | "version": "0.1.7", 574 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 575 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 576 | }, 577 | "node_modules/proxy-addr": { 578 | "version": "2.0.7", 579 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 580 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 581 | "dependencies": { 582 | "forwarded": "0.2.0", 583 | "ipaddr.js": "1.9.1" 584 | }, 585 | "engines": { 586 | "node": ">= 0.10" 587 | } 588 | }, 589 | "node_modules/qs": { 590 | "version": "6.9.7", 591 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", 592 | "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", 593 | "engines": { 594 | "node": ">=0.6" 595 | }, 596 | "funding": { 597 | "url": "https://github.com/sponsors/ljharb" 598 | } 599 | }, 600 | "node_modules/range-parser": { 601 | "version": "1.2.1", 602 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 603 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 604 | "engines": { 605 | "node": ">= 0.6" 606 | } 607 | }, 608 | "node_modules/raw-body": { 609 | "version": "2.4.3", 610 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", 611 | "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", 612 | "dependencies": { 613 | "bytes": "3.1.2", 614 | "http-errors": "1.8.1", 615 | "iconv-lite": "0.4.24", 616 | "unpipe": "1.0.0" 617 | }, 618 | "engines": { 619 | "node": ">= 0.8" 620 | } 621 | }, 622 | "node_modules/safe-buffer": { 623 | "version": "5.2.1", 624 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 625 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 626 | "funding": [ 627 | { 628 | "type": "github", 629 | "url": "https://github.com/sponsors/feross" 630 | }, 631 | { 632 | "type": "patreon", 633 | "url": "https://www.patreon.com/feross" 634 | }, 635 | { 636 | "type": "consulting", 637 | "url": "https://feross.org/support" 638 | } 639 | ] 640 | }, 641 | "node_modules/safer-buffer": { 642 | "version": "2.1.2", 643 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 644 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 645 | }, 646 | "node_modules/send": { 647 | "version": "0.17.2", 648 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", 649 | "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", 650 | "dependencies": { 651 | "debug": "2.6.9", 652 | "depd": "~1.1.2", 653 | "destroy": "~1.0.4", 654 | "encodeurl": "~1.0.2", 655 | "escape-html": "~1.0.3", 656 | "etag": "~1.8.1", 657 | "fresh": "0.5.2", 658 | "http-errors": "1.8.1", 659 | "mime": "1.6.0", 660 | "ms": "2.1.3", 661 | "on-finished": "~2.3.0", 662 | "range-parser": "~1.2.1", 663 | "statuses": "~1.5.0" 664 | }, 665 | "engines": { 666 | "node": ">= 0.8.0" 667 | } 668 | }, 669 | "node_modules/send/node_modules/ms": { 670 | "version": "2.1.3", 671 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 672 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 673 | }, 674 | "node_modules/serve-static": { 675 | "version": "1.14.2", 676 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", 677 | "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", 678 | "dependencies": { 679 | "encodeurl": "~1.0.2", 680 | "escape-html": "~1.0.3", 681 | "parseurl": "~1.3.3", 682 | "send": "0.17.2" 683 | }, 684 | "engines": { 685 | "node": ">= 0.8.0" 686 | } 687 | }, 688 | "node_modules/setprototypeof": { 689 | "version": "1.2.0", 690 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 691 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 692 | }, 693 | "node_modules/statuses": { 694 | "version": "1.5.0", 695 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 696 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 697 | "engines": { 698 | "node": ">= 0.6" 699 | } 700 | }, 701 | "node_modules/toidentifier": { 702 | "version": "1.0.1", 703 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 704 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 705 | "engines": { 706 | "node": ">=0.6" 707 | } 708 | }, 709 | "node_modules/type-is": { 710 | "version": "1.6.18", 711 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 712 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 713 | "dependencies": { 714 | "media-typer": "0.3.0", 715 | "mime-types": "~2.1.24" 716 | }, 717 | "engines": { 718 | "node": ">= 0.6" 719 | } 720 | }, 721 | "node_modules/uniqid": { 722 | "version": "5.4.0", 723 | "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-5.4.0.tgz", 724 | "integrity": "sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A==" 725 | }, 726 | "node_modules/unpipe": { 727 | "version": "1.0.0", 728 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 729 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 730 | "engines": { 731 | "node": ">= 0.8" 732 | } 733 | }, 734 | "node_modules/utils-merge": { 735 | "version": "1.0.1", 736 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 737 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 738 | "engines": { 739 | "node": ">= 0.4.0" 740 | } 741 | }, 742 | "node_modules/vary": { 743 | "version": "1.1.2", 744 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 745 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 746 | "engines": { 747 | "node": ">= 0.8" 748 | } 749 | } 750 | }, 751 | "dependencies": { 752 | "@types/bn.js": { 753 | "version": "5.1.0", 754 | "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", 755 | "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", 756 | "dev": true, 757 | "requires": { 758 | "@types/node": "*" 759 | } 760 | }, 761 | "@types/body-parser": { 762 | "version": "1.19.2", 763 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", 764 | "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", 765 | "dev": true, 766 | "requires": { 767 | "@types/connect": "*", 768 | "@types/node": "*" 769 | } 770 | }, 771 | "@types/connect": { 772 | "version": "3.4.35", 773 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", 774 | "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", 775 | "dev": true, 776 | "requires": { 777 | "@types/node": "*" 778 | } 779 | }, 780 | "@types/elliptic": { 781 | "version": "6.4.14", 782 | "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.14.tgz", 783 | "integrity": "sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ==", 784 | "dev": true, 785 | "requires": { 786 | "@types/bn.js": "*" 787 | } 788 | }, 789 | "@types/express": { 790 | "version": "4.17.13", 791 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", 792 | "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", 793 | "dev": true, 794 | "requires": { 795 | "@types/body-parser": "*", 796 | "@types/express-serve-static-core": "^4.17.18", 797 | "@types/qs": "*", 798 | "@types/serve-static": "*" 799 | } 800 | }, 801 | "@types/express-serve-static-core": { 802 | "version": "4.17.28", 803 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", 804 | "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", 805 | "dev": true, 806 | "requires": { 807 | "@types/node": "*", 808 | "@types/qs": "*", 809 | "@types/range-parser": "*" 810 | } 811 | }, 812 | "@types/mime": { 813 | "version": "1.3.2", 814 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 815 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 816 | "dev": true 817 | }, 818 | "@types/node": { 819 | "version": "17.0.23", 820 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", 821 | "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", 822 | "dev": true 823 | }, 824 | "@types/qs": { 825 | "version": "6.9.7", 826 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", 827 | "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", 828 | "dev": true 829 | }, 830 | "@types/range-parser": { 831 | "version": "1.2.4", 832 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", 833 | "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", 834 | "dev": true 835 | }, 836 | "@types/serve-static": { 837 | "version": "1.13.10", 838 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", 839 | "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", 840 | "dev": true, 841 | "requires": { 842 | "@types/mime": "^1", 843 | "@types/node": "*" 844 | } 845 | }, 846 | "@types/uniqid": { 847 | "version": "5.3.2", 848 | "resolved": "https://registry.npmjs.org/@types/uniqid/-/uniqid-5.3.2.tgz", 849 | "integrity": "sha512-/NYoaZpWsnAJDsGYeMNDeG3p3fuUb4AiC7MfKxi5VSu18tXd08w6Ch0fKW94T4FeLXXZwZPoFgHA1O0rDYKyMQ==", 850 | "dev": true 851 | }, 852 | "@types/uuid": { 853 | "version": "8.3.4", 854 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", 855 | "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==", 856 | "dev": true 857 | }, 858 | "accepts": { 859 | "version": "1.3.8", 860 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 861 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 862 | "requires": { 863 | "mime-types": "~2.1.34", 864 | "negotiator": "0.6.3" 865 | } 866 | }, 867 | "ansicolor": { 868 | "version": "1.1.100", 869 | "resolved": "https://registry.npmjs.org/ansicolor/-/ansicolor-1.1.100.tgz", 870 | "integrity": "sha512-Jl0pxRfa9WaQVUX57AB8/V2my6FJxrOR1Pp2qqFbig20QB4HzUoQ48THTKAgHlUCJeQm/s2WoOPcoIDhyCL/kw==" 871 | }, 872 | "array-flatten": { 873 | "version": "1.1.1", 874 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 875 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 876 | }, 877 | "axios": { 878 | "version": "0.26.1", 879 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", 880 | "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", 881 | "requires": { 882 | "follow-redirects": "^1.14.8" 883 | } 884 | }, 885 | "bn.js": { 886 | "version": "4.12.0", 887 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", 888 | "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" 889 | }, 890 | "body-parser": { 891 | "version": "1.19.2", 892 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", 893 | "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", 894 | "requires": { 895 | "bytes": "3.1.2", 896 | "content-type": "~1.0.4", 897 | "debug": "2.6.9", 898 | "depd": "~1.1.2", 899 | "http-errors": "1.8.1", 900 | "iconv-lite": "0.4.24", 901 | "on-finished": "~2.3.0", 902 | "qs": "6.9.7", 903 | "raw-body": "2.4.3", 904 | "type-is": "~1.6.18" 905 | } 906 | }, 907 | "brorand": { 908 | "version": "1.1.0", 909 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 910 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 911 | }, 912 | "bytes": { 913 | "version": "3.1.2", 914 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 915 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 916 | }, 917 | "chalk": { 918 | "version": "5.0.1", 919 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", 920 | "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==" 921 | }, 922 | "commander": { 923 | "version": "9.2.0", 924 | "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", 925 | "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==" 926 | }, 927 | "content-disposition": { 928 | "version": "0.5.4", 929 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 930 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 931 | "requires": { 932 | "safe-buffer": "5.2.1" 933 | } 934 | }, 935 | "content-type": { 936 | "version": "1.0.4", 937 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 938 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 939 | }, 940 | "cookie": { 941 | "version": "0.4.2", 942 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", 943 | "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" 944 | }, 945 | "cookie-signature": { 946 | "version": "1.0.6", 947 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 948 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 949 | }, 950 | "debug": { 951 | "version": "2.6.9", 952 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 953 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 954 | "requires": { 955 | "ms": "2.0.0" 956 | } 957 | }, 958 | "depd": { 959 | "version": "1.1.2", 960 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 961 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 962 | }, 963 | "destroy": { 964 | "version": "1.0.4", 965 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 966 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 967 | }, 968 | "ee-first": { 969 | "version": "1.1.1", 970 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 971 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 972 | }, 973 | "elliptic": { 974 | "version": "6.5.4", 975 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", 976 | "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", 977 | "requires": { 978 | "bn.js": "^4.11.9", 979 | "brorand": "^1.1.0", 980 | "hash.js": "^1.0.0", 981 | "hmac-drbg": "^1.0.1", 982 | "inherits": "^2.0.4", 983 | "minimalistic-assert": "^1.0.1", 984 | "minimalistic-crypto-utils": "^1.0.1" 985 | } 986 | }, 987 | "encodeurl": { 988 | "version": "1.0.2", 989 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 990 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 991 | }, 992 | "escape-html": { 993 | "version": "1.0.3", 994 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 995 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 996 | }, 997 | "etag": { 998 | "version": "1.8.1", 999 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 1000 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 1001 | }, 1002 | "express": { 1003 | "version": "4.17.3", 1004 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", 1005 | "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", 1006 | "requires": { 1007 | "accepts": "~1.3.8", 1008 | "array-flatten": "1.1.1", 1009 | "body-parser": "1.19.2", 1010 | "content-disposition": "0.5.4", 1011 | "content-type": "~1.0.4", 1012 | "cookie": "0.4.2", 1013 | "cookie-signature": "1.0.6", 1014 | "debug": "2.6.9", 1015 | "depd": "~1.1.2", 1016 | "encodeurl": "~1.0.2", 1017 | "escape-html": "~1.0.3", 1018 | "etag": "~1.8.1", 1019 | "finalhandler": "~1.1.2", 1020 | "fresh": "0.5.2", 1021 | "merge-descriptors": "1.0.1", 1022 | "methods": "~1.1.2", 1023 | "on-finished": "~2.3.0", 1024 | "parseurl": "~1.3.3", 1025 | "path-to-regexp": "0.1.7", 1026 | "proxy-addr": "~2.0.7", 1027 | "qs": "6.9.7", 1028 | "range-parser": "~1.2.1", 1029 | "safe-buffer": "5.2.1", 1030 | "send": "0.17.2", 1031 | "serve-static": "1.14.2", 1032 | "setprototypeof": "1.2.0", 1033 | "statuses": "~1.5.0", 1034 | "type-is": "~1.6.18", 1035 | "utils-merge": "1.0.1", 1036 | "vary": "~1.1.2" 1037 | } 1038 | }, 1039 | "finalhandler": { 1040 | "version": "1.1.2", 1041 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 1042 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 1043 | "requires": { 1044 | "debug": "2.6.9", 1045 | "encodeurl": "~1.0.2", 1046 | "escape-html": "~1.0.3", 1047 | "on-finished": "~2.3.0", 1048 | "parseurl": "~1.3.3", 1049 | "statuses": "~1.5.0", 1050 | "unpipe": "~1.0.0" 1051 | } 1052 | }, 1053 | "follow-redirects": { 1054 | "version": "1.14.9", 1055 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", 1056 | "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" 1057 | }, 1058 | "forwarded": { 1059 | "version": "0.2.0", 1060 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1061 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 1062 | }, 1063 | "fresh": { 1064 | "version": "0.5.2", 1065 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1066 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1067 | }, 1068 | "hash.js": { 1069 | "version": "1.1.7", 1070 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 1071 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 1072 | "requires": { 1073 | "inherits": "^2.0.3", 1074 | "minimalistic-assert": "^1.0.1" 1075 | } 1076 | }, 1077 | "hex-to-bin": { 1078 | "version": "1.0.1", 1079 | "resolved": "https://registry.npmjs.org/hex-to-bin/-/hex-to-bin-1.0.1.tgz", 1080 | "integrity": "sha512-qKdiDve+8NxdC3w/bINXfKMiv2oPK0T7RHowDEwrzEbdebKjEZqiMz1aMMXbuULjq6Qo9Yg8jLVnlpYRUKMFPQ==" 1081 | }, 1082 | "hex-to-binary": { 1083 | "version": "1.0.1", 1084 | "resolved": "https://registry.npmjs.org/hex-to-binary/-/hex-to-binary-1.0.1.tgz", 1085 | "integrity": "sha1-YcevAW/CK86pcE2fLpo46MfbuFQ=" 1086 | }, 1087 | "hmac-drbg": { 1088 | "version": "1.0.1", 1089 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 1090 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 1091 | "requires": { 1092 | "hash.js": "^1.0.3", 1093 | "minimalistic-assert": "^1.0.0", 1094 | "minimalistic-crypto-utils": "^1.0.1" 1095 | } 1096 | }, 1097 | "http-errors": { 1098 | "version": "1.8.1", 1099 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", 1100 | "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", 1101 | "requires": { 1102 | "depd": "~1.1.2", 1103 | "inherits": "2.0.4", 1104 | "setprototypeof": "1.2.0", 1105 | "statuses": ">= 1.5.0 < 2", 1106 | "toidentifier": "1.0.1" 1107 | } 1108 | }, 1109 | "iconv-lite": { 1110 | "version": "0.4.24", 1111 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1112 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1113 | "requires": { 1114 | "safer-buffer": ">= 2.1.2 < 3" 1115 | } 1116 | }, 1117 | "inherits": { 1118 | "version": "2.0.4", 1119 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1120 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1121 | }, 1122 | "ipaddr.js": { 1123 | "version": "1.9.1", 1124 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1125 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 1126 | }, 1127 | "media-typer": { 1128 | "version": "0.3.0", 1129 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1130 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1131 | }, 1132 | "merge-descriptors": { 1133 | "version": "1.0.1", 1134 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1135 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1136 | }, 1137 | "methods": { 1138 | "version": "1.1.2", 1139 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1140 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1141 | }, 1142 | "mime": { 1143 | "version": "1.6.0", 1144 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1145 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 1146 | }, 1147 | "mime-db": { 1148 | "version": "1.52.0", 1149 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1150 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 1151 | }, 1152 | "mime-types": { 1153 | "version": "2.1.35", 1154 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1155 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1156 | "requires": { 1157 | "mime-db": "1.52.0" 1158 | } 1159 | }, 1160 | "minimalistic-assert": { 1161 | "version": "1.0.1", 1162 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 1163 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 1164 | }, 1165 | "minimalistic-crypto-utils": { 1166 | "version": "1.0.1", 1167 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 1168 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 1169 | }, 1170 | "ms": { 1171 | "version": "2.0.0", 1172 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1173 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1174 | }, 1175 | "negotiator": { 1176 | "version": "0.6.3", 1177 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1178 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 1179 | }, 1180 | "on-finished": { 1181 | "version": "2.3.0", 1182 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1183 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1184 | "requires": { 1185 | "ee-first": "1.1.1" 1186 | } 1187 | }, 1188 | "parseurl": { 1189 | "version": "1.3.3", 1190 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1191 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1192 | }, 1193 | "path-to-regexp": { 1194 | "version": "0.1.7", 1195 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1196 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1197 | }, 1198 | "proxy-addr": { 1199 | "version": "2.0.7", 1200 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1201 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1202 | "requires": { 1203 | "forwarded": "0.2.0", 1204 | "ipaddr.js": "1.9.1" 1205 | } 1206 | }, 1207 | "qs": { 1208 | "version": "6.9.7", 1209 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", 1210 | "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" 1211 | }, 1212 | "range-parser": { 1213 | "version": "1.2.1", 1214 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1215 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1216 | }, 1217 | "raw-body": { 1218 | "version": "2.4.3", 1219 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", 1220 | "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", 1221 | "requires": { 1222 | "bytes": "3.1.2", 1223 | "http-errors": "1.8.1", 1224 | "iconv-lite": "0.4.24", 1225 | "unpipe": "1.0.0" 1226 | } 1227 | }, 1228 | "safe-buffer": { 1229 | "version": "5.2.1", 1230 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1231 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 1232 | }, 1233 | "safer-buffer": { 1234 | "version": "2.1.2", 1235 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1236 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1237 | }, 1238 | "send": { 1239 | "version": "0.17.2", 1240 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", 1241 | "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", 1242 | "requires": { 1243 | "debug": "2.6.9", 1244 | "depd": "~1.1.2", 1245 | "destroy": "~1.0.4", 1246 | "encodeurl": "~1.0.2", 1247 | "escape-html": "~1.0.3", 1248 | "etag": "~1.8.1", 1249 | "fresh": "0.5.2", 1250 | "http-errors": "1.8.1", 1251 | "mime": "1.6.0", 1252 | "ms": "2.1.3", 1253 | "on-finished": "~2.3.0", 1254 | "range-parser": "~1.2.1", 1255 | "statuses": "~1.5.0" 1256 | }, 1257 | "dependencies": { 1258 | "ms": { 1259 | "version": "2.1.3", 1260 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1261 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1262 | } 1263 | } 1264 | }, 1265 | "serve-static": { 1266 | "version": "1.14.2", 1267 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", 1268 | "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", 1269 | "requires": { 1270 | "encodeurl": "~1.0.2", 1271 | "escape-html": "~1.0.3", 1272 | "parseurl": "~1.3.3", 1273 | "send": "0.17.2" 1274 | } 1275 | }, 1276 | "setprototypeof": { 1277 | "version": "1.2.0", 1278 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1279 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1280 | }, 1281 | "statuses": { 1282 | "version": "1.5.0", 1283 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1284 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1285 | }, 1286 | "toidentifier": { 1287 | "version": "1.0.1", 1288 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1289 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1290 | }, 1291 | "type-is": { 1292 | "version": "1.6.18", 1293 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1294 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1295 | "requires": { 1296 | "media-typer": "0.3.0", 1297 | "mime-types": "~2.1.24" 1298 | } 1299 | }, 1300 | "uniqid": { 1301 | "version": "5.4.0", 1302 | "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-5.4.0.tgz", 1303 | "integrity": "sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A==" 1304 | }, 1305 | "unpipe": { 1306 | "version": "1.0.0", 1307 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1308 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1309 | }, 1310 | "utils-merge": { 1311 | "version": "1.0.1", 1312 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1313 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1314 | }, 1315 | "vary": { 1316 | "version": "1.1.2", 1317 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1318 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1319 | } 1320 | } 1321 | } 1322 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "ansicolor": "^1.1.100", 4 | "axios": "^0.26.1", 5 | "chalk": "^5.0.1", 6 | "commander": "^9.2.0", 7 | "elliptic": "^6.5.4", 8 | "express": "^4.17.3", 9 | "hex-to-bin": "^1.0.1", 10 | "hex-to-binary": "^1.0.1", 11 | "uniqid": "^5.4.0" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^17.0.23", 15 | "@types/elliptic": "^6.4.14", 16 | "@types/express": "^4.17.13", 17 | "@types/uniqid": "^5.3.2", 18 | "@types/uuid": "^8.3.4" 19 | }, 20 | "name": "developix-blockchain", 21 | "version": "1.0.0", 22 | "main": "config.js", 23 | "bin": { 24 | "dpx": "./Bin/dpx" 25 | }, 26 | "scripts": { 27 | "start": "node ./App/index.js", 28 | "test": "echo \"Error: no test specified\" && exit 1" 29 | }, 30 | "author": "", 31 | "license": "ISC", 32 | "description": "" 33 | } 34 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "ES6", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "CommonJS", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 36 | // "resolveJsonModule": true, /* Enable importing .json files */ 37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 38 | 39 | /* JavaScript Support */ 40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 43 | 44 | /* Emit */ 45 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 50 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 51 | // "removeComments": true, /* Disable emitting comments. */ 52 | // "noEmit": true, /* Disable emitting files from a compilation. */ 53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 55 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 61 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 67 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 68 | 69 | /* Interop Constraints */ 70 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 71 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 72 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 73 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 74 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 75 | 76 | /* Type Checking */ 77 | "strict": true, /* Enable all strict type-checking options. */ 78 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 79 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 80 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 81 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 82 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 83 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 84 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 85 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 86 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 87 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 88 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 89 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 90 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 91 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 92 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 93 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 94 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 95 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 96 | 97 | /* Completeness */ 98 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 99 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 100 | } 101 | } 102 | --------------------------------------------------------------------------------