pub const SIGN_HTML: &str = r#"
<!DOCTYPE html>
<html>
<head>
<title>Sign-In with Ethereum</title>
<script src="https://cdn.jsdelivr.net/npm/ethers@6.13.3/dist/ethers.umd.min.js"></script>
<style>
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
font-family: Arial, sans-serif;
}
.status {
margin-top: 20px;
padding: 10px;
border-radius: 5px;
}
.error {
background-color: #ffebee;
color: #c62828;
}
.success {
background-color: #e8f5e9;
color: #2e7d32;
}
.message-box {
margin-top: 20px;
padding: 15px;
background-color: #f5f5f5;
border-radius: 5px;
white-space: pre-wrap;
font-family: monospace;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #2196f3;
color: white;
border: none;
border-radius: 5px;
}
button:hover {
background-color: #1976d2;
}
</style>
</head>
<body>
<div class="container">
<h1>Sign Aqua Chain With Metamask</h1>
<button onclick="login()">Connect with MetaMask ...</button>
<div id="status" class="status"></div>
<div id="message" class="message-box"></div>
</div>
<script>
const ETH_CHAINID_MAP = {
'mainnet': '0x1',
'sepolia': '0xaa36a7',
'holesky': '0x4268',
};
const ETH_CHAIN_ADDRESSES_MAP = {
'mainnet': '0x45f59310ADD88E6d23ca58A0Fa7A55BEE6d2a611',
'sepolia': '0x45f59310ADD88E6d23ca58A0Fa7A55BEE6d2a611',
'holesky': '0x45f59310ADD88E6d23ca58A0Fa7A55BEE6d2a611',
};
function showStatus(message, isError = false) {
const statusDiv = document.getElementById('status');
statusDiv.className = `status ${isError ? 'error' : 'success'}`;
statusDiv.textContent = message;
}
function showMessage(message) {
const messageDiv = document.getElementById('message');
messageDiv.textContent = message;
}
async function getSignMessage() {
const response = await fetch('/message');
if (!response.ok) {
throw new Error('Failed to get sign message');
}
return response.json();
}
async function getSignNetwork() {
const response = await fetch('/network');
if (!response.ok) {
throw new Error('Failed to get sign message');
}
return response.json();
}
async function switchNetwork(chainId) {
// const chainId = '0x89'; // Example: Polygon Mainnet chain ID
if (typeof window.ethereum !== 'undefined') {
try {
// Check if the network is already set
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId }],
});
console.log("Network switched successfully");
} catch (error) {
// If the network is not added, request MetaMask to add it
console.log("Network switched error", error);
}
} else {
console.error("MetaMask is not installed.");
}
}
async function login() {
if (typeof window.ethereum === 'undefined') {
showStatus('Please install MetaMask!', true);
return;
}
try {
showStatus('Requesting account access...');
// Request account access
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts'
});
const account = accounts[0];
if (!account) {
alert("Please connect your wallet to continue");
return;
}
showStatus('Account connected: ' + account);
// Get message to sign from server
const { message } = await getSignMessage();
showMessage(message);
console.log("message ", message)
// Create a instance
const provider = new ethers.BrowserProvider(window.ethereum);
// const networkId = "sepolia";
// const currentChainId = "0xaa36a7"
let network = "sepolia";
try {
const data = await getSignNetwork();
console.log("Response network "+data.network +" from network ",data)
// if (data.network != network) {
network = data.network;
let chainId = ETH_CHAINID_MAP[network];
console.log("Chain id "+ chainId);
await switchNetwork(chainId);
// }
} catch (e) {
console.log("Error fetching network ", e)
}
const signer = await provider.getSigner();
showStatus('Please sign the message in MetaMask...');
// Hash the message (optional but recommended)
const messageHash = ethers.hashMessage(message);
// Sign the message using ethers.js
const signature = await signer.signMessage(message);
const signerAddress = await signer.getAddress()
console.log("Signature: ", signature)
if (!signature) {
alert("Signature not found ...");
return;
}
const publicKey = ethers.SigningKey.recoverPublicKey(
messageHash,
signature,
)
showStatus('Message signed, sending to server...');
const walletAddress = ethers.getAddress(account)
console.log("Signature:", signature);
console.log("Public Key:", publicKey);
console.log("account :", account);
console.log("Wallet Address:", walletAddress);
// Send to server
const response = await fetch('/auth', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
signature: signature,
public_key: publicKey,
wallet_address: walletAddress
})
});
if (!response.ok) {
throw new Error(`Server responded with status: ${response.status}`);
}
const result = await response.json();
showStatus('Signing successful!, closing the tab in 2 seconds');
setTimeout(() => {
window.close()
}, 200);
} catch (err) {
console.error(err);
console.log("eRROR " + err.message);
showStatus("Error =>" + err.message);
// showStatus('Failed to authenticate: ' + err.message, true);
}
}
(async () => {
// Get message to sign from server
const { message } = await getSignMessage();
showMessage(message);
await login();
})()
</script>
</body>
</html>
"#;