document.addEventListener('DOMContentLoaded', () => {
const assetSelect = document.getElementById('asset-select');
const toggleButton = document.getElementById('day-night-toggle');
const body = document.body;
// Parse query parameters from the URL
const params = new URLSearchParams(window.location.search);
let selectedAsset = params.get('asset');
// Function to populate the asset select dropdown (no await)
function populateAssetSelect() {
fetch('/api?cmd=getAssets')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
// Clear existing options
assetSelect.innerHTML = '';
// Populate the dropdown with fetched data
data.forEach(asset => {
const option = document.createElement('option');
option.value = asset; // Assuming data is an array of strings
option.textContent = 'KNOLIX / '+asset;
assetSelect.appendChild(option);
});
// Set the initial value
if (selectedAsset) {
// If URL has an asset parameter, use it
assetSelect.value = selectedAsset;
}
})
.catch(error => {
console.error('Error fetching assets:', error);
assetSelect.innerHTML = '';
});
}
// Populate the dropdown on page load
populateAssetSelect();
if( selectedAsset===null ) {
selectedAsset = 'TRX';
}
// Handle asset selection change
assetSelect.addEventListener('change', () => {
const newAsset = assetSelect.value;
window.location.href = `/?asset=${newAsset}`;
});
// Toggle Night/Day Mode
toggleButton.addEventListener('click', () => {
body.classList.toggle('night-mode');
toggleButton.textContent = body.classList.contains('night-mode') ? '🌞' : '🌙';
});
// Select all buttons with class 'vote-btn'
const voteButtons = document.querySelectorAll('.vote-btn');
// Add click event listener to each button
voteButtons.forEach(button => {
button.addEventListener('click', function() {
// Get the value from the data-value attribute
const value = this.getAttribute('data-value');
// Handle the click event with the specific value
handleVote(value);
});
});
function handleVote(Asset) {
fetch(`/api.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'vote', asset: Asset })
})
.then(response => response.json())
.then(data => {
if (data.address) {
document.getElementById('modalpay').style.display='block';
document.getElementById('in-name').innerHTML = 'KNOLIX';
document.getElementById('in-address').innerHTML = data.address;
document.getElementById('in-qr').src = 'https://quickchart.io/qr?text='+data.address;
document.getElementById('out-name').innerHTML = 'VOTE';
document.getElementById('out-address').innerHTML = 'VOTE for '+Asset;
deposit_addr = data.address;
deposit_coin = "KNOX";
startWatcher('p2');
}
if (data.err) {
alert(data.err);
}
})
.catch(error => {
console.error('Error:', error);
alert(error);
});
}
// Select all buttons with class 'donate-btn'
const donateButtons = document.querySelectorAll('.donate-btn');
// Add click event listener to each button
donateButtons.forEach(button => {
button.addEventListener('click', function() {
// Get the value from the data-value attribute
const value = this.getAttribute('data-value');
const parts = value.split(':');
const Asset = parts[0];
const W = parts[1];
handleDonate(Asset,W);
});
});
function handleDonate(Asset,W) {
fetch(`/api.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'donate', asset: Asset })
})
.then(response => response.json())
.then(data => {
if (data.address) {
document.getElementById('modalpay').style.display='block';
document.getElementById('in-name').innerHTML = Asset;
document.getElementById('in-address').innerHTML = data.address;
document.getElementById('in-qr').src = 'https://quickchart.io/qr?text='+data.address;
document.getElementById('out-name').innerHTML = 'DONATE';
document.getElementById('out-address').innerHTML = 'DONATE '+Asset;
deposit_addr = data.address;
deposit_coin = Asset;
startWatcher(W);
}
if (data.err) {
alert(data.err);
}
})
.catch(error => {
console.error('Error:', error);
alert(error);
});
}
// Select all buttons with class 'liquid-btn'
const liquidButtons = document.querySelectorAll('.liquid-btn');
// Add click event listener to each button
liquidButtons.forEach(button => {
button.addEventListener('click', function() {
// Get the value from the data-value attribute
const value = this.getAttribute('data-value');
const parts = value.split(':');
const Asset = parts[0];
const W = parts[1];
handleLiquid(Asset,W);
});
});
function handleLiquid(Asset,W) {
const knolixAddress = prompt(`Enter KNOLIX address:`);
if (knolixAddress) {
fetch(`/api.php`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'liquid', asset: Asset, address: knolixAddress })
})
.then(response => response.json())
.then(data => {
if (data.address) {
document.getElementById('modalpay').style.display='block';
document.getElementById('in-name').innerHTML = Asset;
document.getElementById('in-address').innerHTML = data.address;
document.getElementById('in-qr').src = 'https://quickchart.io/qr?text='+data.address;
document.getElementById('out-name').innerHTML = 'LIQUID';
document.getElementById('out-address').innerHTML = 'LIQUID '+Asset;
deposit_addr = data.address;
deposit_coin = Asset;
startWatcher(W);
}
if (data.err) {
alert(data.err);
}
})
.catch(error => {
console.error('Error:', error);
alert(error);
});
} else {
alert(' KNOLIX address is required to proceed.');
}
}
/**
* Copy Address to Clipboard
*/
function copyAddress() {
const textElement = document.getElementById('in-address');
if (!textElement) {
console.error("Element with ID 'in-address' not found.");
return; // Exit if the element doesn't exist
}
const textToCopy = textElement.innerText.trim();
if (!textToCopy) {
alert("No deposit address found to copy.");
return; // Exit if there's no text after trimming
}
navigator.clipboard.writeText(textToCopy)
.then(() => alert("Deposit address copied to clipboard!"))
.catch(err => {
console.error('Failed to copy text:', err);
alert("Failed to copy address. Please copy manually.");
});
}
const inAddressElement = document.getElementById('in-address');
inAddressElement.addEventListener('click', copyAddress);
/**
* P2P Watcher Logic
*/
let ws = null;
let heartbeatInterval = null;
let deposit_addr = null;
let deposit_coin = null;
//const logsArea = document.getElementById('logs');
const txList = document.getElementById('tx-list');
const statusDot = document.getElementById('status-dot');
const notifySound = document.getElementById('notify-sound');
function addLog(msg) {
const time = new Date().toLocaleTimeString();
//logsArea.innerHTML = `[${time}] ${msg}
` + logsArea.innerHTML;
console.log(`[${time}] ${msg}
`);
}
function triggerAlert() {
notifySound.currentTime = 0;
notifySound.play().catch(e => console.log("Sound blocked."));
// Brief visual flash on the deposit card
const card = document.getElementById('depAddr').parentElement.parentElement;
card.style.background = "#e8f5e9";
setTimeout(() => { card.style.background = "#fff"; }, 500);
}
function addTx(data) {
if (txList.innerHTML.includes("No deposits detected")) txList.innerHTML = '';
const card = document.createElement('div');
card.className = 'tx-card tx-matched';
card.innerHTML = `
DEPOSIT DETECTED
${data.txid}
`;
txList.prepend(card);
triggerAlert();
}
function startWatcher(w) {
let url;
if( w==='ex' ) {
url = `wss://p2p-watch1.skynex66.workers.dev/?coin=${deposit_coin}&addr=${deposit_addr}`;
} else if( w==='p2' ) {
url = `wss://p2p-watch.skynex66.workers.dev/?coin=${deposit_coin}&addr=${deposit_addr}`;
}
console.log(url);
if (ws) ws.close();
ws = new WebSocket(url);
ws.onopen = () => {
statusDot.className = 'status-dot online';
addLog("P2P Network Connected.");
// Keep-alive
if (heartbeatInterval) clearInterval(heartbeatInterval);
heartbeatInterval = setInterval(() => {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'browser_ping' }));
}
}, 20000);
};
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
if (data.type === 'heartbeat') return;
if (data.type === 'subscribed') {
addLog("Monitoring Mempool...");
}
else if (data.type === 'match') {
addLog("MATCH! Deposit found.");
addTx(data);
}
else if (data.type === 'status') {
addLog(data.message);
}
} catch (e) {}
};
ws.onclose = () => {
statusDot.className = 'status-dot offline';
addLog("Disconnected. Retrying in 10s...");
setTimeout(() => startWatcher(w), 10000);
};
}
});