|
|
<!DOCTYPE html> |
|
|
<html lang="vi"> |
|
|
<head> |
|
|
<meta charset="UTF-8" /> |
|
|
<title>Solana IDM Demo – Fixed Buffer</title> |
|
|
<style> |
|
|
body { font-family: sans-serif; padding: 20px; max-width: 500px; margin: auto; } |
|
|
input, textarea, button { width: 100%; margin-top: 10px; padding: 10px; font-size: 16px; } |
|
|
button { background: #4CAF50; color: white; border: none; cursor: pointer; } |
|
|
button:hover { background: #45a049; } |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<h2>📨 Gửi Tin nhắn (IDM) qua Solana</h2> |
|
|
<button onclick="connectWallet()">🔌 Kết nối ví Phantom</button> |
|
|
<div id="wallet-address" style="margin-top:10px; font-weight: bold;"></div> |
|
|
|
|
|
<input type="text" id="recipient" placeholder="🎯 Nhập địa chỉ ví người nhận (ví dụ: của bạn)"> |
|
|
<textarea id="message" rows="4" placeholder="💬 Nhập nội dung IDM (Memo)"></textarea> |
|
|
<button onclick="sendMemo()">📤 Gửi IDM</button> |
|
|
|
|
|
<div id="result" style="margin-top: 15px;"></div> |
|
|
|
|
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/buffer/6.0.3/buffer.min.js"></script> |
|
|
<script> |
|
|
window.global = window; |
|
|
window.Buffer = buffer.Buffer; |
|
|
</script> |
|
|
|
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/@solana/web3.js@1.77.2/lib/index.iife.min.js"></script> |
|
|
|
|
|
<script> |
|
|
let provider = null; |
|
|
|
|
|
async function connectWallet() { |
|
|
if ('solana' in window) { |
|
|
provider = window.solana; |
|
|
if (provider.isPhantom) { |
|
|
try { |
|
|
const resp = await provider.connect(); |
|
|
document.getElementById("wallet-address").innerText = "🪪 Đã kết nối: " + resp.publicKey.toString(); |
|
|
} catch (err) { |
|
|
alert("Kết nối bị từ chối!"); |
|
|
} |
|
|
} else { |
|
|
alert("Cài ví Phantom trước nhé!"); |
|
|
} |
|
|
} else { |
|
|
alert("Trình duyệt không tìm thấy ví Solana."); |
|
|
} |
|
|
} |
|
|
|
|
|
async function sendMemo() { |
|
|
const connection = new solanaWeb3.Connection(solanaWeb3.clusterApiUrl('devnet')); |
|
|
const recipient = document.getElementById("recipient").value.trim(); |
|
|
const message = document.getElementById("message").value.trim(); |
|
|
|
|
|
if (!provider || !provider.publicKey) { |
|
|
alert("Bạn chưa kết nối ví Phantom!"); |
|
|
return; |
|
|
} |
|
|
if (!recipient || !message) { |
|
|
alert("Vui lòng nhập đầy đủ địa chỉ và nội dung."); |
|
|
return; |
|
|
} |
|
|
|
|
|
try { |
|
|
const transaction = new solanaWeb3.Transaction(); |
|
|
|
|
|
transaction.add(solanaWeb3.SystemProgram.transfer({ |
|
|
fromPubkey: provider.publicKey, |
|
|
toPubkey: new solanaWeb3.PublicKey(recipient), |
|
|
lamports: 0 |
|
|
})); |
|
|
|
|
|
transaction.add(new solanaWeb3.TransactionInstruction({ |
|
|
keys: [], |
|
|
programId: new solanaWeb3.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"), |
|
|
data: new TextEncoder().encode(message) |
|
|
})); |
|
|
|
|
|
transaction.feePayer = provider.publicKey; |
|
|
const blockhashObj = await connection.getLatestBlockhash(); |
|
|
transaction.recentBlockhash = blockhashObj.blockhash; |
|
|
|
|
|
const signed = await provider.signTransaction(transaction); |
|
|
const txid = await connection.sendRawTransaction(signed.serialize()); |
|
|
|
|
|
await connection.confirmTransaction(txid); |
|
|
document.getElementById("result").innerHTML = |
|
|
`✅ Đã gửi! <br>🧾 TxID: <a href="https://explorer.solana.com/tx/${txid}?cluster=devnet" target="_blank">${txid}</a>`; |
|
|
|
|
|
} catch (err) { |
|
|
console.error("Lỗi khi gửi giao dịch:", err); |
|
|
document.getElementById("result").innerText = "❌ Gửi thất bại: " + err.message; |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</body> |
|
|
</html> |
|
|
|