much improved

This commit is contained in:
Jincheng Lu 2025-11-28 20:48:23 +08:00
parent 14c082d2b9
commit 13ba689069
3 changed files with 122 additions and 29 deletions

View File

@ -3,27 +3,30 @@ import { Buffer } from 'buffer';
// code from https://docs.metamask.io/wallet/how-to/sign-data/#use-personal_sign // code from https://docs.metamask.io/wallet/how-to/sign-data/#use-personal_sign
export const signMessage = async (provider: EIP1193Provider,userAccount: string) => { export const getPublicKey = async (provider: EIP1193Provider, userAccount: string) => {
const publicKey = await provider.request({
method: 'eth_getEncryptionPublicKey',
params: [userAccount],
})
return publicKey;
}
export const signMessage = async (message: string,provider: EIP1193Provider,userAccount: string) => {
try { try {
// 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 publicKey = await provider.request({
method: 'eth_getEncryptionPublicKey',
params: [userAccount],
})
// const bytes = new TextEncoder().encode(String(publicKey)); // 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' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
const msg = `0x${Buffer.from(String(publicKey), "utf8").toString("hex")}` const msg = `0x${Buffer.from(message, "utf8").toString("hex")}`
const sign = await provider.request({ const sig = await provider.request({
method: "personal_sign", method: "personal_sign",
params: [msg, userAccount], params: [msg, userAccount],
}) })
console.log("Encoded Public Key: ", msg); console.log("Encoded Public Key: ", msg);
return { publicKey, sign }; return sig;
} catch (err) { } catch (err) {
console.error(err) console.error(err)
} }

View File

@ -1,28 +1,117 @@
import { NavLink, Link } from "react-router"; import React from "react";
import { Grid } from "@mui/material"; 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';
import Toolbar from '@mui/material/Toolbar'; import Toolbar from '@mui/material/Toolbar';
import Button from '@mui/material/Button'; import Button from "@mui/material/Button";
import AccountCircleIcon from "@mui/icons-material/AccountCircle";
import LoginIcon from "@mui/icons-material/Login";
import { Typography, Menu, MenuItem, IconButton, Avatar, Tooltip } from "@mui/material";
import useAuth from "~/hooks/useAuth";
import { signMessage } from './Metamask/Connections';
export default function ButtonAppBar() { export default function ButtonAppBar() {
const { auth, setAuth } = useAuth();
const account = auth?.accounts?.[0];
const isAuthed = Boolean(account);
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleOpen = (e: React.MouseEvent<HTMLElement>) => setAnchorEl(e.currentTarget);
const handleClose = () => setAnchorEl(null);
const handleLogout = () => {
if (setAuth) {
setAuth({ providerWithInfo: undefined as any, accounts: [] } as any);
}
handleClose();
};
const register = async () => {
const sig = await signMessage("test message",auth.providerWithInfo.provider, auth.accounts[0]);
try {
const res_string = sig;
} catch (error) {
console.error('Error:', error);
}
}
return ( return (
<Box sx={{ flexGrow: 1 }}> <Box sx={{ flexGrow: 1 }}>
<AppBar position="static"> <AppBar position="static">
<Toolbar> <Toolbar sx={{ width: '100%', display: 'flex', gap: 2 }}>
<nav> {}
<Grid container spacing={2}> <Box sx={{ display: 'flex', alignItems: 'center', gap: 3 }}>
<Grid size={4}> <Typography
<NavLink to="/" end>Home</NavLink> component={NavLink as any}
</Grid> to="/"
<Grid size={4}> end
<NavLink to="/wallets">Wallets</NavLink> sx={{ color: 'inherit', textDecoration: 'none' }}
</Grid> >
<Grid size={4}> Home
<NavLink to="/about">About</NavLink> </Typography>
</Grid>
</Grid> <Typography
</nav> component={NavLink as any}
to="/about"
sx={{ color: 'inherit', textDecoration: 'none' }}
>
About
</Typography>
</Box>
{}
<Box sx={{ flexGrow: 1 }} />
{}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
{}
{!isAuthed && (
<Button
component={NavLink as any}
to="/wallets"
color="inherit"
startIcon={<LoginIcon />}
variant="text"
size="small"
sx={{ color: 'inherit' }}
>
Login
</Button>
)}
{}
{isAuthed && (
<>
<Tooltip title={account ? `Account: ${account}` : "Account"}>
<IconButton
size="small"
onClick={handleOpen}
sx={{ ml: 1, color: 'inherit' }}
aria-controls={open ? 'account-menu' : undefined}
aria-haspopup="true"
aria-expanded={open ? 'true' : undefined}
>
<Avatar sx={{ width: 32, height: 32 }} src={auth.providerWithInfo.info.icon} alt={auth.providerWithInfo.info.name}>
</Avatar>
</IconButton>
</Tooltip>
<Menu
anchorEl={anchorEl}
id="account-menu"
open={open}
onClose={handleClose}
onClick={handleClose}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
>
<MenuItem onClick={register}>Register</MenuItem>
<MenuItem onClick={handleLogout}>Logout</MenuItem>
</Menu>
</>
)}
</Box>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
</Box> </Box>

View File

@ -9,7 +9,7 @@ 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 useAuth from '~/hooks/useAuth'; import useAuth from '~/hooks/useAuth';
import { signMessage } from './Metamask/Connections'; import { getPublicKey,signMessage } from './Metamask/Connections';
import axios from 'axios'; import axios from 'axios';
interface Node { interface Node {
@ -25,9 +25,10 @@ function NodeItem({node}: {node: Node}) {
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);
const connect = async ({ip}: {ip: string}) => { const connect = async ({ip}: {ip: string}) => {
const res = await signMessage(auth.providerWithInfo.provider, auth.accounts[0]); const publicKey = await getPublicKey(auth.providerWithInfo.provider, auth.accounts[0]);
const sig = await signMessage("test message",auth.providerWithInfo.provider, auth.accounts[0]);
try { try {
const res_string = res?.publicKey + '\n' + res?.sign; const res_string = publicKey + '\n' + sig;
let response = await axios.post('http://' + ip + ":8080/connect", res_string); let response = await axios.post('http://' + ip + ":8080/connect", res_string);
console.log(response.data); // Log the response from the server console.log(response.data); // Log the response from the server
} catch (error) { } catch (error) {