- Details
+ {servers?.length > 0 && (
+
+
+
+
+
+
+ Physical Metal Card
-
-
+ )}
);
-}
+});
export default VPNServers;
diff --git a/src/store/store.js b/src/store/store.js
index cddc394..2fc6c58 100644
--- a/src/store/store.js
+++ b/src/store/store.js
@@ -3,27 +3,30 @@ import {
makeAutoObservable,
onBecomeObserved,
onBecomeUnobserved,
-} from "mobx";
-import { cryptography } from "@liskhq/lisk-client";
-import { passphrase } from "@liskhq/lisk-client";
-import { getNodeInfo } from "../api/node";
-import { fetchWrapper } from "../shared/fetchWrapper";
-import { labelMap } from "../shared/labelMap";
-import { statusMap } from "../shared/statusMap";
-import { generateSvgAvatar } from "../images/GenerateOnboardingSvg/GenerateSvg";
-import { decryptedData } from "../utils/decryptedData";
+} from 'mobx';
+import { cryptography } from '@liskhq/lisk-client';
+import { passphrase } from '@liskhq/lisk-client';
+import { getNodeInfo } from '../api/node';
+import { fetchWrapper } from '../shared/fetchWrapper';
+import { labelMap } from '../shared/labelMap';
+import { statusMap } from '../shared/statusMap';
+import { generateSvgAvatar } from '../images/GenerateOnboardingSvg/GenerateSvg';
+import { decryptedData } from '../utils/decryptedData';
import {
+ bytesToMbytes,
encryptAccountData,
encryptSharedData,
+ formatBytes,
generateTransaction,
hashAccountData,
-} from "../utils/Utils";
-import sodium from "sodium-universal";
+} from '../utils/Utils';
+import sodium from 'sodium-universal';
+import { countryCodes } from '../utils/countryCodes';
class Store {
_accountData = [];
- _passPhrase = "";
+ _passPhrase = '';
_nodeInfo = {};
@@ -63,18 +66,18 @@ class Store {
() => this.address,
() => this.fetchAccountInfo()
);
- onBecomeObserved(this, "decryptedAccountData", () =>
+ onBecomeObserved(this, 'decryptedAccountData', () =>
this.fetchNewAccountData()
);
- onBecomeUnobserved(this, "decryptedAccountData", () =>
+ onBecomeUnobserved(this, 'decryptedAccountData', () =>
this.unobservedAccountData()
);
- onBecomeObserved(this, "sharedData", () => this.fetchKeysArray());
- onBecomeUnobserved(this, "sharedData", () => this.unobservedSharedData());
- onBecomeObserved(this, "transactionsInfo", () =>
+ onBecomeObserved(this, 'sharedData', () => this.fetchKeysArray());
+ onBecomeUnobserved(this, 'sharedData', () => this.unobservedSharedData());
+ onBecomeObserved(this, 'transactionsInfo', () =>
this.fetchTransactionsInfo()
);
- onBecomeUnobserved(this, "transactionsInfo", () =>
+ onBecomeUnobserved(this, 'transactionsInfo', () =>
this.unobservedTransactionsInfo()
);
@@ -83,7 +86,7 @@ class Store {
fetchVPNServers() {
fetchWrapper
- .getAuth("vpn/servers", {
+ .getAuth('vpn/servers', {
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID,
})
@@ -97,17 +100,12 @@ class Store {
}
fetchNewAccountData() {
- getNodeInfo()
- .then((info) => {
- this.fetchNodeInfoSuccess(info);
- fetchWrapper
- .getAuth("data/private", {
- networkIdentifier: this.nodeInfo.networkIdentifier,
- lastBlockID: this.nodeInfo.lastBlockID,
- })
- .then((res) => this.accountDataFetchChange(res))
- .catch((err) => this.throwError(err));
+ fetchWrapper
+ .getAuth('data/private', {
+ networkIdentifier: this.nodeInfo.networkIdentifier,
+ lastBlockID: this.nodeInfo.lastBlockID,
})
+ .then((res) => this.accountDataFetchChange(res))
.catch((err) => this.throwError(err));
}
@@ -123,7 +121,7 @@ class Store {
.then((info) => {
this.fetchNodeInfoSuccess(info);
fetchWrapper
- .getAuth("data/shared/", {
+ .getAuth('data/shared/', {
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID,
})
@@ -144,13 +142,13 @@ class Store {
fetchTempTransactions() {
fetchWrapper
- .get("node/transactions")
+ .get('node/transactions')
.then((res) => this.fetchTempTransactionsSuccess(res))
.catch((err) => this.throwError(err));
}
fetchPassPhrase() {
- this._passPhrase = sessionStorage.getItem("passPhrase") || "";
+ this._passPhrase = sessionStorage.getItem('passPhrase') || '';
}
fetchSharedData() {
@@ -173,7 +171,7 @@ class Store {
if (data.length > 0) {
fetchWrapper
.postAuth(
- "data/shared",
+ 'data/shared',
{
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID,
@@ -190,7 +188,7 @@ class Store {
pushAccountData(data = this.accountData) {
fetchWrapper
.postAuth(
- "data/private",
+ 'data/private',
{
networkIdentifier: this.nodeInfo.networkIdentifier,
lastBlockID: this.nodeInfo.lastBlockID,
@@ -221,7 +219,7 @@ class Store {
if (changed.length !== 0) signedTx = builder.update(changed);
if (signedTx) {
fetchWrapper
- .post("transactions", {}, signedTx)
+ .post('transactions', {}, signedTx)
.then(() => this.fetchTempTransactions())
.catch((err) => this.throwError(err));
this.accountInfo.sequence.nonce++;
@@ -240,7 +238,7 @@ class Store {
if (signedTx) {
fetchWrapper
- .post("transactions", {}, signedTx)
+ .post('transactions', {}, signedTx)
.then(() => this.fetchTempTransactions())
.catch((err) => this.throwError(err));
this.accountInfo.sequence.nonce++;
@@ -262,7 +260,7 @@ class Store {
if (signedTx) {
fetchWrapper
- .post("transactions", {}, signedTx)
+ .post('transactions', {}, signedTx)
.then(() => this.fetchTempTransactions())
.catch((err) => this.throwError(err));
this.accountInfo.sequence.nonce++;
@@ -271,12 +269,12 @@ class Store {
generatePassPhrase() {
this._passPhrase = passphrase.Mnemonic.generateMnemonic();
- sessionStorage.setItem("passPhrase", this._passPhrase);
+ sessionStorage.setItem('passPhrase', this._passPhrase);
}
savePastPassPhrase(phrase) {
this._passPhrase = phrase;
- sessionStorage.setItem("passPhrase", this._passPhrase);
+ sessionStorage.setItem('passPhrase', this._passPhrase);
}
unobservedTransactionsInfo() {
@@ -398,12 +396,12 @@ class Store {
}
get firstName() {
- return this.decryptedAccountData.find((item) => item.key === "firstname")
+ return this.decryptedAccountData.find((item) => item.key === 'firstname')
?.value;
}
get lastName() {
- return this.decryptedAccountData.find((item) => item.key === "secondname")
+ return this.decryptedAccountData.find((item) => item.key === 'secondname')
?.value;
}
@@ -444,27 +442,27 @@ class Store {
let x25519_sk = Buffer.alloc(sodium.crypto_box_SECRETKEYBYTES);
sodium.crypto_sign_ed25519_sk_to_curve25519(
x25519_sk,
- Buffer.from(this.privateKey, "hex")
+ Buffer.from(this.privateKey, 'hex')
);
- return x25519_sk.toString("Base64");
+ return x25519_sk.toString('Base64');
}
get pubKey() {
- return this.addressAndPubKey.publicKey.toString("hex");
+ return this.addressAndPubKey.publicKey.toString('hex');
}
get address() {
- return this.addressAndPubKey.address.toString("hex");
+ return this.addressAndPubKey.address.toString('hex');
}
get tokenKey() {
const stringToSign =
this.nodeInfo.networkIdentifier + this.nodeInfo.lastBlockID;
- if (!stringToSign) return "";
+ if (!stringToSign) return '';
const sign = cryptography
- .signDataWithPassphrase(Buffer.from(stringToSign, "hex"), this.passPhrase)
- .toString("hex");
- return this.pubKey + ":" + sign;
+ .signDataWithPassphrase(Buffer.from(stringToSign, 'hex'), this.passPhrase)
+ .toString('hex');
+ return this.pubKey + ':' + sign;
}
get accountIdentity() {
@@ -598,7 +596,19 @@ class Store {
}
get vpnServers() {
- return this._vpnServers;
+ return this._vpnServers?.map((server) => ({
+ ...server,
+ transferSum: formatBytes(
+ Number(server.transferTx || 0) + Number(server.transferRx || 0)
+ ),
+ trafficUsed: Math.floor(
+ ((Number(server.transferTx || 0) + Number(server.transferRx || 0)) /
+ (50 * 1024 * 1024 * 1024)) *
+ 100
+ ),
+ state: server.state === '1',
+ country: countryCodes[server.country] || 'US',
+ }));
}
get canVPN() {
@@ -611,13 +621,13 @@ class Store {
let amount = this.processedVotes[address];
- if (amount) return "Pending";
+ if (amount) return 'Pending';
amount = this.accountSentVotes[address];
- if (amount) return "Unvote";
+ if (amount) return 'Unvote';
- return "Vote";
+ return 'Vote';
};
return this._delegates.data.map((delegate) => ({
diff --git a/src/utils/Utils.js b/src/utils/Utils.js
index 44cf4de..3e35050 100644
--- a/src/utils/Utils.js
+++ b/src/utils/Utils.js
@@ -139,6 +139,18 @@ export const hashValue = (value = '', seed = '') =>
Buffer.concat([Buffer.from(seed, 'utf8'), cryptography.hash(value, 'utf8')])
);
+export const formatBytes = (bytes, decimals = 2) => {
+ if (!+bytes) return '0 Bytes';
+
+ const k = 1024;
+ const dm = decimals < 0 ? 0 : decimals;
+ const sizes = ['Bytes', '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 const generateTransaction = (
nonce = BigInt(0),
senderPublicKey = '',
diff --git a/src/utils/countryCodes.js b/src/utils/countryCodes.js
new file mode 100644
index 0000000..5ed7164
--- /dev/null
+++ b/src/utils/countryCodes.js
@@ -0,0 +1,252 @@
+export const countryCodes = {
+ BGD: 'BD',
+ BEL: 'BE',
+ BFA: 'BF',
+ BGR: 'BG',
+ BIH: 'BA',
+ BRB: 'BB',
+ WLF: 'WF',
+ BLM: 'BL',
+ BMU: 'BM',
+ BRN: 'BN',
+ BOL: 'BO',
+ BHR: 'BH',
+ BDI: 'BI',
+ BEN: 'BJ',
+ BTN: 'BT',
+ JAM: 'JM',
+ BVT: 'BV',
+ BWA: 'BW',
+ WSM: 'WS',
+ BES: 'BQ',
+ BRA: 'BR',
+ BHS: 'BS',
+ JEY: 'JE',
+ BLR: 'BY',
+ BLZ: 'BZ',
+ RUS: 'RU',
+ RWA: 'RW',
+ SRB: 'RS',
+ TLS: 'TL',
+ REU: 'RE',
+ TKM: 'TM',
+ TJK: 'TJ',
+ ROU: 'RO',
+ TKL: 'TK',
+ GNB: 'GW',
+ GUM: 'GU',
+ GTM: 'GT',
+ SGS: 'GS',
+ GRC: 'GR',
+ GNQ: 'GQ',
+ GLP: 'GP',
+ JPN: 'JP',
+ GUY: 'GY',
+ GGY: 'GG',
+ GUF: 'GF',
+ GEO: 'GE',
+ GRD: 'GD',
+ GBR: 'GB',
+ GAB: 'GA',
+ SLV: 'SV',
+ GIN: 'GN',
+ GMB: 'GM',
+ GRL: 'GL',
+ GIB: 'GI',
+ GHA: 'GH',
+ OMN: 'OM',
+ TUN: 'TN',
+ JOR: 'JO',
+ HRV: 'HR',
+ HTI: 'HT',
+ HUN: 'HU',
+ HKG: 'HK',
+ HND: 'HN',
+ HMD: 'HM',
+ VEN: 'VE',
+ PRI: 'PR',
+ PSE: 'PS',
+ PLW: 'PW',
+ PRT: 'PT',
+ SJM: 'SJ',
+ PRY: 'PY',
+ IRQ: 'IQ',
+ PAN: 'PA',
+ PYF: 'PF',
+ PNG: 'PG',
+ PER: 'PE',
+ PAK: 'PK',
+ PHL: 'PH',
+ PCN: 'PN',
+ POL: 'PL',
+ SPM: 'PM',
+ ZMB: 'ZM',
+ ESH: 'EH',
+ EST: 'EE',
+ EGY: 'EG',
+ ZAF: 'ZA',
+ ECU: 'EC',
+ ITA: 'IT',
+ VNM: 'VN',
+ SLB: 'SB',
+ ETH: 'ET',
+ SOM: 'SO',
+ ZWE: 'ZW',
+ SAU: 'SA',
+ ESP: 'ES',
+ ERI: 'ER',
+ MNE: 'ME',
+ MDA: 'MD',
+ MDG: 'MG',
+ MAF: 'MF',
+ MAR: 'MA',
+ MCO: 'MC',
+ UZB: 'UZ',
+ MMR: 'MM',
+ MLI: 'ML',
+ MAC: 'MO',
+ MNG: 'MN',
+ MHL: 'MH',
+ MKD: 'MK',
+ MUS: 'MU',
+ MLT: 'MT',
+ MWI: 'MW',
+ MDV: 'MV',
+ MTQ: 'MQ',
+ MNP: 'MP',
+ MSR: 'MS',
+ MRT: 'MR',
+ IMN: 'IM',
+ UGA: 'UG',
+ TZA: 'TZ',
+ MYS: 'MY',
+ MEX: 'MX',
+ ISR: 'IL',
+ FRA: 'FR',
+ IOT: 'IO',
+ SHN: 'SH',
+ FIN: 'FI',
+ FJI: 'FJ',
+ FLK: 'FK',
+ FSM: 'FM',
+ FRO: 'FO',
+ NIC: 'NI',
+ NLD: 'NL',
+ NOR: 'NO',
+ NAM: 'NA',
+ VUT: 'VU',
+ NCL: 'NC',
+ NER: 'NE',
+ NFK: 'NF',
+ NGA: 'NG',
+ NZL: 'NZ',
+ NPL: 'NP',
+ NRU: 'NR',
+ NIU: 'NU',
+ COK: 'CK',
+ XKX: 'XK',
+ CIV: 'CI',
+ CHE: 'CH',
+ COL: 'CO',
+ CHN: 'CN',
+ CMR: 'CM',
+ CHL: 'CL',
+ CCK: 'CC',
+ CAN: 'CA',
+ COG: 'CG',
+ CAF: 'CF',
+ COD: 'CD',
+ CZE: 'CZ',
+ CYP: 'CY',
+ CXR: 'CX',
+ CRI: 'CR',
+ CUW: 'CW',
+ CPV: 'CV',
+ CUB: 'CU',
+ SWZ: 'SZ',
+ SYR: 'SY',
+ SXM: 'SX',
+ KGZ: 'KG',
+ KEN: 'KE',
+ SSD: 'SS',
+ SUR: 'SR',
+ KIR: 'KI',
+ KHM: 'KH',
+ KNA: 'KN',
+ COM: 'KM',
+ STP: 'ST',
+ SVK: 'SK',
+ KOR: 'KR',
+ SVN: 'SI',
+ PRK: 'KP',
+ KWT: 'KW',
+ SEN: 'SN',
+ SMR: 'SM',
+ SLE: 'SL',
+ SYC: 'SC',
+ KAZ: 'KZ',
+ CYM: 'KY',
+ SGP: 'SG',
+ SWE: 'SE',
+ SDN: 'SD',
+ DOM: 'DO',
+ DMA: 'DM',
+ DJI: 'DJ',
+ DNK: 'DK',
+ VGB: 'VG',
+ DEU: 'DE',
+ YEM: 'YE',
+ DZA: 'DZ',
+ USA: 'US',
+ URY: 'UY',
+ MYT: 'YT',
+ UMI: 'UM',
+ LBN: 'LB',
+ LCA: 'LC',
+ LAO: 'LA',
+ TUV: 'TV',
+ TWN: 'TW',
+ TTO: 'TT',
+ TUR: 'TR',
+ LKA: 'LK',
+ LIE: 'LI',
+ LVA: 'LV',
+ TON: 'TO',
+ LTU: 'LT',
+ LUX: 'LU',
+ LBR: 'LR',
+ LSO: 'LS',
+ THA: 'TH',
+ ATF: 'TF',
+ TGO: 'TG',
+ TCD: 'TD',
+ TCA: 'TC',
+ LBY: 'LY',
+ VAT: 'VA',
+ VCT: 'VC',
+ ARE: 'AE',
+ AND: 'AD',
+ ATG: 'AG',
+ AFG: 'AF',
+ AIA: 'AI',
+ VIR: 'VI',
+ ISL: 'IS',
+ IRN: 'IR',
+ ARM: 'AM',
+ ALB: 'AL',
+ AGO: 'AO',
+ ATA: 'AQ',
+ ASM: 'AS',
+ ARG: 'AR',
+ AUS: 'AU',
+ AUT: 'AT',
+ ABW: 'AW',
+ IND: 'IN',
+ ALA: 'AX',
+ AZE: 'AZ',
+ IRL: 'IE',
+ IDN: 'ID',
+ UKR: 'UA',
+ QAT: 'QA',
+ MOZ: 'MZ',
+};
diff --git a/webpack.config.js b/webpack.config.js
index 8c6221b..3d83bea 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,19 +1,19 @@
-const path = require("path");
-const HtmlWebpackPlugin = require("html-webpack-plugin");
-const webpack = require("webpack");
+const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const webpack = require('webpack');
const plugins = [
new HtmlWebpackPlugin({
- favicon: "./public/favicon.ico",
- template: "./public/index.html",
+ favicon: './public/favicon.ico',
+ template: './public/index.html',
}),
new webpack.ProvidePlugin({
- Buffer: ["buffer", "Buffer"],
+ Buffer: ['buffer', 'Buffer'],
}),
new webpack.ProvidePlugin({
- process: "process/browser",
+ process: 'process/browser',
}),
- require("tailwindcss"),
+ require('tailwindcss'),
new webpack.ContextReplacementPlugin(/sodium/, (data) => {
delete data.dependencies[0].critical;
return data;
@@ -21,86 +21,83 @@ const plugins = [
];
module.exports = (env, argv) => ({
- entry: "./src/main.jsx",
- mode: argv.mode || "development",
- devtool: argv.mode === "production" ? false : "eval-source-map",
+ entry: './src/main.jsx',
+ mode: argv.mode || 'development',
+ devtool: argv.mode === 'production' ? false : 'eval-source-map',
plugins,
output: {
clean: true,
- path: path.resolve(__dirname, "build"),
- assetModuleFilename: "assets/[fullhash:12][ext]",
- filename: "main.[fullhash:8].js",
+ path: path.resolve(__dirname, 'build'),
+ assetModuleFilename: 'assets/[fullhash:12][ext]',
+ filename: 'main.[fullhash:8].js',
},
devServer: {
open: true,
static: {
- directory: path.join(__dirname, "public"),
+ directory: path.join(__dirname, 'public'),
},
compress: true,
- port: "auto",
+ port: 'auto',
hot: true,
client: {
progress: true,
},
proxy: {
- "/api/**": {
- target: "https://tn-alpha.idntty.org:8080/",
+ '/api/**': {
+ target: 'https://tn-alpha.idntty.org:8080/',
secure: false,
changeOrigin: true,
},
},
},
-
- ignoreWarnings: [() => false],
-
module: {
rules: [
- { test: /\.(html)$/, use: ["html-loader"] },
+ { test: /\.(html)$/, use: ['html-loader'] },
{
test: /\.m?jsx?$/,
exclude: /(node_modules|bower_components)/,
use: {
- loader: "babel-loader",
+ loader: 'babel-loader',
},
},
{
test: /\.scss$/,
use: [
{
- loader: "style-loader",
+ loader: 'style-loader',
},
{
- loader: "css-loader",
+ loader: 'css-loader',
},
{
- loader: "postcss-loader",
+ loader: 'postcss-loader',
},
{
- loader: "sass-loader",
+ loader: 'sass-loader',
},
],
},
{
test: /\.(png|svg|jpg|gif)$/,
- loader: "file-loader",
+ loader: 'file-loader',
options: {
- outputPath: "assets",
+ outputPath: 'assets',
},
},
],
},
resolve: {
- extensions: [".js", ".jsx"],
+ extensions: ['.js', '.jsx'],
fallback: {
- path: require.resolve("path-browserify"),
- os: require.resolve("os-browserify/browser"),
- querystring: require.resolve("querystring-es3"),
- crypto: require.resolve("crypto-browserify"),
- util: require.resolve("util/"),
- stream: require.resolve("stream-browserify"),
- url: require.resolve("url/"),
- buffer: require.resolve("buffer/"),
+ path: require.resolve('path-browserify'),
+ os: require.resolve('os-browserify/browser'),
+ querystring: require.resolve('querystring-es3'),
+ crypto: require.resolve('crypto-browserify'),
+ util: require.resolve('util/'),
+ stream: require.resolve('stream-browserify'),
+ url: require.resolve('url/'),
+ buffer: require.resolve('buffer/'),
fs: false,
},
},