UNPKG

envio

Version:

A latency and sync speed optimized, developer friendly blockchain data indexer.

185 lines (171 loc) • 5.14 kB
// Generated by ReScript, PLEASE EDIT WITH CARE import * as Time from "../Time.res.mjs"; import * as Logging from "../Logging.res.mjs"; import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js"; import * as HyperFuelClient from "./HyperFuelClient.res.mjs"; import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs"; import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js"; let cache = {}; function getClient(url) { let client = cache[url]; if (client !== undefined) { return Primitive_option.valFromOption(client); } let newClient = HyperFuelClient.make({ url: url }); cache[url] = newClient; return newClient; } function queryErrorToMsq(e) { let match = e._0; return match.queryName + ` query failed due to unexpected missing params on response: ` + match.missingParams.join(", "); } let $$Error = /* @__PURE__ */Primitive_exceptions.create("HyperFuel.GetLogs.Error"); function makeRequestBody(fromBlock, toBlockInclusive, recieptsSelection) { return { fromBlock: fromBlock, toBlock: toBlockInclusive !== undefined ? toBlockInclusive + 1 | 0 : undefined, receipts: recieptsSelection, fieldSelection: { block: [ "id", "height", "time" ], receipt: [ "tx_id", "block_height", "root_contract_id", "data", "receipt_index", "receipt_type", "rb", "sub_id", "val", "amount", "to_address", "asset_id", "to" ] } }; } function getParam(param, name) { if (param !== undefined) { return Primitive_option.valFromOption(param); } throw { RE_EXN_ID: $$Error, _1: { TAG: "UnexpectedMissingParams", missingParams: [name] }, Error: new Error() }; } function decodeLogQueryPageItems(response_data) { let blocksDict = {}; response_data.blocks.forEach(block => { blocksDict[block.height] = block; }); let items = []; response_data.receipts.forEach(receipt => { let contractId = receipt.rootContractId; if (contractId === undefined) { return; } let block = getParam(blocksDict[receipt.blockHeight], "Failed to find block associated to receipt"); items.push({ transactionId: receipt.txId, contractId: Primitive_option.valFromOption(contractId), receipt: receipt, receiptIndex: receipt.receiptIndex, block: { id: block.id, time: block.time, height: block.height } }); }); return items; } async function query(serverUrl, fromBlock, toBlock, recieptsSelection) { let query$1 = makeRequestBody(fromBlock, toBlock, recieptsSelection); let hyperFuelClient = getClient(serverUrl); let res = await hyperFuelClient.getSelectedData(query$1); if (res.nextBlock <= fromBlock) { throw { RE_EXN_ID: $$Error, _1: "WrongInstance", Error: new Error() }; } return { items: decodeLogQueryPageItems(res.data), nextBlock: res.nextBlock, archiveHeight: Stdlib_Option.getOr(res.archiveHeight, 0) }; } async function queryBlockData(serverUrl, blockNumber, logger) { let query_toBlock = blockNumber + 1 | 0; let query_inputs = [{}]; let query_outputs = [{}]; let query_includeAllBlocks = true; let query_fieldSelection = { block: [ "height", "id", "time" ] }; let query = { fromBlock: blockNumber, toBlock: query_toBlock, inputs: query_inputs, outputs: query_outputs, includeAllBlocks: query_includeAllBlocks, fieldSelection: query_fieldSelection }; let hyperFuelClient = getClient(serverUrl); let logger$1 = Logging.createChildFrom(logger, { logType: "hypersync get blockhash query", blockNumber: blockNumber }); let executeQuery = () => hyperFuelClient.getSelectedData(query); let res = await Time.retryAsyncWithExponentialBackOff(undefined, undefined, undefined, undefined, logger$1, executeQuery); if (res.nextBlock > blockNumber) { return Stdlib_Option.flatMap(res.data.blocks, blocks => Stdlib_Option.map(blocks[0], block => ({ blockHash: block.id, blockNumber: block.height, blockTimestamp: block.time }))); } let logger$2 = Logging.createChild({ url: serverUrl }); Logging.childInfo(logger$2, `Block #` + blockNumber.toString() + ` not found in HyperFuel. HyperFuel has multiple instances and it's possible that they drift independently slightly from the head. Indexing should continue correctly after retrying the query in ` + (100).toString() + `ms.`); await Time.resolvePromiseAfterDelay(100); return await queryBlockData(serverUrl, blockNumber, logger$2); } function heightRoute() { return { method: "GET", path: "/height", input: param => {}, responses: [s => s.field("height", S$RescriptSchema.int)] }; } let GetLogs = { $$Error: $$Error, query: query }; export { queryErrorToMsq, GetLogs, queryBlockData, heightRoute, } /* Time Not a pure module */