diff --git a/src/components/wallet/Wallet.js b/src/components/wallet/Wallet.js
index fc2cbb9..08fb4a0 100644
--- a/src/components/wallet/Wallet.js
+++ b/src/components/wallet/Wallet.js
@@ -355,23 +355,14 @@ export async function WalletComponent(container) {
try {
await syncWalletState();
- // ✅ FORCE FRESH FETCH AFTER WALLET SYNC
const [balance, transactions, utxos] = await Promise.all([
- fetchBalance(),
- fetchTransactions(),
- fetchUtxos(),
- ]);
-
- // Save to cache
- saveWalletToCache(balance, transactions, utxos);
-
- // Update UI
- await Promise.all([
updateBalance(false),
updateTransactions(false),
updateUtxos(false),
]);
+ if (balance) saveWalletToCache(balance, transactions, utxos);
+
refreshBtn.textContent = 'Refreshed!';
setTimeout(() => {
refreshBtn.textContent = originalText;
@@ -520,28 +511,21 @@ export async function WalletComponent(container) {
});
}
- // Initialize data
- updateBalance();
- updateTransactions();
- updateUtxos();
-
- // ✅ SMART INITIALIZATION
if (shouldFetchFresh) {
- console.log('🔄 Fetching fresh data...');
- // Fetch fresh data
+ console.log('🔄 Syncing and fetching fresh data...');
+ try {
+ await window.api.taker.sync();
+ } catch (syncErr) {
+ console.warn('⚠️ Initial wallet sync failed, proceeding anyway:', syncErr.message);
+ }
const [balance, transactions, utxos] = await Promise.all([
updateBalance(false),
updateTransactions(false),
updateUtxos(false),
]);
-
- // Save to cache
- if (balance && transactions && utxos) {
- saveWalletToCache(balance, transactions, utxos);
- }
+ if (balance) saveWalletToCache(balance, transactions, utxos);
} else {
console.log('⚡ Using cached data (still fresh)');
- // Just use cache
await Promise.all([
updateBalance(true),
updateTransactions(true),
diff --git a/src/js/app.js b/src/js/app.js
index c5ef83e..7c5e0d4 100644
--- a/src/js/app.js
+++ b/src/js/app.js
@@ -184,7 +184,8 @@ async function checkTakerInitialization(config) {
if (result.success) {
console.log('✅ Taker initialized');
- await performLaunchSync(startMainApp);
+ startMainApp();
+ startBackgroundOfferbookSync();
} else {
console.error('❌ Taker initialization failed:', result.error);
alert('Failed to initialize: ' + result.error);
@@ -283,7 +284,8 @@ async function showPasswordPrompt(config) {
if (result.success) {
modal.remove();
resolve(true);
- await performLaunchSync(startMainApp);
+ startMainApp();
+ startBackgroundOfferbookSync();
} else if (result.wrongPassword) {
errorDiv.classList.remove('hidden');
errorDiv.querySelector('p').textContent =
@@ -317,206 +319,34 @@ async function showPasswordPrompt(config) {
});
}
-/**
- * Show an offerbook sync overlay, wait for sync to complete, then call onComplete.
- * Used on launch so the user sees makers as soon as the app opens.
- */
-async function performLaunchSync(onComplete) {
- const escapeHtml = (value) => {
- const div = document.createElement('div');
- div.textContent = value || '';
- return div.innerHTML;
- };
-
- const parseLogLine = (line) => {
- const match = line.match(
- /^(\d{4}-\d{2}-\d{2}T[\d:.]+)[^\s]*\s+(INFO|WARN|ERROR|DEBUG|TRACE)\s+(.+)$/
- );
- if (!match) {
- return {
- timestamp: Date.now(),
- type: 'info',
- message: line,
- };
- }
-
- return {
- timestamp: new Date(match[1]).getTime(),
- type: match[2].toLowerCase(),
- message: match[3],
- };
- };
-
- const getTypeColor = (type) => {
- switch (type) {
- case 'error':
- return 'text-red-400';
- case 'warn':
- return 'text-yellow-400';
- case 'debug':
- return 'text-blue-400';
- case 'trace':
- return 'text-purple-400';
- default:
- return 'text-green-400';
- }
- };
-
- const formatTime = (timestamp) =>
- new Date(timestamp).toLocaleTimeString('en-US', { hour12: false });
-
- const overlay = document.createElement('div');
- overlay.id = 'launch-sync-overlay';
- overlay.className = 'fixed inset-0 bg-[#0f1419] flex items-center justify-center z-50';
- overlay.innerHTML = `
-
-
-
- ⏳
-
-
Syncing Market Data
-
Discovering available makers via Tor. This may take a minute...
-
Starting offerbook sync...
-
-
-
-
-
-
-
-
Live sync logs
-
Latest coinswap and backend activity during startup
-
-
0 lines
-
-
-
-
- `;
- document.body.appendChild(overlay);
-
- const logOutput = overlay.querySelector('#launch-sync-log-output');
- const logCount = overlay.querySelector('#launch-sync-log-count');
- const statusLabel = overlay.querySelector('#launch-sync-status');
- const progressBar = overlay.querySelector('#launch-sync-progress');
- const syncStartedAt = Date.now();
- let logPoll = null;
-
- function renderLogs(logs) {
- if (!logOutput) return;
-
- if (logCount) {
- logCount.textContent = `${logs.length} ${logs.length === 1 ? 'line' : 'lines'}`;
- }
-
- if (logs.length === 0) {
- logOutput.innerHTML =
- 'Waiting for startup logs...
';
- return;
- }
-
- logOutput.innerHTML = logs
- .map((log) => {
- return `
-
- [${formatTime(log.timestamp)}]
- [${log.type.toUpperCase()}]
- ${escapeHtml(log.message)}
-
- `;
- })
- .join('');
- logOutput.scrollTop = logOutput.scrollHeight;
- }
-
- async function refreshLaunchLogs() {
- try {
- const data = await window.api.logs.get(120);
- if (!data.success || !Array.isArray(data.logs)) return;
-
- const recentLogs = data.logs
- .map(parseLogLine)
- .filter((log) => log.timestamp >= syncStartedAt - 5000)
- .slice(-50);
-
- renderLogs(recentLogs);
- } catch (error) {
- console.error('Failed to refresh launch sync logs:', error);
- }
- }
-
+async function startBackgroundOfferbookSync() {
try {
- await refreshLaunchLogs();
- logPoll = setInterval(refreshLaunchLogs, 1500);
-
const syncResult = await window.api.taker.syncOfferbookAndWait();
- if (syncResult.success) {
- if (statusLabel) statusLabel.textContent = 'Offerbook sync in progress...';
- if (progressBar) progressBar.style.width = '52%';
-
- const syncId = syncResult.syncId;
- await new Promise((resolve) => {
- const poll = setInterval(async () => {
- try {
- const status = await window.api.taker.getSyncStatus(syncId);
- const sync = status.sync || {};
- const syncStatus = sync.status || 'syncing';
- const syncMessage =
- sync.message ||
- (syncStatus === 'completed'
- ? 'Offerbook ready'
- : syncStatus === 'failed'
- ? 'Sync failed'
- : 'Syncing offerbook...');
-
- if (statusLabel) statusLabel.textContent = syncMessage;
- if (progressBar) {
- const nextWidth =
- typeof sync.progress === 'number'
- ? Math.max(18, Math.min(100, sync.progress))
- : syncStatus === 'completed'
- ? 100
- : syncStatus === 'failed'
- ? 100
- : 76;
- progressBar.style.width = `${nextWidth}%`;
- }
-
- const done =
- !status.success ||
- syncStatus === 'completed' ||
- syncStatus === 'failed';
- if (done) {
- clearInterval(poll);
- resolve();
- }
- } catch (err) {
- console.error('Sync polling error:', err);
+ if (!syncResult.success) {
+ console.warn('⚠️ Background offerbook sync failed to start:', syncResult.error);
+ return;
+ }
+ const syncId = syncResult.syncId;
+ await new Promise((resolve) => {
+ const poll = setInterval(async () => {
+ try {
+ const status = await window.api.taker.getSyncStatus(syncId);
+ const syncStatus = (status.sync || {}).status || 'syncing';
+ if (!status.success || syncStatus === 'completed' || syncStatus === 'failed') {
clearInterval(poll);
resolve();
}
- }, 1000);
- });
- } else {
- if (statusLabel) {
- statusLabel.textContent =
- syncResult.error || 'Unable to start offerbook sync';
- }
- if (progressBar) progressBar.style.width = '100%';
- }
+ } catch (err) {
+ console.warn('⚠️ Sync poll error:', err.message);
+ clearInterval(poll);
+ resolve();
+ }
+ }, 1000);
+ });
+ console.log('✅ Background offerbook sync complete');
} catch (err) {
- console.warn('⚠️ Launch offerbook sync error:', err.message);
- if (statusLabel) statusLabel.textContent = 'Offerbook sync hit an issue';
- if (progressBar) progressBar.style.width = '100%';
- } finally {
- if (logPoll) clearInterval(logPoll);
- await refreshLaunchLogs();
+ console.warn('⚠️ Background offerbook sync error:', err.message);
}
-
- overlay.remove();
- onComplete();
}
// Start the main app after bitcoind connection is established
diff --git a/src/styles/output.css b/src/styles/output.css
index ffaa9a2..65c3e2d 100644
--- a/src/styles/output.css
+++ b/src/styles/output.css
@@ -45,7 +45,6 @@
--spacing: 0.25rem;
--container-md: 28rem;
--container-2xl: 42rem;
- --container-3xl: 48rem;
--container-5xl: 64rem;
--container-7xl: 80rem;
--text-xs: 0.75rem;
@@ -516,9 +515,6 @@
.max-w-2xl {
max-width: var(--container-2xl);
}
- .max-w-3xl {
- max-width: var(--container-3xl);
- }
.max-w-5xl {
max-width: var(--container-5xl);
}
@@ -792,9 +788,6 @@
.border-\[\#FF6B35\] {
border-color: #FF6B35;
}
- .border-\[\#FF6B35\]\/10 {
- border-color: color-mix(in oklab, #FF6B35 10%, transparent);
- }
.border-\[\#FF6B35\]\/20 {
border-color: color-mix(in oklab, #FF6B35 20%, transparent);
}
@@ -882,12 +875,6 @@
.border-transparent {
border-color: transparent;
}
- .border-white\/5 {
- border-color: color-mix(in srgb, #fff 5%, transparent);
- @supports (color: color-mix(in lab, red, red)) {
- border-color: color-mix(in oklab, var(--color-white) 5%, transparent);
- }
- }
.border-yellow-500\/30 {
border-color: color-mix(in srgb, oklch(79.5% 0.184 86.047) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) {
@@ -1278,10 +1265,6 @@
--tw-font-weight: var(--font-weight-semibold);
font-weight: var(--font-weight-semibold);
}
- .tracking-\[0\.2em\] {
- --tw-tracking: 0.2em;
- letter-spacing: 0.2em;
- }
.tracking-wide {
--tw-tracking: var(--tracking-wide);
letter-spacing: var(--tracking-wide);
@@ -1628,16 +1611,6 @@
}
}
}
- .hover\:bg-white\/5 {
- &:hover {
- @media (hover: hover) {
- background-color: color-mix(in srgb, #fff 5%, transparent);
- @supports (color: color-mix(in lab, red, red)) {
- background-color: color-mix(in oklab, var(--color-white) 5%, transparent);
- }
- }
- }
- }
.hover\:text-\[\#FF6B35\] {
&:hover {
@media (hover: hover) {