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
|
3 months ago
|
<!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>
|