Implement search type tabs for balance and transaction details; enhance UI for better usability and sharing functionality
This commit is contained in:
parent
b303575bb3
commit
4ede245060
218
css/main.css
218
css/main.css
@ -1399,8 +1399,6 @@ body {
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Transaction Filter and Pagination Controls */
|
/* Transaction Filter and Pagination Controls */
|
||||||
.transaction-controls {
|
.transaction-controls {
|
||||||
background: var(--surface-color);
|
background: var(--surface-color);
|
||||||
@ -1659,7 +1657,6 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.wallet-recovered h3 {
|
.wallet-recovered h3 {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -2480,12 +2477,18 @@ sm-popup::part(popup) {
|
|||||||
|
|
||||||
.balance-header {
|
.balance-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.balance-header .share-btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.balance-header h3 {
|
.balance-header h3 {
|
||||||
margin: 0 0 0.5rem 0;
|
margin: 0 0 0.5rem 0;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
@ -3246,7 +3249,6 @@ sm-popup::part(popup) {
|
|||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.modern-popup-container {
|
.modern-popup-container {
|
||||||
max-height: 75vh !important;
|
max-height: 75vh !important;
|
||||||
@ -4060,3 +4062,207 @@ sm-popup::part(popup) {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== SEARCH TYPE TABS ===== */
|
||||||
|
.search-type-tabs {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: calc(var(--border-radius) - 0.25rem);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn:hover {
|
||||||
|
background: var(--surface-color);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn.active {
|
||||||
|
background: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
box-shadow: 0 2px 4px rgba(var(--primary-rgb), 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-section {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== SHARE BUTTON STYLES ===== */
|
||||||
|
.share-btn {
|
||||||
|
background: var(--accent-color);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-btn:hover {
|
||||||
|
background: var(--accent-dark);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-details-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-details-header .share-btn {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transaction-details-header h3 {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== TRANSACTION DETAILS CONTENT ===== */
|
||||||
|
.transaction-details-content {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-card {
|
||||||
|
background: var(--surface-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
padding: 1rem;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-card:hover {
|
||||||
|
border-color: var(--primary-color);
|
||||||
|
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
min-width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-value {
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
word-break: break-all;
|
||||||
|
text-align: right;
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-value.success {
|
||||||
|
color: var(--success-color);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-value.failed {
|
||||||
|
color: var(--error-color);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-value.amount {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== MOBILE RESPONSIVE FOR NEW ELEMENTS ===== */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.search-type-tabs {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-btn {
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: 0.625rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-header,
|
||||||
|
.transaction-details-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-btn {
|
||||||
|
align-self: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-row {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-value {
|
||||||
|
text-align: left;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tx-detail-label {
|
||||||
|
min-width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
130
index.html
130
index.html
@ -92,44 +92,105 @@
|
|||||||
<div id="connectPage" class="page">
|
<div id="connectPage" class="page">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h2><i class="fas fa-search-dollar"></i> Check Balance</h2>
|
<h2><i class="fas fa-search-dollar"></i> Check Balance</h2>
|
||||||
<p>
|
<p>Check XRP balance or view transaction details</p>
|
||||||
Check the XRP balance and transaction history for any Ripple
|
|
||||||
address
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<!-- Search Type Selector -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="checkAddress">
|
<label>Search Type:</label>
|
||||||
<i class="fas fa-wallet"></i> XRP Address or Private Key
|
<div class="search-type-tabs">
|
||||||
</label>
|
<button
|
||||||
<input
|
type="button"
|
||||||
type="text"
|
class="tab-btn active"
|
||||||
id="checkAddress"
|
onclick="switchSearchType('balance')"
|
||||||
class="form-input"
|
id="balanceTab"
|
||||||
placeholder="Enter XRP address (r...), private key (BTC/FLO)"
|
>
|
||||||
autocomplete="off"
|
<i class="fas fa-wallet"></i> Balance & History
|
||||||
/>
|
</button>
|
||||||
<div class="input-help">
|
<button
|
||||||
Enter an XRP address,private key (BTC/FLO) to check XRP balance
|
type="button"
|
||||||
|
class="tab-btn"
|
||||||
|
onclick="switchSearchType('transaction')"
|
||||||
|
id="transactionTab"
|
||||||
|
>
|
||||||
|
<i class="fas fa-receipt"></i> Transaction Details
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<!-- Balance Search -->
|
||||||
onclick="checkBalanceAndTransactions()"
|
<div id="balanceSearch" class="search-section">
|
||||||
class="btn btn-primary btn-block"
|
<div class="form-group">
|
||||||
|
<label for="checkAddress">
|
||||||
|
<i class="fas fa-wallet"></i> XRP Address or Private Key
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="checkAddress"
|
||||||
|
class="form-input"
|
||||||
|
placeholder="Enter XRP address (r...), BTC/FLO private key, or XRP seed"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
<div class="input-help">
|
||||||
|
Enter an XRP address, private key (BTC/FLO), or XRP seed to
|
||||||
|
check balance
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onclick="checkBalanceAndTransactions()"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
|
<i class="fas fa-search-dollar"></i> Check Balance
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Transaction Hash Search -->
|
||||||
|
<div
|
||||||
|
id="transactionSearch"
|
||||||
|
class="search-section"
|
||||||
|
style="display: none"
|
||||||
>
|
>
|
||||||
<i class="fas fa-search-dollar"></i> Check Balance
|
<div class="form-group">
|
||||||
</button>
|
<label for="checkTransactionHash">
|
||||||
|
<i class="fas fa-receipt"></i> Transaction Hash
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="checkTransactionHash"
|
||||||
|
class="form-input"
|
||||||
|
placeholder="Enter transaction hash (TX ID)"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
<div class="input-help">
|
||||||
|
Enter a transaction hash to view transaction details
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onclick="checkTransactionDetails()"
|
||||||
|
class="btn btn-primary btn-block"
|
||||||
|
>
|
||||||
|
<i class="fas fa-search"></i> View Transaction
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Balance Info Display -->
|
<!-- Balance Info Display -->
|
||||||
<div class="card balance-info" id="balanceInfo" style="display: none">
|
<div class="card balance-info" id="balanceInfo" style="display: none">
|
||||||
<div class="balance-header">
|
<div class="balance-header">
|
||||||
<h3><i class="fas fa-coins"></i> Account Balance</h3>
|
<h3><i class="fas fa-coins"></i> Account Balance</h3>
|
||||||
<div class="balance-display">
|
<button
|
||||||
<span class="balance-amount" id="displayBalance">0 XRP</span>
|
onclick="copyBalanceLink()"
|
||||||
</div>
|
class="btn-icon share-btn"
|
||||||
|
title="Copy Shareable Link"
|
||||||
|
>
|
||||||
|
<i class="fas fa-share-alt"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="balance-display">
|
||||||
|
<span class="balance-amount" id="displayBalance">0 XRP</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="account-details">
|
<div class="account-details">
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
@ -148,6 +209,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Transaction Details Display -->
|
||||||
|
<div
|
||||||
|
class="card transaction-details"
|
||||||
|
id="transactionDetails"
|
||||||
|
style="display: none"
|
||||||
|
>
|
||||||
|
<div class="transaction-details-header">
|
||||||
|
<h3><i class="fas fa-receipt"></i> Transaction Details</h3>
|
||||||
|
<button
|
||||||
|
onclick="copyTransactionLink()"
|
||||||
|
class="btn-icon share-btn"
|
||||||
|
title="Copy Shareable Link"
|
||||||
|
>
|
||||||
|
<i class="fas fa-share-alt"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="transactionDetailsContent">
|
||||||
|
<!-- Transaction details -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Transaction Section -->
|
<!-- Transaction Section -->
|
||||||
<div
|
<div
|
||||||
id="transactionSection"
|
id="transactionSection"
|
||||||
|
|||||||
@ -775,7 +775,7 @@ async function confirmSend() {
|
|||||||
confirmBtn.innerHTML = originalText;
|
confirmBtn.innerHTML = originalText;
|
||||||
confirmBtn.disabled = false;
|
confirmBtn.disabled = false;
|
||||||
|
|
||||||
// Don't close popup here - it's handled in success/error cases
|
// Don't close popup here
|
||||||
window.pendingTransaction = null;
|
window.pendingTransaction = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -795,12 +795,12 @@ function displaySearchedAddresses(addresses) {
|
|||||||
let container = document.getElementById("searchedAddressesContainer");
|
let container = document.getElementById("searchedAddressesContainer");
|
||||||
|
|
||||||
if (!container && addresses.length > 0) {
|
if (!container && addresses.length > 0) {
|
||||||
// Create the container after the balance check card
|
// Create the container at the end of the connectPage
|
||||||
const balanceCard = document.querySelector("#connectPage .card");
|
const connectPage = document.getElementById("connectPage");
|
||||||
container = document.createElement("div");
|
container = document.createElement("div");
|
||||||
container.id = "searchedAddressesContainer";
|
container.id = "searchedAddressesContainer";
|
||||||
container.className = "card searched-addresses-card";
|
container.className = "card searched-addresses-card";
|
||||||
balanceCard.parentNode.insertBefore(container, balanceCard.nextSibling);
|
connectPage.appendChild(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
@ -1305,7 +1305,7 @@ async function checkBalanceAndTransactions() {
|
|||||||
try {
|
try {
|
||||||
if (!userInput) {
|
if (!userInput) {
|
||||||
notify(
|
notify(
|
||||||
"Please enter an XRP address, BTC private key, or FLO private key",
|
"Please enter an XRP address, XRP seed, BTC private key, or FLO private key",
|
||||||
"error"
|
"error"
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@ -1343,11 +1343,34 @@ async function checkBalanceAndTransactions() {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Detect if input is a private key and convert to XRP address
|
// Detect if input is a private key/seed and convert to XRP address
|
||||||
else if (!userInput.startsWith("r")) {
|
else if (!userInput.startsWith("r")) {
|
||||||
try {
|
try {
|
||||||
|
// Check if it's an XRP seed first (starts with 's')
|
||||||
|
if (userInput.startsWith("s") && userInput.length >= 25) {
|
||||||
|
try {
|
||||||
|
notify("Detected XRP seed - converting to XRP address...", "info");
|
||||||
|
|
||||||
|
const rippleWallet = xrpl.Wallet.fromSeed(userInput);
|
||||||
|
actualXRPAddress = rippleWallet.address;
|
||||||
|
|
||||||
|
sourceInfo = {
|
||||||
|
type: "XRP Seed",
|
||||||
|
originalKey: userInput,
|
||||||
|
originalAddress: actualXRPAddress,
|
||||||
|
blockchain: "XRP",
|
||||||
|
};
|
||||||
|
|
||||||
|
notify(
|
||||||
|
`Converted XRP seed to address: ${actualXRPAddress}`,
|
||||||
|
"success"
|
||||||
|
);
|
||||||
|
} catch (seedError) {
|
||||||
|
throw new Error("Invalid XRP seed format");
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if it's a Bitcoin WIF format (starts with "L" or "K")
|
// Check if it's a Bitcoin WIF format (starts with "L" or "K")
|
||||||
if (userInput.startsWith("L") || userInput.startsWith("K")) {
|
else if (userInput.startsWith("L") || userInput.startsWith("K")) {
|
||||||
notify(
|
notify(
|
||||||
"Detected Bitcoin private key - converting to XRP address...",
|
"Detected Bitcoin private key - converting to XRP address...",
|
||||||
"info"
|
"info"
|
||||||
@ -1460,6 +1483,12 @@ async function checkBalanceAndTransactions() {
|
|||||||
document.getElementById("checkedAddress").textContent =
|
document.getElementById("checkedAddress").textContent =
|
||||||
actualXRPAddress;
|
actualXRPAddress;
|
||||||
|
|
||||||
|
// Update URL for sharing
|
||||||
|
const currentUrl = new URL(window.location);
|
||||||
|
currentUrl.searchParams.set("address", actualXRPAddress);
|
||||||
|
currentUrl.searchParams.delete("tx"); // Remove transaction param if exists
|
||||||
|
window.history.pushState({}, "", currentUrl);
|
||||||
|
|
||||||
// Save to IndexedDB with source information
|
// Save to IndexedDB with source information
|
||||||
try {
|
try {
|
||||||
await searchedAddressDB.saveSearchedAddress(
|
await searchedAddressDB.saveSearchedAddress(
|
||||||
@ -1482,6 +1511,12 @@ async function checkBalanceAndTransactions() {
|
|||||||
document.getElementById("checkedAddress").textContent =
|
document.getElementById("checkedAddress").textContent =
|
||||||
actualXRPAddress;
|
actualXRPAddress;
|
||||||
|
|
||||||
|
// Update URL for sharing
|
||||||
|
const currentUrl = new URL(window.location);
|
||||||
|
currentUrl.searchParams.set("address", actualXRPAddress);
|
||||||
|
currentUrl.searchParams.delete("tx"); // Remove transaction param if exists
|
||||||
|
window.history.pushState({}, "", currentUrl);
|
||||||
|
|
||||||
// Save to IndexedDB with source information
|
// Save to IndexedDB with source information
|
||||||
try {
|
try {
|
||||||
await searchedAddressDB.saveSearchedAddress(
|
await searchedAddressDB.saveSearchedAddress(
|
||||||
@ -1906,6 +1941,282 @@ function generateFLOFromPrivateKey(privateKey) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Switch between search types
|
||||||
|
function switchSearchType(type) {
|
||||||
|
const balanceTab = document.getElementById("balanceTab");
|
||||||
|
const transactionTab = document.getElementById("transactionTab");
|
||||||
|
const balanceSearch = document.getElementById("balanceSearch");
|
||||||
|
const transactionSearch = document.getElementById("transactionSearch");
|
||||||
|
|
||||||
|
if (type === "balance") {
|
||||||
|
balanceTab.classList.add("active");
|
||||||
|
transactionTab.classList.remove("active");
|
||||||
|
balanceSearch.style.display = "block";
|
||||||
|
transactionSearch.style.display = "none";
|
||||||
|
|
||||||
|
// Hide transaction details if visible
|
||||||
|
document.getElementById("transactionDetails").style.display = "none";
|
||||||
|
} else {
|
||||||
|
transactionTab.classList.add("active");
|
||||||
|
balanceTab.classList.remove("active");
|
||||||
|
transactionSearch.style.display = "block";
|
||||||
|
balanceSearch.style.display = "none";
|
||||||
|
|
||||||
|
// Hide balance info if visible
|
||||||
|
document.getElementById("balanceInfo").style.display = "none";
|
||||||
|
document.getElementById("transactionSection").style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check transaction details by hash
|
||||||
|
async function checkTransactionDetails() {
|
||||||
|
const hashInput = document.getElementById("checkTransactionHash");
|
||||||
|
const txHash = hashInput.value.trim();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!txHash) {
|
||||||
|
notify("Please enter a transaction hash", "error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
const checkBtn = document.querySelector(
|
||||||
|
'[onclick="checkTransactionDetails()"]'
|
||||||
|
);
|
||||||
|
const originalText = checkBtn.innerHTML;
|
||||||
|
checkBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Loading...';
|
||||||
|
checkBtn.disabled = true;
|
||||||
|
|
||||||
|
// Create XRPL client instance
|
||||||
|
const client = new xrpl.Client("wss://s.altnet.rippletest.net:51233");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.connect();
|
||||||
|
|
||||||
|
// Get transaction details
|
||||||
|
const txResponse = await client.request({
|
||||||
|
command: "tx",
|
||||||
|
transaction: txHash,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (txResponse.result) {
|
||||||
|
displayTransactionDetails(txResponse.result);
|
||||||
|
|
||||||
|
// Update URL for sharing
|
||||||
|
const currentUrl = new URL(window.location);
|
||||||
|
currentUrl.searchParams.set("tx", txHash);
|
||||||
|
window.history.pushState({}, "", currentUrl);
|
||||||
|
|
||||||
|
notify("Transaction details loaded successfully", "success");
|
||||||
|
} else {
|
||||||
|
notify("Transaction not found", "error");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Transaction lookup error:", error);
|
||||||
|
if (error.data && error.data.error === "txnNotFound") {
|
||||||
|
notify(
|
||||||
|
"Transaction not found. Please check the hash and try again.",
|
||||||
|
"error"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
notify(
|
||||||
|
"Failed to fetch transaction details: " + error.message,
|
||||||
|
"error"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await client.disconnect();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in checkTransactionDetails:", error);
|
||||||
|
notify("An error occurred while checking transaction details", "error");
|
||||||
|
} finally {
|
||||||
|
// Restore button state
|
||||||
|
const checkBtn = document.querySelector(
|
||||||
|
'[onclick="checkTransactionDetails()"]'
|
||||||
|
);
|
||||||
|
if (checkBtn) {
|
||||||
|
checkBtn.innerHTML = '<i class="fas fa-search"></i> View Transaction';
|
||||||
|
checkBtn.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display transaction details
|
||||||
|
function displayTransactionDetails(txData) {
|
||||||
|
const detailsContainer = document.getElementById("transactionDetailsContent");
|
||||||
|
// console.log(txData);
|
||||||
|
// console.log(parseFloat(txData.Amount)/ 1000000);
|
||||||
|
// console.log(parseFloat(txData.Fee)/ 1000000);
|
||||||
|
|
||||||
|
const txType = txData.TransactionType || "Unknown";
|
||||||
|
const account = txData.Account || "N/A";
|
||||||
|
const destination = txData.Destination || "N/A";
|
||||||
|
const amount = txData.Amount
|
||||||
|
? parseFloat(txData.Amount) / 1000000 + " XRP"
|
||||||
|
: "N/A";
|
||||||
|
const fee = txData.Fee ? parseFloat(txData.Fee) / 1000000 + " XRP" : "N/A";
|
||||||
|
const sequence = txData.Sequence || "N/A";
|
||||||
|
const ledgerIndex = txData.ledger_index || "N/A";
|
||||||
|
const hash = txData.hash || "N/A";
|
||||||
|
const date = txData.date
|
||||||
|
? new Date((txData.date + 946684800) * 1000).toLocaleString()
|
||||||
|
: "N/A";
|
||||||
|
const validated = txData.validated ? "Validated" : "Not Validated";
|
||||||
|
|
||||||
|
detailsContainer.innerHTML = `
|
||||||
|
<div class="tx-detail-card">
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-check-circle"></i>
|
||||||
|
Status:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value success">${validated}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-exchange-alt"></i>
|
||||||
|
Type:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${txType}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-coins"></i>
|
||||||
|
Amount:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value amount">${amount}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-receipt"></i>
|
||||||
|
Fee:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${fee}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tx-detail-card">
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-user-minus"></i>
|
||||||
|
From:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${account}</span>
|
||||||
|
</div>
|
||||||
|
${
|
||||||
|
destination !== "N/A"
|
||||||
|
? `
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-user-plus"></i>
|
||||||
|
To:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${destination}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-hashtag"></i>
|
||||||
|
Hash:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${hash}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tx-detail-card">
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-layer-group"></i>
|
||||||
|
Ledger:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${ledgerIndex}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-sort-numeric-up"></i>
|
||||||
|
Sequence:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${sequence}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tx-detail-row">
|
||||||
|
<span class="tx-detail-label">
|
||||||
|
<i class="fas fa-clock"></i>
|
||||||
|
Date:
|
||||||
|
</span>
|
||||||
|
<span class="tx-detail-value">${date}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.getElementById("transactionDetails").style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
// shareable balance link
|
||||||
|
function copyBalanceLink() {
|
||||||
|
const address = document.getElementById("checkedAddress").textContent;
|
||||||
|
if (address && address !== "-") {
|
||||||
|
const currentUrl = new URL(window.location);
|
||||||
|
currentUrl.searchParams.set("address", address);
|
||||||
|
currentUrl.searchParams.delete("tx"); // Remove transaction param if exists
|
||||||
|
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(currentUrl.toString())
|
||||||
|
.then(() => {
|
||||||
|
notify("Balance link copied to clipboard!", "success");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
notify("Failed to copy link", "error");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notify("No address available to share", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// shareable transaction link
|
||||||
|
function copyTransactionLink() {
|
||||||
|
const currentUrl = new URL(window.location);
|
||||||
|
const txHash = currentUrl.searchParams.get("tx");
|
||||||
|
|
||||||
|
if (txHash) {
|
||||||
|
navigator.clipboard
|
||||||
|
.writeText(currentUrl.toString())
|
||||||
|
.then(() => {
|
||||||
|
notify("Transaction link copied to clipboard!", "success");
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
notify("Failed to copy link", "error");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notify("No transaction hash available to share", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle URL parameters on page load
|
||||||
|
function handleUrlParameters() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const address = urlParams.get("address");
|
||||||
|
const txHash = urlParams.get("tx");
|
||||||
|
|
||||||
|
if (address) {
|
||||||
|
// Auto-fill address and check balance
|
||||||
|
document.getElementById("checkAddress").value = address;
|
||||||
|
switchSearchType("balance");
|
||||||
|
setTimeout(() => {
|
||||||
|
checkBalanceAndTransactions();
|
||||||
|
}, 500);
|
||||||
|
} else if (txHash) {
|
||||||
|
// Auto-fill transaction hash and check details
|
||||||
|
document.getElementById("checkTransactionHash").value = txHash;
|
||||||
|
switchSearchType("transaction");
|
||||||
|
setTimeout(() => {
|
||||||
|
checkTransactionDetails();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window.sendXRP = sendXRP;
|
window.sendXRP = sendXRP;
|
||||||
|
|
||||||
window.retrieveXRPAddress = retrieveXRPAddress;
|
window.retrieveXRPAddress = retrieveXRPAddress;
|
||||||
@ -1915,6 +2226,12 @@ window.confirmSend = confirmSend;
|
|||||||
window.closePopup = closePopup;
|
window.closePopup = closePopup;
|
||||||
window.checkBalanceAndTransactions = checkBalanceAndTransactions;
|
window.checkBalanceAndTransactions = checkBalanceAndTransactions;
|
||||||
|
|
||||||
|
window.switchSearchType = switchSearchType;
|
||||||
|
window.checkTransactionDetails = checkTransactionDetails;
|
||||||
|
window.copyBalanceLink = copyBalanceLink;
|
||||||
|
window.copyTransactionLink = copyTransactionLink;
|
||||||
|
window.handleUrlParameters = handleUrlParameters;
|
||||||
|
|
||||||
window.convertWIFtoRippleWallet = convertWIFtoRippleWallet;
|
window.convertWIFtoRippleWallet = convertWIFtoRippleWallet;
|
||||||
|
|
||||||
// Multi-blockchain function exports
|
// Multi-blockchain function exports
|
||||||
@ -1938,4 +2255,5 @@ window.copyCurrentAddress = copyCurrentAddress;
|
|||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
initializeInputControls();
|
initializeInputControls();
|
||||||
|
handleUrlParameters();
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user