import {Injectable} from '@angular/core'; import {Settings} from '@app/_models'; import Web3 from 'web3'; import {CICRegistry, TransactionHelper} from 'cic-client'; import {first} from 'rxjs/operators'; import {TransactionService} from '@app/_services/transaction.service'; import {environment} from '@src/environments/environment'; import {HttpGetter} from '@app/_helpers'; @Injectable({ providedIn: 'root' }) export class BlockSyncService { readyStateTarget: number = 2; readyState: number = 0; fileGetter = new HttpGetter(); constructor(private transactionService: TransactionService) { } blockSync(): any { const settings = new Settings(this.scan); const provider = environment.web3Provider; const readyStateElements = { network: 2 }; settings.w3.provider = provider; settings.w3.engine = new Web3(provider); settings.registry = new CICRegistry(settings.w3.engine, environment.registryAddress, this.fileGetter, ['../../assets/js/block-sync/data']); settings.registry.declaratorHelper.addTrust(environment.trustedDeclaratorAddress); settings.txHelper = new TransactionHelper(settings.w3.engine, settings.registry); settings.txHelper.ontransfer = async (transaction: any): Promise => { window.dispatchEvent(this.newTransferEvent(transaction)); }; settings.txHelper.onconversion = async (transaction: any): Promise => { window.dispatchEvent(this.newConversionEvent(transaction)); }; settings.registry.onload = (addressReturned: number): void => { console.log('loaded network contracts', addressReturned); this.readyStateProcessor(settings, readyStateElements.network); }; settings.registry.load(); } readyStateProcessor(settings, bit): void { this.readyState |= bit; if (this.readyStateTarget === this.readyState && this.readyStateTarget) { // console.log('reached readyState target', this.readyStateTarget); const wHeadSync = new Worker('./../assets/js/block-sync/head.js'); wHeadSync.onmessage = (m) => { settings.txHelper.processReceipt(m.data); }; wHeadSync.postMessage({ w3_provider: settings.w3.provider, }); this.fetcher(settings); } } newTransferEvent(tx): any { return new CustomEvent('cic_transfer', { detail: { tx, }, }); } newConversionEvent(tx): any { return new CustomEvent('cic_convert', { detail: { tx, }, }); } async scan(settings, lo, hi, bloomBlockBytes, bloomBlocktxBytes, bloomRounds): Promise { const w = new Worker('./../assets/js/block-sync/ondemand.js'); w.onmessage = (m) => { settings.txHelper.processReceipt(m.data); }; w.postMessage({ w3_provider: settings.w3.provider, lo, hi, filters: [ bloomBlockBytes, bloomBlocktxBytes, ], filter_rounds: bloomRounds, }); } fetcher(settings: any, offset: number = 0, limit: number = 100): void { this.transactionService.getAllTransactions(offset, limit).pipe(first()).subscribe(data => { const blockFilterBinstr = window.atob(data.block_filter); const bOne = new Uint8Array(blockFilterBinstr.length); bOne.map((e, i, v) => v[i] = blockFilterBinstr.charCodeAt(i)); const blocktxFilterBinstr = window.atob(data.blocktx_filter); const bTwo = new Uint8Array(blocktxFilterBinstr.length); bTwo.map((e, i, v) => v[i] = blocktxFilterBinstr.charCodeAt(i)); for (let i = 0; i < blockFilterBinstr.length; i++) { if (bOne[i] > 0 ) { // console.debug('blocktx value on', i); } } settings.scanFilter(settings, data.low, data.high, bOne, bTwo, data.filter_rounds); }); } }