diff --git a/api1.js b/api1.js index 2736f59..25b8d87 100644 --- a/api1.js +++ b/api1.js @@ -404,50 +404,36 @@ function registerTakerHandlers() { source: source, }); - // ✅ Trigger manual sync - api1State.takerInstance.runOfferSyncNow(); + // Trigger sync and wait for completion in the native layer. + api1State.takerInstance.syncOfferbookAndWait(); - // Monitor until complete - const checkInterval = setInterval(() => { - try { - const isSyncing = api1State.takerInstance.isOfferbookSyncing(); - - if (!isSyncing) { - clearInterval(checkInterval); - - console.log(`✅ Offerbook sync completed (${source})`); - api1State.activeSyncs.set(syncId, { - ...api1State.activeSyncs.get(syncId), - status: 'completed', - completedAt: Date.now(), - }); - - // Clear flags - api1State.syncState.isRunning = false; - api1State.syncState.currentSyncId = null; - api1State.syncState.lastSyncTime = Date.now(); - } - } catch (err) { - clearInterval(checkInterval); - console.error(`❌ Sync check failed:`, err); - - api1State.syncState.isRunning = false; - api1State.syncState.currentSyncId = null; - - api1State.activeSyncs.set(syncId, { - ...api1State.activeSyncs.get(syncId), - status: 'failed', - error: err.message, - }); - } - }, 1000); + const completedAt = Date.now(); + console.log(`✅ Offerbook sync completed (${source})`); + api1State.activeSyncs.set(syncId, { + ...api1State.activeSyncs.get(syncId), + status: 'completed', + completedAt, + }); + api1State.syncState.lastSyncTime = completedAt; return { success: true, syncId, source }; } catch (error) { console.error('❌ Sync offerbook failed:', error); + + if (api1State.syncState.currentSyncId) { + const failedSyncId = api1State.syncState.currentSyncId; + api1State.activeSyncs.set(failedSyncId, { + ...api1State.activeSyncs.get(failedSyncId), + status: 'failed', + error: error.message, + completedAt: Date.now(), + }); + } + + return { success: false, error: error.message }; + } finally { api1State.syncState.isRunning = false; api1State.syncState.currentSyncId = null; - return { success: false, error: error.message }; } } @@ -654,25 +640,6 @@ function registerTakerHandlers() { } }); - // Check if offerbook is syncing - ipcMain.handle('taker:isOfferbookSyncing', async () => { - try { - if (!api1State.takerInstance) { - return { success: false, error: 'Taker not initialized' }; - } - - const isSyncing = api1State.takerInstance.isOfferbookSyncing(); - - return { - success: true, - isSyncing: isSyncing, - }; - } catch (error) { - console.error('Failed to check offerbook sync status:', error); - return { success: false, error: error.message, isSyncing: false }; - } - }); - // Get UTXOs ipcMain.handle('taker:getUtxos', async () => { try { @@ -865,8 +832,8 @@ function registerTakerHandlers() { } ); - // Sync offerbook - ipcMain.handle('taker:syncOfferbook', async () => { + // Sync offerbook and wait for completion + ipcMain.handle('taker:syncOfferbookAndWait', async () => { return await startOfferbookSync('manual'); }); @@ -1047,8 +1014,8 @@ function registerCoinswapHandlers() { while (retries < maxRetries) { try { - // Check if sync is still running - const isSyncing = api1State.takerInstance.isOfferbookSyncing(); + // Check if app-level sync is still running. + const isSyncing = api1State.syncState.isRunning; if (!isSyncing) { // Sync complete - now check if we have enough makers diff --git a/package-lock.json b/package-lock.json index 82b229f..5b1a254 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "taker-app", - "version": "1.0.0", + "name": "coinswap-taker", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "taker-app", - "version": "1.0.0", + "name": "coinswap-taker", + "version": "0.2.0", "license": "ISC", "dependencies": { "@tailwindcss/cli": "^4.1.14", diff --git a/preload.js b/preload.js index 3fb88ec..869c472 100644 --- a/preload.js +++ b/preload.js @@ -12,7 +12,8 @@ contextBridge.exposeInMainWorld('api', { getBalance: () => ipcRenderer.invoke('taker:getBalance'), getNextAddress: () => ipcRenderer.invoke('taker:getNextAddress'), sync: () => ipcRenderer.invoke('taker:sync'), - syncOfferbook: () => ipcRenderer.invoke('taker:syncOfferbook'), + syncOfferbookAndWait: () => + ipcRenderer.invoke('taker:syncOfferbookAndWait'), getSyncStatus: (syncId) => ipcRenderer.invoke('taker:getSyncStatus', syncId), getOffers: () => ipcRenderer.invoke('taker:getOffers'), @@ -30,7 +31,6 @@ contextBridge.exposeInMainWorld('api', { testTorConnection: (config) => ipcRenderer.invoke('tor:testConnection', config), getProtocol: () => ipcRenderer.invoke('taker:getProtocol'), - isOfferbookSyncing: () => ipcRenderer.invoke('taker:isOfferbookSyncing'), setupLogging: (dataDir, level) => ipcRenderer.invoke('taker:setupLogging', { dataDir, level }), diff --git a/src/components/market/Market.js b/src/components/market/Market.js index 85f6272..3520588 100644 --- a/src/components/market/Market.js +++ b/src/components/market/Market.js @@ -152,7 +152,7 @@ export function Market(container) { } } - async function syncOfferbook() { + async function syncOfferbookAndWait() { try { // Check if sync is already running const activeSyncId = localStorage.getItem('active_sync_id'); @@ -169,7 +169,7 @@ export function Market(container) { console.log('🔄 Starting offerbook sync...'); - const result = await window.api.taker.syncOfferbook(); + const result = await window.api.taker.syncOfferbookAndWait(); if (!result.success) { throw new Error(result.error || 'Failed to start sync'); @@ -286,7 +286,7 @@ export function Market(container) { updateUI(); try { - const result = await window.api.taker.syncOfferbook(); + const result = await window.api.taker.syncOfferbookAndWait(); if (!result.success) { throw new Error(result.error || 'Failed to start sync'); @@ -296,20 +296,6 @@ export function Market(container) { console.log('📡 Sync started:', syncId); localStorage.setItem('active_sync_id', syncId); - // Poll until sync completes - let isSyncing = true; - while (isSyncing) { - await new Promise((resolve) => setTimeout(resolve, 1000)); - - const statusResult = await window.api.taker.isOfferbookSyncing(); - if (statusResult.success) { - isSyncing = statusResult.isSyncing; - if (isSyncing) { - console.log('⏳ Still syncing...'); - } - } - } - // Sync is done - wait for file write console.log('✅ Offerbook synced - waiting for file write...'); await new Promise((resolve) => setTimeout(resolve, 2000)); @@ -361,11 +347,11 @@ export function Market(container) { } banner.classList.remove('hidden'); - // ✅ CHECK: Is offerbook currently syncing? + // Check if app-level sync is currently running. try { - const syncingResult = await window.api.taker.isOfferbookSyncing(); + const syncingResult = await window.api.taker.getCurrentSyncState(); - if (syncingResult.success && syncingResult.isSyncing) { + if (syncingResult.success && syncingResult.isRunning) { console.log('⏳ Background sync in progress, waiting...'); isLoading = true; updateUI(); @@ -418,15 +404,15 @@ export function Market(container) { isLoading = true; updateUI(); - // ✅ SIMPLE: Just poll until sync is done + // Poll app sync state until sync is done. let isSyncing = true; while (isSyncing) { await new Promise((resolve) => setTimeout(resolve, 1000)); try { - const result = await window.api.taker.isOfferbookSyncing(); + const result = await window.api.taker.getCurrentSyncState(); if (result.success) { - isSyncing = result.isSyncing; + isSyncing = result.isRunning; if (isSyncing) { console.log('⏳ Still syncing...'); } diff --git a/src/components/taker/TakerInitialization.js b/src/components/taker/TakerInitialization.js index 6cae7c9..39ec0a7 100644 --- a/src/components/taker/TakerInitialization.js +++ b/src/components/taker/TakerInitialization.js @@ -325,8 +325,8 @@ export function sendToAddress(address, amount) { return window.api.taker.sendToAddress(address, amount); } -export function syncOfferbook() { - return window.api.taker.fetchOffers(); +export function syncOfferbookAndWait() { + return window.api.taker.syncOfferbookAndWait(); } export function getOfferbook() {