feat: Add hip02 support
All checks were successful
Build Docker / BuildImage (push) Successful in 1m0s
Check Code Quality / RuffCheck (push) Successful in 1m0s

This commit is contained in:
2025-11-21 00:24:51 +11:00
parent 16d7b9f942
commit 3d5d203831
7 changed files with 723 additions and 22 deletions

View File

@@ -70,6 +70,9 @@ header h1 {
align-items: center;
gap: 0.5rem;
}
header a:hover {
text-decoration: none;
}
.subtitle {
color: var(--text-secondary);

View File

@@ -34,7 +34,7 @@
<header>
<div class="container">
<div class="brand">
<h1><img src="/assets/img/favicon.png" alt="Fire Icon" style="height: 1.2em; vertical-align: middle;"> Fire Explorer</h1>
<a href="/"><h1><img src="/assets/img/favicon.png" alt="Fire Icon" style="height: 1.2em; vertical-align: middle;"> Fire Explorer</h1></a>
<span class="subtitle">Handshake Blockchain Explorer</span>
</div>
</div>
@@ -78,6 +78,9 @@
<button onclick="searchAddressTx()">Get Transactions</button>
<button onclick="searchAddressCoins()">Get Coins</button>
</div>
<p style="font-size: 0.85rem; color: var(--text-secondary); margin-top: -0.5rem; margin-bottom: 1.5rem; padding-left: 0.5rem;">
<span style="color: var(--accent-color);">Tip:</span> Use <span class="mono" style="color: var(--text-primary);">@name</span> to search via HIP02 alias
</p>
<div id="address-result" class="result-box"></div>
</div>
@@ -215,6 +218,21 @@
}
}
// Resolve HIP02 alias
async function resolveHip02(input) {
if (!input.startsWith('@')) return { success: true, address: input };
const name = input.substring(1);
try {
// Try HTTPS first
const response = await fetch(`/api/v1/hip02/${name}`);
const data = await response.json();
return data;
} catch (e) {
return { success: false, error: 'Failed to resolve HIP02 alias. ' + e.message };
}
}
// Format chain data nicely
function formatChainData(chain) {
return `
@@ -929,7 +947,7 @@
element.innerHTML = `
<div class="loading-container">
<div class="loading-spinner"></div>
<div class="loading-text">Searching Fire...</div>
<div class="loading-text">Lighing Fire...</div>
</div>
`;
}
@@ -1017,18 +1035,39 @@
}
async function searchAddressTx() {
const address = document.getElementById('address-input').value.trim().replace(/,/g, '');
let address = document.getElementById('address-input').value.trim().replace(/,/g, '');
if (!address) {
alert('Please enter an address');
return;
}
showLoading('address-result');
const resultElement = document.getElementById('address-result');
// Check for HIP02 alias
if (address.startsWith('@')) {
const hip02Result = await resolveHip02(address);
if (hip02Result.success && hip02Result.address) {
address = hip02Result.address;
// Update input to show resolved address
document.getElementById('address-input').value = address;
// Add a note about resolution
const note = document.createElement('div');
note.className = 'success-message';
note.style.marginBottom = '1rem';
note.innerHTML = `Resolved alias <strong>${hip02Result.name || address}</strong> to address`;
resultElement.parentNode.insertBefore(note, resultElement);
setTimeout(() => note.remove(), 5000);
} else {
resultElement.innerHTML = `<div class="error">HIP02 Error: ${hip02Result.error || 'Could not resolve alias'}</div>`;
return;
}
}
updateURL('address', address);
const data = await apiCall(`tx/address/${address}`);
// Use formatted display instead of raw JSON
const resultElement = document.getElementById('address-result');
if (data.error) {
resultElement.innerHTML = `<div class="error">Error: ${data.error}</div>`;
} else {
@@ -1037,18 +1076,32 @@
}
async function searchAddressCoins() {
const address = document.getElementById('address-input').value.trim().replace(/,/g, '');
let address = document.getElementById('address-input').value.trim().replace(/,/g, '');
if (!address) {
alert('Please enter an address');
return;
}
showLoading('address-result');
const resultElement = document.getElementById('address-result');
// Check for HIP02 alias
if (address.startsWith('@')) {
const hip02Result = await resolveHip02(address);
if (hip02Result.success && hip02Result.address) {
address = hip02Result.address;
// Update input to show resolved address
document.getElementById('address-input').value = address;
} else {
resultElement.innerHTML = `<div class="error">HIP02 Error: ${hip02Result.error || 'Could not resolve alias'}</div>`;
return;
}
}
updateURL('address', address);
const data = await apiCall(`coin/address/${address}`);
// Use formatted display instead of raw JSON
const resultElement = document.getElementById('address-result');
if (data.error) {
resultElement.innerHTML = `<div class="error">Error: ${data.error}</div>`;
} else {