diff --git a/basicswap/static/js/wallets.js b/basicswap/static/js/wallets.js new file mode 100644 index 0000000..4f5f70c --- /dev/null +++ b/basicswap/static/js/wallets.js @@ -0,0 +1,654 @@ +const Wallets = (function() { + const CONFIG = { + MAX_RETRIES: 5, + BASE_DELAY: 500, + CACHE_EXPIRATION: 5 * 60 * 1000, + PRICE_UPDATE_INTERVAL: 5 * 60 * 1000, + API_TIMEOUT: 30000, + DEBOUNCE_DELAY: 300, + CACHE_MIN_INTERVAL: 60 * 1000, + DEFAULT_TTL: 300, + PRICE_SOURCE: { + PRIMARY: 'coingecko.com', + FALLBACK: 'cryptocompare.com', + ENABLED_SOURCES: ['coingecko.com', 'cryptocompare.com'] + } + }; + + const COIN_SYMBOLS = { + 'Bitcoin': 'BTC', + 'Particl': 'PART', + 'Monero': 'XMR', + 'Wownero': 'WOW', + 'Litecoin': 'LTC', + 'Dogecoin': 'DOGE', + 'Firo': 'FIRO', + 'Dash': 'DASH', + 'PIVX': 'PIVX', + 'Decred': 'DCR', + 'Bitcoin Cash': 'BCH' + }; + + const COINGECKO_IDS = { + 'BTC': 'btc', + 'PART': 'part', + 'XMR': 'xmr', + 'WOW': 'wownero', + 'LTC': 'ltc', + 'DOGE': 'doge', + 'FIRO': 'firo', + 'DASH': 'dash', + 'PIVX': 'pivx', + 'DCR': 'dcr', + 'BCH': 'bch' + }; + + const SHORT_NAMES = { + 'Bitcoin': 'BTC', + 'Particl': 'PART', + 'Monero': 'XMR', + 'Wownero': 'WOW', + 'Litecoin': 'LTC', + 'Litecoin MWEB': 'LTC MWEB', + 'Firo': 'FIRO', + 'Dash': 'DASH', + 'PIVX': 'PIVX', + 'Decred': 'DCR', + 'Bitcoin Cash': 'BCH', + 'Dogecoin': 'DOGE' + }; + + class Cache { + constructor(expirationTime) { + this.data = null; + this.timestamp = null; + this.expirationTime = expirationTime; + } + + isValid() { + return Boolean( + this.data && + this.timestamp && + (Date.now() - this.timestamp < this.expirationTime) + ); + } + + set(data) { + this.data = data; + this.timestamp = Date.now(); + } + + get() { + if (this.isValid()) { + return this.data; + } + return null; + } + + clear() { + this.data = null; + this.timestamp = null; + } + } + + class ApiClient { + constructor() { + this.cache = new Cache(CONFIG.CACHE_EXPIRATION); + this.lastFetchTime = 0; + } + + async fetchPrices(forceUpdate = false) { + const now = Date.now(); + const timeSinceLastFetch = now - this.lastFetchTime; + + if (!forceUpdate && timeSinceLastFetch < CONFIG.CACHE_MIN_INTERVAL) { + const cachedData = this.cache.get(); + if (cachedData) { + return cachedData; + } + } + + let lastError = null; + for (let attempt = 0; attempt < CONFIG.MAX_RETRIES; attempt++) { + try { + const processedData = {}; + const currentSource = CONFIG.PRICE_SOURCE.PRIMARY; + + const shouldIncludeWow = currentSource === 'coingecko.com'; + + const coinsToFetch = Object.values(COIN_SYMBOLS) + .filter(symbol => shouldIncludeWow || symbol !== 'WOW') + .map(symbol => COINGECKO_IDS[symbol] || symbol.toLowerCase()) + .join(','); + + const mainResponse = await fetch("/json/coinprices", { + method: "POST", + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + coins: coinsToFetch, + source: currentSource, + ttl: CONFIG.DEFAULT_TTL + }) + }); + + if (!mainResponse.ok) { + throw new Error(`HTTP error: ${mainResponse.status}`); + } + + const mainData = await mainResponse.json(); + + if (mainData && mainData.rates) { + Object.entries(mainData.rates).forEach(([coinId, price]) => { + const symbol = Object.entries(COINGECKO_IDS).find(([sym, id]) => id.toLowerCase() === coinId.toLowerCase())?.[0]; + if (symbol) { + const coinKey = Object.keys(COIN_SYMBOLS).find(key => COIN_SYMBOLS[key] === symbol); + if (coinKey) { + processedData[coinKey.toLowerCase().replace(' ', '-')] = { + usd: price, + btc: symbol === 'BTC' ? 1 : price / (mainData.rates.btc || 1) + }; + } + } + }); + } + + if (!shouldIncludeWow && !processedData['wownero']) { + try { + const wowResponse = await fetch("/json/coinprices", { + method: "POST", + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + coins: "wownero", + source: "coingecko.com", + ttl: CONFIG.DEFAULT_TTL + }) + }); + + if (wowResponse.ok) { + const wowData = await wowResponse.json(); + if (wowData && wowData.rates && wowData.rates.wownero) { + processedData['wownero'] = { + usd: wowData.rates.wownero, + btc: processedData.bitcoin ? wowData.rates.wownero / processedData.bitcoin.usd : 0 + }; + } + } + } catch (wowError) { + console.error('Error fetching WOW price:', wowError); + } + } + + this.cache.set(processedData); + this.lastFetchTime = now; + return processedData; + } catch (error) { + lastError = error; + console.error(`Price fetch attempt ${attempt + 1} failed:`, error); + + if (attempt === CONFIG.MAX_RETRIES - 1 && + CONFIG.PRICE_SOURCE.FALLBACK && + CONFIG.PRICE_SOURCE.FALLBACK !== CONFIG.PRICE_SOURCE.PRIMARY) { + const temp = CONFIG.PRICE_SOURCE.PRIMARY; + CONFIG.PRICE_SOURCE.PRIMARY = CONFIG.PRICE_SOURCE.FALLBACK; + CONFIG.PRICE_SOURCE.FALLBACK = temp; + + console.warn(`Switching to fallback source: ${CONFIG.PRICE_SOURCE.PRIMARY}`); + attempt = -1; + continue; + } + + if (attempt < CONFIG.MAX_RETRIES - 1) { + const delay = Math.min(CONFIG.BASE_DELAY * Math.pow(2, attempt), 10000); + await new Promise(resolve => setTimeout(resolve, delay)); + } + } + } + + const cachedData = this.cache.get(); + if (cachedData) { + console.warn('Using cached data after fetch failures'); + return cachedData; + } + + throw lastError || new Error('Failed to fetch prices'); + } + + setPriceSource(primarySource, fallbackSource = null) { + if (!CONFIG.PRICE_SOURCE.ENABLED_SOURCES.includes(primarySource)) { + throw new Error(`Invalid primary source: ${primarySource}`); + } + + if (fallbackSource && !CONFIG.PRICE_SOURCE.ENABLED_SOURCES.includes(fallbackSource)) { + throw new Error(`Invalid fallback source: ${fallbackSource}`); + } + + CONFIG.PRICE_SOURCE.PRIMARY = primarySource; + if (fallbackSource) { + CONFIG.PRICE_SOURCE.FALLBACK = fallbackSource; + } + } + } + + class UiManager { + constructor() { + this.api = new ApiClient(); + this.toggleInProgress = false; + this.toggleDebounceTimer = null; + this.priceUpdateInterval = null; + this.lastUpdateTime = parseInt(localStorage.getItem(STATE_KEYS.LAST_UPDATE) || '0'); + this.isWalletsPage = document.querySelector('.wallet-list') !== null || + window.location.pathname.includes('/wallets'); + } + + getShortName(fullName) { + return SHORT_NAMES[fullName] || fullName; + } + + storeOriginalValues() { + document.querySelectorAll('.coinname-value').forEach(el => { + const coinName = el.getAttribute('data-coinname'); + const value = el.textContent?.trim() || ''; + + if (coinName) { + const amount = value ? parseFloat(value.replace(/[^0-9.-]+/g, '')) : 0; + const coinId = COIN_SYMBOLS[coinName]; + const shortName = this.getShortName(coinName); + + if (coinId) { + if (coinName === 'Particl') { + const isBlind = el.closest('.flex')?.querySelector('h4')?.textContent?.includes('Blind'); + const isAnon = el.closest('.flex')?.querySelector('h4')?.textContent?.includes('Anon'); + const balanceType = isBlind ? 'blind' : isAnon ? 'anon' : 'public'; + localStorage.setItem(`particl-${balanceType}-amount`, amount.toString()); + } else if (coinName === 'Litecoin') { + const isMWEB = el.closest('.flex')?.querySelector('h4')?.textContent?.includes('MWEB'); + const balanceType = isMWEB ? 'mweb' : 'public'; + localStorage.setItem(`litecoin-${balanceType}-amount`, amount.toString()); + } else { + localStorage.setItem(`${coinId.toLowerCase()}-amount`, amount.toString()); + } + + el.setAttribute('data-original-value', `${amount} ${shortName}`); + } + } + }); + + document.querySelectorAll('.usd-value').forEach(el => { + const text = el.textContent?.trim() || ''; + if (text === 'Loading...') { + el.textContent = ''; + } + }); + } + + async updatePrices(forceUpdate = false) { + try { + const prices = await this.api.fetchPrices(forceUpdate); + let newTotal = 0; + + const currentTime = Date.now(); + localStorage.setItem(STATE_KEYS.LAST_UPDATE, currentTime.toString()); + this.lastUpdateTime = currentTime; + + if (prices) { + Object.entries(prices).forEach(([coinId, priceData]) => { + if (priceData?.usd) { + localStorage.setItem(`${coinId}-price`, priceData.usd.toString()); + } + }); + } + + document.querySelectorAll('.coinname-value').forEach(el => { + const coinName = el.getAttribute('data-coinname'); + const amountStr = el.getAttribute('data-original-value') || el.textContent?.trim() || ''; + + if (!coinName) return; + + let amount = 0; + if (amountStr) { + const matches = amountStr.match(/([0-9]*[.])?[0-9]+/); + if (matches && matches.length > 0) { + amount = parseFloat(matches[0]); + } + } + + const coinId = coinName.toLowerCase().replace(' ', '-'); + + if (!prices[coinId]) { + return; + } + + const price = prices[coinId]?.usd || parseFloat(localStorage.getItem(`${coinId}-price`) || '0'); + if (!price) return; + + const usdValue = (amount * price).toFixed(2); + + if (coinName === 'Particl') { + const isBlind = el.closest('.flex')?.querySelector('h4')?.textContent?.includes('Blind'); + const isAnon = el.closest('.flex')?.querySelector('h4')?.textContent?.includes('Anon'); + const balanceType = isBlind ? 'blind' : isAnon ? 'anon' : 'public'; + localStorage.setItem(`particl-${balanceType}-last-value`, usdValue); + localStorage.setItem(`particl-${balanceType}-amount`, amount.toString()); + } else if (coinName === 'Litecoin') { + const isMWEB = el.closest('.flex')?.querySelector('h4')?.textContent?.includes('MWEB'); + const balanceType = isMWEB ? 'mweb' : 'public'; + localStorage.setItem(`litecoin-${balanceType}-last-value`, usdValue); + localStorage.setItem(`litecoin-${balanceType}-amount`, amount.toString()); + } else { + localStorage.setItem(`${coinId}-last-value`, usdValue); + localStorage.setItem(`${coinId}-amount`, amount.toString()); + } + + if (amount > 0) { + newTotal += parseFloat(usdValue); + } + + let usdEl = null; + + const flexContainer = el.closest('.flex'); + if (flexContainer) { + const nextFlex = flexContainer.nextElementSibling; + if (nextFlex) { + const usdInNextFlex = nextFlex.querySelector('.usd-value'); + if (usdInNextFlex) { + usdEl = usdInNextFlex; + } + } + } + + if (!usdEl) { + const parentCell = el.closest('td'); + if (parentCell) { + const usdInSameCell = parentCell.querySelector('.usd-value'); + if (usdInSameCell) { + usdEl = usdInSameCell; + } + } + } + + if (!usdEl) { + const sibling = el.nextElementSibling; + if (sibling && sibling.classList.contains('usd-value')) { + usdEl = sibling; + } + } + + if (!usdEl) { + const parentElement = el.parentElement; + if (parentElement) { + const usdElNearby = parentElement.querySelector('.usd-value'); + if (usdElNearby) { + usdEl = usdElNearby; + } + } + } + + if (usdEl) { + usdEl.textContent = `$${usdValue}`; + usdEl.setAttribute('data-original-value', usdValue); + } + }); + + document.querySelectorAll('.usd-value').forEach(el => { + if (el.closest('tr')?.querySelector('td')?.textContent?.includes('Fee Estimate:')) { + const parentCell = el.closest('td'); + if (!parentCell) return; + + const coinValueEl = parentCell.querySelector('.coinname-value'); + if (!coinValueEl) return; + + const coinName = coinValueEl.getAttribute('data-coinname'); + if (!coinName) return; + + const amountStr = coinValueEl.textContent?.trim() || '0'; + const amount = parseFloat(amountStr) || 0; + + const coinId = coinName.toLowerCase().replace(' ', '-'); + if (!prices[coinId]) return; + + const price = prices[coinId]?.usd || parseFloat(localStorage.getItem(`${coinId}-price`) || '0'); + if (!price) return; + + const usdValue = (amount * price).toFixed(8); + el.textContent = `$${usdValue}`; + el.setAttribute('data-original-value', usdValue); + } + }); + + if (this.isWalletsPage) { + this.updateTotalValues(newTotal, prices?.bitcoin?.usd); + } + + localStorage.setItem(STATE_KEYS.PREVIOUS_TOTAL, localStorage.getItem(STATE_KEYS.CURRENT_TOTAL) || '0'); + localStorage.setItem(STATE_KEYS.CURRENT_TOTAL, newTotal.toString()); + + return true; + } catch (error) { + console.error('Price update failed:', error); + return false; + } + } + + updateTotalValues(totalUsd, btcPrice) { + const totalUsdEl = document.getElementById('total-usd-value'); + if (totalUsdEl) { + totalUsdEl.textContent = `$${totalUsd.toFixed(2)}`; + totalUsdEl.setAttribute('data-original-value', totalUsd.toString()); + localStorage.setItem('total-usd', totalUsd.toString()); + } + + if (btcPrice) { + const btcTotal = btcPrice ? totalUsd / btcPrice : 0; + const totalBtcEl = document.getElementById('total-btc-value'); + if (totalBtcEl) { + totalBtcEl.textContent = `~ ${btcTotal.toFixed(8)} BTC`; + totalBtcEl.setAttribute('data-original-value', btcTotal.toString()); + } + } + } + + async toggleBalances() { + if (this.toggleInProgress) return; + + try { + this.toggleInProgress = true; + const balancesVisible = localStorage.getItem('balancesVisible') === 'true'; + const newVisibility = !balancesVisible; + + localStorage.setItem('balancesVisible', newVisibility.toString()); + this.updateVisibility(newVisibility); + + if (this.toggleDebounceTimer) { + clearTimeout(this.toggleDebounceTimer); + } + + this.toggleDebounceTimer = window.setTimeout(async () => { + this.toggleInProgress = false; + if (newVisibility) { + await this.updatePrices(true); + } + }, CONFIG.DEBOUNCE_DELAY); + } catch (error) { + console.error('Failed to toggle balances:', error); + this.toggleInProgress = false; + } + } + + updateVisibility(isVisible) { + if (isVisible) { + this.showBalances(); + } else { + this.hideBalances(); + } + + const eyeIcon = document.querySelector("#hide-usd-amount-toggle svg"); + if (eyeIcon) { + eyeIcon.innerHTML = isVisible ? + '' : + ''; + } + } + + showBalances() { + const usdText = document.getElementById('usd-text'); + if (usdText) { + usdText.style.display = 'inline'; + } + + document.querySelectorAll('.coinname-value').forEach(el => { + const originalValue = el.getAttribute('data-original-value'); + if (originalValue) { + el.textContent = originalValue; + } + }); + + document.querySelectorAll('.usd-value').forEach(el => { + const storedValue = el.getAttribute('data-original-value'); + if (storedValue !== null && storedValue !== undefined) { + if (el.closest('tr')?.querySelector('td')?.textContent?.includes('Fee Estimate:')) { + el.textContent = `$${parseFloat(storedValue).toFixed(8)}`; + } else { + el.textContent = `$${parseFloat(storedValue).toFixed(2)}`; + } + } else { + if (el.closest('tr')?.querySelector('td')?.textContent?.includes('Fee Estimate:')) { + el.textContent = '$0.00000000'; + } else { + el.textContent = '$0.00'; + } + } + }); + + if (this.isWalletsPage) { + ['total-usd-value', 'total-btc-value'].forEach(id => { + const el = document.getElementById(id); + const originalValue = el?.getAttribute('data-original-value'); + if (el && originalValue) { + if (id === 'total-usd-value') { + el.textContent = `$${parseFloat(originalValue).toFixed(2)}`; + el.classList.add('font-extrabold'); + } else { + el.textContent = `~ ${parseFloat(originalValue).toFixed(8)} BTC`; + } + } + }); + } + } + + hideBalances() { + const usdText = document.getElementById('usd-text'); + if (usdText) { + usdText.style.display = 'none'; + } + + document.querySelectorAll('.coinname-value').forEach(el => { + el.textContent = '****'; + }); + + document.querySelectorAll('.usd-value').forEach(el => { + el.textContent = '****'; + }); + + if (this.isWalletsPage) { + ['total-usd-value', 'total-btc-value'].forEach(id => { + const el = document.getElementById(id); + if (el) { + el.textContent = '****'; + } + }); + + const totalUsdEl = document.getElementById('total-usd-value'); + if (totalUsdEl) { + totalUsdEl.classList.remove('font-extrabold'); + } + } + } + + async initialize() { + document.querySelectorAll('.usd-value').forEach(el => { + const text = el.textContent?.trim() || ''; + if (text === 'Loading...') { + el.textContent = ''; + } + }); + + this.storeOriginalValues(); + + if (localStorage.getItem('balancesVisible') === null) { + localStorage.setItem('balancesVisible', 'true'); + } + + const hideBalancesToggle = document.getElementById('hide-usd-amount-toggle'); + if (hideBalancesToggle) { + hideBalancesToggle.addEventListener('click', () => this.toggleBalances()); + } + + await this.loadBalanceVisibility(); + + if (this.priceUpdateInterval) { + clearInterval(this.priceUpdateInterval); + } + + this.priceUpdateInterval = setInterval(() => { + if (localStorage.getItem('balancesVisible') === 'true' && !this.toggleInProgress) { + this.updatePrices(false); + } + }, CONFIG.PRICE_UPDATE_INTERVAL); + } + + async loadBalanceVisibility() { + const balancesVisible = localStorage.getItem('balancesVisible') === 'true'; + this.updateVisibility(balancesVisible); + + if (balancesVisible) { + await this.updatePrices(true); + } + } + + cleanup() { + if (this.priceUpdateInterval) { + clearInterval(this.priceUpdateInterval); + } + } + } + + const STATE_KEYS = { + LAST_UPDATE: 'last-update-time', + PREVIOUS_TOTAL: 'previous-total-usd', + CURRENT_TOTAL: 'current-total-usd', + BALANCES_VISIBLE: 'balancesVisible' + }; + + return { + initialize: function() { + const uiManager = new UiManager(); + + window.cryptoPricingManager = uiManager; + + window.addEventListener('beforeunload', () => { + uiManager.cleanup(); + }); + + uiManager.initialize().catch(error => { + console.error('Failed to initialize crypto pricing:', error); + }); + + return uiManager; + }, + + getUiManager: function() { + return window.cryptoPricingManager; + }, + + setPriceSource: function(primarySource, fallbackSource = null) { + const uiManager = this.getUiManager(); + if (uiManager && uiManager.api) { + uiManager.api.setPriceSource(primarySource, fallbackSource); + } + } + }; +})(); + +document.addEventListener('DOMContentLoaded', function() { + Wallets.initialize(); +}); diff --git a/basicswap/templates/header.html b/basicswap/templates/header.html index a8ed7ae..0e8b867 100644 --- a/basicswap/templates/header.html +++ b/basicswap/templates/header.html @@ -120,8 +120,25 @@ updateShutdownButtons(); }); - + + + -
-
-
-
- -
-
-
-
-
-
-
dots-red wave + +
+
+
+ dots-red + wave
-

