Преглед изворни кода

feat: sync on-chain position to DB on engine start

When DB is empty (e.g. after clearing), scan chain for existing
user bins before opening a new position to avoid orphaning liquidity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zhangchunrui пре 3 недеља
родитељ
комит
e391543b4f
1 измењених фајлова са 48 додато и 1 уклоњено
  1. 48 1
      src/lib/engine/engine.ts

+ 48 - 1
src/lib/engine/engine.ts

@@ -8,6 +8,7 @@ import {
   openPosition,
   closePosition,
   rebalanceSwap,
+  findUserBinIds,
 } from '../chain'
 import {
   getCurrentPosition,
@@ -53,12 +54,16 @@ export class RebalancerEngine {
     return g[GLOBAL_KEY]
   }
 
-  start(): void {
+  async start(): Promise<void> {
     if (this.running) return
     this.status = 'running'
     this.startedAt = Date.now()
     this.stopRequested = false
     setEngineState('status', 'running')
+
+    // Sync on-chain position to DB if DB is empty
+    await this.syncPositionFromChain()
+
     console.log('[engine] Started')
     this.runLoop()
   }
@@ -151,6 +156,48 @@ export class RebalancerEngine {
     }
   }
 
+  // ── Sync on-chain position to DB ──
+
+  private async syncPositionFromChain(): Promise<void> {
+    const existing = getCurrentPosition()
+    if (existing) {
+      console.log(
+        `[engine] DB has position: bin=${existing.activeId}, range=[${existing.minBin}, ${existing.maxBin}]`,
+      )
+      return
+    }
+
+    console.log('[engine] No position in DB, scanning chain...')
+    try {
+      const binIds = await findUserBinIds(100)
+      if (binIds.length === 0) {
+        console.log('[engine] No on-chain position found')
+        return
+      }
+
+      const minBin = Math.min(...binIds)
+      const maxBin = Math.max(...binIds)
+      const centerBin = Math.round((minBin + maxBin) / 2)
+      const price = getPriceFromBinId(centerBin)
+
+      upsertPosition({
+        activeId: centerBin,
+        minBin,
+        maxBin,
+        numBins: binIds.length,
+        binIds,
+        amounts: binIds.map(() => '0'),
+        priceAtOpen: price,
+      })
+
+      console.log(
+        `[engine] Recovered on-chain position: ${binIds.length} bins, range=[${minBin}, ${maxBin}]`,
+      )
+    } catch (err) {
+      console.error('[engine] Chain sync failed:', err instanceof Error ? err.message : err)
+    }
+  }
+
   // ── Main loop: sequential, waits for each cycle to finish ──
 
   private async runLoop(): Promise<void> {