// // Copyright 2021 Vulcanize, Inc. // import assert from 'assert'; import BigInt from 'apollo-type-bigint'; import debug from 'debug'; import { ValueResult } from '@vulcanize/util'; import { Indexer } from './indexer'; import { EventWatcher } from './events'; const log = debug('vulcanize:resolver'); export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatcher): Promise => { assert(indexer); return { BigInt: new BigInt('bigInt'), Event: { __resolveType: (obj: any) => { assert(obj.__typename); return obj.__typename; } }, Subscription: { onEvent: { subscribe: () => eventWatcher.getEventIterator() } }, Mutation: { watchContract: (_: any, { contractAddress, kind, startingBlock = 1 }: { contractAddress: string, kind: string, startingBlock: number }): Promise => { log('watchContract', contractAddress, kind, startingBlock); return indexer.watchContract(contractAddress, kind, startingBlock); } }, Query: { {{#each queries}} {{this.name}}: (_: any, { blockHash, contractAddress {{~#each this.params}}, {{this.name~}} {{/each}} }: { blockHash: string, contractAddress: string {{~#each this.params}}, {{this.name}}: {{this.type~}} {{/each}} }): Promise => { log('{{this.name}}', blockHash, contractAddress {{~#each this.params}}, {{this.name~}} {{/each}}); return indexer.{{this.name}}(blockHash, contractAddress {{~#each this.params}}, {{this.name~}} {{/each}}); }, {{/each}} events: async (_: any, { blockHash, contractAddress, name }: { blockHash: string, contractAddress: string, name?: string }) => { log('events', blockHash, contractAddress, name); const block = await indexer.getBlockProgress(blockHash); if (!block || !block.isComplete) { throw new Error(`Block hash ${blockHash} number ${block?.blockNumber} not processed yet`); } const events = await indexer.getEventsByFilter(blockHash, contractAddress, name); return events.map(event => indexer.getResultEvent(event)); }, eventsInRange: async (_: any, { fromBlockNumber, toBlockNumber }: { fromBlockNumber: number, toBlockNumber: number }) => { log('eventsInRange', fromBlockNumber, toBlockNumber); const { expected, actual } = await indexer.getProcessedBlockCountForRange(fromBlockNumber, toBlockNumber); if (expected !== actual) { throw new Error(`Range not available, expected ${expected}, got ${actual} blocks in range`); } const events = await indexer.getEventsInRange(fromBlockNumber, toBlockNumber); return events.map(event => indexer.getResultEvent(event)); }, getStateByCID: async (_: any, { cid }: { cid: string }) => { log('getStateByCID', cid); const ipldBlock = await indexer.getIPLDBlockByCid(cid); return ipldBlock && ipldBlock.block.isComplete ? indexer.getResultIPLDBlock(ipldBlock) : undefined; }, getState: async (_: any, { blockHash, contractAddress }: { blockHash: string, contractAddress: string }) => { log('getState', blockHash, contractAddress); const ipldBlock = await indexer.getPrevIPLDBlock(blockHash, contractAddress); return ipldBlock && ipldBlock.block.isComplete ? indexer.getResultIPLDBlock(ipldBlock) : undefined; } } }; };