Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 27 additions & 60 deletions api1.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
}
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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');
});

Expand Down Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand All @@ -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 }),

Expand Down
32 changes: 9 additions & 23 deletions src/components/market/Market.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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');
Expand Down Expand Up @@ -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');
Expand All @@ -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));
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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...');
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/taker/TakerInitialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Comment on lines +328 to 330
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider adding try-catch for consistency.

The function correctly delegates to the new API method, but per coding guidelines, IPC calls should be wrapped in try-catch. While callers in Market.js do handle errors, adding defensive error handling here would improve robustness.

🛡️ Optional: Add error handling
-export function syncOfferbookAndWait() {
-  return window.api.taker.syncOfferbookAndWait();
+export async function syncOfferbookAndWait() {
+  try {
+    return await window.api.taker.syncOfferbookAndWait();
+  } catch (error) {
+    console.error('⚠️ Sync offerbook failed:', error);
+    throw error;
+  }
 }

As per coding guidelines: "Always wrap IPC calls in try-catch" and "Log errors with context using console.error('⚠️ Context:', error)".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function syncOfferbookAndWait() {
return window.api.taker.syncOfferbookAndWait();
}
export async function syncOfferbookAndWait() {
try {
return await window.api.taker.syncOfferbookAndWait();
} catch (error) {
console.error('⚠️ Sync offerbook failed:', error);
throw error;
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/taker/TakerInitialization.js` around lines 328 - 330, Wrap the
IPC call in syncOfferbookAndWait() with a try-catch: call
window.api.taker.syncOfferbookAndWait() inside try, catch any error, log it with
console.error('⚠️ syncOfferbookAndWait:', error) (per guideline) and rethrow the
error so callers (e.g., Market.js) can still handle it; update the function
definition for syncOfferbookAndWait accordingly.


export function getOfferbook() {
Expand Down
Loading