<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>COTI Private Messaging</title>
<script src="https://cdn.jsdelivr.net/npm/ethers@5.7.2/dist/ethers.umd.min.js"></script>
<style>
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f4f7f6; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; }
.container { background-color: #fff; padding: 2rem; border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.1); width: 100%; max-width: 500px; border-top: 5px solid #007bff; }
h1 { color: #333; font-size: 1.5rem; margin-bottom: 0.5rem; text-align: center; }
p.subtitle { text-align: center; color: #888; font-size: 0.85rem; margin-bottom: 1.5rem; }
.form-group { margin-bottom: 1.25rem; }
label { display: block; margin-bottom: 0.5rem; color: #555; font-weight: 600; }
input, textarea { width: 100%; padding: 0.85rem; border: 1px solid #e1e1e1; border-radius: 6px; box-sizing: border-box; font-size: 0.95rem; transition: border-color 0.2s; }
input:focus, textarea:focus { outline: none; border-color: #007bff; }
textarea { height: 120px; resize: none; }
button { width: 100%; padding: 0.9rem; border: none; border-radius: 6px; background-color: #007bff; color: white; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.2s; }
button:hover { background-color: #0056b3; transform: translateY(-1px); }
button:active { transform: translateY(0); }
button:disabled { background-color: #cbd5e0; cursor: not-allowed; }
#walletBtn { background-color: #2d3748; margin-bottom: 1rem; }
#walletBtn.connected { background-color: #48bb78; }
#status { margin-top: 1.5rem; padding: 1rem; border-radius: 6px; display: none; text-align: center; font-size: 0.9rem; line-height: 1.4; word-break: break-all; }
.success { background-color: #c6f6d5; color: #22543d; display: block !important; }
.error { background-color: #fed7d7; color: #822727; display: block !important; }
.info { background-color: #ebf8ff; color: #2c5282; display: block !important; }
</style>
</head>
<body>
<div class="container">
<h1>Private Messaging</h1>
<p class="subtitle">Securely send encrypted messages on COTI Mainnet</p>
<button id="walletBtn">Connect Wallet</button>
<div class="form-group">
<label for="recipient">Recipient Wallet Address</label>
<input type="text" id="recipient" placeholder="0x..." autocomplete="off">
</div>
<div class="form-group">
<label for="message">Your Private Message</label>
<textarea id="message" placeholder="Type your confidential message here..."></textarea>
</div>
<button id="sendBtn" disabled>Send Encrypted Message</button>
<div id="status"></div>
</div>
<script>
const CONTRACT_ADDRESS = "0xa354bFd7f53bE4972501633BA26F0423a7323ce0";
const ABI = [
"function addMessage(string message, address receiver) public"
];
let provider, signer, account;
const statusDiv = document.getElementById('status');
const walletBtn = document.getElementById('walletBtn');
const sendBtn = document.getElementById('sendBtn');
function showStatus(text, type) {
statusDiv.innerHTML = text;
statusDiv.className = type;
}
walletBtn.onclick = async () => {
if (typeof window.ethereum !== 'undefined') {
try {
await window.ethereum.request({ method: 'eth_requestAccounts' });
provider = new ethers.providers.Web3Provider(window.ethereum);
signer = provider.getSigner();
account = await signer.getAddress();
walletBtn.innerText = "Connected: " + account.substring(0, 6) + "..." + account.substring(38);
walletBtn.classList.add('connected');
sendBtn.disabled = false;
showStatus("Wallet connected successfully.", "success");
} catch (err) {
showStatus("Connection error: " + err.message, "error");
}
} else {
showStatus("MetaMask not found. Please install a Web3 wallet.", "error");
}
};
sendBtn.onclick = async () => {
const recipient = document.getElementById('recipient').value.trim();
const message = document.getElementById('message').value.trim();
if (!ethers.utils.isAddress(recipient)) {
return showStatus("Please enter a valid recipient address.", "error");
}
if (!message) {
return showStatus("Message cannot be empty.", "error");
}
try {
sendBtn.disabled = true;
showStatus("Initiating transaction... Please confirm in your wallet.", "info");
const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, signer);
const tx = await contract.addMessage(message, recipient);
showStatus("Transaction submitted!<br>Hash: " + tx.hash, "info");
await tx.wait();
showStatus("Message sent and secured on-chain!", "success");
document.getElementById('message').value = "";
} catch (err) {
console.error(err);
showStatus("Transaction failed: " + (err.data?.message || err.message), "error");
} finally {
sendBtn.disabled = false;
}
};
</script>
</body>
</html>