Skip to content

Commit

Permalink
Add WebSocket logic to fetch real-time mempool data for fee rates and…
Browse files Browse the repository at this point in the history
… block height; display updates in footer with periodic reconnection every minute for refreshed data.
  • Loading branch information
StellarStoic committed Sep 3, 2024
1 parent 36ef185 commit ea425f6
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 60 deletions.
40 changes: 30 additions & 10 deletions converter.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="converter.css">
<link href="https://cdn.lineicons.com/3.0/lineicons.css" rel="stylesheet">


<title>Hi Satoshi</title>
</head>
Expand Down Expand Up @@ -56,23 +57,41 @@ <h4>Select a Currency</h4>
</div>
</div>



<!-- ---------------------------------------------------------------------- -->
<!-- Footer with Email and Lightning Icon -->
<footer class="footer">
<a href="mailto:&#111;&#110;&#101;&#064;&#115;&#097;&#116;&#111;&#115;&#104;&#105;&#046;&#115;&#105;?subject=mail to one Satoshi from satoshi.si" target="_blank">
[email protected]
</a>
<!-- Lightning Icon -->
<i class="lni lni-bolt-alt" onclick="openQRCodeModal()" title="Support me with a sat or two!"></i>
<!-- Footer with Email, Lightning Icon, Block Height, and Fee Rate -->
<footer class="footer">
<!-- Email Link -->
<a href="mailto:&#111;&#110;&#101;&#064;&#115;&#097;&#116;&#111;&#115;&#104;&#105;&#046;&#115;&#105;?subject=mail to one Satoshi from satoshi.si" target="_blank">
[email protected]
</a>

<!-- Block Height Display (Left Side) -->
<span id="block-height" title="Block Height" onclick="openMempoolTinyDataModal()">
</span>

<!-- Fee Rate Display (Right Side) -->
<span id="fee-rate" title="Network fee rate" onclick="openMempoolTinyDataModal()">
</span>

<!-- Lightning Icon -->
<i class="lni lni-bolt-alt" onclick="openQRCodeModal()" title="Support me with a sat or two!"></i>
</footer>

<!-- modal for Mempool Tiny Data Modal -->
<div id="mempoolTinyDataModal" class="description-modal">
<div class="modal-content">
<span class="close-button" onclick="closeMempoolTinyDataModal()">&times;</span>
<h2>This section is still under development...</h2>
<!-- Content for mempool data goes here -->
</div>
</div>


<!-- Modal for QR Code donation -->
<div id="qrCodeModal" class="description-modal">
<div class="modal-content">
<span class="close-icon" onclick="closeQRCodeModal()">&times;</span>
<h4 id="gratitudeHeader">If you like what you see, consider contributing a few sats. Thanks!</h4>
<h4 id="gratitudeHeader">If you find this website valuable, consider contributing a sat or two. Thank you.</h4>
<div class="qr-code-container">
<!-- Lightning QR Code -->
<div class="qr-code-wrapper">
Expand Down Expand Up @@ -116,6 +135,7 @@ <h6>The G.D.P.R. (Greatly Demanding Privacy Rules) requires us to share this wit