{{ w.name }}({{ w.ticker }}) {{ w.name }} Wallet

+

+ + {{ w.name }}({{ w.ticker }}) {{ w.name }} Wallet

-
- {% include 'inc_messages.html' %} - {% if w.updating %} +
+ +{% include 'inc_messages.html' %} + +{% if w.updating %} - {% endif %} - {% if w.havedata %} - {% if w.error %} +{% endif %} + +{% if w.havedata %} +{% if w.error %} - {% else %} +{% else %} + {% if w.cid == '18' %} {# DOGE #}
-
    -
  • NOTICE:
  • - This version of DOGE Core is experimental and has been custom-built for compatibility with BasicSwap. As a result, it may not always be fully aligned with upstream changes, features unrelated to BasicSwap might not work as expected, and its code may differ from the official release. + NOTICE: This version of DOGE Core is experimental and has been custom-built for compatibility with BasicSwap. As a result, it may not always be fully aligned with upstream changes, features unrelated to BasicSwap might not work as expected, and its code may differ from the official release.
@@ -102,9 +94,10 @@
{% endif %} -
+ +
-
+
@@ -125,39 +118,46 @@ {{ w.name }} Balance: - {{ w.balance }} {{ w.ticker }} () - {% if w.pending %} - Pending: +{{ w.pending }} {{ w.ticker }} - {% endif %} - + + {{ w.balance }} {{ w.ticker }} + () + {% if w.pending %} + Pending: +{{ w.pending }} {{ w.ticker }} + {% endif %} + {% if w.cid == '1' %} {# PART #} {{ w.name }} Blind Blind Balance: - {{ w.blind_balance }} {{ w.ticker }} () - {% if w.blind_unconfirmed %} - Unconfirmed: +{{ w.blind_unconfirmed }} {{ w.ticker }} - {% endif %} - + + {{ w.blind_balance }} {{ w.ticker }} + () + {% if w.blind_unconfirmed %} + Unconfirmed: +{{ w.blind_unconfirmed }} {{ w.ticker }} + {% endif %} + {{ w.name }} Anon Anon Balance: - {{ w.anon_balance }} {{ w.ticker }} () + + {{ w.anon_balance }} {{ w.ticker }} + () {% if w.anon_pending %} - Pending: +{{ w.anon_pending }} {{ w.ticker }} - {% endif %} - - + Pending: +{{ w.anon_pending }} {{ w.ticker }} + {% endif %} + {# / PART #} {% elif w.cid == '3' %} {# LTC #} {{ w.name }} MWEB MWEB Balance: - {{ w.mweb_balance }} {{ w.ticker }} () - {% if w.mweb_pending %} - Pending: +{{ w.mweb_pending }} {{ w.ticker }} - {% endif %} - + + {{ w.mweb_balance }} {{ w.ticker }} + () + {% if w.mweb_pending %} + Pending: +{{ w.mweb_pending }} {{ w.ticker }} + {% endif %} + {% endif %} {# / LTC #} @@ -222,8 +222,9 @@
-
- {% if block_unknown_seeds and w.expected_seed != true %} {# Only show addresses if wallet seed is correct #} +
+ +{% if block_unknown_seeds and w.expected_seed != true %} {# Only show addresses if wallet seed is correct #}
@@ -246,6 +247,7 @@ {% else %} +
@@ -253,6 +255,7 @@
+
@@ -276,9 +279,8 @@
Main Address:
-
{{ w.main_address }}
+
{{ w.main_address }}
- @@ -292,11 +294,7 @@
- @@ -316,14 +314,13 @@
Subaddress:
-
{{ w.deposit_address }}
+
{{ w.deposit_address }}
-
Stealth Address:
-
{{ w.stealth_address }} +
{{ w.stealth_address }}
-
MWEB Address:
-
{{ w.mweb_address }}
+
{{ w.mweb_address }}
@@ -350,11 +346,8 @@
- @@ -368,7 +361,8 @@
- {% if w.cid == '1' %} + +{% if w.cid == '1' %} {# PART #} + {% elif w.cid == '3' %} {# LTC #} {% endif %} + {% if w.cid in '6, 9' %} {# XMR | WOW #} + + {% else %} + {% endif %} + -
+ +

Withdraw

-
-
-
-
-
-
-
-
-
-
- - - - - - - - - - - - {% if w.cid == '3' %} - {# LTC #} - - - - - {% elif w.cid == '1' %} - {# PART #} - - - - - - - - - {% endif %} - - - - - - - - - - {% if w.cid in '6, 9' %} {# XMR | WOW #} - - - {% else %} - - - {% endif %} - - - {% if w.cid == '1' %} - {# PART #} - - - - - - - - - {# / PART #} - {% elif w.cid == '3' %} {# LTC #} - - - - - {% endif %} - {# / LTC #} - {% if w.cid not in '6,9' %} {# Not XMR WOW #} - - - - - - - - - {% endif %} -
-
Options
-
-
Input
-
{{ w.name }} Balance: {{ w.balance }} {{ w.ticker }}
{{ w.name }} MWEB Balance: {{ w.mweb_balance }} {{ w.ticker }}
{{ w.name }} Blind Balance: {{ w.blind_balance }} {{ w.ticker }}
{{ w.name }} Anon Balance: {{ w.anon_balance }} {{ w.ticker }}
{{ w.name }} Address:
{{ w.name }} Amount: - -
-
+ + +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + {% if w.cid == '3' %} + {# LTC #} + + + + + {% elif w.cid == '1' %} + {# PART #} + + + + + + + + + {% endif %} + + + + + + + + + + {% if w.cid in '6, 9' %} {# XMR | WOW #} + + + {% else %} + + + {% endif %} + + + {% if w.cid == '1' %} + {# PART #} + + + + + + + + + {# / PART #} + {% elif w.cid == '3' %} {# LTC #} + + + + + {% endif %} + {# / LTC #} + {% if w.cid not in '6,9' %} {# Not XMR WOW #} + + + + + + + + + {% endif %} +
+
Options
+
+
Input
+
{{ w.name }} Balance: + {{ w.balance }} {{ w.ticker }} + () +
{{ w.name }} MWEB Balance: + {{ w.mweb_balance }} {{ w.ticker }} + () +
{{ w.name }} Blind Balance: + {{ w.blind_balance }} {{ w.ticker }} + () +
{{ w.name }} Anon Balance: + {{ w.anon_balance }} {{ w.ticker }} + () +
{{ w.name }} Address:
{{ w.name }} Amount: + +
+
+ {% if w.cid == '1' %} {# PART #} + + {# / PART #} + {% elif w.cid == '3' %} {# LTC #} + + {# / LTC #} {% else %} + -{% endif %} + let sweepAllCheckbox = document.getElementById('sweepall'); + if (sweepAllCheckbox) { + if (specialCids.includes(parseInt(cid)) && percent === 1) { + sweepAllCheckbox.checked = true; + console.log("Sweep All checkbox checked"); + } else { + sweepAllCheckbox.checked = false; + console.log("Sweep All checkbox unchecked"); + } + } + + let subfeeCheckbox = document.querySelector(`[name="subfee_${cid}"]`); + if (subfeeCheckbox) { + subfeeCheckbox.checked = (percent === 1); + console.log("Subfee checkbox status for CID", cid, ":", subfeeCheckbox.checked); + } + } + + {% endif %} +
+
+
Subtract Fee: + + +
Type From: +
+
{{ select_box_arrow_svg | safe }}
+
+
Type To: +
+
{{ select_box_arrow_svg }}
+
+
Type From: +
+
{{ select_box_arrow_svg }}
+
+
Fee Rate:{{ w.fee_rate }}
Fee Estimate: + {{ w.est_fee }} + () +
+
+
+
+
-
Subtract Fee: - - -
Type From: -
-
{{ select_box_arrow_svg | safe }}
-
-
Type To: -
-
{{ select_box_arrow_svg }}
-
-
Type From: -
-
{{ select_box_arrow_svg }}
-
-
Fee Rate:{{ w.fee_rate }}
Fee Estimate: {{ w.est_fee }}
-
-
-
-
-
-
-
-
-
-
+ + +
+ +
@@ -787,8 +968,9 @@ document.addEventListener('DOMContentLoaded', function() {
-
- {% if w.show_utxo_groups %} +
+ +{% if w.show_utxo_groups %}
@@ -796,6 +978,7 @@ document.addEventListener('DOMContentLoaded', function() {
+
@@ -834,6 +1017,7 @@ document.addEventListener('DOMContentLoaded', function() {
+
@@ -851,166 +1035,155 @@ document.addEventListener('DOMContentLoaded', function() {
- {% else %} {% endif %} + {% endif %} {% endif %} {% endif %} + + + + + {% include 'footer.html' %} diff --git a/basicswap/templates/wallets.html b/basicswap/templates/wallets.html index cee0aac..86b0a2a 100644 --- a/basicswap/templates/wallets.html +++ b/basicswap/templates/wallets.html @@ -1,29 +1,15 @@ {% include 'header.html' %} {% from 'style.html' import breadcrumb_line_svg, circular_arrows_svg, withdraw_svg, utxo_groups_svg, create_utxo_svg, lock_svg, eye_show_svg %} -
-
-
-
-
    -
  • Home

  • -
  • {{ breadcrumb_line_svg | safe }}
  • -
  • Wallets
  • -
  • {{ breadcrumb_line_svg | safe }}
  • -
-
-
-
- -
-
-
+
+
> +
dots-red dots-red wave
-

Wallets

+

Wallets

Total Assets:

@@ -42,11 +28,11 @@
- + {% include 'inc_messages.html' %}
-
+
{% for w in wallets %} {% if w.havedata %} @@ -73,7 +59,7 @@
{{ w.balance }} {{ w.ticker }}
-

{{ w.ticker }} USD value:

+

{{ w.ticker }} USD value:

{% if w.pending %} @@ -202,448 +188,10 @@ {% endfor %}
-
+ + + {% include 'footer.html' %} - -