successfully generates the wireguard config file
This commit is contained in:
parent
cf3d999a2e
commit
c4a50e8b3b
@ -1,8 +1,22 @@
|
|||||||
import { Box, Card, CardContent, Typography, Link, Button, Avatar, Stack } from "@mui/material";
|
import { Box, Card, CardContent, Typography, Link, Button, Avatar, Stack } from "@mui/material";
|
||||||
import GitHubIcon from "@mui/icons-material/GitHub";
|
import GitHubIcon from "@mui/icons-material/GitHub";
|
||||||
|
import GetAppIcon from "@mui/icons-material/GetApp";
|
||||||
|
|
||||||
|
const WIREGUARD_COLOR = "#88171A";
|
||||||
|
|
||||||
|
function WireGuardLogo({ size = 40 }: { size?: number }) {
|
||||||
|
return (
|
||||||
|
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden>
|
||||||
|
<circle cx="12" cy="12" r="12" fill={WIREGUARD_COLOR} />
|
||||||
|
<path d="M6 12c0-3.314 2.686-6 6-6s6 2.686 6 6-2.686 6-6 6S6 15.314 6 12z" fill="#fff" opacity="0.15" />
|
||||||
|
<path d="M8.5 11.5c1-2 3-3 5-3s4 1 5 3" stroke="#fff" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" />
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function About() {
|
export default function About() {
|
||||||
const repo = "https://github.com/cochrane2063/MSBD5017-Depin-WebClient";
|
const repo = "https://github.com/cochrane2063/MSBD5017-Depin-WebClient";
|
||||||
|
const wireguard = "https://www.wireguard.com/install/";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
|
<Box sx={{ display: "flex", justifyContent: "center", p: 3 }}>
|
||||||
@ -32,6 +46,59 @@ export default function About() {
|
|||||||
</Stack>
|
</Stack>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
<Card
|
||||||
|
sx={{
|
||||||
|
width: 420,
|
||||||
|
maxWidth: "100%",
|
||||||
|
borderLeft: `6px solid ${WIREGUARD_COLOR}`,
|
||||||
|
background: "linear-gradient(180deg, rgba(122,193,67,0.04), transparent 60%)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CardContent>
|
||||||
|
<Stack direction="row" spacing={2} alignItems="center" sx={{ mb: 1 }}>
|
||||||
|
<Avatar sx={{ bgcolor: "transparent" }}>
|
||||||
|
<WireGuardLogo />
|
||||||
|
</Avatar>
|
||||||
|
<Typography variant="h5" sx={{ color: WIREGUARD_COLOR, fontWeight: 700 }}>
|
||||||
|
Download Wireguard Client
|
||||||
|
</Typography>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Typography variant="body1" color="text.secondary" paragraph>
|
||||||
|
Wireguard client for the MSBD5017 Depin project.
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Typography variant="body2" color="text.secondary" paragraph>
|
||||||
|
This project uses the Wireguard VPN protocol. You can download the Wireguard client from the official website.
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Stack direction="row" spacing={2} alignItems="center">
|
||||||
|
<Link href={wireguard} target="_blank" rel="noopener noreferrer" underline="none">
|
||||||
|
<Button
|
||||||
|
startIcon={<GetAppIcon />}
|
||||||
|
variant="contained"
|
||||||
|
sx={{
|
||||||
|
bgcolor: WIREGUARD_COLOR,
|
||||||
|
"&:hover": { bgcolor: "#65a836" },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Download WireGuard
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outlined"
|
||||||
|
href="https://www.wireguard.com/quickstart/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
sx={{ borderColor: WIREGUARD_COLOR, color: WIREGUARD_COLOR }}
|
||||||
|
>
|
||||||
|
Quickstart Guide
|
||||||
|
</Button>
|
||||||
|
</Stack>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
420
app/Components/Contracts/CLRToken/CLRToken.json
Normal file
420
app/Components/Contracts/CLRToken/CLRToken.json
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "constructor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "allowance",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "needed",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ERC20InsufficientAllowance",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "sender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "balance",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "needed",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ERC20InsufficientBalance",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "approver",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ERC20InvalidApprover",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "receiver",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ERC20InvalidReceiver",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "sender",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ERC20InvalidSender",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "ERC20InvalidSpender",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "OwnableInvalidOwner",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "account",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "OwnableUnauthorizedAccount",
|
||||||
|
"type": "error"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Approval",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "previousOwner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "newOwner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "OwnershipTransferred",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"anonymous": false,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": true,
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"indexed": false,
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Transfer",
|
||||||
|
"type": "event"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "owner",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "allowance",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "spender",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "approve",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "account",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "balanceOf",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "burn",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "decimals",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint8",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint8"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "_to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_amount",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "mint",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "name",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "string",
|
||||||
|
"name": "",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "owner",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "renounceOwnership",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "symbol",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "string",
|
||||||
|
"name": "",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "totalSupply",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transfer",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "from",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "to",
|
||||||
|
"type": "address"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "value",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferFrom",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "bool",
|
||||||
|
"name": "",
|
||||||
|
"type": "bool"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "newOwner",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "transferOwnership",
|
||||||
|
"outputs": [],
|
||||||
|
"stateMutability": "nonpayable",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
]
|
||||||
@ -615,6 +615,25 @@
|
|||||||
"stateMutability": "nonpayable",
|
"stateMutability": "nonpayable",
|
||||||
"type": "function"
|
"type": "function"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "activeChannelIds",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address",
|
||||||
|
"name": "",
|
||||||
|
"type": "address"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
@ -740,6 +759,48 @@
|
|||||||
"stateMutability": "view",
|
"stateMutability": "view",
|
||||||
"type": "function"
|
"type": "function"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"inputs": [],
|
||||||
|
"name": "getActivePaymentChannels",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address[]",
|
||||||
|
"name": "",
|
||||||
|
"type": "address[]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_offset",
|
||||||
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "_limit",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "getActivePaymentChannelsPaginated",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "address[]",
|
||||||
|
"name": "channels",
|
||||||
|
"type": "address[]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "total",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stateMutability": "view",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"inputs": [
|
"inputs": [
|
||||||
{
|
{
|
||||||
@ -1,28 +1,87 @@
|
|||||||
import { Web3 } from 'web3';
|
import { Web3 } from 'web3';
|
||||||
import clearNetJson from './ClearNet.json';
|
import type { Node, NodeInfo, PaymentChannelInfo } from '../Util';
|
||||||
|
import clearNetJson from './ClearNet/ClearNet.json';
|
||||||
|
import clrTokenJson from './CLRTOKEN/CLRToken.json';
|
||||||
|
|
||||||
const clearNetABI = (clearNetJson as any).abi ?? clearNetJson;
|
const clearNetABI = (clearNetJson as any).abi ?? clearNetJson;
|
||||||
const clearNetAddress = "0xf04cbb756045b276ea962ea98d938a0ed8101f51";
|
const clrTokenABI = (clrTokenJson as any).abi ?? clrTokenJson;
|
||||||
|
const clearNetAddress = "0xb6f537b38b82d08ff3ed796754d9d85b5cfe9cb5";
|
||||||
|
const clrTokenAddress = "0xf1664c17887767c8f58695846babb349ca61d2e9";
|
||||||
|
const DEFAULT_MIN_STAKE = BigInt(10000) * BigInt(1e18); // 10000 CLR
|
||||||
|
|
||||||
export const getActiveNodes = async (provider: any) => {
|
|
||||||
|
export const getActiveNodes = async (provider: any): Promise<Node[]> => {
|
||||||
|
if (!provider) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
const web3 = new Web3(provider);
|
const web3 = new Web3(provider);
|
||||||
const contract = new web3.eth.Contract(clearNetABI, clearNetAddress);
|
const clearnet_contract = new web3.eth.Contract(clearNetABI, clearNetAddress);
|
||||||
const activeNodes = await contract.methods.getActiveNodes().call();
|
const activeNodes: string[] = await clearnet_contract.methods.getActiveNodes().call();
|
||||||
return activeNodes;
|
const nodes: Node[] = await Promise.all(activeNodes.map(async (node: string) => {
|
||||||
|
const nodeInfo: NodeInfo = await clearnet_contract.methods.getNodeInfo(node).call();
|
||||||
|
return {
|
||||||
|
ip: nodeInfo.ipAddress,
|
||||||
|
port: Number(nodeInfo.port),
|
||||||
|
traffic: 0,
|
||||||
|
price: Number(nodeInfo.pricePerMinute) / 1e18,
|
||||||
|
rating: Number(nodeInfo.reputationScore) / 1000,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
console.log("Fetched nodes:", nodes);
|
||||||
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function registerNode(provider: any,account: string) {
|
export async function approveCLRTokenSpending(provider: any,account: string) {
|
||||||
const web3 = new Web3(provider);
|
const web3 = new Web3(provider);
|
||||||
const contract = new web3.eth.Contract(clearNetABI, clearNetAddress);
|
const clr_token_contract = new web3.eth.Contract(clrTokenABI, clrTokenAddress);
|
||||||
const gasPrice = await web3.eth.getGasPrice();
|
const gasPrice = await web3.eth.getGasPrice();
|
||||||
const gasLimit = 300000;
|
const gasLimit = 300000;
|
||||||
const tx = await contract.methods.registerNode("57.158.82.48", 51820, 1000000000000000000n).send({
|
const tx = await clr_token_contract.methods.approve(clearNetAddress, DEFAULT_MIN_STAKE).send({
|
||||||
|
from: account,
|
||||||
|
gas: String(gasLimit),
|
||||||
|
gasPrice: String(gasPrice),
|
||||||
|
});
|
||||||
|
console.log(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function openPaymentChannel(provider: any,account: string,amount: BigInt) {
|
||||||
|
const web3 = new Web3(provider);
|
||||||
|
const clearnet_contract = new web3.eth.Contract(clearNetABI, clearNetAddress);
|
||||||
|
const gasPrice = await web3.eth.getGasPrice();
|
||||||
|
const gasLimit = 300000;
|
||||||
|
const tx = await clearnet_contract.methods.openPaymentChannel(amount).send({
|
||||||
from: account,
|
from: account,
|
||||||
gas: String(gasLimit),
|
gas: String(gasLimit),
|
||||||
gasPrice: String(gasPrice),
|
gasPrice: String(gasPrice),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(tx);
|
console.log(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function closePaymentChannel(provider: any,account: string) {
|
||||||
|
const web3 = new Web3(provider);
|
||||||
|
const clearnet_contract = new web3.eth.Contract(clearNetABI, clearNetAddress);
|
||||||
|
const gasPrice = await web3.eth.getGasPrice();
|
||||||
|
const gasLimit = 300000;
|
||||||
|
const tx = await clearnet_contract.methods.closePaymentChannel().send({
|
||||||
|
from: account,
|
||||||
|
gas: String(gasLimit),
|
||||||
|
gasPrice: String(gasPrice),
|
||||||
|
});
|
||||||
|
console.log(tx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getPaymentChannelInfo(provider: any,account: string) : Promise<PaymentChannelInfo> {
|
||||||
|
if (!provider) {
|
||||||
|
return { balance: BigInt(0), nonce: BigInt(0), isActive: false};
|
||||||
|
}
|
||||||
|
const web3 = new Web3(provider);
|
||||||
|
const clearnet_contract = new web3.eth.Contract(clearNetABI, clearNetAddress);
|
||||||
|
const channelInfo: PaymentChannelInfo = await clearnet_contract.methods.getPaymentChannelInfo(account).call();
|
||||||
|
return {
|
||||||
|
balance: channelInfo.balance,
|
||||||
|
nonce: channelInfo.nonce,
|
||||||
|
isActive: channelInfo.isActive,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@ -16,8 +16,6 @@ export const signMessage = async (message: string,provider: EIP1193Provider,user
|
|||||||
// For historical reasons, you must submit the message to sign in hex-encoded UTF-8.
|
// For historical reasons, you must submit the message to sign in hex-encoded UTF-8.
|
||||||
// This uses a Node.js-style buffer shim in the browser.
|
// This uses a Node.js-style buffer shim in the browser.
|
||||||
|
|
||||||
// const bytes = new TextEncoder().encode(String(publicKey));
|
|
||||||
// const msg = '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
||||||
const msg = `0x${Buffer.from(message, "utf8").toString("hex")}`
|
const msg = `0x${Buffer.from(message, "utf8").toString("hex")}`
|
||||||
const sig = await provider.request({
|
const sig = await provider.request({
|
||||||
method: "personal_sign",
|
method: "personal_sign",
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// ...existing code...
|
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useSyncProviders } from "./useSyncProviders";
|
import { useSyncProviders } from "./useSyncProviders";
|
||||||
import useAuth from "~/hooks/useAuth";
|
import useAuth from "~/hooks/useAuth";
|
||||||
@ -122,5 +121,4 @@ export const DiscoverWalletProviders: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DiscoverWalletProviders;
|
export default DiscoverWalletProviders;
|
||||||
// ...existing code...
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import { NavLink } from "react-router";
|
import { NavLink } from "react-router";
|
||||||
import AppBar from '@mui/material/AppBar';
|
import AppBar from '@mui/material/AppBar';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
@ -7,13 +7,16 @@ import Button from "@mui/material/Button";
|
|||||||
import LoginIcon from "@mui/icons-material/Login";
|
import LoginIcon from "@mui/icons-material/Login";
|
||||||
import { Typography, Menu, MenuItem, IconButton, Avatar, Tooltip } from "@mui/material";
|
import { Typography, Menu, MenuItem, IconButton, Avatar, Tooltip } from "@mui/material";
|
||||||
import useAuth from "~/hooks/useAuth";
|
import useAuth from "~/hooks/useAuth";
|
||||||
import { signMessage } from './Metamask/Connections';
|
import type { PaymentChannelInfo } from './Util';
|
||||||
|
import { approveCLRTokenSpending, openPaymentChannel, closePaymentChannel, getPaymentChannelInfo } from './Contracts/Connections';
|
||||||
|
|
||||||
export default function ButtonAppBar() {
|
export default function ButtonAppBar() {
|
||||||
const { auth, setAuth } = useAuth();
|
const { auth, setAuth } = useAuth();
|
||||||
const account = auth?.accounts?.[0];
|
const account = auth?.accounts?.[0];
|
||||||
const isAuthed = Boolean(account);
|
const isAuthed = Boolean(account);
|
||||||
|
|
||||||
|
const [paymentChannelInfo, setPaymentChannelInfo] = React.useState<PaymentChannelInfo | null>(null);
|
||||||
|
const [registered, setRegistered] = React.useState<boolean>(false);
|
||||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
const handleOpen = (e: React.MouseEvent<HTMLElement>) => setAnchorEl(e.currentTarget);
|
const handleOpen = (e: React.MouseEvent<HTMLElement>) => setAnchorEl(e.currentTarget);
|
||||||
@ -27,14 +30,28 @@ export default function ButtonAppBar() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const register = async () => {
|
const register = async () => {
|
||||||
const sig = await signMessage("H8zfXnSclIQ/wLy7GSt7GNqa1utAi4Uvr7Dg3p9vdHQ=",auth.providerWithInfo.provider, auth.accounts[0]);
|
const clr_deposit_amount = BigInt(10000) * BigInt(1e18); // 10000 CLR
|
||||||
try {
|
await approveCLRTokenSpending(auth.providerWithInfo.provider, account!);
|
||||||
const res_string = sig;
|
await openPaymentChannel(auth.providerWithInfo.provider, account!, clr_deposit_amount);
|
||||||
} catch (error) {
|
setRegistered(true);
|
||||||
console.error('Error:', error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deRegister = async () => {
|
||||||
|
await closePaymentChannel(auth.providerWithInfo.provider, account!);
|
||||||
|
setRegistered(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getPaymentChannelInfo(auth.providerWithInfo ? auth.providerWithInfo.provider : undefined, account!).then((info) => {
|
||||||
|
setPaymentChannelInfo(info);
|
||||||
|
if(registered !== info.isActive) {
|
||||||
|
setRegistered(info.isActive);
|
||||||
|
}
|
||||||
|
console.log("Payment Channel Info:", info);
|
||||||
|
});
|
||||||
|
}, [account, auth.providerWithInfo?.provider,registered]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ flexGrow: 1 }}>
|
<Box sx={{ flexGrow: 1 }}>
|
||||||
<AppBar position="static">
|
<AppBar position="static">
|
||||||
@ -78,8 +95,7 @@ export default function ButtonAppBar() {
|
|||||||
Login
|
Login
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{}
|
|
||||||
{isAuthed && (
|
{isAuthed && (
|
||||||
<>
|
<>
|
||||||
<Tooltip title={account ? `Account: ${account}` : "Account"}>
|
<Tooltip title={account ? `Account: ${account}` : "Account"}>
|
||||||
@ -105,7 +121,7 @@ export default function ButtonAppBar() {
|
|||||||
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
|
||||||
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
|
||||||
>
|
>
|
||||||
<MenuItem onClick={register}>Register</MenuItem>
|
{(paymentChannelInfo && paymentChannelInfo.isActive) ? (<MenuItem onClick={deRegister}>DeRegister</MenuItem>) : (<MenuItem onClick={register}>Register</MenuItem>)}
|
||||||
<MenuItem onClick={handleLogout}>Logout</MenuItem>
|
<MenuItem onClick={handleLogout}>Logout</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -2,27 +2,41 @@ import * as React from 'react';
|
|||||||
import ButtonGroup from '@mui/material/ButtonGroup';
|
import ButtonGroup from '@mui/material/ButtonGroup';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import Avatar from '@mui/material/Avatar';
|
import Avatar from '@mui/material/Avatar';
|
||||||
import { Grid, Card, CardContent, CardActions, Typography, Box, Chip, Dialog, DialogTitle, DialogContent, DialogActions, TextField } from "@mui/material";
|
import {
|
||||||
|
Grid,
|
||||||
|
Card,
|
||||||
|
CardContent,
|
||||||
|
CardActions,
|
||||||
|
Typography,
|
||||||
|
Box,
|
||||||
|
Chip,
|
||||||
|
Dialog,
|
||||||
|
DialogTitle,
|
||||||
|
DialogContent,
|
||||||
|
DialogActions,
|
||||||
|
IconButton,
|
||||||
|
Tooltip,
|
||||||
|
CircularProgress,
|
||||||
|
} from "@mui/material";
|
||||||
import ServerIcon from '@mui/icons-material/Dns';
|
import ServerIcon from '@mui/icons-material/Dns';
|
||||||
import SignalCellularAltIcon from '@mui/icons-material/SignalCellularAlt';
|
import SignalCellularAltIcon from '@mui/icons-material/SignalCellularAlt';
|
||||||
import AttachMoneyIcon from '@mui/icons-material/AttachMoney';
|
import AttachMoneyIcon from '@mui/icons-material/AttachMoney';
|
||||||
import StarIcon from '@mui/icons-material/Star';
|
import StarIcon from '@mui/icons-material/Star';
|
||||||
import Rating from '@mui/material/Rating';
|
import Rating from '@mui/material/Rating';
|
||||||
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
import useAuth from '~/hooks/useAuth';
|
import useAuth from '~/hooks/useAuth';
|
||||||
|
import type { AccountInfo } from '~/context/AuthProvider';
|
||||||
import { signMessage } from './Metamask/Connections';
|
import { signMessage } from './Metamask/Connections';
|
||||||
import { downloadWireguardConfig } from './WireguardConfig';
|
import { generateWireguardKeyPair, downloadWireguardConfig } from './WireguardConfig';
|
||||||
|
import type { Node } from './Util';
|
||||||
|
import { getActiveNodes } from './Contracts/Connections';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
interface Node {
|
|
||||||
ip: string;
|
|
||||||
traffic: number;
|
|
||||||
price : number;
|
|
||||||
rating : number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function NodeItem({node}: {node: Node}) {
|
|
||||||
|
function NodeItem({node, auth}: {node: Node, auth: AccountInfo}) {
|
||||||
const port = 8080;
|
const port = 8080;
|
||||||
const { auth } = useAuth();
|
|
||||||
const [ratingOpen, setRatingOpen] = React.useState(false);
|
const [ratingOpen, setRatingOpen] = React.useState(false);
|
||||||
const [ratingValue, setRatingValue] = React.useState<number | null>(null);
|
const [ratingValue, setRatingValue] = React.useState<number | null>(null);
|
||||||
const [submittingRating, setSubmittingRating] = React.useState(false);
|
const [submittingRating, setSubmittingRating] = React.useState(false);
|
||||||
@ -31,13 +45,16 @@ function NodeItem({node}: {node: Node}) {
|
|||||||
// const publicKey = await getPublicKey(auth.providerWithInfo.provider, auth.accounts[0]);
|
// const publicKey = await getPublicKey(auth.providerWithInfo.provider, auth.accounts[0]);
|
||||||
try {
|
try {
|
||||||
const iv = await axios.get(getUrl() + "/connect");
|
const iv = await axios.get(getUrl() + "/connect");
|
||||||
console.log(iv.data);
|
const { privatekey: clientPrivateKey, publicKey: clientPublicKey } = generateWireguardKeyPair();
|
||||||
|
|
||||||
const sig = await signMessage(iv.data + "H8zfXnSclIQ/wLy7GSt7GNqa1utAi4Uvr7Dg3p9vdHQ=",auth.providerWithInfo.provider, auth.accounts[0]);
|
const sig = await signMessage(iv.data + clientPublicKey,auth.providerWithInfo.provider, auth.accounts[0]);
|
||||||
const res_string = iv.data + '\n' + "H8zfXnSclIQ/wLy7GSt7GNqa1utAi4Uvr7Dg3p9vdHQ=" + '\n' + sig;
|
const res_string = iv.data + '\n' + clientPublicKey + '\n' + sig;
|
||||||
let response = await axios.post(getUrl() + "/connect", res_string);
|
let response = await axios.post(getUrl() + "/connect", res_string);
|
||||||
|
const clientCIDR = response.data.WireguardClientCIDR;
|
||||||
|
const serverPublicKey = response.data.WireguardServerPublicKey;
|
||||||
|
const dns = response.data.WireguardDNS;
|
||||||
console.log(response.data);
|
console.log(response.data);
|
||||||
downloadWireguardConfig("", "", "", "", node.ip, "51820", "0.0.0.0/0");
|
downloadWireguardConfig(clientPrivateKey, serverPublicKey, clientCIDR, dns, node.ip, String(node.port), "0.0.0.0/0");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error:', error);
|
console.error('Error:', error);
|
||||||
}
|
}
|
||||||
@ -180,33 +197,69 @@ function NodeItem({node}: {node: Node}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function FolderList() {
|
export default function FolderList() {
|
||||||
const [nodes, setNodes] = React.useState<Node[]>([
|
const { auth } = useAuth();
|
||||||
{ ip: "57.158.82.48", traffic: 5, price: 10, rating: 3 },
|
const [nodes, setNodes] = React.useState<Node[]>([]);
|
||||||
{ ip: "8.210.33.199", traffic: 3, price: 15, rating: 4 },
|
const [loading, setLoading] = React.useState(false);
|
||||||
{ ip: "45.77.12.5", traffic: 7, price: 20, rating: 5 },
|
const fetchNodes = React.useCallback(async () => {
|
||||||
{ ip: "203.120.45.78", traffic: 2, price: 8, rating: 2 },
|
setLoading(true);
|
||||||
{ ip: "91.189.88.25", traffic: 6, price: 12, rating: 4 },
|
try {
|
||||||
{ ip: "132.148.9.201", traffic: 9, price: 18, rating: 5 },
|
const provider = auth?.providerWithInfo?.provider;
|
||||||
{ ip: "60.12.180.99", traffic: 4, price: 14, rating: 3 },
|
const fetchedNodes = await getActiveNodes(provider);
|
||||||
{ ip: "199.59.243.100", traffic: 1, price: 6, rating: 1 },
|
setNodes(fetchedNodes);
|
||||||
{ ip: "34.216.77.3", traffic: 8, price: 22, rating: 5 },
|
} catch (err) {
|
||||||
{ ip: "185.199.108.153", traffic: 5, price: 11, rating: 4 },
|
console.error("Failed to fetch nodes", err);
|
||||||
{ ip: "13.107.21.200", traffic: 7, price: 16, rating: 4 },
|
} finally {
|
||||||
{ ip: "216.58.214.14", traffic: 3, price: 9, rating: 2 },
|
setLoading(false);
|
||||||
{ ip: "104.21.44.33", traffic: 10, price: 25, rating: 5 },
|
}
|
||||||
{ ip: "47.90.12.201", traffic: 2, price: 7, rating: 1 },
|
}, [auth]);
|
||||||
{ ip: "23.45.67.89", traffic: 6, price: 13, rating: 3 },
|
|
||||||
{ ip: "192.0.2.123", traffic: 4, price: 17, rating: 4 },
|
useEffect(() => {
|
||||||
]);
|
fetchNodes();
|
||||||
|
}, [fetchNodes]);
|
||||||
|
// const [nodes, setNodes] = React.useState<Node[]>([
|
||||||
|
// { ip: "57.158.82.48", traffic: 5, price: 10, rating: 3 },
|
||||||
|
// { ip: "8.210.33.199", traffic: 3, price: 15, rating: 4 },
|
||||||
|
// { ip: "45.77.12.5", traffic: 7, price: 20, rating: 5 },
|
||||||
|
// { ip: "203.120.45.78", traffic: 2, price: 8, rating: 2 },
|
||||||
|
// { ip: "91.189.88.25", traffic: 6, price: 12, rating: 4 },
|
||||||
|
// { ip: "132.148.9.201", traffic: 9, price: 18, rating: 5 },
|
||||||
|
// { ip: "60.12.180.99", traffic: 4, price: 14, rating: 3 },
|
||||||
|
// { ip: "199.59.243.100", traffic: 1, price: 6, rating: 1 },
|
||||||
|
// { ip: "34.216.77.3", traffic: 8, price: 22, rating: 5 },
|
||||||
|
// { ip: "185.199.108.153", traffic: 5, price: 11, rating: 4 },
|
||||||
|
// { ip: "13.107.21.200", traffic: 7, price: 16, rating: 4 },
|
||||||
|
// { ip: "216.58.214.14", traffic: 3, price: 9, rating: 2 },
|
||||||
|
// { ip: "104.21.44.33", traffic: 10, price: 25, rating: 5 },
|
||||||
|
// { ip: "47.90.12.201", traffic: 2, price: 7, rating: 1 },
|
||||||
|
// { ip: "23.45.67.89", traffic: 6, price: 13, rating: 3 },
|
||||||
|
// { ip: "192.0.2.123", traffic: 4, price: 17, rating: 4 },
|
||||||
|
// ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ flexGrow: 1, p: 3 }}>
|
<Box sx={{ flexGrow: 1, p: 3 }}>
|
||||||
<Typography variant="h4" gutterBottom component="div" sx={{ mb: 4, fontWeight: 'bold' }}>
|
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', mb: 3 }}>
|
||||||
Available Servers
|
<Typography variant="h4" component="div" sx={{ fontWeight: 'bold' }}>
|
||||||
</Typography>
|
Available Servers
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Box>
|
||||||
|
<Tooltip title="Refresh servers">
|
||||||
|
<span>
|
||||||
|
<IconButton
|
||||||
|
onClick={fetchNodes}
|
||||||
|
disabled={loading || auth?.providerWithInfo === undefined}
|
||||||
|
color="primary"
|
||||||
|
aria-label="refresh servers"
|
||||||
|
>
|
||||||
|
{loading ? <CircularProgress size={20} /> : <RefreshIcon />}
|
||||||
|
</IconButton>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
<Grid container spacing={3}>
|
<Grid container spacing={3}>
|
||||||
{nodes.map((node, index) => (
|
{nodes.map((node, index) => (
|
||||||
<NodeItem key={index} node={node} />
|
<NodeItem key={index} node={node} auth={auth}/>
|
||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
23
app/Components/Util.tsx
Normal file
23
app/Components/Util.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
export interface Node {
|
||||||
|
ip: string;
|
||||||
|
port: number;
|
||||||
|
traffic: number;
|
||||||
|
price : number;
|
||||||
|
rating : number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NodeInfo {
|
||||||
|
ipAddress: string;
|
||||||
|
port: number;
|
||||||
|
pricePerMinute : BigInt;
|
||||||
|
reputationScore : BigInt;
|
||||||
|
totalMinutesServed : BigInt;
|
||||||
|
totalEarnings : BigInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PaymentChannelInfo {
|
||||||
|
balance: BigInt;
|
||||||
|
nonce: BigInt;
|
||||||
|
isActive: boolean;
|
||||||
|
}
|
||||||
@ -1,13 +1,57 @@
|
|||||||
|
// import { utils } from 'noble-ed25519';
|
||||||
|
import nacl from "tweetnacl";
|
||||||
|
|
||||||
|
function bytesToBase64(bytes: Uint8Array) {
|
||||||
|
let binary = '';
|
||||||
|
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
||||||
|
return btoa(binary);
|
||||||
|
}
|
||||||
|
|
||||||
|
function base64ToBytes(base64: string): Uint8Array {
|
||||||
|
// support URL-safe base64
|
||||||
|
base64 = base64.replace(/-/g, "+").replace(/_/g, "/");
|
||||||
|
// pad to multiple of 4
|
||||||
|
const pad = base64.length % 4;
|
||||||
|
if (pad) base64 += "=".repeat(4 - pad);
|
||||||
|
|
||||||
|
const binary = atob(base64);
|
||||||
|
const len = binary.length;
|
||||||
|
const bytes = new Uint8Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = binary.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateWireGuardPrivateKey = () => {
|
||||||
|
// const privateKeyBytes = utils.randomPrivateKey();
|
||||||
|
// const privateKeyBase64 = bytesToBase64(privateKeyBytes);
|
||||||
|
const privateKey = nacl.randomBytes(32);
|
||||||
|
|
||||||
|
return bytesToBase64(privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getWireguardPublicKey = (privateKey: string) => {
|
||||||
|
const privateKeyBytes = base64ToBytes(privateKey);
|
||||||
|
const publicKey = nacl.scalarMult.base(privateKeyBytes);
|
||||||
|
return bytesToBase64(publicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const generateWireguardKeyPair = () => {
|
||||||
|
const privatekey = generateWireGuardPrivateKey();
|
||||||
|
const publicKey = getWireguardPublicKey(privatekey);
|
||||||
|
return { privatekey, publicKey };
|
||||||
|
}
|
||||||
|
|
||||||
|
export const downloadWireguardConfig = async (clientPrivateKey: string, serverPubcliKey: string ,localCIDR: string, dns: string, peerIp: string, peerPort: string, allowedIPs: string) => {
|
||||||
|
|
||||||
export const downloadWireguardConfig = (privateKey: string, publicKey: string, localCIDR: string, dns: string, peerIp: string, peerPort: string, allowedIPs: string) => {
|
|
||||||
const content = `[Interface]`+'\n'+
|
const content = `[Interface]`+'\n'+
|
||||||
`PrivateKey = ${privateKey}`+'\n'+
|
`PrivateKey = ${clientPrivateKey}`+'\n'+
|
||||||
`Address = ${localCIDR}`+'\n'+
|
`Address = ${localCIDR}`+'\n'+
|
||||||
`DNS = ${dns}`+'\n'+
|
`DNS = ${dns}`+'\n'+
|
||||||
'\n'+
|
'\n'+
|
||||||
`[Peer]`+'\n'+
|
`[Peer]`+'\n'+
|
||||||
`PublicKey = ${publicKey}`+'\n'+
|
`PublicKey = ${serverPubcliKey}`+'\n'+
|
||||||
`AllowedIPs = ${allowedIPs}`+'\n'+
|
`AllowedIPs = ${allowedIPs}`+'\n'+
|
||||||
`Endpoint = ${peerIp}:${peerPort}`;
|
`Endpoint = ${peerIp}:${peerPort}`;
|
||||||
|
|
||||||
|
|||||||
15
package-lock.json
generated
15
package-lock.json
generated
@ -14,9 +14,11 @@
|
|||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"isbot": "^5.1.31",
|
"isbot": "^5.1.31",
|
||||||
|
"noble-ed25519": "^1.2.6",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
"react-router": "^7.9.2",
|
"react-router": "^7.9.2",
|
||||||
|
"tweetnacl": "^1.0.3",
|
||||||
"web3": "^4.16.0"
|
"web3": "^4.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -4513,6 +4515,13 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/noble-ed25519": {
|
||||||
|
"version": "1.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/noble-ed25519/-/noble-ed25519-1.2.6.tgz",
|
||||||
|
"integrity": "sha512-zfnWqg9FVMp8CnzUpAjbt1nDXpDjCvxYiCXdnW1mY8zQHw/6twUlkFm14VPdojVzc0kcd+i9zT79+26GcNbsuQ==",
|
||||||
|
"deprecated": "Switch to namespaced @noble/ed25519 for security and feature updates",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
@ -5676,6 +5685,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tweetnacl": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
|
||||||
|
"license": "Unlicense"
|
||||||
|
},
|
||||||
"node_modules/type-is": {
|
"node_modules/type-is": {
|
||||||
"version": "1.6.18",
|
"version": "1.6.18",
|
||||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||||
|
|||||||
@ -18,9 +18,11 @@
|
|||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"isbot": "^5.1.31",
|
"isbot": "^5.1.31",
|
||||||
|
"noble-ed25519": "^1.2.6",
|
||||||
"react": "^19.1.1",
|
"react": "^19.1.1",
|
||||||
"react-dom": "^19.1.1",
|
"react-dom": "^19.1.1",
|
||||||
"react-router": "^7.9.2",
|
"react-router": "^7.9.2",
|
||||||
|
"tweetnacl": "^1.0.3",
|
||||||
"web3": "^4.16.0"
|
"web3": "^4.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user