// // Copyright 2021 Vulcanize, Inc. // import assert from 'assert'; import { DeepPartial, FindConditions, FindManyOptions } from 'typeorm'; import debug from 'debug'; import JSONbig from 'json-bigint'; import { ethers } from 'ethers'; import { JsonFragment } from '@ethersproject/abi'; import { BaseProvider } from '@ethersproject/providers'; import { EthClient } from '@cerc-io/ipld-eth-client'; import { MappingKey, StorageLayout } from '@cerc-io/solidity-mapper'; import { Indexer as BaseIndexer, IndexerInterface, ValueResult, ServerConfig, JobQueue, Where, QueryOptions, StateKind, StateStatus, ResultEvent, getResultEvent, DatabaseInterface, Clients } from '@cerc-io/util'; import ConditionalStarReleaseArtifacts from './artifacts/ConditionalStarRelease.json'; import { Database, ENTITIES } from './database'; import { createInitialState, handleEvent, createStateDiff, createStateCheckpoint } from './hooks'; import { Contract } from './entity/Contract'; import { Event } from './entity/Event'; import { SyncStatus } from './entity/SyncStatus'; import { StateSyncStatus } from './entity/StateSyncStatus'; import { BlockProgress } from './entity/BlockProgress'; import { State } from './entity/State'; // eslint-disable-next-line @typescript-eslint/no-unused-vars const log = debug('vulcanize:indexer'); const JSONbigNative = JSONbig({ useNativeBigInt: true }); const KIND_CONDITIONALSTARRELEASE = 'ConditionalStarRelease'; export class Indexer implements IndexerInterface { _db: Database; _ethClient: EthClient; _ethProvider: BaseProvider; _baseIndexer: BaseIndexer; _serverConfig: ServerConfig; _abiMap: Map; _storageLayoutMap: Map; _contractMap: Map; constructor (serverConfig: ServerConfig, db: DatabaseInterface, clients: Clients, ethProvider: BaseProvider, jobQueue: JobQueue) { assert(db); assert(clients.ethClient); this._db = db as Database; this._ethClient = clients.ethClient; this._ethProvider = ethProvider; this._serverConfig = serverConfig; this._baseIndexer = new BaseIndexer(this._serverConfig, this._db, this._ethClient, this._ethProvider, jobQueue); this._abiMap = new Map(); this._storageLayoutMap = new Map(); this._contractMap = new Map(); const { abi: ConditionalStarReleaseABI } = ConditionalStarReleaseArtifacts; assert(ConditionalStarReleaseABI); this._abiMap.set(KIND_CONDITIONALSTARRELEASE, ConditionalStarReleaseABI); this._contractMap.set(KIND_CONDITIONALSTARRELEASE, new ethers.utils.Interface(ConditionalStarReleaseABI)); } get serverConfig (): ServerConfig { return this._serverConfig; } get storageLayoutMap (): Map { return this._storageLayoutMap; } async init (): Promise { await this._baseIndexer.fetchContracts(); await this._baseIndexer.fetchStateStatus(); } getResultEvent (event: Event): ResultEvent { return getResultEvent(event); } async isActive (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getIsActive({ blockHash, contractAddress, _point }); if (entity) { log('isActive: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isActive: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isActive(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsActive({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getKeyRevisionNumber (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetKeyRevisionNumber({ blockHash, contractAddress, _point }); if (entity) { log('getKeyRevisionNumber: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getKeyRevisionNumber: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getKeyRevisionNumber(_point, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetKeyRevisionNumber({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async hasBeenLinked (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getHasBeenLinked({ blockHash, contractAddress, _point }); if (entity) { log('hasBeenLinked: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('hasBeenLinked: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.hasBeenLinked(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveHasBeenLinked({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isLive (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getIsLive({ blockHash, contractAddress, _point }); if (entity) { log('isLive: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isLive: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isLive(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsLive({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getContinuityNumber (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetContinuityNumber({ blockHash, contractAddress, _point }); if (entity) { log('getContinuityNumber: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getContinuityNumber: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getContinuityNumber(_point, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetContinuityNumber({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSpawnCount (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetSpawnCount({ blockHash, contractAddress, _point }); if (entity) { log('getSpawnCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getSpawnCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSpawnCount(_point, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetSpawnCount({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSpawned (blockHash: string, contractAddress: string, _point: bigint): Promise { log('getSpawned: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSpawned(_point, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async hasSponsor (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getHasSponsor({ blockHash, contractAddress, _point }); if (entity) { log('hasSponsor: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('hasSponsor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.hasSponsor(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveHasSponsor({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSponsor (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetSponsor({ blockHash, contractAddress, _point }); if (entity) { log('getSponsor: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getSponsor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSponsor(_point, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetSponsor({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isSponsor (blockHash: string, contractAddress: string, _point: bigint, _sponsor: bigint): Promise { const entity = await this._db.getIsSponsor({ blockHash, contractAddress, _point, _sponsor }); if (entity) { log('isSponsor: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isSponsor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isSponsor(_point, _sponsor, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsSponsor({ blockHash, blockNumber, contractAddress, _point, _sponsor, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSponsoringCount (blockHash: string, contractAddress: string, _sponsor: bigint): Promise { const entity = await this._db.getGetSponsoringCount({ blockHash, contractAddress, _sponsor }); if (entity) { log('getSponsoringCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getSponsoringCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSponsoringCount(_sponsor, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetSponsoringCount({ blockHash, blockNumber, contractAddress, _sponsor, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSponsoring (blockHash: string, contractAddress: string, _sponsor: bigint): Promise { log('getSponsoring: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSponsoring(_sponsor, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async isEscaping (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getIsEscaping({ blockHash, contractAddress, _point }); if (entity) { log('isEscaping: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isEscaping: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isEscaping(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsEscaping({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getEscapeRequest (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetEscapeRequest({ blockHash, contractAddress, _point }); if (entity) { log('getEscapeRequest: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getEscapeRequest: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getEscapeRequest(_point, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetEscapeRequest({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isRequestingEscapeTo (blockHash: string, contractAddress: string, _point: bigint, _sponsor: bigint): Promise { const entity = await this._db.getIsRequestingEscapeTo({ blockHash, contractAddress, _point, _sponsor }); if (entity) { log('isRequestingEscapeTo: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isRequestingEscapeTo: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isRequestingEscapeTo(_point, _sponsor, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsRequestingEscapeTo({ blockHash, blockNumber, contractAddress, _point, _sponsor, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getEscapeRequestsCount (blockHash: string, contractAddress: string, _sponsor: bigint): Promise { const entity = await this._db.getGetEscapeRequestsCount({ blockHash, contractAddress, _sponsor }); if (entity) { log('getEscapeRequestsCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getEscapeRequestsCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getEscapeRequestsCount(_sponsor, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetEscapeRequestsCount({ blockHash, blockNumber, contractAddress, _sponsor, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getEscapeRequests (blockHash: string, contractAddress: string, _sponsor: bigint): Promise { log('getEscapeRequests: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getEscapeRequests(_sponsor, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async getOwner (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetOwner({ blockHash, contractAddress, _point }); if (entity) { log('getOwner: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getOwner: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getOwner(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetOwner({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isOwner (blockHash: string, contractAddress: string, _point: bigint, _address: string): Promise { const entity = await this._db.getIsOwner({ blockHash, contractAddress, _point, _address }); if (entity) { log('isOwner: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isOwner: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isOwner(_point, _address, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsOwner({ blockHash, blockNumber, contractAddress, _point, _address, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getOwnedPointCount (blockHash: string, contractAddress: string, _whose: string): Promise { const entity = await this._db.getGetOwnedPointCount({ blockHash, contractAddress, _whose }); if (entity) { log('getOwnedPointCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getOwnedPointCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getOwnedPointCount(_whose, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetOwnedPointCount({ blockHash, blockNumber, contractAddress, _whose, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getOwnedPoints (blockHash: string, contractAddress: string, _whose: string): Promise { log('getOwnedPoints: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getOwnedPoints(_whose, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async getOwnedPointAtIndex (blockHash: string, contractAddress: string, _whose: string, _index: bigint): Promise { const entity = await this._db.getGetOwnedPointAtIndex({ blockHash, contractAddress, _whose, _index }); if (entity) { log('getOwnedPointAtIndex: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getOwnedPointAtIndex: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getOwnedPointAtIndex(_whose, _index, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetOwnedPointAtIndex({ blockHash, blockNumber, contractAddress, _whose, _index, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getManagementProxy (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetManagementProxy({ blockHash, contractAddress, _point }); if (entity) { log('getManagementProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getManagementProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getManagementProxy(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetManagementProxy({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isManagementProxy (blockHash: string, contractAddress: string, _point: bigint, _proxy: string): Promise { const entity = await this._db.getIsManagementProxy({ blockHash, contractAddress, _point, _proxy }); if (entity) { log('isManagementProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isManagementProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isManagementProxy(_point, _proxy, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsManagementProxy({ blockHash, blockNumber, contractAddress, _point, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async canManage (blockHash: string, contractAddress: string, _point: bigint, _who: string): Promise { const entity = await this._db.getCanManage({ blockHash, contractAddress, _point, _who }); if (entity) { log('canManage: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('canManage: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.canManage(_point, _who, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveCanManage({ blockHash, blockNumber, contractAddress, _point, _who, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getManagerForCount (blockHash: string, contractAddress: string, _proxy: string): Promise { const entity = await this._db.getGetManagerForCount({ blockHash, contractAddress, _proxy }); if (entity) { log('getManagerForCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getManagerForCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getManagerForCount(_proxy, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetManagerForCount({ blockHash, blockNumber, contractAddress, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getManagerFor (blockHash: string, contractAddress: string, _proxy: string): Promise { log('getManagerFor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getManagerFor(_proxy, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async getSpawnProxy (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetSpawnProxy({ blockHash, contractAddress, _point }); if (entity) { log('getSpawnProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getSpawnProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getSpawnProxy(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetSpawnProxy({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isSpawnProxy (blockHash: string, contractAddress: string, _point: bigint, _proxy: string): Promise { const entity = await this._db.getIsSpawnProxy({ blockHash, contractAddress, _point, _proxy }); if (entity) { log('isSpawnProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isSpawnProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isSpawnProxy(_point, _proxy, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsSpawnProxy({ blockHash, blockNumber, contractAddress, _point, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async canSpawnAs (blockHash: string, contractAddress: string, _point: bigint, _who: string): Promise { const entity = await this._db.getCanSpawnAs({ blockHash, contractAddress, _point, _who }); if (entity) { log('canSpawnAs: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('canSpawnAs: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.canSpawnAs(_point, _who, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveCanSpawnAs({ blockHash, blockNumber, contractAddress, _point, _who, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSpawningForCount (blockHash: string, contractAddress: string, _proxy: string): Promise { const entity = await this._db.getGetSpawningForCount({ blockHash, contractAddress, _proxy }); if (entity) { log('getSpawningForCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getSpawningForCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSpawningForCount(_proxy, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetSpawningForCount({ blockHash, blockNumber, contractAddress, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSpawningFor (blockHash: string, contractAddress: string, _proxy: string): Promise { log('getSpawningFor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSpawningFor(_proxy, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async getVotingProxy (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetVotingProxy({ blockHash, contractAddress, _point }); if (entity) { log('getVotingProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getVotingProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getVotingProxy(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetVotingProxy({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isVotingProxy (blockHash: string, contractAddress: string, _point: bigint, _proxy: string): Promise { const entity = await this._db.getIsVotingProxy({ blockHash, contractAddress, _point, _proxy }); if (entity) { log('isVotingProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isVotingProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isVotingProxy(_point, _proxy, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsVotingProxy({ blockHash, blockNumber, contractAddress, _point, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async canVoteAs (blockHash: string, contractAddress: string, _point: bigint, _who: string): Promise { const entity = await this._db.getCanVoteAs({ blockHash, contractAddress, _point, _who }); if (entity) { log('canVoteAs: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('canVoteAs: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.canVoteAs(_point, _who, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveCanVoteAs({ blockHash, blockNumber, contractAddress, _point, _who, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getVotingForCount (blockHash: string, contractAddress: string, _proxy: string): Promise { const entity = await this._db.getGetVotingForCount({ blockHash, contractAddress, _proxy }); if (entity) { log('getVotingForCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getVotingForCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getVotingForCount(_proxy, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetVotingForCount({ blockHash, blockNumber, contractAddress, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getVotingFor (blockHash: string, contractAddress: string, _proxy: string): Promise { log('getVotingFor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getVotingFor(_proxy, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async getTransferProxy (blockHash: string, contractAddress: string, _point: bigint): Promise { const entity = await this._db.getGetTransferProxy({ blockHash, contractAddress, _point }); if (entity) { log('getTransferProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getTransferProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getTransferProxy(_point, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetTransferProxy({ blockHash, blockNumber, contractAddress, _point, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isTransferProxy (blockHash: string, contractAddress: string, _point: bigint, _proxy: string): Promise { const entity = await this._db.getIsTransferProxy({ blockHash, contractAddress, _point, _proxy }); if (entity) { log('isTransferProxy: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isTransferProxy: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isTransferProxy(_point, _proxy, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsTransferProxy({ blockHash, blockNumber, contractAddress, _point, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async canTransfer (blockHash: string, contractAddress: string, _point: bigint, _who: string): Promise { const entity = await this._db.getCanTransfer({ blockHash, contractAddress, _point, _who }); if (entity) { log('canTransfer: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('canTransfer: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.canTransfer(_point, _who, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveCanTransfer({ blockHash, blockNumber, contractAddress, _point, _who, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getTransferringForCount (blockHash: string, contractAddress: string, _proxy: string): Promise { const entity = await this._db.getGetTransferringForCount({ blockHash, contractAddress, _proxy }); if (entity) { log('getTransferringForCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getTransferringForCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getTransferringForCount(_proxy, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetTransferringForCount({ blockHash, blockNumber, contractAddress, _proxy, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getTransferringFor (blockHash: string, contractAddress: string, _proxy: string): Promise { log('getTransferringFor: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getTransferringFor(_proxy, { blockTag: blockHash }); value = value.map((val: ethers.BigNumber) => ethers.BigNumber.from(val).toBigInt()); const result: ValueResult = { value }; return result; } async isOperator (blockHash: string, contractAddress: string, _owner: string, _operator: string): Promise { const entity = await this._db.getIsOperator({ blockHash, contractAddress, _owner, _operator }); if (entity) { log('isOperator: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isOperator: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isOperator(_owner, _operator, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsOperator({ blockHash, blockNumber, contractAddress, _owner, _operator, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getUpgradeProposals (blockHash: string, contractAddress: string): Promise { log('getUpgradeProposals: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getUpgradeProposals({ blockTag: blockHash }); const result: ValueResult = { value }; return result; } async getUpgradeProposalCount (blockHash: string, contractAddress: string): Promise { const entity = await this._db.getGetUpgradeProposalCount({ blockHash, contractAddress }); if (entity) { log('getUpgradeProposalCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getUpgradeProposalCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getUpgradeProposalCount({ blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetUpgradeProposalCount({ blockHash, blockNumber, contractAddress, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getDocumentProposals (blockHash: string, contractAddress: string): Promise { log('getDocumentProposals: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getDocumentProposals({ blockTag: blockHash }); const result: ValueResult = { value }; return result; } async getDocumentProposalCount (blockHash: string, contractAddress: string): Promise { const entity = await this._db.getGetDocumentProposalCount({ blockHash, contractAddress }); if (entity) { log('getDocumentProposalCount: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getDocumentProposalCount: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getDocumentProposalCount({ blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetDocumentProposalCount({ blockHash, blockNumber, contractAddress, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getDocumentMajorities (blockHash: string, contractAddress: string): Promise { log('getDocumentMajorities: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getDocumentMajorities({ blockTag: blockHash }); const result: ValueResult = { value }; return result; } async hasVotedOnUpgradePoll (blockHash: string, contractAddress: string, _galaxy: number, _proposal: string): Promise { const entity = await this._db.getHasVotedOnUpgradePoll({ blockHash, contractAddress, _galaxy, _proposal }); if (entity) { log('hasVotedOnUpgradePoll: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('hasVotedOnUpgradePoll: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.hasVotedOnUpgradePoll(_galaxy, _proposal, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveHasVotedOnUpgradePoll({ blockHash, blockNumber, contractAddress, _galaxy, _proposal, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async hasVotedOnDocumentPoll (blockHash: string, contractAddress: string, _galaxy: number, _proposal: string): Promise { const entity = await this._db.getHasVotedOnDocumentPoll({ blockHash, contractAddress, _galaxy, _proposal }); if (entity) { log('hasVotedOnDocumentPoll: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('hasVotedOnDocumentPoll: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.hasVotedOnDocumentPoll(_galaxy, _proposal, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveHasVotedOnDocumentPoll({ blockHash, blockNumber, contractAddress, _galaxy, _proposal, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async findClaim (blockHash: string, contractAddress: string, _whose: bigint, _protocol: string, _claim: string): Promise { const entity = await this._db.getFindClaim({ blockHash, contractAddress, _whose, _protocol, _claim }); if (entity) { log('findClaim: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('findClaim: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.findClaim(_whose, _protocol, _claim, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveFindClaim({ blockHash, blockNumber, contractAddress, _whose, _protocol, _claim, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async supportsInterface (blockHash: string, contractAddress: string, _interfaceId: string): Promise { const entity = await this._db.getSupportsInterface({ blockHash, contractAddress, _interfaceId }); if (entity) { log('supportsInterface: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('supportsInterface: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.supportsInterface(_interfaceId, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveSupportsInterface({ blockHash, blockNumber, contractAddress, _interfaceId, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async balanceOf (blockHash: string, contractAddress: string, _owner: string): Promise { const entity = await this._db.getBalanceOf({ blockHash, contractAddress, _owner }); if (entity) { log('balanceOf: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('balanceOf: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.balanceOf(_owner, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveBalanceOf({ blockHash, blockNumber, contractAddress, _owner, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async ownerOf (blockHash: string, contractAddress: string, _tokenId: bigint): Promise { const entity = await this._db.getOwnerOf({ blockHash, contractAddress, _tokenId }); if (entity) { log('ownerOf: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('ownerOf: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.ownerOf(_tokenId, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveOwnerOf({ blockHash, blockNumber, contractAddress, _tokenId, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async exists (blockHash: string, contractAddress: string, _tokenId: bigint): Promise { const entity = await this._db.getExists({ blockHash, contractAddress, _tokenId }); if (entity) { log('exists: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('exists: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.exists(_tokenId, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveExists({ blockHash, blockNumber, contractAddress, _tokenId, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getApproved (blockHash: string, contractAddress: string, _tokenId: bigint): Promise { const entity = await this._db.getGetApproved({ blockHash, contractAddress, _tokenId }); if (entity) { log('getApproved: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getApproved: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getApproved(_tokenId, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetApproved({ blockHash, blockNumber, contractAddress, _tokenId, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async isApprovedForAll (blockHash: string, contractAddress: string, _owner: string, _operator: string): Promise { const entity = await this._db.getIsApprovedForAll({ blockHash, contractAddress, _owner, _operator }); if (entity) { log('isApprovedForAll: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('isApprovedForAll: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.isApprovedForAll(_owner, _operator, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveIsApprovedForAll({ blockHash, blockNumber, contractAddress, _owner, _operator, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async totalSupply (blockHash: string, contractAddress: string): Promise { const entity = await this._db.getTotalSupply({ blockHash, contractAddress }); if (entity) { log('totalSupply: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('totalSupply: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.totalSupply({ blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveTotalSupply({ blockHash, blockNumber, contractAddress, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async tokenOfOwnerByIndex (blockHash: string, contractAddress: string, _owner: string, _index: bigint): Promise { const entity = await this._db.getTokenOfOwnerByIndex({ blockHash, contractAddress, _owner, _index }); if (entity) { log('tokenOfOwnerByIndex: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('tokenOfOwnerByIndex: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.tokenOfOwnerByIndex(_owner, _index, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveTokenOfOwnerByIndex({ blockHash, blockNumber, contractAddress, _owner, _index, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async tokenByIndex (blockHash: string, contractAddress: string, _index: bigint): Promise { const entity = await this._db.getTokenByIndex({ blockHash, contractAddress, _index }); if (entity) { log('tokenByIndex: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('tokenByIndex: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.tokenByIndex(_index, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveTokenByIndex({ blockHash, blockNumber, contractAddress, _index, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async name (blockHash: string, contractAddress: string): Promise { const entity = await this._db.getName({ blockHash, contractAddress }); if (entity) { log('name: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('name: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.name({ blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveName({ blockHash, blockNumber, contractAddress, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async symbol (blockHash: string, contractAddress: string): Promise { const entity = await this._db.getSymbol({ blockHash, contractAddress }); if (entity) { log('symbol: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('symbol: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.symbol({ blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveSymbol({ blockHash, blockNumber, contractAddress, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async tokenURI (blockHash: string, contractAddress: string, _tokenId: bigint): Promise { const entity = await this._db.getTokenURI({ blockHash, contractAddress, _tokenId }); if (entity) { log('tokenURI: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('tokenURI: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.tokenURI(_tokenId, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveTokenURI({ blockHash, blockNumber, contractAddress, _tokenId, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getSpawnLimit (blockHash: string, contractAddress: string, _point: bigint, _time: bigint): Promise { const entity = await this._db.getGetSpawnLimit({ blockHash, contractAddress, _point, _time }); if (entity) { log('getSpawnLimit: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getSpawnLimit: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); let value = await contract.getSpawnLimit(_point, _time, { blockTag: blockHash }); value = value.toString(); value = BigInt(value); const result: ValueResult = { value }; await this._db.saveGetSpawnLimit({ blockHash, blockNumber, contractAddress, _point, _time, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async canEscapeTo (blockHash: string, contractAddress: string, _point: bigint, _sponsor: bigint): Promise { const entity = await this._db.getCanEscapeTo({ blockHash, contractAddress, _point, _sponsor }); if (entity) { log('canEscapeTo: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('canEscapeTo: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.canEscapeTo(_point, _sponsor, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveCanEscapeTo({ blockHash, blockNumber, contractAddress, _point, _sponsor, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async withdrawLimit (blockHash: string, contractAddress: string, _participant: string, _batch: number): Promise { const entity = await this._db.getWithdrawLimit({ blockHash, contractAddress, _participant, _batch }); if (entity) { log('withdrawLimit: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('withdrawLimit: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.withdrawLimit(_participant, _batch, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveWithdrawLimit({ blockHash, blockNumber, contractAddress, _participant, _batch, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async verifyBalance (blockHash: string, contractAddress: string, _participant: string): Promise { const entity = await this._db.getVerifyBalance({ blockHash, contractAddress, _participant }); if (entity) { log('verifyBalance: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('verifyBalance: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.verifyBalance(_participant, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveVerifyBalance({ blockHash, blockNumber, contractAddress, _participant, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getBatches (blockHash: string, contractAddress: string, _participant: string): Promise { log('getBatches: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getBatches(_participant, { blockTag: blockHash }); const result: ValueResult = { value }; return result; } async getBatch (blockHash: string, contractAddress: string, _participant: string, _batch: number): Promise { const entity = await this._db.getGetBatch({ blockHash, contractAddress, _participant, _batch }); if (entity) { log('getBatch: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getBatch: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getBatch(_participant, _batch, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetBatch({ blockHash, blockNumber, contractAddress, _participant, _batch, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getWithdrawn (blockHash: string, contractAddress: string, _participant: string): Promise { log('getWithdrawn: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getWithdrawn(_participant, { blockTag: blockHash }); const result: ValueResult = { value }; return result; } async getWithdrawnFromBatch (blockHash: string, contractAddress: string, _participant: string, _batch: number): Promise { const entity = await this._db.getGetWithdrawnFromBatch({ blockHash, contractAddress, _participant, _batch }); if (entity) { log('getWithdrawnFromBatch: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('getWithdrawnFromBatch: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getWithdrawnFromBatch(_participant, _batch, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveGetWithdrawnFromBatch({ blockHash, blockNumber, contractAddress, _participant, _batch, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getForfeited (blockHash: string, contractAddress: string, _participant: string): Promise { log('getForfeited: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getForfeited(_participant, { blockTag: blockHash }); const result: ValueResult = { value }; return result; } async hasForfeitedBatch (blockHash: string, contractAddress: string, _participant: string, _batch: number): Promise { const entity = await this._db.getHasForfeitedBatch({ blockHash, contractAddress, _participant, _batch }); if (entity) { log('hasForfeitedBatch: db hit.'); return { value: entity.value, proof: JSON.parse(entity.proof) }; } const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = ethers.BigNumber.from(number).toNumber(); log('hasForfeitedBatch: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.hasForfeitedBatch(_participant, _batch, { blockTag: blockHash }); const result: ValueResult = { value }; await this._db.saveHasForfeitedBatch({ blockHash, blockNumber, contractAddress, _participant, _batch, value: result.value, proof: JSONbigNative.stringify(result.proof) }); return result; } async getRemainingStars (blockHash: string, contractAddress: string, _participant: string): Promise { log('getRemainingStars: db miss, fetching from upstream server'); const abi = this._abiMap.get(KIND_CONDITIONALSTARRELEASE); assert(abi); const contract = new ethers.Contract(contractAddress, abi, this._ethProvider); const value = await contract.getRemainingStars(_participant, { blockTag: blockHash }); const result: ValueResult = { value }; return result; } async getStorageValue (storageLayout: StorageLayout, blockHash: string, contractAddress: string, variable: string, ...mappingKeys: MappingKey[]): Promise { return this._baseIndexer.getStorageValue( storageLayout, blockHash, contractAddress, variable, ...mappingKeys ); } async getEntitiesForBlock (blockHash: string, tableName: string): Promise { return this._db.getEntitiesForBlock(blockHash, tableName); } async processInitialState (contractAddress: string, blockHash: string): Promise { // Call initial state hook. return createInitialState(this, contractAddress, blockHash); } async processStateCheckpoint (contractAddress: string, blockHash: string): Promise { // Call checkpoint hook. return createStateCheckpoint(this, contractAddress, blockHash); } async processCanonicalBlock (blockHash: string): Promise { console.time('time:indexer#processCanonicalBlock-finalize_auto_diffs'); // Finalize staged diff blocks if any. await this._baseIndexer.finalizeDiffStaged(blockHash); console.timeEnd('time:indexer#processCanonicalBlock-finalize_auto_diffs'); // Call custom stateDiff hook. await createStateDiff(this, blockHash); } async processCheckpoint (blockHash: string): Promise { // Return if checkpointInterval is <= 0. const checkpointInterval = this._serverConfig.checkpointInterval; if (checkpointInterval <= 0) return; console.time('time:indexer#processCheckpoint-checkpoint'); await this._baseIndexer.processCheckpoint(this, blockHash, checkpointInterval); console.timeEnd('time:indexer#processCheckpoint-checkpoint'); } async processCLICheckpoint (contractAddress: string, blockHash?: string): Promise { return this._baseIndexer.processCLICheckpoint(this, contractAddress, blockHash); } async getPrevState (blockHash: string, contractAddress: string, kind?: string): Promise { return this._db.getPrevState(blockHash, contractAddress, kind); } async getLatestState (contractAddress: string, kind: StateKind | null, blockNumber?: number): Promise { return this._db.getLatestState(contractAddress, kind, blockNumber); } async getStatesByHash (blockHash: string): Promise { return this._baseIndexer.getStatesByHash(blockHash); } async getStateByCID (cid: string): Promise { return this._baseIndexer.getStateByCID(cid); } async getStates (where: FindConditions): Promise { return this._db.getStates(where); } getStateData (state: State): any { return this._baseIndexer.getStateData(state); } // Method used to create auto diffs (diff_staged). async createDiffStaged (contractAddress: string, blockHash: string, data: any): Promise { console.time('time:indexer#createDiffStaged-auto_diff'); await this._baseIndexer.createDiffStaged(contractAddress, blockHash, data); console.timeEnd('time:indexer#createDiffStaged-auto_diff'); } // Method to be used by createStateDiff hook. async createDiff (contractAddress: string, blockHash: string, data: any): Promise { const block = await this.getBlockProgress(blockHash); assert(block); await this._baseIndexer.createDiff(contractAddress, block, data); } // Method to be used by createStateCheckpoint hook. async createStateCheckpoint (contractAddress: string, blockHash: string, data: any): Promise { const block = await this.getBlockProgress(blockHash); assert(block); return this._baseIndexer.createStateCheckpoint(contractAddress, block, data); } // Method to be used by export-state CLI. async createCheckpoint (contractAddress: string, blockHash: string): Promise { const block = await this.getBlockProgress(blockHash); assert(block); return this._baseIndexer.createCheckpoint(this, contractAddress, block); } async saveOrUpdateState (state: State): Promise { return this._baseIndexer.saveOrUpdateState(state); } async removeStates (blockNumber: number, kind: StateKind): Promise { await this._baseIndexer.removeStates(blockNumber, kind); } async triggerIndexingOnEvent (event: Event): Promise { const resultEvent = this.getResultEvent(event); // Call custom hook function for indexing on event. await handleEvent(this, resultEvent); } async processEvent (event: Event): Promise { // Trigger indexing of data based on the event. await this.triggerIndexingOnEvent(event); } async processBlock (blockProgress: BlockProgress): Promise { console.time('time:indexer#processBlock-init_state'); // Call a function to create initial state for contracts. await this._baseIndexer.createInit(this, blockProgress.blockHash, blockProgress.blockNumber); console.timeEnd('time:indexer#processBlock-init_state'); } parseEventNameAndArgs (kind: string, logObj: any): any { const { topics, data } = logObj; const contract = this._contractMap.get(kind); assert(contract); const logDescription = contract.parseLog({ data, topics }); const { eventName, eventInfo, eventSignature } = this._baseIndexer.parseEvent(logDescription); return { eventName, eventInfo, eventSignature }; } async getStateSyncStatus (): Promise { return this._db.getStateSyncStatus(); } async updateStateSyncStatusIndexedBlock (blockNumber: number, force?: boolean): Promise { const dbTx = await this._db.createTransactionRunner(); let res; try { res = await this._db.updateStateSyncStatusIndexedBlock(dbTx, blockNumber, force); await dbTx.commitTransaction(); } catch (error) { await dbTx.rollbackTransaction(); throw error; } finally { await dbTx.release(); } return res; } async updateStateSyncStatusCheckpointBlock (blockNumber: number, force?: boolean): Promise { const dbTx = await this._db.createTransactionRunner(); let res; try { res = await this._db.updateStateSyncStatusCheckpointBlock(dbTx, blockNumber, force); await dbTx.commitTransaction(); } catch (error) { await dbTx.rollbackTransaction(); throw error; } finally { await dbTx.release(); } return res; } async getLatestCanonicalBlock (): Promise { const syncStatus = await this.getSyncStatus(); assert(syncStatus); const latestCanonicalBlock = await this.getBlockProgress(syncStatus.latestCanonicalBlockHash); assert(latestCanonicalBlock); return latestCanonicalBlock; } async getLatestStateIndexedBlock (): Promise { return this._baseIndexer.getLatestStateIndexedBlock(); } async watchContract (address: string, kind: string, checkpoint: boolean, startingBlock: number): Promise { return this._baseIndexer.watchContract(address, kind, checkpoint, startingBlock); } updateStateStatusMap (address: string, stateStatus: StateStatus): void { this._baseIndexer.updateStateStatusMap(address, stateStatus); } cacheContract (contract: Contract): void { return this._baseIndexer.cacheContract(contract); } async saveEventEntity (dbEvent: Event): Promise { return this._baseIndexer.saveEventEntity(dbEvent); } async getEventsByFilter (blockHash: string, contract?: string, name?: string): Promise> { return this._baseIndexer.getEventsByFilter(blockHash, contract, name); } isWatchedContract (address : string): Contract | undefined { return this._baseIndexer.isWatchedContract(address); } getContractsByKind (kind: string): Contract[] { return this._baseIndexer.getContractsByKind(kind); } async getProcessedBlockCountForRange (fromBlockNumber: number, toBlockNumber: number): Promise<{ expected: number, actual: number }> { return this._baseIndexer.getProcessedBlockCountForRange(fromBlockNumber, toBlockNumber); } async getEventsInRange (fromBlockNumber: number, toBlockNumber: number): Promise> { return this._baseIndexer.getEventsInRange(fromBlockNumber, toBlockNumber, this._serverConfig.maxEventsBlockRange); } async getSyncStatus (): Promise { return this._baseIndexer.getSyncStatus(); } async getBlocks (blockFilter: { blockHash?: string, blockNumber?: number }): Promise { return this._baseIndexer.getBlocks(blockFilter); } async updateSyncStatusIndexedBlock (blockHash: string, blockNumber: number, force = false): Promise { return this._baseIndexer.updateSyncStatusIndexedBlock(blockHash, blockNumber, force); } async updateSyncStatusChainHead (blockHash: string, blockNumber: number, force = false): Promise { return this._baseIndexer.updateSyncStatusChainHead(blockHash, blockNumber, force); } async updateSyncStatusCanonicalBlock (blockHash: string, blockNumber: number, force = false): Promise { const syncStatus = this._baseIndexer.updateSyncStatusCanonicalBlock(blockHash, blockNumber, force); return syncStatus; } async getEvent (id: string): Promise { return this._baseIndexer.getEvent(id); } async getBlockProgress (blockHash: string): Promise { return this._baseIndexer.getBlockProgress(blockHash); } async getBlockProgressEntities (where: FindConditions, options: FindManyOptions): Promise { return this._baseIndexer.getBlockProgressEntities(where, options); } async getBlocksAtHeight (height: number, isPruned: boolean): Promise { return this._baseIndexer.getBlocksAtHeight(height, isPruned); } async saveBlockAndFetchEvents (block: DeepPartial): Promise<[BlockProgress, DeepPartial[]]> { return this._saveBlockAndFetchEvents(block); } async getBlockEvents (blockHash: string, where: Where, queryOptions: QueryOptions): Promise> { return this._baseIndexer.getBlockEvents(blockHash, where, queryOptions); } async removeUnknownEvents (block: BlockProgress): Promise { return this._baseIndexer.removeUnknownEvents(Event, block); } async markBlocksAsPruned (blocks: BlockProgress[]): Promise { await this._baseIndexer.markBlocksAsPruned(blocks); } async updateBlockProgress (block: BlockProgress, lastProcessedEventIndex: number): Promise { return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex); } async getAncestorAtDepth (blockHash: string, depth: number): Promise { return this._baseIndexer.getAncestorAtDepth(blockHash, depth); } async resetWatcherToBlock (blockNumber: number): Promise { const entities = [...ENTITIES]; await this._baseIndexer.resetWatcherToBlock(blockNumber, entities); } async _saveBlockAndFetchEvents ({ cid: blockCid, blockHash, blockNumber, blockTimestamp, parentHash }: DeepPartial): Promise<[BlockProgress, DeepPartial[]]> { assert(blockHash); assert(blockNumber); const dbEvents = await this._baseIndexer.fetchEvents(blockHash, blockNumber, this.parseEventNameAndArgs.bind(this)); const dbTx = await this._db.createTransactionRunner(); try { const block = { cid: blockCid, blockHash, blockNumber, blockTimestamp, parentHash }; console.time(`time:indexer#_saveBlockAndFetchEvents-db-save-${blockNumber}`); const blockProgress = await this._db.saveBlockWithEvents(dbTx, block, dbEvents); await dbTx.commitTransaction(); console.timeEnd(`time:indexer#_saveBlockAndFetchEvents-db-save-${blockNumber}`); return [blockProgress, []]; } catch (error) { await dbTx.rollbackTransaction(); throw error; } finally { await dbTx.release(); } } }