You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
289 lines
11 KiB
289 lines
11 KiB
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>PoWH Program Test - Devnet</title> |
|
<style> |
|
body { |
|
font-family: Arial, sans-serif; |
|
max-width: 800px; |
|
margin: 0 auto; |
|
padding: 20px; |
|
background-color: #1a1a1a; |
|
color: #ffffff; |
|
} |
|
.container { |
|
background-color: #2d2d2d; |
|
border-radius: 10px; |
|
padding: 20px; |
|
margin: 20px 0; |
|
} |
|
button { |
|
background-color: #4CAF50; |
|
border: none; |
|
color: white; |
|
padding: 15px 32px; |
|
text-align: center; |
|
text-decoration: none; |
|
display: inline-block; |
|
font-size: 16px; |
|
margin: 4px 2px; |
|
cursor: pointer; |
|
border-radius: 5px; |
|
} |
|
button:hover { |
|
background-color: #45a049; |
|
} |
|
button:disabled { |
|
background-color: #666; |
|
cursor: not-allowed; |
|
} |
|
.status { |
|
background-color: #333; |
|
padding: 10px; |
|
border-radius: 5px; |
|
margin: 10px 0; |
|
font-family: monospace; |
|
} |
|
.success { color: #4CAF50; } |
|
.error { color: #f44336; } |
|
.warning { color: #ff9800; } |
|
.info { color: #2196F3; } |
|
input { |
|
padding: 10px; |
|
margin: 5px 0; |
|
border: 1px solid #555; |
|
background-color: #444; |
|
color: white; |
|
border-radius: 3px; |
|
width: 200px; |
|
} |
|
h1 { |
|
color: #4CAF50; |
|
text-align: center; |
|
} |
|
h2 { |
|
color: #2196F3; |
|
} |
|
</style> |
|
<script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script> |
|
<script src="https://unpkg.com/@coral-xyz/anchor@latest/dist/browser.js"></script> |
|
</head> |
|
<body> |
|
<h1>🧪 PoWH Program Test - Devnet</h1> |
|
|
|
<div class="container"> |
|
<h2>Connection Status</h2> |
|
<div id="connection-status" class="status">Not connected</div> |
|
<button onclick="connectWallet()">Connect Phantom Wallet</button> |
|
</div> |
|
|
|
<div class="container"> |
|
<h2>Program Information</h2> |
|
<div class="status"> |
|
<div>Program ID: <span id="program-id">Loading...</span></div> |
|
<div>Mint Address: <span id="mint-address">Loading...</span></div> |
|
<div>Cluster: <span id="cluster">devnet</span></div> |
|
<div>State PDA: <span id="state-pda">Not calculated</span></div> |
|
<div>Vault PDA: <span id="vault-pda">Not calculated</span></div> |
|
</div> |
|
<button onclick="calculatePDAs()">Calculate PDAs</button> |
|
</div> |
|
|
|
<div class="container"> |
|
<h2>Program Initialization</h2> |
|
<div id="init-status" class="status">Ready to initialize</div> |
|
<button onclick="initializeProgram()">Initialize Program</button> |
|
</div> |
|
|
|
<div class="container"> |
|
<h2>Test Trading</h2> |
|
<div> |
|
<input type="number" id="sol-amount" placeholder="SOL Amount" step="0.1" value="0.1"> |
|
<button onclick="buyTokens()">Buy Tokens</button> |
|
</div> |
|
<div> |
|
<input type="number" id="token-amount" placeholder="Token Amount" step="1000000" value="1000000"> |
|
<button onclick="sellTokens()">Sell Tokens</button> |
|
</div> |
|
<div id="trade-status" class="status">Ready to trade</div> |
|
</div> |
|
|
|
<script> |
|
// Load configuration |
|
const CONFIG = { |
|
"programId": "8hcuEUBcuVBYyD53QPFQrRSWJjQy3UVURiqJpcuvgrTf", |
|
"mintAddress": "GrCHRSRHdZtiz2fiv1iUgigXCfB5Ta3j8gXepZUUTPP2", |
|
"devWallet": "GPFYcM3svcM4Srko6ExLYeSW4Gjwf6XoV4k1eSXoGHoK", |
|
"cluster": "devnet", |
|
"rpcUrl": "https://api.devnet.solana.com" |
|
}; |
|
|
|
let connection; |
|
let wallet; |
|
let program; |
|
let statePda; |
|
let vaultPda; |
|
|
|
// Update UI with config |
|
document.getElementById('program-id').textContent = CONFIG.programId; |
|
document.getElementById('mint-address').textContent = CONFIG.mintAddress; |
|
|
|
function log(message, type = 'info') { |
|
console.log(message); |
|
const status = document.getElementById('connection-status'); |
|
status.innerHTML = `<span class="${type}">${new Date().toLocaleTimeString()}: ${message}</span>`; |
|
} |
|
|
|
async function connectWallet() { |
|
try { |
|
if (window.solana) { |
|
const response = await window.solana.connect(); |
|
wallet = window.solana; |
|
connection = new solanaWeb3.Connection(CONFIG.rpcUrl, 'confirmed'); |
|
|
|
log(`Connected to wallet: ${response.publicKey.toString()}`, 'success'); |
|
|
|
// Check balance |
|
const balance = await connection.getBalance(response.publicKey); |
|
log(`Wallet balance: ${balance / solanaWeb3.LAMPORTS_PER_SOL} SOL`, 'info'); |
|
|
|
} else { |
|
log('Phantom wallet not found!', 'error'); |
|
} |
|
} catch (error) { |
|
log(`Connection failed: ${error.message}`, 'error'); |
|
} |
|
} |
|
|
|
async function calculatePDAs() { |
|
if (!connection) { |
|
log('Connect wallet first!', 'error'); |
|
return; |
|
} |
|
|
|
try { |
|
const programId = new solanaWeb3.PublicKey(CONFIG.programId); |
|
|
|
[statePda] = await solanaWeb3.PublicKey.findProgramAddress( |
|
[Buffer.from("state")], |
|
programId |
|
); |
|
|
|
[vaultPda] = await solanaWeb3.PublicKey.findProgramAddress( |
|
[Buffer.from("vault")], |
|
programId |
|
); |
|
|
|
document.getElementById('state-pda').textContent = statePda.toString(); |
|
document.getElementById('vault-pda').textContent = vaultPda.toString(); |
|
|
|
log('PDAs calculated successfully', 'success'); |
|
|
|
} catch (error) { |
|
log(`PDA calculation failed: ${error.message}`, 'error'); |
|
} |
|
} |
|
|
|
async function initializeProgram() { |
|
if (!wallet || !connection || !statePda || !vaultPda) { |
|
log('Please connect wallet and calculate PDAs first!', 'error'); |
|
return; |
|
} |
|
|
|
try { |
|
document.getElementById('init-status').innerHTML = '<span class="warning">Initializing...</span>'; |
|
|
|
// Create transaction manually since we don't have working Anchor JS |
|
const mintPubkey = new solanaWeb3.PublicKey(CONFIG.mintAddress); |
|
const programId = new solanaWeb3.PublicKey(CONFIG.programId); |
|
|
|
// Create initialize instruction data |
|
// This is the discriminator for initialize function from the IDL |
|
const initDiscriminator = [175, 175, 109, 31, 13, 152, 155, 237]; |
|
const data = Buffer.from(initDiscriminator); |
|
|
|
const instruction = new solanaWeb3.TransactionInstruction({ |
|
keys: [ |
|
{ pubkey: statePda, isSigner: false, isWritable: true }, |
|
{ pubkey: vaultPda, isSigner: false, isWritable: true }, |
|
{ pubkey: mintPubkey, isSigner: false, isWritable: true }, |
|
{ pubkey: wallet.publicKey, isSigner: true, isWritable: true }, |
|
{ pubkey: solanaWeb3.SystemProgram.programId, isSigner: false, isWritable: false }, |
|
{ pubkey: new solanaWeb3.PublicKey("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"), isSigner: false, isWritable: false }, |
|
], |
|
programId: programId, |
|
data: data |
|
}); |
|
|
|
const transaction = new solanaWeb3.Transaction().add(instruction); |
|
const signature = await wallet.signAndSendTransaction(transaction); |
|
|
|
document.getElementById('init-status').innerHTML = `<span class="success">Initialized! Tx: ${signature}</span>`; |
|
log(`Program initialized successfully: ${signature}`, 'success'); |
|
|
|
} catch (error) { |
|
document.getElementById('init-status').innerHTML = `<span class="error">Failed: ${error.message}</span>`; |
|
log(`Initialization failed: ${error.message}`, 'error'); |
|
} |
|
} |
|
|
|
async function buyTokens() { |
|
if (!wallet || !connection) { |
|
log('Connect wallet first!', 'error'); |
|
return; |
|
} |
|
|
|
const solAmount = parseFloat(document.getElementById('sol-amount').value); |
|
if (!solAmount || solAmount <= 0) { |
|
log('Enter a valid SOL amount!', 'error'); |
|
return; |
|
} |
|
|
|
try { |
|
document.getElementById('trade-status').innerHTML = '<span class="warning">Creating buy transaction...</span>'; |
|
|
|
// You would need to implement the full buy transaction here |
|
// For now, just show that we're connected and ready |
|
document.getElementById('trade-status').innerHTML = `<span class="info">Ready to buy ${solAmount} SOL worth of tokens</span>`; |
|
log(`Buy tokens functionality ready (${solAmount} SOL)`, 'info'); |
|
|
|
} catch (error) { |
|
document.getElementById('trade-status').innerHTML = `<span class="error">Buy failed: ${error.message}</span>`; |
|
log(`Buy failed: ${error.message}`, 'error'); |
|
} |
|
} |
|
|
|
async function sellTokens() { |
|
if (!wallet || !connection) { |
|
log('Connect wallet first!', 'error'); |
|
return; |
|
} |
|
|
|
const tokenAmount = parseInt(document.getElementById('token-amount').value); |
|
if (!tokenAmount || tokenAmount <= 0) { |
|
log('Enter a valid token amount!', 'error'); |
|
return; |
|
} |
|
|
|
try { |
|
document.getElementById('trade-status').innerHTML = '<span class="warning">Creating sell transaction...</span>'; |
|
|
|
// You would need to implement the full sell transaction here |
|
document.getElementById('trade-status').innerHTML = `<span class="info">Ready to sell ${tokenAmount} tokens</span>`; |
|
log(`Sell tokens functionality ready (${tokenAmount} tokens)`, 'info'); |
|
|
|
} catch (error) { |
|
document.getElementById('trade-status').innerHTML = `<span class="error">Sell failed: ${error.message}</span>`; |
|
log(`Sell failed: ${error.message}`, 'error'); |
|
} |
|
} |
|
|
|
// Auto-calculate PDAs on page load |
|
window.addEventListener('load', () => { |
|
log('Test page loaded. Ready to test devnet deployment!', 'info'); |
|
}); |
|
</script> |
|
</body> |
|
</html> |