envio
Version:
A latency and sync speed optimized, developer friendly blockchain data indexer.
185 lines (171 loc) • 5.14 kB
JavaScript
// 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 */