dop-wallet-v6 1.3.38 → 1.3.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -191,6 +191,20 @@ const startDopEngine = async (walletSource, db, shouldDebug, artifactStore, useN
|
|
|
191
191
|
const engine = await dop_engine_v3_1.DopEngine.initForWallet(walletSource, db, artifacts_1.artifactGetterDownloadJustInTime, quick_sync_events_1.quickSyncEventsGraph, dop_txid_sync_graph_v2_1.quickSyncDopTransactionsV2, shouldDebug ? createEngineDebugger(verboseScanLogging) : undefined, skipMerkletreeScans);
|
|
192
192
|
(0, engine_1.setEngine)(engine);
|
|
193
193
|
(0, engine_1.setDatabase)(db); // Store database instance for force persist access
|
|
194
|
+
// Initialize prover's groth16 with a stub for React Native
|
|
195
|
+
// This allows the custom prover interception in getProver() to work
|
|
196
|
+
// The stub provides placeholder methods that will be replaced by the backend prover
|
|
197
|
+
if (!engine.prover.groth16) {
|
|
198
|
+
engine.prover.setSnarkJSGroth16({
|
|
199
|
+
fullProve: async () => {
|
|
200
|
+
throw new Error('SnarkJS fullProve should not be called - custom prover should be used');
|
|
201
|
+
},
|
|
202
|
+
fullProveDop: async () => {
|
|
203
|
+
throw new Error('SnarkJS fullProveDop should not be called - custom prover should be used');
|
|
204
|
+
},
|
|
205
|
+
verify: async () => true,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
194
208
|
setOnUTXOMerkletreeScanCompletionListener();
|
|
195
209
|
setOnUTXOScanDecryptBalancesCompleteListener();
|
|
196
210
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../src/services/dop/core/init.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractLevelDOWN } from 'abstract-leveldown';\nimport {\n DopEngine,\n EngineEvent,\n MerkletreeHistoryScanEventData,\n POIList,\n POIListType,\n UTXOScanDecryptBalancesCompleteEventData,\n AbstractWallet,\n POIMerklerootsValidator,\n} from 'dop-engine-v3';\nimport {\n MerkletreeScanUpdateEvent,\n MerkletreeScanStatus,\n isDefined,\n type Chain,\n TXIDVersion,\n} from 'dop-sharedmodels-v3';\nimport { sendErrorMessage, sendMessage } from '../../../utils/logger';\nimport {\n artifactGetterDownloadJustInTime,\n setArtifactStore,\n setUseNativeArtifacts,\n} from './artifacts';\nimport { ArtifactStore } from '../../artifacts/artifact-store';\nimport { reportAndSanitizeError } from '../../../utils/error';\nimport { quickSyncEventsGraph } from '../quick-sync/quick-sync-events';\nimport { quickSyncDopTransactionsV2 } from '../dop-txids/dop-txid-sync-graph-v2';\nimport { setEngine, getEngine, hasEngine, setDatabase, getDatabase } from './engine';\nimport { onBalancesUpdate } from '../wallets/balance-update';\n\nexport type EngineDebugger = {\n log: (msg: string) => void;\n error: (error: Error) => void;\n verboseScanLogging: boolean;\n};\n\nconst createEngineDebugger = (verboseScanLogging: boolean): EngineDebugger => {\n return {\n log: (msg: string) => sendMessage(msg),\n error: (error: Error) => sendErrorMessage(error),\n verboseScanLogging,\n };\n};\n\nexport const setOnUTXOMerkletreeScanCallback = (\n onUTXOMerkletreeScanCallback: (scanData: MerkletreeScanUpdateEvent) => void,\n) => {\n const engine = getEngine();\n engine.on(\n EngineEvent.UTXOMerkletreeHistoryScanUpdate,\n ({ chain, scanStatus, progress }: MerkletreeHistoryScanEventData) =>\n onUTXOMerkletreeScanCallback({\n scanStatus,\n chain,\n progress: progress ?? 0.0,\n }),\n );\n};\n\nexport const setOnTXIDMerkletreeScanCallback = (\n onTXIDMerkletreeScanCallback: (scanData: MerkletreeScanUpdateEvent) => void,\n) => {\n const engine = getEngine();\n engine.on(\n EngineEvent.TXIDMerkletreeHistoryScanUpdate,\n ({ chain, scanStatus, progress }: MerkletreeHistoryScanEventData) =>\n onTXIDMerkletreeScanCallback({\n scanStatus,\n chain,\n progress: progress ?? 0.0,\n }),\n );\n};\n\n// Track which chains have completed scans to avoid duplicate emissions\nconst scanCompletedKeys = new Set<string>();\n// Store resolve functions for pending scan completion promises\nconst scanCompletionPromises = new Map<string, () => void>();\n\nconst setOnUTXOMerkletreeScanCompletionListener = () => {\n const engine = getEngine();\n engine.on(\n EngineEvent.UTXOMerkletreeHistoryScanUpdate,\n ({ chain, scanStatus, txidVersion }: MerkletreeHistoryScanEventData) => {\n // Only handle the FIRST \"Complete\" status for this scan\n if (scanStatus === 'Complete') {\n const key = `${txidVersion}-${chain.type}-${chain.id}`;\n \n // If we've already handled completion for this scan, ignore\n if (scanCompletedKeys.has(key)) {\n return;\n }\n \n // Mark this scan as completed\n scanCompletedKeys.add(key);\n \n sendMessage(`📊 UTXO Merkletree scan completed for ${key}`);\n sendMessage(`🔍 [TRACE] About to handle completion for ${key}`);\n \n // Emit scan complete event after merkletree finishes\n // This handles case where there are NO new transactions to decrypt\n // (UTXOScanDecryptBalancesComplete won't fire in that case)\n const handleCompletion = async () => {\n sendMessage(`🔍 [TRACE] Inside handleCompletion for ${key}`);\n \n // Force persistence even if no new balances\n const db = getDatabase();\n sendMessage(`🔍 [TRACE] Got database: ${isDefined(db) ? 'YES' : 'NO'}`);\n \n if (isDefined(db) && typeof db.forcePersist === 'function') {\n try {\n sendMessage(`🔍 [TRACE] Calling forcePersist...`);\n await db.forcePersist();\n sendMessage('✅ Database persisted after merkletree scan completion');\n } catch (error) {\n sendErrorMessage(\n new Error(`Failed to persist database: ${error instanceof Error ? error.message : String(error)}`)\n );\n }\n } else {\n sendMessage(`⚠️ [TRACE] Database or forcePersist not available, skipping persist`);\n }\n \n // Resolve any pending promises waiting for this scan to complete\n const resolveFunc = scanCompletionPromises.get(key);\n if (isDefined(resolveFunc)) {\n sendMessage(`🔍 [TRACE] Resolving promise for ${key}`);\n resolveFunc();\n scanCompletionPromises.delete(key);\n } else {\n sendMessage(`⚠️ [TRACE] No promise waiting for ${key}`);\n }\n };\n \n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n handleCompletion();\n }\n },\n );\n};\n\nconst setOnUTXOScanDecryptBalancesCompleteListener = () => {\n const engine = getEngine();\n engine.on(\n EngineEvent.UTXOScanDecryptBalancesComplete,\n ({\n txidVersion,\n chain,\n walletIdFilter,\n }: UTXOScanDecryptBalancesCompleteEventData) => {\n const updateWalletBalances = async () => {\n const key = `${txidVersion}-${chain.type}-${chain.id}`;\n sendMessage(`💰 Balance decrypt complete for ${key}, updating wallets...`);\n \n let walletsToUpdate: AbstractWallet[] = Object.values(engine.wallets);\n if (isDefined(walletIdFilter)) {\n walletsToUpdate = walletsToUpdate.filter(wallet =>\n walletIdFilter.includes(wallet.id),\n );\n }\n\n // await onBalancesUpdate calls for each wallet\n await Promise.all(\n walletsToUpdate.map(wallet =>\n onBalancesUpdate(txidVersion, wallet, chain),\n ),\n );\n\n // Force immediate persistence to AsyncStorage/disk after balance updates\n // This ensures balance data is saved before potential app crash/restart\n const db = getDatabase();\n if (isDefined(db) && typeof db.forcePersist === 'function') {\n try {\n await db.forcePersist();\n sendMessage('✅ Database persisted after balance updates');\n } catch (error) {\n sendErrorMessage(\n new Error(`Failed to persist database after balance update: ${error instanceof Error ? error.message : String(error)}`)\n );\n }\n }\n\n // The scan completion will be triggered by the merkletree Complete status event\n // OR we can resolve the promise here since balance updates are done\n sendMessage(`✅ Balance updates and persistence complete for ${key}`);\n \n // Resolve promise immediately after balance updates - data is ready!\n const resolveFunc = scanCompletionPromises.get(key);\n if (isDefined(resolveFunc)) {\n sendMessage(`🔍 [TRACE] Resolving promise after balance updates for ${key}`);\n resolveFunc();\n scanCompletionPromises.delete(key);\n scanCompletedKeys.add(key); // Mark as completed\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n updateWalletBalances();\n },\n );\n};\n\n/**\n * Wait for complete scan including balance updates and persistence.\n * This waits for the merkletree scan Complete status AFTER:\n * - Merkletree scanning completes\n * - Balances are decrypted and updated (if any new transactions)\n * - Database is persisted to storage\n * \n * @param chain - The chain to wait for\n * @param txidVersion - The TXID version being scanned\n * @param timeout - Timeout in milliseconds (default: 600000 = 10 minutes)\n * \n * @example\n * ```typescript\n * const engine = getEngine();\n * engine.scanContractHistory(chain, [walletID]);\n * await awaitScanHistoryComplete(chain, TXIDVersion.V3_PoseidonMerkle);\n * // Now ALL data is persisted and ready!\n * ```\n */\nexport const awaitScanHistoryComplete = (\n chain: Chain,\n txidVersion: TXIDVersion,\n timeout = 600000,\n): Promise<void> => {\n const key = `${txidVersion}-${chain.type}-${chain.id}`;\n \n sendMessage(`🔍 [TRACE] Setting up promise for scan completion: ${key}`);\n \n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n scanCompletionPromises.delete(key);\n reject(new Error(`Scan history completion timeout after ${timeout}ms for chain ${chain.type}:${chain.id}`));\n }, timeout);\n\n // Store the resolve function so the completion listener can call it\n const resolveFunc = () => {\n sendMessage(`🎉 [TRACE] Promise resolved for ${key}`);\n clearTimeout(timeoutId);\n resolve();\n };\n \n scanCompletionPromises.set(key, resolveFunc);\n sendMessage(`✅ [TRACE] Promise registered for ${key}`);\n });\n};\n\n/**\n *\n * @param walletSource - Name for your wallet implementation. Encrypted and viewable in private transaction history. Maximum of 16 characters, lowercase.\n * @param db - LevelDOWN compatible database for storing encrypted wallets.\n * @param shouldDebug - Whether to forward Engine debug logs to Logger.\n * @param artifactStore - Persistent store for downloading large artifact files. See Wallet SDK Developer Guide for platform implementations.\n * @param useNativeArtifacts - Whether to download native C++ or web-assembly artifacts. TRUE for mobile. FALSE for nodejs and browser.\n * @param skipMerkletreeScans - Whether to skip merkletree syncs and private balance scans. Only set to TRUE in encrypt-only applications that don't load private wallets or balances.\n * @param poiNodeURLs - List of POI aggregator node URLs, in order of priority.\n * @param customPOILists - POI lists to use for additional wallet protections after default lists.\n * @returns\n */\nexport const startDopEngine = async (\n walletSource: string,\n db: AbstractLevelDOWN,\n shouldDebug: boolean,\n artifactStore: ArtifactStore,\n useNativeArtifacts: boolean,\n skipMerkletreeScans: boolean,\n verboseScanLogging = false,\n): Promise<void> => {\n if (hasEngine()) {\n return;\n }\n try {\n setArtifactStore(artifactStore);\n setUseNativeArtifacts(useNativeArtifacts);\n\n const engine = await DopEngine.initForWallet(\n walletSource,\n db,\n artifactGetterDownloadJustInTime,\n quickSyncEventsGraph,\n quickSyncDopTransactionsV2,\n shouldDebug ? createEngineDebugger(verboseScanLogging) : undefined,\n skipMerkletreeScans,\n );\n setEngine(engine);\n setDatabase(db); // Store database instance for force persist access\n\n setOnUTXOMerkletreeScanCompletionListener();\n setOnUTXOScanDecryptBalancesCompleteListener();\n } catch (err) {\n throw reportAndSanitizeError(startDopEngine.name, err);\n }\n};\n\nexport const stopDopEngine = async () => {\n if (!hasEngine()) {\n return;\n }\n await getEngine()?.unload();\n setEngine(undefined);\n setDatabase(undefined); // Clear database reference\n scanCompletedKeys.clear(); // Clear completion tracking for next engine start\n};\n\n scanCompletionPromises.clear(); // Clear pending promises\nexport { POIList, POIListType };\n"]}
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../src/services/dop/core/init.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractLevelDOWN } from 'abstract-leveldown';\nimport {\n DopEngine,\n EngineEvent,\n MerkletreeHistoryScanEventData,\n POIList,\n POIListType,\n UTXOScanDecryptBalancesCompleteEventData,\n AbstractWallet,\n POIMerklerootsValidator,\n} from 'dop-engine-v3';\nimport {\n MerkletreeScanUpdateEvent,\n MerkletreeScanStatus,\n isDefined,\n type Chain,\n TXIDVersion,\n} from 'dop-sharedmodels-v3';\nimport { sendErrorMessage, sendMessage } from '../../../utils/logger';\nimport {\n artifactGetterDownloadJustInTime,\n setArtifactStore,\n setUseNativeArtifacts,\n} from './artifacts';\nimport { ArtifactStore } from '../../artifacts/artifact-store';\nimport { reportAndSanitizeError } from '../../../utils/error';\nimport { quickSyncEventsGraph } from '../quick-sync/quick-sync-events';\nimport { quickSyncDopTransactionsV2 } from '../dop-txids/dop-txid-sync-graph-v2';\nimport { setEngine, getEngine, hasEngine, setDatabase, getDatabase } from './engine';\nimport { onBalancesUpdate } from '../wallets/balance-update';\n\nexport type EngineDebugger = {\n log: (msg: string) => void;\n error: (error: Error) => void;\n verboseScanLogging: boolean;\n};\n\nconst createEngineDebugger = (verboseScanLogging: boolean): EngineDebugger => {\n return {\n log: (msg: string) => sendMessage(msg),\n error: (error: Error) => sendErrorMessage(error),\n verboseScanLogging,\n };\n};\n\nexport const setOnUTXOMerkletreeScanCallback = (\n onUTXOMerkletreeScanCallback: (scanData: MerkletreeScanUpdateEvent) => void,\n) => {\n const engine = getEngine();\n engine.on(\n EngineEvent.UTXOMerkletreeHistoryScanUpdate,\n ({ chain, scanStatus, progress }: MerkletreeHistoryScanEventData) =>\n onUTXOMerkletreeScanCallback({\n scanStatus,\n chain,\n progress: progress ?? 0.0,\n }),\n );\n};\n\nexport const setOnTXIDMerkletreeScanCallback = (\n onTXIDMerkletreeScanCallback: (scanData: MerkletreeScanUpdateEvent) => void,\n) => {\n const engine = getEngine();\n engine.on(\n EngineEvent.TXIDMerkletreeHistoryScanUpdate,\n ({ chain, scanStatus, progress }: MerkletreeHistoryScanEventData) =>\n onTXIDMerkletreeScanCallback({\n scanStatus,\n chain,\n progress: progress ?? 0.0,\n }),\n );\n};\n\n// Track which chains have completed scans to avoid duplicate emissions\nconst scanCompletedKeys = new Set<string>();\n// Store resolve functions for pending scan completion promises\nconst scanCompletionPromises = new Map<string, () => void>();\n\nconst setOnUTXOMerkletreeScanCompletionListener = () => {\n const engine = getEngine();\n engine.on(\n EngineEvent.UTXOMerkletreeHistoryScanUpdate,\n ({ chain, scanStatus, txidVersion }: MerkletreeHistoryScanEventData) => {\n // Only handle the FIRST \"Complete\" status for this scan\n if (scanStatus === 'Complete') {\n const key = `${txidVersion}-${chain.type}-${chain.id}`;\n \n // If we've already handled completion for this scan, ignore\n if (scanCompletedKeys.has(key)) {\n return;\n }\n \n // Mark this scan as completed\n scanCompletedKeys.add(key);\n \n sendMessage(`📊 UTXO Merkletree scan completed for ${key}`);\n sendMessage(`🔍 [TRACE] About to handle completion for ${key}`);\n \n // Emit scan complete event after merkletree finishes\n // This handles case where there are NO new transactions to decrypt\n // (UTXOScanDecryptBalancesComplete won't fire in that case)\n const handleCompletion = async () => {\n sendMessage(`🔍 [TRACE] Inside handleCompletion for ${key}`);\n \n // Force persistence even if no new balances\n const db = getDatabase();\n sendMessage(`🔍 [TRACE] Got database: ${isDefined(db) ? 'YES' : 'NO'}`);\n \n if (isDefined(db) && typeof db.forcePersist === 'function') {\n try {\n sendMessage(`🔍 [TRACE] Calling forcePersist...`);\n await db.forcePersist();\n sendMessage('✅ Database persisted after merkletree scan completion');\n } catch (error) {\n sendErrorMessage(\n new Error(`Failed to persist database: ${error instanceof Error ? error.message : String(error)}`)\n );\n }\n } else {\n sendMessage(`⚠️ [TRACE] Database or forcePersist not available, skipping persist`);\n }\n \n // Resolve any pending promises waiting for this scan to complete\n const resolveFunc = scanCompletionPromises.get(key);\n if (isDefined(resolveFunc)) {\n sendMessage(`🔍 [TRACE] Resolving promise for ${key}`);\n resolveFunc();\n scanCompletionPromises.delete(key);\n } else {\n sendMessage(`⚠️ [TRACE] No promise waiting for ${key}`);\n }\n };\n \n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n handleCompletion();\n }\n },\n );\n};\n\nconst setOnUTXOScanDecryptBalancesCompleteListener = () => {\n const engine = getEngine();\n engine.on(\n EngineEvent.UTXOScanDecryptBalancesComplete,\n ({\n txidVersion,\n chain,\n walletIdFilter,\n }: UTXOScanDecryptBalancesCompleteEventData) => {\n const updateWalletBalances = async () => {\n const key = `${txidVersion}-${chain.type}-${chain.id}`;\n sendMessage(`💰 Balance decrypt complete for ${key}, updating wallets...`);\n \n let walletsToUpdate: AbstractWallet[] = Object.values(engine.wallets);\n if (isDefined(walletIdFilter)) {\n walletsToUpdate = walletsToUpdate.filter(wallet =>\n walletIdFilter.includes(wallet.id),\n );\n }\n\n // await onBalancesUpdate calls for each wallet\n await Promise.all(\n walletsToUpdate.map(wallet =>\n onBalancesUpdate(txidVersion, wallet, chain),\n ),\n );\n\n // Force immediate persistence to AsyncStorage/disk after balance updates\n // This ensures balance data is saved before potential app crash/restart\n const db = getDatabase();\n if (isDefined(db) && typeof db.forcePersist === 'function') {\n try {\n await db.forcePersist();\n sendMessage('✅ Database persisted after balance updates');\n } catch (error) {\n sendErrorMessage(\n new Error(`Failed to persist database after balance update: ${error instanceof Error ? error.message : String(error)}`)\n );\n }\n }\n\n // The scan completion will be triggered by the merkletree Complete status event\n // OR we can resolve the promise here since balance updates are done\n sendMessage(`✅ Balance updates and persistence complete for ${key}`);\n \n // Resolve promise immediately after balance updates - data is ready!\n const resolveFunc = scanCompletionPromises.get(key);\n if (isDefined(resolveFunc)) {\n sendMessage(`🔍 [TRACE] Resolving promise after balance updates for ${key}`);\n resolveFunc();\n scanCompletionPromises.delete(key);\n scanCompletedKeys.add(key); // Mark as completed\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n updateWalletBalances();\n },\n );\n};\n\n/**\n * Wait for complete scan including balance updates and persistence.\n * This waits for the merkletree scan Complete status AFTER:\n * - Merkletree scanning completes\n * - Balances are decrypted and updated (if any new transactions)\n * - Database is persisted to storage\n * \n * @param chain - The chain to wait for\n * @param txidVersion - The TXID version being scanned\n * @param timeout - Timeout in milliseconds (default: 600000 = 10 minutes)\n * \n * @example\n * ```typescript\n * const engine = getEngine();\n * engine.scanContractHistory(chain, [walletID]);\n * await awaitScanHistoryComplete(chain, TXIDVersion.V3_PoseidonMerkle);\n * // Now ALL data is persisted and ready!\n * ```\n */\nexport const awaitScanHistoryComplete = (\n chain: Chain,\n txidVersion: TXIDVersion,\n timeout = 600000,\n): Promise<void> => {\n const key = `${txidVersion}-${chain.type}-${chain.id}`;\n \n sendMessage(`🔍 [TRACE] Setting up promise for scan completion: ${key}`);\n \n return new Promise((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n scanCompletionPromises.delete(key);\n reject(new Error(`Scan history completion timeout after ${timeout}ms for chain ${chain.type}:${chain.id}`));\n }, timeout);\n\n // Store the resolve function so the completion listener can call it\n const resolveFunc = () => {\n sendMessage(`🎉 [TRACE] Promise resolved for ${key}`);\n clearTimeout(timeoutId);\n resolve();\n };\n \n scanCompletionPromises.set(key, resolveFunc);\n sendMessage(`✅ [TRACE] Promise registered for ${key}`);\n });\n};\n\n/**\n *\n * @param walletSource - Name for your wallet implementation. Encrypted and viewable in private transaction history. Maximum of 16 characters, lowercase.\n * @param db - LevelDOWN compatible database for storing encrypted wallets.\n * @param shouldDebug - Whether to forward Engine debug logs to Logger.\n * @param artifactStore - Persistent store for downloading large artifact files. See Wallet SDK Developer Guide for platform implementations.\n * @param useNativeArtifacts - Whether to download native C++ or web-assembly artifacts. TRUE for mobile. FALSE for nodejs and browser.\n * @param skipMerkletreeScans - Whether to skip merkletree syncs and private balance scans. Only set to TRUE in encrypt-only applications that don't load private wallets or balances.\n * @param poiNodeURLs - List of POI aggregator node URLs, in order of priority.\n * @param customPOILists - POI lists to use for additional wallet protections after default lists.\n * @returns\n */\nexport const startDopEngine = async (\n walletSource: string,\n db: AbstractLevelDOWN,\n shouldDebug: boolean,\n artifactStore: ArtifactStore,\n useNativeArtifacts: boolean,\n skipMerkletreeScans: boolean,\n verboseScanLogging = false,\n): Promise<void> => {\n if (hasEngine()) {\n return;\n }\n try {\n setArtifactStore(artifactStore);\n setUseNativeArtifacts(useNativeArtifacts);\n\n const engine = await DopEngine.initForWallet(\n walletSource,\n db,\n artifactGetterDownloadJustInTime,\n quickSyncEventsGraph,\n quickSyncDopTransactionsV2,\n shouldDebug ? createEngineDebugger(verboseScanLogging) : undefined,\n skipMerkletreeScans,\n );\n setEngine(engine);\n setDatabase(db); // Store database instance for force persist access\n \n // Initialize prover's groth16 with a stub for React Native\n // This allows the custom prover interception in getProver() to work\n // The stub provides placeholder methods that will be replaced by the backend prover\n if (!engine.prover.groth16) {\n engine.prover.setSnarkJSGroth16({\n fullProve: async () => {\n throw new Error('SnarkJS fullProve should not be called - custom prover should be used');\n },\n fullProveDop: async () => {\n throw new Error('SnarkJS fullProveDop should not be called - custom prover should be used');\n },\n verify: async () => true,\n } as any);\n }\n\n setOnUTXOMerkletreeScanCompletionListener();\n setOnUTXOScanDecryptBalancesCompleteListener();\n } catch (err) {\n throw reportAndSanitizeError(startDopEngine.name, err);\n }\n};\n\nexport const stopDopEngine = async () => {\n if (!hasEngine()) {\n return;\n }\n await getEngine()?.unload();\n setEngine(undefined);\n setDatabase(undefined); // Clear database reference\n scanCompletedKeys.clear(); // Clear completion tracking for next engine start\n};\n\n scanCompletionPromises.clear(); // Clear pending promises\nexport { POIList, POIListType };\n"]}
|