From f1dbef966aa26d11a4ca5cd6858436afcfcb0d6e Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Budisteanu Date: Mon, 5 Jul 2021 02:22:57 +0300 Subject: [PATCH] init commit --- .babelrc | 16 ++ .gitignore | 7 +- README.md | 5 +- build/deploy/webpack-deploy.config.js | 21 ++ build/vue-loader.config.js | 9 + build/webpack-app.config.js | 30 +++ build/webpack-hot-loader.config.js | 45 +++++ build/webpack.base.config.js | 80 ++++++++ dist/build/index.html | 17 ++ dist/dev/index.html | 22 +++ package.json | 60 ++++++ src/app/app-vue.js | 24 +++ src/app/app.vue | 28 +++ src/assets/common.css | 0 src/components/layout/layout.vue | 48 +++++ src/main.js | 28 +++ src/pages/addresses/address.page.vue | 144 ++++++++++++++ src/pages/blocks/block.page.vue | 174 +++++++++++++++++ src/pages/home/home.page.vue | 263 ++++++++++++++++++++++++++ src/pages/txs/tx.page.vue | 162 ++++++++++++++++ src/router/router.index.js | 33 ++++ src/store/store.js | 16 ++ src/utils/address-helper.js | 125 ++++++++++++ src/utils/http-helper.js | 21 ++ src/utils/string-helper.js | 73 +++++++ 25 files changed, 1449 insertions(+), 2 deletions(-) create mode 100755 .babelrc mode change 100644 => 100755 .gitignore mode change 100644 => 100755 README.md create mode 100755 build/deploy/webpack-deploy.config.js create mode 100755 build/vue-loader.config.js create mode 100755 build/webpack-app.config.js create mode 100755 build/webpack-hot-loader.config.js create mode 100755 build/webpack.base.config.js create mode 100755 dist/build/index.html create mode 100755 dist/dev/index.html create mode 100755 package.json create mode 100644 src/app/app-vue.js create mode 100644 src/app/app.vue create mode 100755 src/assets/common.css create mode 100644 src/components/layout/layout.vue create mode 100755 src/main.js create mode 100644 src/pages/addresses/address.page.vue create mode 100644 src/pages/blocks/block.page.vue create mode 100644 src/pages/home/home.page.vue create mode 100644 src/pages/txs/tx.page.vue create mode 100755 src/router/router.index.js create mode 100755 src/store/store.js create mode 100644 src/utils/address-helper.js create mode 100755 src/utils/http-helper.js create mode 100644 src/utils/string-helper.js diff --git a/.babelrc b/.babelrc new file mode 100755 index 0000000..6e9f02a --- /dev/null +++ b/.babelrc @@ -0,0 +1,16 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8", "ie >= 11"] + } + } + ] + ], + "plugins": [ + "@babel/plugin-syntax-dynamic-import" + ] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index 6704566..15ec7dc --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ yarn-debug.log* yarn-error.log* lerna-debug.log* +.idea/ + # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -80,7 +82,6 @@ typings/ # Nuxt.js build / generate output .nuxt -dist # Gatsby files .cache/ @@ -102,3 +103,7 @@ dist # TernJS port file .tern-port + + +dist/build/assets +dist/dev/assets diff --git a/README.md b/README.md old mode 100644 new mode 100755 index a851d5d..4a1b9bb --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -# blockchain-explorer-frontend \ No newline at end of file +# WebDollar Explorer Frontend + +Theme based on +https://demo.dashboardpack.com/architectui-html-pro/# diff --git a/build/deploy/webpack-deploy.config.js b/build/deploy/webpack-deploy.config.js new file mode 100755 index 0000000..f3ef75a --- /dev/null +++ b/build/deploy/webpack-deploy.config.js @@ -0,0 +1,21 @@ +const path = require('path') +const webpack = require('webpack'); +const base = require('../webpack-app.config'); +const merge = require('webpack-merge'); +const CopyPlugin = require('copy-webpack-plugin'); + +const config = merge(base, { + + output: { + path: path.resolve( __dirname, "./../dist/build" ), + publicPath: "/", + filename: 'Bundle.js' + }, + + plugins: [ + new CopyPlugin([ + ]) + ] +}); + +module.exports = config; diff --git a/build/vue-loader.config.js b/build/vue-loader.config.js new file mode 100755 index 0000000..7c31b63 --- /dev/null +++ b/build/vue-loader.config.js @@ -0,0 +1,9 @@ +module.exports = { + extractCSS: process.env.NODE_ENV === 'production', + preserveWhitespace: false, + postcss: [ + require('autoprefixer')({ + browsers: ['last 3 versions'] + }) + ] +} diff --git a/build/webpack-app.config.js b/build/webpack-app.config.js new file mode 100755 index 0000000..78949d8 --- /dev/null +++ b/build/webpack-app.config.js @@ -0,0 +1,30 @@ +const webpack = require('webpack') +const base = require('./webpack.base.config') +const merge = require('webpack-merge') +const path = require('path') +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = merge(base, { + target: 'web', + + //define entry point + entry: { + app: "./src/main.js", + }, + output: { + path: path.resolve(__dirname, "./../dist/build"), + publicPath: "/", + filename: "Bundle.js" + }, + + plugins: [ + new webpack.DefinePlugin({ + "process.env": { + BROWSER: 'true' + }, + }), + new CopyPlugin([ + ]) + ] + +}); diff --git a/build/webpack-hot-loader.config.js b/build/webpack-hot-loader.config.js new file mode 100755 index 0000000..a4ef730 --- /dev/null +++ b/build/webpack-hot-loader.config.js @@ -0,0 +1,45 @@ +const path = require('path') +const webpack = require('webpack'); +const base = require('./webpack-app.config'); +const merge = require('webpack-merge'); + +module.exports = merge(base, { + + devtool: 'cheap-module-eval-source-map', + mode: 'development', + + entry: [ + 'webpack-hot-middleware/client', + './src/main.js' + ], + + output: { + path: path.resolve(__dirname, "./../dist/dev"), + publicPath: "/", + filename: "Bundle-dev.js" + }, + + devServer: { + historyApiFallback: true, + hot: true, + open: true, + overlay: true, + port: 8082, + stats: { + normal: true + }, + }, + + plugins: [ + + new webpack.DefinePlugin({ + "process.env": { + DEV_SERVER: 'true', + BROWSER: 'true' + } + }), + + ] + +}); + diff --git a/build/webpack.base.config.js b/build/webpack.base.config.js new file mode 100755 index 0000000..5aabfa4 --- /dev/null +++ b/build/webpack.base.config.js @@ -0,0 +1,80 @@ +const path = require('path'); +const webpack = require('webpack'); +const vueConfig = require('./vue-loader.config'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const VueLoaderPlugin = require('vue-loader/lib/plugin') + + +const isProd = process.env.NODE_ENV === 'production'; +const isAnalyze = process.argv.includes('--analyze') || process.argv.includes('--analyse'); + +//const isAnalyze = true; + +module.exports = webpackConfig = { + + node: { + child_process: "empty", + dgram: "empty", + fs: 'empty', + net: 'empty', + tls: 'empty', + uws: 'empty' + }, + + //define entry point + entry: ['babel-regenerator-runtime'], + devtool: isProd ? false : '#cheap-module-source-map', + // send to distribution + output: { + path: path.resolve(__dirname, './../dist'), + publicPath: '/', + filename: '[name].[chunkhash].js' + }, + resolve: { + extensions: [ '.js', '.vue' ], + alias: { + src: path.resolve(__dirname + '/../src'), + consts: path.resolve(__dirname + '/../consts'), + } + }, + module: { + noParse: /es6-promise\.js$/, // avoid webpack shimming process + + rules: [ + + { + test: /\.vue$/, + loader: 'vue-loader', + options: vueConfig + }, + { + test: /\.css$/, + use: isProd + ? ExtractTextPlugin.extract({ + use: 'css-loader?minimize', + fallback: 'vue-style-loader' + }) + : ['vue-style-loader', 'css-loader'] + } + ] + }, + plugins: isProd + ? [ + ...(isAnalyze ? [new BundleAnalyzerPlugin()] : []), + + new webpack.optimize.UglifyJsPlugin({ + compress: { warnings: false } + }), + new ExtractTextPlugin({ + filename: 'common.[chunkhash].css' + }), + new VueLoaderPlugin(), + ] + : [ + ...(isAnalyze ? [new BundleAnalyzerPlugin()] : []), + new FriendlyErrorsPlugin(), + new VueLoaderPlugin(), + ] +}; diff --git a/dist/build/index.html b/dist/build/index.html new file mode 100755 index 0000000..01f08fb --- /dev/null +++ b/dist/build/index.html @@ -0,0 +1,17 @@ + + + + + + + + PandoraPay Wallet + + + + + +
+ + + diff --git a/dist/dev/index.html b/dist/dev/index.html new file mode 100755 index 0000000..3500380 --- /dev/null +++ b/dist/dev/index.html @@ -0,0 +1,22 @@ + + + + + + + + WEBDEXPLORE + + + + + + + + + + +
+ + + diff --git a/package.json b/package.json new file mode 100755 index 0000000..c319769 --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "wallet", + "keywords": [], + "scripts": { + "build-deploy": "webpack --config build/deploy/webpack-deploy.config.js", + "build-wallet": "webpack --config build/webpack-app.config.js", + "build-wallet-analyzer": "webpack --config build/webpack-app.config.js --mode development --analyzer", + "build": "npm run build-wallet && npm run deploy", + "test": "npm run build-wallet", + "dev": "webpack-dev-server --config=./build/webpack-hot-loader.config.js --content-base dist/dev --hot --inline --host 0.0.0.0" + }, + "dependencies": { + "@babel/polyfill": "~7.2", + "axios": "^0.21.1", + "file-saver": "^2.0.5", + "qrcode-vue": "^1.2.0", + "strength": "^0.1.4", + "v-tooltip": "^2.1.2", + "vue": "^2.6.12", + "vue-clickaway": "^2.2.2", + "vue-clipboard2": "^0.3.1", + "vue-notification": "^1.3.20", + "vue-qrcode-reader": "^2.3.16", + "vue-router": "^3.5.1", + "vuex": "^3.6.2" + }, + "devDependencies": { + "@babel/core": "~7.2", + "@babel/plugin-proposal-class-properties": "~7.3", + "@babel/plugin-proposal-decorators": "~7.3", + "@babel/plugin-proposal-json-strings": "~7.2", + "@babel/plugin-syntax-dynamic-import": "~7.2", + "@babel/plugin-syntax-import-meta": "~7.2", + "@babel/preset-env": "~7.3", + "@webpack-cli/serve": "^1.3.0", + "autoprefixer": "^9.8.6", + "babel-eslint": "~10.0", + "babel-loader": "~8.0", + "compression-webpack-plugin": "^7.1.2", + "copy-webpack-plugin": "^5.1.2", + "cross-env": "~5.2", + "css-loader": "~2.1", + "extract-text-webpack-plugin": "^3.0.2", + "file-loader": "^5.1.0", + "friendly-errors-webpack-plugin": "~1.7", + "html-webpack-plugin": "~3.2", + "mini-css-extract-plugin": "~0.5", + "optimize-css-assets-webpack-plugin": "^5.0.4", + "uglifyjs-webpack-plugin": "~1.2", + "vue-loader": "~15.6", + "vue-style-loader": "~4.1", + "vue-template-compiler": "^2.6.12", + "webpack": "~4.29", + "webpack-bundle-analyzer": "~3.3", + "webpack-cli": "~3.2", + "webpack-dev-server": "~3.1", + "webpack-hot-middleware": "~2.24", + "webpack-merge": "~4.2" + } +} diff --git a/src/app/app-vue.js b/src/app/app-vue.js new file mode 100644 index 0000000..b25a588 --- /dev/null +++ b/src/app/app-vue.js @@ -0,0 +1,24 @@ +import Vue from "vue"; +import Loading from './app'; + +import VueRouter from 'vue-router'; +Vue.use(VueRouter); + +import router from "src/router/router.index" + +export default (params) => { + + return window.Frontend = new Vue({ + el: '#app', + router, + render: (createElement) => { + + return createElement( Loading, { + props: { + } + }); + + } + }); + +} diff --git a/src/app/app.vue b/src/app/app.vue new file mode 100644 index 0000000..857fdae --- /dev/null +++ b/src/app/app.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/src/assets/common.css b/src/assets/common.css new file mode 100755 index 0000000..e69de29 diff --git a/src/components/layout/layout.vue b/src/components/layout/layout.vue new file mode 100644 index 0000000..954e2f0 --- /dev/null +++ b/src/components/layout/layout.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/main.js b/src/main.js new file mode 100755 index 0000000..f79d95c --- /dev/null +++ b/src/main.js @@ -0,0 +1,28 @@ +import App from "src/app/app-vue" + +class Main { + + constructor(){ + + window.addEventListener("load", () => { + this.initialize() + } ); + + } + + initialize(){ + this.start() + } + + start(){ + this.app = App({}) + } + +} + +const main = new Main(); + +if ( typeof window !== 'undefined') + window.App = main; + +export default main; diff --git a/src/pages/addresses/address.page.vue b/src/pages/addresses/address.page.vue new file mode 100644 index 0000000..df5892c --- /dev/null +++ b/src/pages/addresses/address.page.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/pages/blocks/block.page.vue b/src/pages/blocks/block.page.vue new file mode 100644 index 0000000..5ff85eb --- /dev/null +++ b/src/pages/blocks/block.page.vue @@ -0,0 +1,174 @@ + + + + + diff --git a/src/pages/home/home.page.vue b/src/pages/home/home.page.vue new file mode 100644 index 0000000..b7eba9b --- /dev/null +++ b/src/pages/home/home.page.vue @@ -0,0 +1,263 @@ + + + + + diff --git a/src/pages/txs/tx.page.vue b/src/pages/txs/tx.page.vue new file mode 100644 index 0000000..6d6c852 --- /dev/null +++ b/src/pages/txs/tx.page.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/src/router/router.index.js b/src/router/router.index.js new file mode 100755 index 0000000..ee18878 --- /dev/null +++ b/src/router/router.index.js @@ -0,0 +1,33 @@ +import VueRouter from "vue-router" +import Vue from "vue"; + +import HomePage from "src/pages/home/home.page" +import BlockPage from "src/pages/blocks/block.page" +import TxPage from "src/pages/txs/tx.page" +import AddressPage from "src/pages/addresses/address.page" + +Vue.use(VueRouter); + +const routes = [ + { path: '/', component: HomePage }, + { path: '/block/:param', component: BlockPage }, + { path: '/tx/:hash', component: TxPage }, + { path: '/address/:address', component: AddressPage }, +]; + +const router = new VueRouter({ + base: '/', + mode: 'history', + scrollBehavior(to, from, savedPosition) { + if (to.hash) { + return { selector: to.hash } + } else if (savedPosition) { + return savedPosition; + } else { + return { x: 0, y: 0 } + } + }, + routes // short for `routes: routes` +}); + +export default router; diff --git a/src/store/store.js b/src/store/store.js new file mode 100755 index 0000000..c8664c7 --- /dev/null +++ b/src/store/store.js @@ -0,0 +1,16 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; + +Vue.use(Vuex); + +const store = new Vuex.Store({ + + modules: { + + + }, + + +}); + +export default store; diff --git a/src/utils/address-helper.js b/src/utils/address-helper.js new file mode 100644 index 0000000..2841138 --- /dev/null +++ b/src/utils/address-helper.js @@ -0,0 +1,125 @@ +const crypto = require('crypto') + +module.exports = { + + settings: { + + PRIVATE_KEY:{ + WIF:{ + VERSION_PREFIX : "80", //it is in HEX + CHECK_SUM_LENGTH : 4, //in bytes + }, + LENGTH : 64, //ending BASE64 HEX + }, + PUBLIC_KEY:{ + LENGTH : 32, //ending BASE64 HEX + }, + + ADDRESS:{ + + USE_BASE64 : true, + + LENGTH : 20, + + WIF:{ + LENGTH: 0, + + VERSION_PREFIX : "00", //ending BASE64 HEX + CHECK_SUM_LENGTH : 4, //in bytes //ending BASE64 HEX + + PREFIX_BASE64 : "584043fe", //BASE64 HEX WEBD$ + //WEBD 584043 + //WEBD$ 584043FF + + SUFFIX_BASE64 : "FF", //ending BASE64 HEX + //#w$ EC3F + //%#$ 8FBF + + PREFIX_BASE58 : "00", //BASE58 HEX and it will be converted to Base64/58 + SUFFIX_BASE58 : "", + } + + }, + }, + + _encodeBase64(buffer) { + + if (!Buffer.isBuffer(buffer)) + buffer = Buffer.from(buffer); + + let result = buffer.toString('base64'); + + let newStr = ''; + for (let i = 0; i < result.length; i++) { + + if (result[i] === 'O') newStr += '#'; else + if (result[i] === 'l') newStr += '@'; else + if (result[i] === '/') newStr += '$'; + else newStr += result[i]; + + } + + return newStr; + }, + + _toBase(buffer){ + return this._encodeBase64(buffer); + }, + + _SHA256(bytes){ + + let sha256 = crypto.createHash('sha256'); //sha256 + sha256.update(bytes); + + return sha256.digest(); + }, + + _calculateChecksum(privateKeyAndVersion, showDebug){ + + //add 0x80 to the front, https://en.bitcoin.it/wiki/List_of_address_prefixes + + if (!Buffer.isBuffer(privateKeyAndVersion) && typeof privateKeyAndVersion === 'string') + privateKeyAndVersion = Buffer.from(privateKeyAndVersion, 'hex'); + + let secondSHA = this._SHA256(this._SHA256(privateKeyAndVersion)); + let checksum = Buffer.alloc(this.settings.PRIVATE_KEY.WIF.CHECK_SUM_LENGTH); + secondSHA.copy(checksum, 0, 0, this.settings.PRIVATE_KEY.WIF.CHECK_SUM_LENGTH); + + return checksum; + }, + + _generateAddressWIF(address, showDebug, toBase = false){ + + if (!Buffer.isBuffer(address) && typeof address === "string") + address = Buffer.from(address, 'hex'); + + if ( !Buffer.isBuffer(address) ) + throw {message: "invalid address"}; + + let prefix = ( this.settings.ADDRESS.USE_BASE64 ? this.settings.ADDRESS.WIF.PREFIX_BASE64 : this.settings.ADDRESS.WIF.PREFIX_BASE58); + let suffix = ( this.settings.ADDRESS.USE_BASE64 ? this.settings.ADDRESS.WIF.SUFFIX_BASE64 : this.settings.ADDRESS.WIF.SUFFIX_BASE58); + + //maybe address is already a + if (address.length === this.settings.ADDRESS.LENGTH + this.settings.ADDRESS.WIF.CHECK_SUM_LENGTH + this.settings.ADDRESS.WIF.VERSION_PREFIX.length/2 + prefix.length/2 + suffix.length/2) + return (toBase ? this._toBase(address) : address); + + address = Buffer.concat ( [ Buffer.from(this.settings.ADDRESS.WIF.VERSION_PREFIX,"hex"), address ]) ; //if using testnet, would use 0x6F or 111. + + let checksum = this._calculateChecksum(address, showDebug); + + let addressWIF = Buffer.concat([ + Buffer.from( prefix , "hex"), + address, + checksum, + Buffer.from( suffix, "hex") + ]); + + + return (toBase ? this._toBase(addressWIF) : addressWIF); + }, + + convertAddress(unencodedPublicKeyHash){ + return this._toBase(this._generateAddressWIF(unencodedPublicKeyHash)) + } + +} diff --git a/src/utils/http-helper.js b/src/utils/http-helper.js new file mode 100755 index 0000000..cf21208 --- /dev/null +++ b/src/utils/http-helper.js @@ -0,0 +1,21 @@ +const axios = require('axios') + +class HttpHelper { + + async get(address, body, timeout = 20000){ + const out = await axios.get(address, {params: body}) + return out.data + } + + async post(address, body, json = true, timeout = 20000){ + const out = await axios.post(address, body, { + headers: { + 'content-type': 'text/json' + } + } ) + return out.data + } + +} + +export default new HttpHelper(); diff --git a/src/utils/string-helper.js b/src/utils/string-helper.js new file mode 100644 index 0000000..38acbb1 --- /dev/null +++ b/src/utils/string-helper.js @@ -0,0 +1,73 @@ +class StringHelper{ + + formatMiliseconds(millisec){ + + const seconds = (millisec / 1000).toFixed(1); + const minutes = (millisec / (1000 * 60)).toFixed(1); + const hours = (millisec / (1000 * 60 * 60)).toFixed(1); + const days = (millisec / (1000 * 60 * 60 * 24)).toFixed(1); + + if (seconds < 60) return seconds + " Sec"; + else if (minutes < 60) return minutes + " Min"; + else if (hours < 24) return hours + " Hrs"; + else return days + " Days" + + } + + timeSince(date, longVersion = true ) { + + var seconds = Math.floor((new Date().getTime() - date) / 1000); + + var interval = Math.floor(seconds / 31536000); + + if (interval > 1) + return interval + (longVersion ? " years" : ' y'); + + interval = Math.floor(seconds / 2592000); + if (interval > 1) + return interval + (longVersion? " months" : ' mo'); + interval = Math.floor(seconds / 86400); + if (interval > 1) + return interval + (longVersion ? " days" : ' d'); + interval = Math.floor(seconds / 3600); + if (interval > 1) + return interval + (longVersion ? " hours" : ' h'); + + interval = Math.floor(seconds / 60); + if (interval > 1) + return interval + (longVersion ? " minutes" : ' m'); + + return Math.floor(seconds) + (longVersion? " seconds": ' s'); + } + + formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") { + try { + decimalCount = Math.abs(decimalCount); + decimalCount = isNaN(decimalCount) ? 2 : decimalCount; + + const negativeSign = amount < 0 ? "-" : ""; + + let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString(); + let j = (i.length > 3) ? i.length % 3 : 0; + + return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : ""); + } catch (e) { + console.log(e) + } + } + + formatBytes(bytes, decimals = 2) { + if (bytes === 0) return '0 B'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + } + +} + +export default new StringHelper()