diff --git a/basicswap/static/js/offerstable.js b/basicswap/static/js/offerstable.js
index cec0722..db64b3b 100644
--- a/basicswap/static/js/offerstable.js
+++ b/basicswap/static/js/offerstable.js
@@ -12,7 +12,7 @@ let filterTimeout = null;
 
 // Time Constants
 const MIN_REFRESH_INTERVAL = 60; // 60 sec
-const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes 
+const CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
 const FALLBACK_CACHE_DURATION = 24 * 60 * 60 * 1000; // 24 hours
 
 // Application Constants
@@ -67,7 +67,8 @@ const coinNameToDisplayName = {
 const coinIdToName = {
     1: 'particl', 2: 'bitcoin', 3: 'litecoin', 4: 'decred',
     6: 'monero', 7: 'particl blind', 8: 'particl anon',
-    9: 'wownero', 11: 'pivx', 13: 'firo', 17: 'bitcoincash'
+    9: 'wownero', 11: 'pivx', 13: 'firo', 17: 'bitcoincash',
+    18: 'dogecoin'
 };
 
 // DOM ELEMENT REFERENCES
@@ -92,7 +93,7 @@ const WebSocketManager = {
     reconnectDelay: 5000,
     maxQueueSize: 1000,
     isIntentionallyClosed: false,
-    
+
     connectionState: {
         isConnecting: false,
         lastConnectAttempt: null,
@@ -271,7 +272,7 @@ const WebSocketManager = {
         try {
             const response = await fetch(endpoint);
             if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
-            
+
             const newData = await response.json();
             const fetchedOffers = Array.isArray(newData) ? newData : Object.values(newData);
 
@@ -300,7 +301,7 @@ const WebSocketManager = {
         this.reconnectAttempts++;
         if (this.reconnectAttempts <= this.maxReconnectAttempts) {
             console.log(`Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
-            
+
             const delay = Math.min(
                 this.reconnectDelay * Math.pow(1.5, this.reconnectAttempts - 1),
                 30000
@@ -324,11 +325,11 @@ const WebSocketManager = {
 
     cleanup() {
         console.log('Cleaning up WebSocket resources');
-        
+
         clearTimeout(this.debounceTimeout);
         clearTimeout(this.reconnectTimeout);
         clearTimeout(this.connectionState.connectTimeout);
-        
+
         this.messageQueue = [];
         this.processingQueue = false;
         this.connectionState.isConnecting = false;
@@ -365,7 +366,7 @@ const CacheManager = {
     set: function(key, value, customTtl = null) {
         try {
             this.cleanup();
-            
+
             const item = {
                 value: value,
                 timestamp: Date.now(),
@@ -396,7 +397,7 @@ const CacheManager = {
             return false;
         }
     },
-    
+
     get: function(key) {
         try {
             const itemStr = localStorage.getItem(key);
@@ -404,14 +405,14 @@ const CacheManager = {
 
             const item = JSON.parse(itemStr);
             const now = Date.now();
-            
+
             if (now < item.expiresAt) {
                 return {
                     value: item.value,
                     remainingTime: item.expiresAt - now
                 };
             }
-            
+
             localStorage.removeItem(key);
         } catch (error) {
             localStorage.removeItem(key);
@@ -433,7 +434,7 @@ const CacheManager = {
                 const itemStr = localStorage.getItem(key);
                 const size = new Blob([itemStr]).size;
                 const item = JSON.parse(itemStr);
-                
+
                 if (now >= item.expiresAt) {
                     localStorage.removeItem(key);
                     continue;
@@ -445,7 +446,7 @@ const CacheManager = {
                     expiresAt: item.expiresAt,
                     timestamp: item.timestamp
                 });
-                
+
                 totalSize += size;
                 itemCount++;
             } catch (error) {
@@ -455,7 +456,7 @@ const CacheManager = {
 
         if (aggressive || totalSize > this.maxSize || itemCount > this.maxItems) {
             items.sort((a, b) => b.timestamp - a.timestamp);
-            
+
             while ((totalSize > this.maxSize || itemCount > this.maxItems) && items.length > 0) {
                 const item = items.pop();
                 localStorage.removeItem(item.key);
@@ -473,7 +474,7 @@ const CacheManager = {
                 keys.push(key);
             }
         }
-        
+
         keys.forEach(key => localStorage.removeItem(key));
     },
 
@@ -491,10 +492,10 @@ const CacheManager = {
                 const itemStr = localStorage.getItem(key);
                 const size = new Blob([itemStr]).size;
                 const item = JSON.parse(itemStr);
-                
+
                 totalSize += size;
                 itemCount++;
-                
+
                 if (now >= item.expiresAt) {
                     expiredCount++;
                 }
@@ -528,7 +529,7 @@ window.tableRateModule = {
         'Bitcoin Cash': 'BCH',
         'Dogecoin': 'DOGE'
     },
-    
+
     cache: {},
     processedOffers: new Set(),
 
@@ -564,7 +565,7 @@ window.tableRateModule = {
         this.processedOffers.add(offerId);
         return true;
     },
-    
+
     formatUSD(value) {
         if (Math.abs(value) < 0.000001) {
             return value.toExponential(8) + ' USD';
@@ -654,23 +655,23 @@ async function initializePriceData() {
     while (retryCount < PRICE_INIT_RETRIES) {
         try {
             prices = await fetchLatestPrices();
-            
+
             if (prices && Object.keys(prices).length > 0) {
                 console.log('Successfully fetched initial price data');
                 latestPrices = prices;
                 CacheManager.set(PRICES_CACHE_KEY, prices, CACHE_DURATION);
                 return true;
             }
-            
+
             retryCount++;
-            
+
             if (retryCount < PRICE_INIT_RETRIES) {
                 await new Promise(resolve => setTimeout(resolve, PRICE_INIT_RETRY_DELAY));
             }
         } catch (error) {
             console.error(`Error fetching prices (attempt ${retryCount + 1}):`, error);
             retryCount++;
-            
+
             if (retryCount < PRICE_INIT_RETRIES) {
                 await new Promise(resolve => setTimeout(resolve, PRICE_INIT_RETRY_DELAY));
             }
@@ -706,7 +707,7 @@ function checkOfferAgainstFilters(offer, filters) {
         const currentTime = Math.floor(Date.now() / 1000);
         const isExpired = offer.expire_at <= currentTime;
         const isRevoked = Boolean(offer.is_revoked);
-        
+
         switch (filters.status) {
             case 'active':
                 return !isExpired && !isRevoked;
@@ -726,7 +727,7 @@ function initializeFlowbiteTooltips() {
         console.warn('Tooltip is not defined. Make sure the required library is loaded.');
         return;
     }
-    
+
     const tooltipElements = document.querySelectorAll('[data-tooltip-target]');
     tooltipElements.forEach((el) => {
         const tooltipId = el.getAttribute('data-tooltip-target');
@@ -740,10 +741,10 @@ function initializeFlowbiteTooltips() {
 // DATA PROCESSING FUNCTIONS
 async function checkExpiredAndFetchNew() {
     if (isSentOffers) return Promise.resolve();
-    
+
     console.log('Starting checkExpiredAndFetchNew');
     const OFFERS_CACHE_KEY = 'offers_received';
-    
+
     try {
         const response = await fetch('/json/offers');
         const data = await response.json();
@@ -772,9 +773,9 @@ async function checkExpiredAndFetchNew() {
         CacheManager.set(OFFERS_CACHE_KEY, newListings, CACHE_DURATION);
 
         const currentFilters = new FormData(filterForm);
-        const hasActiveFilters = currentFilters.get('coin_to') !== 'any' || 
+        const hasActiveFilters = currentFilters.get('coin_to') !== 'any' ||
                                currentFilters.get('coin_from') !== 'any';
-        
+
         if (hasActiveFilters) {
             jsonData = filterAndSortData();
         } else {
@@ -784,7 +785,7 @@ async function checkExpiredAndFetchNew() {
         updateOffersTable();
         updateJsonView();
         updatePaginationInfo();
-        
+
         if (jsonData.length === 0) {
             handleNoOffersScenario();
         }
@@ -810,7 +811,7 @@ function getValidOffers() {
 
 function filterAndSortData() {
     //console.log('[Debug] Starting filter with data length:', originalJsonData.length);
-    
+
     const formData = new FormData(filterForm);
     const filters = Object.fromEntries(formData);
     //console.log('[Debug] Active filters:', filters);
@@ -825,7 +826,7 @@ function filterAndSortData() {
     let filteredData = [...originalJsonData];
 
     const sentFromFilter = filters.sent_from || 'any';
-    
+
     filteredData = filteredData.filter(offer => {
         if (sentFromFilter === 'public') {
             return offer.is_public;
@@ -842,13 +843,13 @@ function filterAndSortData() {
 
         const coinFrom = (offer.coin_from || '').toLowerCase();
         const coinTo = (offer.coin_to || '').toLowerCase();
-        
+
         if (filters.coin_to !== 'any') {
             if (!coinMatches(coinTo, filters.coin_to)) {
                 return false;
             }
         }
-        
+
         if (filters.coin_from !== 'any') {
             if (!coinMatches(coinFrom, filters.coin_from)) {
                 return false;
@@ -859,7 +860,7 @@ function filterAndSortData() {
             const currentTime = Math.floor(Date.now() / 1000);
             const isExpired = offer.expire_at <= currentTime;
             const isRevoked = Boolean(offer.is_revoked);
-            
+
             switch (filters.status) {
                 case 'active':
                     return !isExpired && !isRevoked;
@@ -878,7 +879,7 @@ function filterAndSortData() {
     if (currentSortColumn !== null) {
         filteredData.sort((a, b) => {
             let comparison = 0;
-            
+
             switch(currentSortColumn) {
                 case 0: // Time
                     comparison = a.created_at - b.created_at;
@@ -891,32 +892,32 @@ function filterAndSortData() {
                     const aToSymbol = getCoinSymbolLowercase(a.coin_to);
                     const bFromSymbol = getCoinSymbolLowercase(b.coin_from);
                     const bToSymbol = getCoinSymbolLowercase(b.coin_to);
-                    
+
                     const aFromPrice = latestPrices[aFromSymbol]?.usd || 0;
                     const aToPrice = latestPrices[aToSymbol]?.usd || 0;
                     const bFromPrice = latestPrices[bFromSymbol]?.usd || 0;
                     const bToPrice = latestPrices[bToSymbol]?.usd || 0;
-                    
+
                     const aMarketRate = aToPrice / aFromPrice;
                     const bMarketRate = bToPrice / bFromPrice;
-                    
+
                     const aOfferedRate = parseFloat(a.rate);
                     const bOfferedRate = parseFloat(b.rate);
-                    
+
                     const aPercentDiff = ((aOfferedRate - aMarketRate) / aMarketRate) * 100;
                     const bPercentDiff = ((bOfferedRate - bMarketRate) / bMarketRate) * 100;
-                    
+
                     comparison = aPercentDiff - bPercentDiff;
                     break;
                 case 7: // Trade
                     comparison = a.offer_id.localeCompare(b.offer_id);
                     break;
             }
-            
+
             return currentSortDirection === 'desc' ? -comparison : comparison;
         });
     }
-    
+
     //console.log(`[Debug] Filtered data length: ${filteredData.length}`);
     return filteredData;
 }
@@ -1019,7 +1020,7 @@ async function fetchLatestPrices() {
     }
 
     const url = `${config.apiEndpoints.coinGecko}/simple/price?ids=bitcoin,bitcoin-cash,dash,dogecoin,decred,litecoin,particl,pivx,monero,zano,wownero,zcoin&vs_currencies=USD,BTC&api_key=${config.apiKeys.coinGecko}`;
-    
+
     try {
         console.log('Fetching fresh price data...');
         const response = await fetch('/json/readurl', {
@@ -1041,7 +1042,7 @@ async function fetchLatestPrices() {
         if (data.Error) {
             throw new Error(data.Error);
         }
-        
+
         if (data && Object.keys(data).length > 0) {
             console.log('Fresh price data received');
 
@@ -1052,7 +1053,7 @@ async function fetchLatestPrices() {
             Object.entries(data).forEach(([coin, prices]) => {
                 tableRateModule.setFallbackValue(coin, prices.usd);
             });
-            
+
             return data;
         } else {
             //console.warn('Received empty price data');
@@ -1075,18 +1076,18 @@ async function fetchOffers(manualRefresh = false) {
         refreshIcon.classList.add('animate-spin');
         refreshText.textContent = 'Refreshing...';
         refreshButton.classList.add('opacity-75', 'cursor-wait');
-        
+
         const endpoint = isSentOffers ? '/json/sentoffers' : '/json/offers';
         const response = await fetch(endpoint);
         const data = await response.json();
-        
+
         jsonData = formatInitialData(data);
         originalJsonData = [...jsonData];
 
         await updateOffersTable();
         updateJsonView();
         updatePaginationInfo();
-        
+
     } catch (error) {
         console.error('[Debug] Error fetching offers:', error);
         ui.displayErrorMessage('Failed to fetch offers. Please try again later.');
@@ -1120,12 +1121,12 @@ function formatInitialData(data) {
 function updateConnectionStatus(status) {
     const dot = document.getElementById('status-dot');
     const text = document.getElementById('status-text');
-    
+
     if (!dot || !text) {
         //console.warn('Status indicators not found in DOM');
         return;
     }
-    
+
     switch(status) {
         case 'connected':
             dot.className = 'w-2.5 h-2.5 rounded-full bg-green-500 mr-2';
@@ -1159,10 +1160,10 @@ function updateRowTimes() {
 
             const newPostedTime = formatTime(offer.created_at, true);
             const newExpiresIn = formatTimeLeft(offer.expire_at);
-            
+
             const postedElement = row.querySelector('.text-xs:first-child');
             const expiresElement = row.querySelector('.text-xs:last-child');
-            
+
             if (postedElement && postedElement.textContent !== `Posted: ${newPostedTime}`) {
                 postedElement.textContent = `Posted: ${newPostedTime}`;
             }
@@ -1212,14 +1213,14 @@ function updatePaginationInfo() {
 
     const showPrev = currentPage > 1;
     const showNext = currentPage < totalPages && totalItems > 0;
-    
+
     prevPageButton.style.display = showPrev ? 'inline-flex' : 'none';
     nextPageButton.style.display = showNext ? 'inline-flex' : 'none';
 
     if (lastRefreshTime) {
         lastRefreshTimeSpan.textContent = new Date(lastRefreshTime).toLocaleTimeString();
     }
-    
+
     if (newEntriesCountSpan) {
         newEntriesCountSpan.textContent = totalItems;
     }
@@ -1255,13 +1256,13 @@ function updateProfitLoss(row, fromCoin, toCoin, fromAmount, toAmount, isOwnOffe
             }
 
             const formattedPercentDiff = percentDiff.toFixed(2);
-            const percentDiffDisplay = formattedPercentDiff === "0.00" ? "0.00" : 
+            const percentDiffDisplay = formattedPercentDiff === "0.00" ? "0.00" :
                                      (percentDiff > 0 ? `+${formattedPercentDiff}` : formattedPercentDiff);
 
             const colorClass = getProfitColorClass(percentDiff);
             profitLossElement.textContent = `${percentDiffDisplay}%`;
             profitLossElement.className = `profit-loss text-lg font-bold ${colorClass}`;
-            
+
             const tooltipId = `percentage-tooltip-${row.getAttribute('data-offer-id')}`;
             const tooltipElement = document.getElementById(tooltipId);
             if (tooltipElement) {
@@ -1310,7 +1311,7 @@ function updateClearFiltersButton() {
         const hasFilters = hasActiveFilters();
         clearButton.classList.toggle('opacity-50', !hasFilters);
         clearButton.disabled = !hasFilters;
-        
+
         // Update button styles based on state
         if (hasFilters) {
             clearButton.classList.add('hover:bg-green-600', 'hover:text-white');
@@ -1325,10 +1326,10 @@ function updateClearFiltersButton() {
 function handleNoOffersScenario() {
     const formData = new FormData(filterForm);
     const filters = Object.fromEntries(formData);
-    const hasActiveFilters = filters.coin_to !== 'any' || 
+    const hasActiveFilters = filters.coin_to !== 'any' ||
                             filters.coin_from !== 'any' ||
                             (filters.status && filters.status !== 'any');
-    
+
     stopRefreshAnimation();
 
     if (hasActiveFilters) {
@@ -1336,7 +1337,7 @@ function handleNoOffersScenario() {
             <tr>
                 <td colspan="9" class="text-center py-8">
                     <div class="flex items-center justify-center text-gray-500 dark:text-white">
-                        No offers match the selected filters. Try different filter options or 
+                        No offers match the selected filters. Try different filter options or
                         <button onclick="clearFilters()" class="ml-1 text-blue-500 hover:text-blue-700 font-semibold">
                             clear filters
                         </button>
@@ -1357,7 +1358,7 @@ async function updateOffersTable() {
     try {
         const PRICES_CACHE_KEY = 'prices_coingecko';
         const cachedPrices = CacheManager.get(PRICES_CACHE_KEY);
-        
+
         if (!cachedPrices || !cachedPrices.remainingTime || cachedPrices.remainingTime < 60000) {
             console.log('Fetching fresh price data...');
             const priceData = await fetchLatestPrices();
@@ -1374,12 +1375,12 @@ async function updateOffersTable() {
         const endIndex = Math.min(startIndex + itemsPerPage, validOffers.length);
         const itemsToDisplay = validOffers.slice(startIndex, endIndex);
 
-        const identityPromises = itemsToDisplay.map(offer => 
+        const identityPromises = itemsToDisplay.map(offer =>
             offer.addr_from ? getIdentityData(offer.addr_from) : Promise.resolve(null)
         );
-        
+
         const identities = await Promise.all(identityPromises);
-        
+
         if (validOffers.length === 0) {
             handleNoOffersScenario();
             return;
@@ -1405,7 +1406,7 @@ async function updateOffersTable() {
             initializeFlowbiteTooltips();
             updateRowTimes();
             updatePaginationControls(totalPages);
-            
+
             if (tableRateModule?.initializeTable) {
                 tableRateModule.initializeTable();
             }
@@ -1482,7 +1483,7 @@ function getIdentityInfo(address, identity) {
 function createTableRow(offer, identity = null) {
     const row = document.createElement('tr');
     const uniqueId = `${offer.offer_id}_${offer.created_at}`;
-    
+
     row.className = 'relative opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600';
     row.setAttribute('data-offer-id', uniqueId);
 
@@ -1504,7 +1505,7 @@ function createTableRow(offer, identity = null) {
     const coinToDisplay = getDisplayName(coinTo);
     const postedTime = formatTime(createdAt, true);
     const expiresIn = formatTime(expireAt);
-    
+
     const currentTime = Math.floor(Date.now() / 1000);
     const isActuallyExpired = currentTime > expireAt;
     const fromAmount = parseFloat(amountFrom) || 0;
@@ -1585,19 +1586,19 @@ function shouldShowPublicTag(offers) {
 
 function truncateText(text, maxLength = 15) {
     if (typeof text !== 'string') return '';
-    return text.length > maxLength 
-        ? text.slice(0, maxLength) + '...' 
+    return text.length > maxLength
+        ? text.slice(0, maxLength) + '...'
         : text;
 }
 
 function createDetailsColumn(offer, identity = null) {
     const addrFrom = offer.addr_from || '';
     const identityInfo = getIdentityInfo(addrFrom, identity);
-    
+
     const showPublicPrivateTags = originalJsonData.some(o => o.is_public !== offer.is_public);
 
-    const tagClass = offer.is_public 
-        ? 'bg-green-600 dark:bg-green-600' 
+    const tagClass = offer.is_public
+        ? 'bg-green-600 dark:bg-green-600'
         : 'bg-red-500 dark:bg-red-500';
     const tagText = offer.is_public ? 'Public' : 'Private';
 
@@ -1605,16 +1606,16 @@ function createDetailsColumn(offer, identity = null) {
         identityInfo.label || addrFrom || 'Unspecified'
     );
 
-    const identifierTextClass = identityInfo.label 
-        ? 'text-white dark:text-white' 
+    const identifierTextClass = identityInfo.label
+        ? 'text-white dark:text-white'
         : 'monospace';
-    
+
     return `
         <td class="py-8 px-4 text-xs text-left hidden xl:block">
             <div class="flex flex-col gap-2 relative">
                 ${showPublicPrivateTags ? `<span class="inline-flex pl-6 pr-6 py-1 justify-center text-[10px] w-1/4 font-medium text-gray-100 rounded-md ${tagClass}">${tagText}</span>
                 ` : ''}
-                
+
                 <a data-tooltip-target="tooltip-recipient-${escapeHtml(offer.offer_id)}" href="/identity/${escapeHtml(addrFrom)}" class="flex items-center">
                     <svg class="w-4 h-4 mr-2 text-gray-400 dark:text-white" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
                      <path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"></path>
@@ -1635,8 +1636,8 @@ function createTakerAmountColumn(offer, coinTo, coinFrom) {
         <td class="py-0">
             <div class="py-3 px-4 text-left">
                 <a data-tooltip-target="tooltip-wallet${escapeHtml(offer.offer_id)}" href="/wallet/${escapeHtml(toSymbol)}" class="items-center monospace">
-                    <div class="pr-2">        
-                        <div class="text-sm font-semibold">${fromAmount.toFixed(4)}</div>          
+                    <div class="pr-2">
+                        <div class="text-sm font-semibold">${fromAmount.toFixed(4)}</div>
                         <div class="text-sm text-gray-500 dark:text-gray-400">${coinTo}</div>
                     </div>
                 </a>
@@ -1679,8 +1680,8 @@ function createOrderbookColumn(offer, coinFrom, coinTo) {
         <td class="p-0">
             <div class="py-3 px-4 text-right">
                 <a data-tooltip-target="tooltip-wallet-maker${escapeHtml(offer.offer_id)}" href="/wallet/${escapeHtml(fromSymbol)}" class="items-center monospace">
-                    <div class="pr-2">        
-                        <div class="text-sm font-semibold">${toAmount.toFixed(4)}</div>           
+                    <div class="pr-2">
+                        <div class="text-sm font-semibold">${toAmount.toFixed(4)}</div>
                         <div class="text-sm text-gray-500 dark:text-gray-400">${coinFrom}</div>
                     </div>
                 </a>
@@ -1694,7 +1695,7 @@ function createRateColumn(offer, coinFrom, coinTo) {
     const inverseRate = 1 / rate;
     const fromSymbol = getCoinSymbol(coinFrom);
     const toSymbol = getCoinSymbol(coinTo);
-    
+
     const getPriceKey = (coin) => {
         const lowerCoin = coin.toLowerCase();
         if (lowerCoin === 'firo' || lowerCoin === 'zcoin') {
@@ -1746,9 +1747,9 @@ function createPercentageColumn(offer) {
 function createActionColumn(offer, isActuallyExpired = false) {
     const isRevoked = Boolean(offer.is_revoked);
     const isTreatedAsSentOffer = offer.is_own_offer;
-    
+
     let buttonClass, buttonText;
-    
+
     if (isRevoked) {
         buttonClass = 'bg-red-500 text-white hover:bg-red-600 transition duration-200';
         buttonText = 'Revoked';
@@ -1786,14 +1787,14 @@ function createTooltips(offer, treatAsSentOffer, coinFrom, coinTo, fromAmount, t
     const identityInfo = getIdentityInfo(addrFrom, identity);
 
     const totalBids = identity ? (
-        identityInfo.stats.sentBidsSuccessful + 
-        identityInfo.stats.recvBidsSuccessful + 
-        identityInfo.stats.sentBidsFailed + 
-        identityInfo.stats.recvBidsFailed + 
-        identityInfo.stats.sentBidsRejected + 
+        identityInfo.stats.sentBidsSuccessful +
+        identityInfo.stats.recvBidsSuccessful +
+        identityInfo.stats.sentBidsFailed +
+        identityInfo.stats.recvBidsFailed +
+        identityInfo.stats.sentBidsRejected +
         identityInfo.stats.recvBidsRejected
     ) : 0;
-    
+
     const successRate = totalBids ? (
         ((identityInfo.stats.sentBidsSuccessful + identityInfo.stats.recvBidsSuccessful) / totalBids) * 100
     ).toFixed(1) : 0;
@@ -1846,14 +1847,14 @@ function createTooltips(offer, treatAsSentOffer, coinFrom, coinTo, fromAmount, t
             </div>
             <div class="tooltip-arrow" data-popper-arrow></div>
         </div>
-       
+
         <div id="tooltip-wallet-${uniqueId}" role="tooltip" class="inline-block absolute invisible z-50 py-2 px-3 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
             <div class="active-revoked-expired">
                 <span class="bold">${treatAsSentOffer ? 'My' : ''} ${coinTo} Wallet</span>
             </div>
             <div class="tooltip-arrow pl-1" data-popper-arrow></div>
         </div>
-        
+
         <div id="tooltip-offer-${uniqueId}" role="tooltip" class="inline-block absolute z-50 py-2 px-3 text-sm font-medium text-white ${isRevoked ? 'bg-red-500' : (offer.is_own_offer ? 'bg-gray-300' : 'bg-green-700')} rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
             <div class="active-revoked-expired">
                 <span class="bold">
@@ -1862,14 +1863,14 @@ function createTooltips(offer, treatAsSentOffer, coinFrom, coinTo, fromAmount, t
             </div>
             <div class="tooltip-arrow pr-6" data-popper-arrow></div>
         </div>
-        
+
         <div id="tooltip-wallet-maker-${uniqueId}" role="tooltip" class="inline-block absolute invisible z-50 py-2 px-3 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
             <div class="active-revoked-expired">
                 <span class="bold">${treatAsSentOffer ? 'My' : ''} ${coinFrom} Wallet</span>
             </div>
             <div class="tooltip-arrow pl-1" data-popper-arrow></div>
         </div>
-        
+
         <div id="tooltip-rate-${uniqueId}" role="tooltip" class="inline-block absolute invisible z-50 py-2 px-3 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip">
             <div class="tooltip-content">
                 ${combinedRateTooltip}
@@ -1903,7 +1904,7 @@ function createRecipientTooltip(uniqueId, identityInfo, identity, successRate, t
     };
 
     return `
-        <div id="tooltip-recipient-${uniqueId}" role="tooltip" 
+        <div id="tooltip-recipient-${uniqueId}" role="tooltip"
             class="fixed z-50 py-3 px-4 text-sm font-medium text-white bg-gray-400 rounded-lg shadow-sm opacity-0 transition-opacity duration-300 tooltip max-w-sm pointer-events-none">
             <div class="identity-info space-y-2">
                 ${identityInfo.label ? `
@@ -1912,7 +1913,7 @@ function createRecipientTooltip(uniqueId, identityInfo, identity, successRate, t
                         <div class="text-white">${escapeHtml(identityInfo.label)}</div>
                     </div>
                 ` : ''}
-                
+
                 <div class="space-y-1">
                     <div class="text-white text-xs tracking-wide font-semibold">Recipient Address:</div>
                     <div class="monospace text-xs break-all bg-gray-500 p-2 rounded-md text-white">
@@ -2001,7 +2002,7 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
     const marketRate = fromPriceUSD / toPriceUSD;
     const offerRate = toAmount / fromAmount;
     let percentDiff;
-    
+
     if (isSentOffers || isOwnOffer) {
         percentDiff = ((toValueUSD / fromValueUSD) - 1) * 100;
     } else {
@@ -2009,7 +2010,7 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
     }
 
     const formattedPercentDiff = percentDiff.toFixed(2);
-    const percentDiffDisplay = formattedPercentDiff === "0.00" ? "0.00" : 
+    const percentDiffDisplay = formattedPercentDiff === "0.00" ? "0.00" :
                              (percentDiff > 0 ? `+${formattedPercentDiff}` : formattedPercentDiff);
 
     const profitLabel = (isSentOffers || isOwnOffer) ? "Max Profit" : "Max Loss";
@@ -2022,8 +2023,8 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
         <p class="mt-1">Percentage difference: ${percentDiffDisplay}%</p>
         <p>${profitLabel}: ${profitUSD > 0 ? '' : '-'}$${Math.abs(profitUSD).toFixed(2)} USD</p>
         <p class="font-bold mt-2">Calculation:</p>
-        <p>Percentage = ${(isSentOffers || isOwnOffer) ? 
-            "((To Amount in USD / From Amount in USD) - 1) * 100" : 
+        <p>Percentage = ${(isSentOffers || isOwnOffer) ?
+            "((To Amount in USD / From Amount in USD) - 1) * 100" :
             "((From Amount in USD / To Amount in USD) - 1) * 100"}</p>
         <p>USD ${profitLabel} = To Amount in USD - From Amount in USD</p>
         <p class="font-bold mt-1">Interpretation:</p>
@@ -2034,8 +2035,8 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
             <p><span class="text-green-500">Positive percentage:</span> You're buying below market rate (savings)</p>
             <p><span class="text-red-500">Negative percentage:</span> You're buying above market rate (premium)</p>
         `}
-        <p class="mt-1"><strong>Note:</strong> ${(isSentOffers || isOwnOffer) ? 
-            "As a seller, a positive percentage means <br/> you're selling for more than the current market value." : 
+        <p class="mt-1"><strong>Note:</strong> ${(isSentOffers || isOwnOffer) ?
+            "As a seller, a positive percentage means <br/> you're selling for more than the current market value." :
             "As a buyer, a positive percentage indicates </br> potential savings compared to current market rates."}</p>
         <p class="mt-1"><strong>Market Rate:</strong> 1 ${coinFrom} = ${marketRate.toFixed(8)} ${coinTo}</p>
         <p><strong>Offer Rate:</strong> 1 ${coinFrom} = ${offerRate.toFixed(8)} ${coinTo}</p>
@@ -2045,7 +2046,7 @@ function createTooltipContent(isSentOffers, coinFrom, coinTo, fromAmount, toAmou
 function createCombinedRateTooltip(offer, coinFrom, coinTo, isSentOffers, treatAsSentOffer) {
     const rate = parseFloat(offer.rate);
     const inverseRate = 1 / rate;
-    
+
     const getPriceKey = (coin) => {
         const lowerCoin = coin.toLowerCase();
         if (lowerCoin === 'firo' || lowerCoin === 'zcoin') {
@@ -2059,16 +2060,16 @@ function createCombinedRateTooltip(offer, coinFrom, coinTo, isSentOffers, treatA
 
     const fromSymbol = getPriceKey(coinFrom);
     const toSymbol = getPriceKey(coinTo);
-    
+
     const fromPriceUSD = latestPrices[fromSymbol]?.usd || 0;
     const toPriceUSD = latestPrices[toSymbol]?.usd || 0;
     const rateInUSD = rate * toPriceUSD;
 
     const marketRate = fromPriceUSD / toPriceUSD;
-    
+
     const percentDiff = ((rate - marketRate) / marketRate) * 100;
     const formattedPercentDiff = percentDiff.toFixed(2);
-    const percentDiffDisplay = formattedPercentDiff === "0.00" ? "0.00" : 
+    const percentDiffDisplay = formattedPercentDiff === "0.00" ? "0.00" :
                             (percentDiff > 0 ? `+${formattedPercentDiff}` : formattedPercentDiff);
     const aboveOrBelow = percentDiff > 0 ? "above" : percentDiff < 0 ? "below" : "at";
 
@@ -2166,7 +2167,7 @@ function hasActiveFilters() {
 
     const selectElements = filterForm.querySelectorAll('select');
     let hasChangedFilters = false;
-    
+
     selectElements.forEach(select => {
         if (select.value !== 'any') {
             hasChangedFilters = true;
@@ -2205,13 +2206,13 @@ function getCoinSymbolLowercase(coin) {
 
 function coinMatches(offerCoin, filterCoin) {
     if (!offerCoin || !filterCoin) return false;
-    
+
     offerCoin = offerCoin.toLowerCase();
     filterCoin = filterCoin.toLowerCase();
-    
+
     if (offerCoin === filterCoin) return true;
 
-    if ((offerCoin === 'firo' || offerCoin === 'zcoin') && 
+    if ((offerCoin === 'firo' || offerCoin === 'zcoin') &&
         (filterCoin === 'firo' || filterCoin === 'zcoin')) {
         return true;
     }
@@ -2229,7 +2230,7 @@ function coinMatches(offerCoin, filterCoin) {
     if (particlVariants.includes(filterCoin)) {
         return offerCoin === filterCoin;
     }
-    
+
     return false;
 }
 
@@ -2259,7 +2260,7 @@ function getTimeUntilNextExpiration() {
         const timeUntilExpiration = offer.expire_at - currentTime;
         return timeUntilExpiration > 0 && timeUntilExpiration < earliest ? timeUntilExpiration : earliest;
     }, Infinity);
-    
+
     return Math.max(MIN_REFRESH_INTERVAL, Math.min(nextExpiration, 300));
 }
 
@@ -2270,7 +2271,7 @@ function calculateInverseRate(rate) {
 function formatTime(timestamp, addAgoSuffix = false) {
     const now = Math.floor(Date.now() / 1000);
     const diff = Math.abs(now - timestamp);
-    
+
     let timeString;
     if (diff < 60) {
         timeString = `${diff} seconds`;
@@ -2308,7 +2309,7 @@ function getCoinSymbol(fullName) {
         'Particl': 'PART', 'Particl Blind': 'PART', 'Particl Anon': 'PART',
         'PIVX': 'PIVX', 'Firo': 'FIRO', 'Zcoin': 'FIRO',
         'Dash': 'DASH', 'Decred': 'DCR', 'Wownero': 'WOW',
-        'Bitcoin Cash': 'BCH'
+        'Bitcoin Cash': 'BCH', 'Dogecoin': 'DOGE'
     };
     return symbolMap[fullName] || fullName;
 }
@@ -2317,7 +2318,7 @@ function getCoinSymbol(fullName) {
 document.querySelectorAll('th[data-sortable="true"]').forEach(header => {
     header.addEventListener('click', () => {
         const columnIndex = parseInt(header.getAttribute('data-column-index'));
-        
+
         if (currentSortColumn === columnIndex) {
             currentSortDirection = currentSortDirection === 'asc' ? 'desc' : 'asc';
         } else {
@@ -2348,7 +2349,7 @@ document.querySelectorAll('th[data-sortable="true"]').forEach(header => {
 
         localStorage.setItem('tableSortColumn', currentSortColumn);
         localStorage.setItem('tableSortDirection', currentSortDirection);
-        
+
         applyFilters();
     });
 
@@ -2357,19 +2358,19 @@ document.querySelectorAll('th[data-sortable="true"]').forEach(header => {
 
 const eventListeners = {
     listeners: [],
-    
+
     add(element, eventType, handler, options = false) {
         element.addEventListener(eventType, handler, options);
         this.listeners.push({ element, eventType, handler, options });
         // console.log(`Added ${eventType} listener to`, element);
     },
-    
+
     addWindowListener(eventType, handler, options = false) {
         window.addEventListener(eventType, handler, options);
         this.listeners.push({ element: window, eventType, handler, options });
         // console.log(`Added ${eventType} window listener`);
     },
-    
+
     removeAll() {
         console.log('Removing all event listeners...');
         this.listeners.forEach(({ element, eventType, handler, options }) => {
@@ -2378,7 +2379,7 @@ const eventListeners = {
         });
         this.listeners = [];
     },
-    
+
     removeByElement(element) {
         const remainingListeners = [];
         this.listeners = this.listeners.filter(listener => {
@@ -2400,29 +2401,29 @@ const eventListeners = {
 const timerManager = {
     intervals: [],
     timeouts: [],
-    
+
     addInterval(callback, delay) {
         const intervalId = setInterval(callback, delay);
         this.intervals.push(intervalId);
         return intervalId;
     },
-    
+
     addTimeout(callback, delay) {
         const timeoutId = setTimeout(callback, delay);
         this.timeouts.push(timeoutId);
         return timeoutId;
     },
-    
+
     clearAllIntervals() {
         this.intervals.forEach(clearInterval);
         this.intervals = [];
     },
-    
+
     clearAllTimeouts() {
         this.timeouts.forEach(clearTimeout);
         this.timeouts = [];
     },
-    
+
     clearAll() {
         this.clearAllIntervals();
         this.clearAllTimeouts();
@@ -2435,7 +2436,7 @@ document.addEventListener('DOMContentLoaded', () => {
     console.log('View type:', isSentOffers ? 'sent offers' : 'received offers');
 
     updateClearFiltersButton();
-    
+
     // Add event listeners for filter controls
     const selectElements = filterForm.querySelectorAll('select');
     selectElements.forEach(select => {
@@ -2443,7 +2444,7 @@ document.addEventListener('DOMContentLoaded', () => {
             updateClearFiltersButton();
         });
     });
-    
+
     filterForm.addEventListener('change', () => {
         applyFilters();
         updateClearFiltersButton();
@@ -2506,7 +2507,7 @@ document.addEventListener('DOMContentLoaded', () => {
 
     eventListeners.add(document.getElementById('refreshOffers'), 'click', async () => {
         console.log('Manual refresh initiated');
-        
+
         const refreshButton = document.getElementById('refreshOffers');
         const refreshIcon = document.getElementById('refreshIcon');
         const refreshText = document.getElementById('refreshText');
@@ -2529,13 +2530,13 @@ document.addEventListener('DOMContentLoaded', () => {
 
             jsonData = formatInitialData(processedNewData);
             originalJsonData = [...jsonData];
-            
+
             await updateOffersTable();
             updateJsonView();
             updatePaginationInfo();
-            
+
             console.log(' Manual refresh completed successfully');
-            
+
         } catch (error) {
             console.error('Error during manual refresh:', error);
             ui.displayErrorMessage('Failed to refresh offers. Please try again later.');