fix vpn servers
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -26,6 +26,7 @@
|
||||
"qrcode.react": "^3.1.0",
|
||||
"querystring-es3": "^0.2.1",
|
||||
"react": "^17.0.2",
|
||||
"react-country-flag": "^3.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-flatpickr": "^3.10.7",
|
||||
"react-loader-spinner": "^5.2.0",
|
||||
@@ -6829,6 +6830,17 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-country-flag": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.0.2.tgz",
|
||||
"integrity": "sha512-JPaz+q3QD0/nZtHBKj5x3O7r/SgSG9kxbymdaIU0RqlDAcorJIe4KV0DFhWIdKh69q5cPVkIVERcMYGZdvXgAA==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||
@@ -13837,6 +13849,12 @@
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"react-country-flag": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-country-flag/-/react-country-flag-3.0.2.tgz",
|
||||
"integrity": "sha512-JPaz+q3QD0/nZtHBKj5x3O7r/SgSG9kxbymdaIU0RqlDAcorJIe4KV0DFhWIdKh69q5cPVkIVERcMYGZdvXgAA==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz",
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"qrcode.react": "^3.1.0",
|
||||
"querystring-es3": "^0.2.1",
|
||||
"react": "^17.0.2",
|
||||
"react-country-flag": "^3.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-flatpickr": "^3.10.7",
|
||||
"react-loader-spinner": "^5.2.0",
|
||||
|
||||
@@ -32,6 +32,10 @@ const App = observer(() => {
|
||||
document.querySelector('html').style.scrollBehavior = '';
|
||||
}, [location.pathname]); // triggered on route change
|
||||
|
||||
if (!store.nodeInfo.networkIdentifier) {
|
||||
return <LoadingOverlay />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{store.loading && <LoadingOverlay />}
|
||||
|
||||
@@ -6,33 +6,45 @@ import { QRCodeSVG } from 'qrcode.react';
|
||||
|
||||
import VPNServeIcon from '../../images/vpn_server_icon.png';
|
||||
import { Filters } from '../../components/Filters';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import ReactCountryFlag from 'react-country-flag';
|
||||
|
||||
const filters = {
|
||||
'View All': '',
|
||||
Active: 'Active',
|
||||
Offline: 'Offline',
|
||||
'View All': 'all',
|
||||
Active: true,
|
||||
Offline: false,
|
||||
};
|
||||
|
||||
function VPNServers() {
|
||||
const VPNServers = observer(() => {
|
||||
const [sidebarOpen, setSidebarOpen] = useState(false);
|
||||
const [selectedServer, setSelectedServer] = useState(0);
|
||||
const [currentFilter, setCurrentFilter] = useState('View All');
|
||||
|
||||
const servers = useMemo(() => {
|
||||
if (filters[currentFilter] === 'all') return store.vpnServers;
|
||||
return store.vpnServers.filter((e) => e.state === filters[currentFilter]);
|
||||
}, [store.vpnServers, currentFilter]);
|
||||
|
||||
const qrContent = useMemo(
|
||||
() => `
|
||||
[Interface]
|
||||
PrivateKey = ${store.vpnPrivateKey}
|
||||
Address = ${store.vpnServers?.[selectedServer]?.address}
|
||||
DNS = ${store.vpnServers?.[selectedServer]?.dns}
|
||||
Address = ${servers?.[selectedServer]?.address}
|
||||
DNS = ${servers?.[selectedServer]?.dns}
|
||||
|
||||
[Peer]
|
||||
PublicKey = ${store.vpnServers?.[selectedServer]?.publicKey}
|
||||
PublicKey = ${servers?.[selectedServer]?.serverPublickKey}
|
||||
AllowedIPs = 0.0.0.0/0
|
||||
Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
Endpoint = ${servers?.[selectedServer]?.endpoint}
|
||||
PersistentKeepalive = 25
|
||||
`,
|
||||
[store.vpnServers, store.vpnPrivateKey]
|
||||
[store.vpnServers, store.vpnPrivateKey, selectedServer]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setSelectedServer(0);
|
||||
}, [currentFilter]);
|
||||
|
||||
const downloadTxtFile = () => {
|
||||
const element = document.createElement('a');
|
||||
const file = new Blob([qrContent], { type: 'text/plain' });
|
||||
@@ -59,7 +71,7 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
<main>
|
||||
<div className="lg:relative lg:flex">
|
||||
{/* Content */}
|
||||
<div className="px-4 sm:px-6 lg:px-8 py-8 w-full max-w-9xl mx-auto">
|
||||
<div className="px-4 sm:px-6 lg:px-8 py-8 w-full max-w-9xl">
|
||||
{/* Page header */}
|
||||
<div className="sm:flex sm:justify-between sm:items-center mb-5">
|
||||
{/* Left: Title */}
|
||||
@@ -79,7 +91,7 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
|
||||
{/* Credit cards */}
|
||||
<div className="space-y-2">
|
||||
{store.vpnServers?.map((e, i) => (
|
||||
{servers?.map((e, i) => (
|
||||
<label
|
||||
className="relative block cursor-pointer text-left w-full"
|
||||
onClick={() => setSelectedServer(i)}
|
||||
@@ -96,28 +108,35 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
<div className="grid grid-cols-12 items-center gap-x-2">
|
||||
{/* Card */}
|
||||
<div className="col-span-6 order-1 sm:order-none sm:col-span-3 flex items-center space-x-4 lg:sidebar-expanded:col-span-6 xl:sidebar-expanded:col-span-3">
|
||||
<img
|
||||
src={VPNServeIcon}
|
||||
width="36"
|
||||
height="36"
|
||||
alt="VPN Country"
|
||||
<ReactCountryFlag
|
||||
countryCode={e.country}
|
||||
svg
|
||||
style={{ width: '36px', height: 'auto' }}
|
||||
/>
|
||||
<div>
|
||||
<div className="text-sm font-medium text-slate-800">
|
||||
{e.endpoint}
|
||||
</div>
|
||||
<div className="text-xs">{e.publicKey}</div>
|
||||
<div className="text-xs">{e.serverPublickKey}</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Card limits */}
|
||||
<div className="col-span-6 order-1 sm:order-none sm:col-span-4 text-right sm:text-center lg:sidebar-expanded:col-span-6 xl:sidebar-expanded:col-span-6">
|
||||
<div className="text-sm">4673,00 Mb / 473,00 Mb</div>
|
||||
<div className="text-sm">
|
||||
{e.transferSum} / 50.00 GB
|
||||
</div>
|
||||
</div>
|
||||
{/* Card status */}
|
||||
<div className="col-span-6 order-2 sm:order-none sm:col-span-2 text-right lg:sidebar-expanded:hidden xl:sidebar-expanded:block">
|
||||
{store.vpnServers?.[selectedServer]?.state ? (
|
||||
<div className="text-xs inline-flex font-medium bg-emerald-100 text-emerald-600 rounded-full text-center px-2.5 py-1">
|
||||
Active
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-xs inline-flex font-medium bg-amber-100 text-amber-600 rounded-full text-center px-2.5 py-1">
|
||||
Offline
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -131,6 +150,7 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
</div>
|
||||
|
||||
{/* Sidebar */}
|
||||
{servers?.length > 0 && (
|
||||
<div>
|
||||
<div className="lg:sticky lg:top-16 bg-slate-50 lg:overflow-x-hidden lg:overflow-y-auto no-scrollbar lg:shrink-0 border-t lg:border-t-0 lg:border-l border-slate-200 lg:w-[390px] lg:h-[calc(100vh-64px)]">
|
||||
<div className="py-8 px-4 lg:px-8 h-full">
|
||||
@@ -159,16 +179,27 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
<li className="flex items-center justify-between py-3 border-b border-slate-200">
|
||||
<div className="text-sm">Server address</div>
|
||||
<div className="text-sm font-medium text-slate-800 ml-2">
|
||||
{store.vpnServers?.[selectedServer]?.endpoint}
|
||||
{servers?.[selectedServer]?.endpoint}
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-center justify-between py-3 border-b border-slate-200">
|
||||
<div className="text-sm">Status</div>
|
||||
<div className="flex items-center whitespace-nowrap">
|
||||
{servers?.[selectedServer]?.state ? (
|
||||
<>
|
||||
<div className="w-2 h-2 rounded-full bg-emerald-500 mr-2" />
|
||||
<div className="text-sm font-medium text-slate-800">
|
||||
Active
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="w-2 h-2 rounded-full mr-2 bg-amber-500" />
|
||||
<div className="text-sm font-medium text-slate-800">
|
||||
Offline
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -183,16 +214,18 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
<div className="flex justify-between text-sm mb-2">
|
||||
<div>Spent This Month</div>
|
||||
<div className="italic">
|
||||
4673,00 Mb{' '}
|
||||
<span className="text-slate-400">/</span> 46730,00
|
||||
Mb
|
||||
{servers?.[selectedServer]?.transferSum}{' '}
|
||||
<span className="text-slate-400">/</span> 50.00
|
||||
GB
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative w-full h-2 bg-slate-300">
|
||||
<div
|
||||
className="absolute inset-0 bg-indigo-500"
|
||||
aria-hidden="true"
|
||||
style={{ width: '10%' }}
|
||||
style={{
|
||||
width: `${servers?.[selectedServer]?.trafficUsed}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,11 +249,12 @@ Endpoint = ${store.vpnServers?.[selectedServer]?.endpoint}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default VPNServers;
|
||||
|
||||
@@ -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,18 +100,13 @@ class Store {
|
||||
}
|
||||
|
||||
fetchNewAccountData() {
|
||||
getNodeInfo()
|
||||
.then((info) => {
|
||||
this.fetchNodeInfoSuccess(info);
|
||||
fetchWrapper
|
||||
.getAuth("data/private", {
|
||||
.getAuth('data/private', {
|
||||
networkIdentifier: this.nodeInfo.networkIdentifier,
|
||||
lastBlockID: this.nodeInfo.lastBlockID,
|
||||
})
|
||||
.then((res) => this.accountDataFetchChange(res))
|
||||
.catch((err) => this.throwError(err));
|
||||
})
|
||||
.catch((err) => this.throwError(err));
|
||||
}
|
||||
|
||||
fetchAccountInfo() {
|
||||
@@ -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) => ({
|
||||
|
||||
@@ -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 = '',
|
||||
|
||||
252
src/utils/countryCodes.js
Normal file
252
src/utils/countryCodes.js
Normal file
@@ -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',
|
||||
};
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user