<script src="coockieConsent.js"></script>
<script src="copyonclick.js"></script>
<script src="mempoolWebSocket.js"></script>
<script src="converter.js"></script>
<script src="index.js"></script>
<script src="burgerMenu.js"></script>
Expand Down
6 changes: 3 additions & 3 deletions converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ document.addEventListener('DOMContentLoaded', function () {
if (cachedRates && cachedExpiry && now < cachedExpiry) {
// Use cached rates if not expired
exchangeRates = JSON.parse(cachedRates);
console.log('Using cached exchange rates:', exchangeRates);
// consol.log('Using cached exchange rates:', exchangeRates);
loadUserSettings(); // Load user settings after fetching rates
updateAllCurrencies();
} else {
Expand All @@ -119,7 +119,7 @@ document.addEventListener('DOMContentLoaded', function () {
.then(response => response.json())
.then(data => {
exchangeRates = data.rates;
console.log('Fetched new exchange rates:', exchangeRates);
// consol.log('Fetched new exchange rates:', exchangeRates);
loadUserSettings(); // Load user settings after fetching rates
updateAllCurrencies();

Expand Down Expand Up @@ -425,7 +425,7 @@ function populateCurrencyList(currencies) {

window.selectCurrency = function (currency) {
selectedCurrency = currency; // Store selected currency
console.log(`Selected currency: ${selectedCurrency}`);
// consol.log(`Selected currency: ${selectedCurrency}`);
closeCurrencyModal();
addCurrencyContainer(); // Call to add the container after currency selection
};
Expand Down
38 changes: 30 additions & 8 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,41 @@
</defs>
</svg>

<!-- Footer with Email and Lightning Icon -->
<footer class="footer">
<a href="mailto:&#111;&#110;&#101;&#064;&#115;&#097;&#116;&#111;&#115;&#104;&#105;&#046;&#115;&#105;?subject=mail to one Satoshi from satoshi.si" target="_blank">
[email protected]
</a>
<!-- Lightning Icon -->
<i class="lni lni-bolt-alt" onclick="openQRCodeModal()" title="Support me with a sat or two!"></i>
<!-- ---------------------------------------------------------------------- -->
<!-- Footer with Email, Lightning Icon, Block Height, and Fee Rate -->
<footer class="footer">
<!-- Email Link -->
<a href="mailto:&#111;&#110;&#101;&#064;&#115;&#097;&#116;&#111;&#115;&#104;&#105;&#046;&#115;&#105;?subject=mail to one Satoshi from satoshi.si" target="_blank">
[email protected]
</a>

<!-- Block Height Display (Left Side) -->
<span id="block-height" title="Block Height" onclick="openMempoolTinyDataModal()">
</span>

<!-- Fee Rate Display (Right Side) -->
<span id="fee-rate" title="Network fee rate" onclick="openMempoolTinyDataModal()">
</span>

<!-- Lightning Icon -->
<i class="lni lni-bolt-alt" onclick="openQRCodeModal()" title="Support me with a sat or two!"></i>
</footer>

<!-- modal for Mempool Tiny Data Modal -->
<div id="mempoolTinyDataModal" class="description-modal">
<div class="modal-content">
<span class="close-button" onclick="closeMempoolTinyDataModal()">&times;</span>
<h2>This section is still under development...</h2>
<!-- Content for mempool data goes here -->
</div>
</div>


<!-- Modal for QR Code donation -->
<div id="qrCodeModal" class="description-modal">
<div class="modal-content">
<span class="close-icon" onclick="closeQRCodeModal()">&times;</span>
<h4 id="gratitudeHeader">If you like what you see, consider contributing a few sats. Thanks!</h4>
<h4 id="gratitudeHeader">If you find this website valuable, consider contributing a sat or two. Thank you.</h4>
<div class="qr-code-container">
<!-- Lightning QR Code -->
<div class="qr-code-wrapper">
Expand Down Expand Up @@ -107,6 +128,7 @@ <h6>The G.D.P.R. (Greatly Demanding Privacy Rules) requires us to share this wit

<script src="coockieConsent.js"></script>
<script src="copyonclick.js"></script>
<script src="mempoolWebSocket.js"></script>
<script src="text.js"></script>
<script src="index.js"></script>
<script src="burgerMenu.js"></script>
Expand Down
57 changes: 45 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
document.addEventListener('DOMContentLoaded', function () {
// Function to open the QR Code modal
function openQRCodeModal(event) {
event.stopPropagation(); // Prevent the click event from bubbling up
console.log('Attempting to open QR Code modal'); // Debugging log
event.stopPropagation();
const qrModal = document.getElementById('qrCodeModal');
if (qrModal) {
console.log('QR Code modal found, opening...'); // Debugging log
closeAllModals(); // Ensure all modals are closed before opening
closeAllModals();
qrModal.classList.add('active');
document.body.classList.add('modal-open');
} else {
Expand All @@ -16,7 +14,6 @@ document.addEventListener('DOMContentLoaded', function () {

// Function to close the QR Code modal
function closeQRCodeModal() {
console.log('Closing QR Code modal'); // Debugging log
const qrModal = document.getElementById('qrCodeModal');
if (qrModal) {
qrModal.classList.remove('active');
Expand All @@ -26,34 +23,59 @@ document.addEventListener('DOMContentLoaded', function () {
}
}

// Function to open the Mempool Tiny Data modal
function openMempoolTinyDataModal(event) {
event.stopPropagation();
const mempoolModal = document.getElementById('mempoolTinyDataModal');
if (mempoolModal) {
closeAllModals();
mempoolModal.classList.add('active');
document.body.classList.add('modal-open');
} else {
console.error('Mempool Tiny Data Modal not found!');
}
}

// Function to close the Mempool Tiny Data modal
function closeMempoolTinyDataModal() {
const mempoolModal = document.getElementById('mempoolTinyDataModal');
if (mempoolModal) {
mempoolModal.classList.remove('active');
document.body.classList.remove('modal-open');
} else {
console.error('Mempool Tiny Data Modal not found!');
}
}

// Function to close all modals
function closeAllModals() {
console.log('Closing all modals'); // Debugging log
document.querySelectorAll('.description-modal.active').forEach(function (modal) {
modal.classList.remove('active');
});
document.body.classList.remove('modal-open');
}



// Attach global functions to the window object
window.openQRCodeModal = openQRCodeModal;
window.closeQRCodeModal = closeQRCodeModal;
window.openMempoolTinyDataModal = openMempoolTinyDataModal;
window.closeMempoolTinyDataModal = closeMempoolTinyDataModal;

// Handle clicks outside of modals to close them
window.addEventListener('click', function (event) {
console.log('Window click detected:', event.target); // Debugging log
const qrModal = document.getElementById('qrCodeModal');
const mempoolModal = document.getElementById('mempoolTinyDataModal');
const activeDescriptionModal = document.querySelector('.description-modal.active');

if (qrModal && qrModal.classList.contains('active') && !qrModal.contains(event.target)) {
console.log('Click outside QR Code modal, closing...'); // Debugging log
closeQRCodeModal();
}

if (mempoolModal && mempoolModal.classList.contains('active') && !mempoolModal.contains(event.target)) {
closeMempoolTinyDataModal();
}

if (activeDescriptionModal && !activeDescriptionModal.contains(event.target) && !event.target.closest('.image-box')) {
console.log('Click outside description modal, closing...'); // Debugging log
activeDescriptionModal.classList.remove('active');
document.body.classList.remove('modal-open');
}
Expand All @@ -62,7 +84,18 @@ document.addEventListener('DOMContentLoaded', function () {
// Attach click event to lightning icon specifically
const lightningIcon = document.querySelector('.lni-bolt-alt');
if (lightningIcon) {
console.log('Lightning icon found, adding click event'); // Debugging log
lightningIcon.addEventListener('click', openQRCodeModal);
}

// Attach click event to block height and fee rate spans
const feeRateSpan = document.getElementById('fee-rate');
const blockHeightSpan = document.getElementById('block-height');

if (feeRateSpan) {
feeRateSpan.addEventListener('click', openMempoolTinyDataModal);
}

if (blockHeightSpan) {
blockHeightSpan.addEventListener('click', openMempoolTinyDataModal);
}
});
61 changes: 61 additions & 0 deletions mempoolWebSocket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Function to establish WebSocket connection and listen for fee rate updates
function connectToMempoolAPI() {
const ws = new WebSocket('wss://mempool.space/api/v1/ws');

ws.onopen = () => {
console.log('WebSocket connection established');
// Subscribe to 'stats' and 'blocks' channels to receive mempool statistics and block info
ws.send(JSON.stringify({
"action": "init",
"channels": ["stats", "blocks"]
}));
};

ws.onmessage = (event) => {
const data = JSON.parse(event.data);

// Log the received data to check its structure
console.log('Received data:', data);

// Extract the half-hour fee rate from the 'fees' object
if (data.fees && data.fees.halfHourFee) {
const feeRate = data.fees.halfHourFee;
document.getElementById('fee-rate').textContent = feeRate + ' sat/vB';
} else {
console.log('Fee rate data not available in the received payload.');
}

// Extract the last block height from the 'blocks' object
if (data.blocks && data.blocks.length > 0) {
const lastBlockHeight = data.blocks[0].height;
document.getElementById('block-height').textContent = '' + lastBlockHeight;
} else {
console.log('Block height data not available in the received payload.');
}
};

ws.onerror = (error) => {
console.error('WebSocket error:', error);
};

ws.onclose = () => {
console.log('WebSocket connection closed');
// Attempt to reconnect after a 15-second delay
setTimeout(connectToMempoolAPI, 60000);
};
}

// Call the function to establish connection on page load
connectToMempoolAPI();

// Function to open the fee rate modal
function openFeeRateModal() {
// Logic to open the modal window displaying more fee rate information
const mempoolModal = document.getElementById('mempoolTinyDataModal');
if (mempoolModal) {
mempoolModal.classList.add('active');
document.body.classList.add('modal-open');
} else {
console.error('Mempool Tiny Data Modal not found!');
}
}
40 changes: 31 additions & 9 deletions nip05.html
Original file line number Diff line number Diff line change
Expand Up @@ -122,20 +122,41 @@
</div>
</div>

<!-- Footer with Email and Lightning Icon -->
<footer class="footer">
<a href="mailto:&#111;&#110;&#101;&#064;&#115;&#097;&#116;&#111;&#115;&#104;&#105;&#046;&#115;&#105;?subject=mail to one Satoshi from satoshi.si" target="_blank">
[email protected]
</a>
<!-- Lightning Icon -->
<i class="lni lni-bolt-alt" onclick="openQRCodeModal()" title="Support me with a sat or two!"></i>
</footer>
<!-- ---------------------------------------------------------------------- -->
<!-- Footer with Email, Lightning Icon, Block Height, and Fee Rate -->
<footer class="footer">
<!-- Email Link -->
<a href="mailto:&#111;&#110;&#101;&#064;&#115;&#097;&#116;&#111;&#115;&#104;&#105;&#046;&#115;&#105;?subject=mail to one Satoshi from satoshi.si" target="_blank">
[email protected]
</a>

<!-- Block Height Display (Left Side) -->
<span id="block-height" title="Block Height" onclick="openMempoolTinyDataModal()">
</span>

<!-- Fee Rate Display (Right Side) -->
<span id="fee-rate" title="Network fee rate" onclick="openMempoolTinyDataModal()">
</span>

<!-- Lightning Icon -->
<i class="lni lni-bolt-alt" onclick="openQRCodeModal()" title="Support me with a sat or two!"></i>
</footer>

<!-- modal for Mempool Tiny Data Modal -->
<div id="mempoolTinyDataModal" class="description-modal">
<div class="modal-content">
<span class="close-button" onclick="closeMempoolTinyDataModal()">&times;</span>
<h2>This section is still under development...</h2>
<!-- Content for mempool data goes here -->
</div>
</div>


<!-- Modal for QR Code donation -->
<div id="qrCodeModal" class="description-modal">
<div class="modal-content">
<span class="close-icon" onclick="closeQRCodeModal()">&times;</span>
<h4 id="gratitudeHeader">If you like what you see, consider contributing a few sats. Thanks!</h4>
<h4 id="gratitudeHeader">If you find this website valuable, consider contributing a sat or two. Thank you.</h4>
<div class="qr-code-container">
<!-- Lightning QR Code -->
<div class="qr-code-wrapper">
Expand Down Expand Up @@ -178,6 +199,7 @@ <h6>The G.D.P.R. (Greatly Demanding Privacy Rules) requires us to share this wit

<script src="coockieConsent.js"></script>
<script src="copyonclick.js"></script>
<script src="mempoolWebSocket.js"></script>
<script src="burgerMenu.js"></script>
<script src="index.js"></script>
<script src="nip05.js"></script>
Expand Down
Loading

0 comments on commit ea425f6

Please sign in to comment.