@@ -20,6 +20,7 @@ import type { TxOptions } from '../../utils/coinUtils.js'
2020import { logger } from '../../utils/logger'
2121import { getMintsToSpend } from './coinOperations'
2222import {
23+ createPrivateCoin ,
2324 createSpendTX ,
2425 getMintCommitmentsForValue ,
2526 parseJsonTransactionForSpend ,
@@ -28,7 +29,7 @@ import {
2829} from './coinUtils'
2930import type { SpendCoin } from './coinUtils.js'
3031import type { PrivateCoin } from './flowTypes'
31- import { denominations , OP_SIGMA_MINT } from './flowTypes'
32+ import { denominations , OP_SIGMA_MINT , RESTORE_FILE } from './flowTypes'
3233import { ZcoinStateExtension } from './zcoinStateExtension'
3334
3435const MILLI_TO_SEC = 1000
@@ -65,6 +66,17 @@ export class ZcoinEngineExtension implements CurrencyEngineExtension {
6566 this . runLooperIfNeed ( )
6667 }
6768
69+ async resyncBlockchain ( ) {
70+ window . setTimeout ( ( ) => {
71+ this . forceReloadSpendTransactions ( )
72+ this . zcoinStateExtensions . wakeUpConnections ( )
73+ } , 5000 )
74+ }
75+
76+ async killEngine ( ) {
77+ this . cancelAllLooperMethods ( )
78+ }
79+
6880 onTxFetched ( txid : string ) {
6981 logger . info ( `zcoinEngineExtension -> onTxFetched called txId ${ txid } ` )
7082 if ( txid in this . savedSpendTransactionValues ) {
@@ -112,6 +124,11 @@ export class ZcoinEngineExtension implements CurrencyEngineExtension {
112124 async loop ( ) {
113125 logger . info ( 'zcoinEngineExtension -> loop called' )
114126
127+ const restored = await this . restore ( )
128+ if ( ! restored ) {
129+ return
130+ }
131+
115132 // TODO: can move into newTx
116133 const utxos = this . engineState . getUTXOs ( )
117134 const needToMint = sumUtxos ( utxos )
@@ -135,7 +152,6 @@ export class ZcoinEngineExtension implements CurrencyEngineExtension {
135152 }
136153 ]
137154 }
138- // mint and getMintMetadataLoop must not work paralelly in order to avoid problems related to modifying mint.json parallely
139155 await this . mint ( edgeInfo )
140156 }
141157
@@ -144,6 +160,86 @@ export class ZcoinEngineExtension implements CurrencyEngineExtension {
144160 this . onBalanceChanged ( )
145161 }
146162
163+ async restore ( ) : Promise < boolean > {
164+ logger. info ( 'zcoinEngineExtension -> restore' )
165+
166+ try {
167+ const restoreJsonStr = await this . walletLocalEncryptedDisklet . getText (
168+ RESTORE_FILE
169+ )
170+ if ( restoreJsonStr && JSON . parse ( restoreJsonStr ) . restored ) {
171+ return true
172+ }
173+ } catch ( e ) {
174+ logger . error ( 'zcoinEngineExtension -> something went wrong' , e )
175+ }
176+
177+ const mintData : PrivateCoin [ ] = [ ]
178+
179+ let usedSerialNumbers = [ ]
180+ const usedCoins = await this . zcoinStateExtensions . retrieveUsedCoinSerials ( )
181+ usedSerialNumbers = usedCoins . serials
182+
183+ const latestCoinIds = await this . zcoinStateExtensions . retrieveLatestCoinIds ( )
184+ let commitmentCount = 0
185+ for ( const coinInfo of latestCoinIds ) {
186+ coinInfo . anonymitySet = [ ]
187+ for ( let i = 0 ; i < coinInfo . id ; i ++ ) {
188+ const anonimitySet = await this . zcoinStateExtensions . retrieveAnonymitySet (
189+ coinInfo . denom ,
190+ i + 1
191+ )
192+ coinInfo . anonymitySet = coinInfo . anonymitySet . concat (
193+ anonimitySet . serializedCoins
194+ )
195+ commitmentCount += anonimitySet . serializedCoins . length
196+ }
197+ }
198+
199+ let counter = 0
200+ let index = - 1
201+ while ( counter ++ < 100 && index ++ < commitmentCount ) {
202+ // commitment is only dependant to private key and index, that's why coin value is hardcoded
203+ const coin = await createPrivateCoin (
204+ 100000000 ,
205+ this . currencyEngine . walletInfo . keys . dataKey ,
206+ index ,
207+ this . io
208+ )
209+ logger . info ( 'zcoinEngineExtension -> restore coin ' , coin )
210+ const isSpend = usedSerialNumbers . includes ( coin . serialNumber )
211+ for ( const coinInfo of latestCoinIds ) {
212+ if ( coinInfo . anonymitySet . includes ( coin . commitment ) ) {
213+ mintData . push ( {
214+ value : coinInfo . denom ,
215+ index : index ,
216+ commitment : coin . commitment ,
217+ serialNumber : '' ,
218+ groupId : coinInfo . id ,
219+ isSpend : isSpend ,
220+ spendTxId : ''
221+ } )
222+ counter = 0
223+ break
224+ }
225+ }
226+ }
227+
228+ try {
229+ logger . info ( 'zcoinEngineExtension -> restore try save ' , mintData )
230+ await this . zcoinStateExtensions . writeMintedCoins ( mintData )
231+ await this . walletLocalEncryptedDisklet . setText (
232+ RESTORE_FILE ,
233+ JSON . stringify ( { restored : true } )
234+ )
235+ logger . info ( 'zcoinEngineExtension -> restored' )
236+ } catch ( e ) {
237+ return false
238+ }
239+
240+ return true
241+ }
242+
147243 runLooperIfNeed ( ) {
148244 this . canRunLoop = true
149245 this . addLooperMethodToLoop ( 'loop' , 60000 )
@@ -657,4 +753,12 @@ export class ZcoinEngineExtension implements CurrencyEngineExtension {
657753
658754 return spendTransactionValues
659755 }
756+
757+ forceReloadSpendTransactions ( ) {
758+ this . zcoinStateExtensions . mintedCoins . forEach ( item => {
759+ if ( item . spendTxId ) {
760+ this . zcoinStateExtensions . handleNewTxid ( item . spendTxId , true )
761+ }
762+ } )
763+ }
660764}
0 commit comments