613 lines
23 KiB
HTML
613 lines
23 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Ripple Wallet</title>
|
|
<link rel="shortcut icon" href="favicon.svg" type="image/x-icon" />
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
|
|
/>
|
|
<link rel="stylesheet" href="css/main.css" />
|
|
|
|
<!-- External Libraries -->
|
|
<script src="https://cdn.jsdelivr.net/npm/xrpl@2.7.0/build/xrpl-latest-min.js"></script>
|
|
<script src="https://unpkg.com/uhtml@3.0.1/es.js"></script>
|
|
|
|
<script src="https://unpkg.com/@preact/signals-core@1.7.0/dist/signals-core.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/elliptic/6.6.1/elliptic.min.js"></script>
|
|
</head>
|
|
<body class="hidden">
|
|
<!-- Loading Screen -->
|
|
<div id="loading_page" class="loading-screen">
|
|
<div class="loading-content">
|
|
<div class="loading-spinner"></div>
|
|
<h2>Ripple Wallet</h2>
|
|
<p>Loading...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Header -->
|
|
<header class="header">
|
|
<div class="header-content">
|
|
<div id="logo" class="app-brand">
|
|
<svg id="main_logo" class="icon" viewBox="0 0 27.25 32">
|
|
<title>RanchiMall</title>
|
|
<path
|
|
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z"
|
|
/>
|
|
</svg>
|
|
<div class="app-name">
|
|
<div class="app-name__company">RanchiMall</div>
|
|
<h4 class="app-name__title">Ripple Wallet</h4>
|
|
</div>
|
|
</div>
|
|
<div class="header-actions">
|
|
<button
|
|
id="themeToggle"
|
|
class="theme-toggle"
|
|
title="Toggle dark/light mode"
|
|
>
|
|
<i class="fas fa-sun" id="themeIcon"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Main Container -->
|
|
<div class="container">
|
|
<!-- Sidebar Navigation -->
|
|
<nav class="sidebar" id="sidebar">
|
|
<div class="sidebar-header">
|
|
<i class="fas fa-wallet"></i>
|
|
<h3>Ripple Wallet</h3>
|
|
</div>
|
|
<ul class="sidebar-menu">
|
|
<li>
|
|
<a
|
|
href="#"
|
|
onclick="showPage('connectPage')"
|
|
class="nav-link active"
|
|
>
|
|
<i class="fas fa-search-dollar"></i>Balance
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#" onclick="showPage('sendPage')" class="nav-link">
|
|
<i class="fas fa-paper-plane"></i> Send XRP
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#" onclick="showPage('generatePage')" class="nav-link">
|
|
<i class="fas fa-plus-circle"></i> Generate Address
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="#" onclick="showPage('recoverPage')" class="nav-link">
|
|
<i class="fas fa-key"></i> Retrieve Address
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- Main Content Area -->
|
|
<main class="main-content">
|
|
<!-- Check Balance & Transactions Page -->
|
|
<div id="connectPage" class="page">
|
|
<div class="page-header">
|
|
<h2><i class="fas fa-search-dollar"></i> Check Balance</h2>
|
|
<p>
|
|
Check the XRP balance and transaction history for any Ripple
|
|
address
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<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...), private key (BTC/FLO)"
|
|
autocomplete="off"
|
|
/>
|
|
<div class="input-help">
|
|
Enter an XRP address,private key (BTC/FLO) to check XRP balance
|
|
</div>
|
|
</div>
|
|
|
|
<button
|
|
onclick="checkBalanceAndTransactions()"
|
|
class="btn btn-primary btn-block"
|
|
>
|
|
<i class="fas fa-search-dollar"></i> Check Balance
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Balance Info Display -->
|
|
<div class="card balance-info" id="balanceInfo" style="display: none">
|
|
<div class="balance-header">
|
|
<h3><i class="fas fa-coins"></i> Account Balance</h3>
|
|
<div class="balance-display">
|
|
<span class="balance-amount" id="displayBalance">0 XRP</span>
|
|
</div>
|
|
</div>
|
|
<div class="account-details">
|
|
<div class="detail-row">
|
|
<label>Address:</label>
|
|
<div class="address-container">
|
|
<span id="checkedAddress" class="address-text">-</span>
|
|
<button
|
|
onclick="copyAddressToClipboard(document.getElementById('checkedAddress').textContent)"
|
|
class="btn-icon"
|
|
title="Copy Address"
|
|
>
|
|
<i class="fas fa-copy"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Transaction Section -->
|
|
<div
|
|
id="transactionSection"
|
|
class="card transaction-section"
|
|
style="display: none"
|
|
>
|
|
<!-- Transaction Header and Filter Controls -->
|
|
<div id="transactionControls" class="transaction-controls">
|
|
<div class="transaction-header">
|
|
<h3>Transactions</h3>
|
|
<div class="filter-buttons">
|
|
<button
|
|
class="filter-btn active"
|
|
data-filter="all"
|
|
onclick="setTransactionFilter('all')"
|
|
>
|
|
<i class="fas fa-list"></i> All
|
|
</button>
|
|
<button
|
|
class="filter-btn"
|
|
data-filter="received"
|
|
onclick="setTransactionFilter('received')"
|
|
>
|
|
<i class="fas fa-arrow-down"></i> Received
|
|
</button>
|
|
<button
|
|
class="filter-btn"
|
|
data-filter="sent"
|
|
onclick="setTransactionFilter('sent')"
|
|
>
|
|
<i class="fas fa-arrow-up"></i> Sent
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Transaction Results -->
|
|
<div id="txList" class="transaction-list">
|
|
<!-- Transaction cards will be inserted here -->
|
|
</div>
|
|
|
|
<!-- Pagination Controls (moved below transaction list) -->
|
|
<div class="pagination-section">
|
|
<div class="pagination-info" id="paginationInfo">
|
|
Showing 0 - 0 of 0 transactions
|
|
</div>
|
|
<div class="pagination-controls">
|
|
<button
|
|
class="pagination-btn"
|
|
id="prevBtn"
|
|
onclick="goToPreviousPage()"
|
|
disabled
|
|
>
|
|
<i class="fas fa-chevron-left"></i>
|
|
</button>
|
|
<div class="page-numbers" id="pageNumbers">
|
|
<!-- Page numbers will be inserted here -->
|
|
</div>
|
|
<button
|
|
class="pagination-btn"
|
|
id="nextBtn"
|
|
onclick="goToNextPage()"
|
|
disabled
|
|
>
|
|
<i class="fas fa-chevron-right"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Send XRP Page -->
|
|
<div id="sendPage" class="page hidden">
|
|
<div class="page-header">
|
|
<h2><i class="fas fa-paper-plane"></i> Send XRP</h2>
|
|
<p>Send XRP to another Ripple address</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="form-group">
|
|
<label for="sendKey">
|
|
<i class="fas fa-key"></i> Your Ripple Seed or Private Key
|
|
(FLO/BTC)
|
|
</label>
|
|
<input
|
|
type="password"
|
|
id="sendKey"
|
|
class="form-input"
|
|
placeholder="Enter your seed (s...) or private key (FLO/BTC)"
|
|
autocomplete="off"
|
|
/>
|
|
<div class="input-help">Use your Ripple seed (s...)</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="recipient">
|
|
<i class="fas fa-user"></i> Recipient Address
|
|
</label>
|
|
<input
|
|
type="text"
|
|
id="recipient"
|
|
class="form-input"
|
|
placeholder="Enter Ripple address (r...)"
|
|
/>
|
|
<small class="help-text"
|
|
>Enter a valid Ripple address starting with 'r' (25-34
|
|
characters)</small
|
|
>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="amount">
|
|
<i class="fas fa-coins"></i> Amount (XRP)
|
|
</label>
|
|
<input
|
|
type="number"
|
|
id="amount"
|
|
class="form-input"
|
|
placeholder="0.00"
|
|
step="0.000001"
|
|
min="0.000001"
|
|
/>
|
|
<div class="input-help">Minimum: 0.000001 XRP</div>
|
|
</div>
|
|
|
|
<button onclick="sendXRP()" class="btn btn-primary btn-block">
|
|
<i class="fas fa-paper-plane"></i> Send XRP
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Generate Address Page -->
|
|
<div id="generatePage" class="page hidden">
|
|
<div class="page-header">
|
|
<h2><i class="fas fa-plus-circle"></i> Generate XRP Address</h2>
|
|
<p>Generate XRP addresses from private keys of any blockchain</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<!-- Private Key Input for XRP Generation -->
|
|
<div class="form-group">
|
|
<label for="generateKey">
|
|
<i class="fas fa-key"></i> Private Key (Required for XRP)
|
|
</label>
|
|
<input
|
|
type="password"
|
|
id="generateKey"
|
|
placeholder="Enter private key from any blockchain (BTC/FLO)"
|
|
class="form-input"
|
|
/>
|
|
<small class="form-text">
|
|
Enter a private key from any blockchain (BTC/FLO) to generate
|
|
the corresponding XRP address.
|
|
</small>
|
|
</div>
|
|
|
|
<div class="generate-actions">
|
|
<button
|
|
onclick="generateXRPAddress()"
|
|
class="btn btn-primary btn-block"
|
|
>
|
|
<i class="fas fa-coins"></i> Generate XRP Address
|
|
</button>
|
|
</div>
|
|
|
|
<!-- XRP Generation Info -->
|
|
<div
|
|
id="xrpGenerationInfo"
|
|
class="card info-card"
|
|
style="display: none"
|
|
>
|
|
<div class="info-header">
|
|
<h3>
|
|
<i class="fas fa-info-circle"></i> XRP Address Generation
|
|
</h3>
|
|
</div>
|
|
<div class="info-content">
|
|
<p>
|
|
<strong>Note:</strong> This wallet doesn't generate XRP
|
|
addresses directly.
|
|
</p>
|
|
<p>To get an XRP address, please:</p>
|
|
<ol>
|
|
<li>Use our BTC wallet to generate a BTC private key</li>
|
|
<li>
|
|
Convert that BTC/FLO private key to Ripple seed using the
|
|
conversion tool below
|
|
</li>
|
|
</ol>
|
|
<button
|
|
onclick="showPage('convertPage')"
|
|
class="btn btn-primary"
|
|
>
|
|
<i class="fas fa-exchange-alt"></i> Go to Conversion Tool
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Generated Address Output -->
|
|
<div id="walletOutput" class="card output-card" style="display: none">
|
|
<!-- Generated address info will be inserted here -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Retrieve Address Page -->
|
|
<div id="recoverPage" class="page hidden">
|
|
<div class="page-header">
|
|
<h2><i class="fas fa-key"></i> Retrieve XRP Address</h2>
|
|
<p>Retrieve your XRP address from private key</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="form-group">
|
|
<label for="recoverKey">
|
|
<i class="fas fa-key"></i> Private Key / Seed
|
|
</label>
|
|
<input
|
|
type="password"
|
|
id="recoverKey"
|
|
class="form-input"
|
|
placeholder="Enter private key or seed"
|
|
autocomplete="off"
|
|
/>
|
|
<div class="input-help">
|
|
Enter your private key from any blockchain (BTC/FLO) or XRP seed
|
|
(s...) to retrieve your XRP address.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="retrieve-actions">
|
|
<button
|
|
onclick="retrieveXRPAddress()"
|
|
class="btn btn-primary btn-block"
|
|
>
|
|
<i class="fas fa-coins"></i> Retrieve XRP Address
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Retrieved Address Output -->
|
|
<div
|
|
id="recoveryOutput"
|
|
class="card output-card"
|
|
style="display: none"
|
|
>
|
|
<!-- Retrieved address info will be inserted here -->
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- Bottom Navigation (Mobile) -->
|
|
<div class="nav-box">
|
|
<button
|
|
onclick="showPage('connectPage')"
|
|
class="nav-btn active"
|
|
data-page="connectPage"
|
|
>
|
|
<i class="fas fa-search-dollar"></i>
|
|
<span>Balance</span>
|
|
</button>
|
|
<button
|
|
onclick="showPage('sendPage')"
|
|
class="nav-btn"
|
|
data-page="sendPage"
|
|
>
|
|
<i class="fas fa-paper-plane"></i>
|
|
<span>Send</span>
|
|
</button>
|
|
<button
|
|
onclick="showPage('generatePage')"
|
|
class="nav-btn"
|
|
data-page="generatePage"
|
|
>
|
|
<i class="fas fa-plus"></i>
|
|
<span>Generate</span>
|
|
</button>
|
|
<button
|
|
onclick="showPage('recoverPage')"
|
|
class="nav-btn"
|
|
data-page="recoverPage"
|
|
>
|
|
<i class="fas fa-key"></i>
|
|
<span>Retrieve</span>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Confirmation Popup -->
|
|
<sm-popup id="sendConfirm">
|
|
<div class="popup-content">
|
|
<h3><i class="fas fa-exclamation-triangle"></i> Confirm Transaction</h3>
|
|
<div class="transaction-details" id="transactionDetails">
|
|
<!-- Transaction details will be populated here -->
|
|
</div>
|
|
<div class="popup-actions">
|
|
<button onclick="closePopup()" class="btn btn-secondary">
|
|
<i class="fas fa-times"></i> Cancel
|
|
</button>
|
|
<button onclick="confirmSend()" class="btn btn-primary">
|
|
<i class="fas fa-paper-plane"></i> Send
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</sm-popup>
|
|
|
|
<!-- Transaction Success Popup -->
|
|
<sm-popup id="transactionSuccess">
|
|
<div class="popup-content">
|
|
<h3><i class="fas fa-check-circle"></i> Transaction Successful!</h3>
|
|
<div class="transaction-details" id="successTransactionDetails">
|
|
<!-- Success transaction details will be populated here -->
|
|
</div>
|
|
<div class="popup-actions">
|
|
<button onclick="closePopup()" class="btn btn-primary">
|
|
<i class="fas fa-check"></i> Close
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</sm-popup>
|
|
|
|
<!-- Standard UI Notifications -->
|
|
|
|
<!-- Confirmation Popup -->
|
|
<sm-popup id="confirmation_popup">
|
|
<div class="popup-content">
|
|
<h3 id="confirm_title">Confirm Action</h3>
|
|
<div id="confirm_message"></div>
|
|
<div class="popup-actions">
|
|
<button class="btn btn-secondary cancel-button">Cancel</button>
|
|
<button class="btn btn-primary confirm-button">OK</button>
|
|
</div>
|
|
</div>
|
|
</sm-popup>
|
|
|
|
<!-- Scripts -->
|
|
<script src="scripts/components.min.js"></script>
|
|
<script src="scripts/btcwallet_scripts_lib.js"></script>
|
|
<script type="text/javascript" src="scripts/floCrypto.js"></script>
|
|
<script type="text/javascript" src="scripts/btcOperator.js"></script>
|
|
|
|
<script type="module" src="scripts/wallet.js"></script>
|
|
<script>
|
|
// UI Enhancement Functions
|
|
function showPage(pageId) {
|
|
// Hide all pages
|
|
document.querySelectorAll(".page").forEach((page) => {
|
|
page.classList.add("hidden");
|
|
});
|
|
|
|
// Show selected page
|
|
document.getElementById(pageId).classList.remove("hidden");
|
|
|
|
// Update navigation states
|
|
updateNavigation(pageId);
|
|
}
|
|
|
|
function updateNavigation(activePageId) {
|
|
// Update sidebar navigation - remove active from all first
|
|
document.querySelectorAll(".sidebar .nav-link").forEach((link) => {
|
|
link.classList.remove("active");
|
|
});
|
|
|
|
// Update bottom navigation
|
|
document.querySelectorAll(".nav-btn").forEach((btn) => {
|
|
btn.classList.remove("active");
|
|
if (btn.dataset.page === activePageId) {
|
|
btn.classList.add("active");
|
|
}
|
|
});
|
|
|
|
// Find and activate corresponding sidebar link
|
|
const activeLink = document.querySelector(
|
|
`.sidebar .nav-link[onclick*="${activePageId}"]`
|
|
);
|
|
if (activeLink) {
|
|
activeLink.classList.add("active");
|
|
}
|
|
}
|
|
|
|
// Theme toggle functionality
|
|
function initializeTheme() {
|
|
const themeToggle = document.getElementById("themeToggle");
|
|
const themeIcon = document.getElementById("themeIcon");
|
|
const body = document.body;
|
|
|
|
// Check for saved theme preference or default to 'light'
|
|
const savedTheme = localStorage.getItem("theme");
|
|
const systemPrefersDark = window.matchMedia(
|
|
"(prefers-color-scheme: dark)"
|
|
).matches;
|
|
|
|
// Set initial theme
|
|
let currentTheme = savedTheme || (systemPrefersDark ? "dark" : "light");
|
|
|
|
// Apply theme
|
|
body.setAttribute("data-theme", currentTheme);
|
|
updateThemeIcon(currentTheme);
|
|
|
|
// Add event listener for theme toggle
|
|
themeToggle.addEventListener("click", () => {
|
|
currentTheme = currentTheme === "light" ? "dark" : "light";
|
|
body.setAttribute("data-theme", currentTheme);
|
|
localStorage.setItem("theme", currentTheme);
|
|
updateThemeIcon(currentTheme);
|
|
notify(`Switched to ${currentTheme} mode`, "success");
|
|
});
|
|
}
|
|
|
|
function updateThemeIcon(theme) {
|
|
const themeIcon = document.getElementById("themeIcon");
|
|
if (theme === "dark") {
|
|
themeIcon.className = "fas fa-sun";
|
|
} else {
|
|
themeIcon.className = "fas fa-moon";
|
|
}
|
|
}
|
|
|
|
// Initialize theme when DOM is loaded
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
initializeTheme();
|
|
|
|
// Initialize searched addresses list
|
|
if (typeof updateSearchedAddressesList === "function") {
|
|
updateSearchedAddressesList();
|
|
}
|
|
|
|
// Add real-time validation for recipient address
|
|
const recipientInput = document.getElementById("recipient");
|
|
const helpText = recipientInput
|
|
? recipientInput.nextElementSibling
|
|
: null;
|
|
|
|
if (recipientInput && helpText) {
|
|
recipientInput.addEventListener("input", function () {
|
|
const address = this.value.trim();
|
|
if (address && typeof validateAddressInput === "function") {
|
|
const validation = validateAddressInput(address);
|
|
if (validation.valid) {
|
|
helpText.textContent = "✓ Valid Ripple address";
|
|
helpText.style.color = "#22c55e";
|
|
} else {
|
|
helpText.textContent = validation.message;
|
|
helpText.style.color = "#ef4444";
|
|
}
|
|
} else {
|
|
helpText.textContent =
|
|
"Enter a valid Ripple address starting with 'r' (25-34 characters)";
|
|
helpText.style.color = "";
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
<div id="notification_drawer" class="notification-drawer"></div>
|
|
</body>
|
|
</html>
|