envio
Version:
A latency and sync speed optimized, developer friendly blockchain data indexer.
331 lines (314 loc) • 11.2 kB
JavaScript
// Generated by ReScript, PLEASE EDIT WITH CARE
import * as Utils from "./Utils.res.mjs";
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
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 MissingRequiredTopic0 = /* @__PURE__ */Primitive_exceptions.create("LogSelection.MissingRequiredTopic0");
function makeTopicSelection(topic0, topic1Opt, topic2Opt, topic3Opt) {
let topic1 = topic1Opt !== undefined ? topic1Opt : [];
let topic2 = topic2Opt !== undefined ? topic2Opt : [];
let topic3 = topic3Opt !== undefined ? topic3Opt : [];
if (Utils.$$Array.isEmpty(topic0)) {
return {
TAG: "Error",
_0: {
RE_EXN_ID: MissingRequiredTopic0
}
};
} else {
return {
TAG: "Ok",
_0: {
topic0: topic0,
topic1: topic1,
topic2: topic2,
topic3: topic3
}
};
}
}
function hasFilters(param) {
return Stdlib_Option.isSome([
param.topic1,
param.topic2,
param.topic3
].find(topic => !Utils.$$Array.isEmpty(topic)));
}
function compressTopicSelections(topicSelections) {
let topic0sOfSelectionsWithoutFilters = [];
let selectionsWithFilters = [];
topicSelections.forEach(selection => {
if (hasFilters(selection)) {
selectionsWithFilters.push(selection);
} else {
selection.topic0.forEach(topic0 => {
topic0sOfSelectionsWithoutFilters.push(topic0);
});
}
});
if (topic0sOfSelectionsWithoutFilters.length === 0) {
return selectionsWithFilters;
}
let selectionWithoutFilters_topic1 = [];
let selectionWithoutFilters_topic2 = [];
let selectionWithoutFilters_topic3 = [];
let selectionWithoutFilters = {
topic0: topic0sOfSelectionsWithoutFilters,
topic1: selectionWithoutFilters_topic1,
topic2: selectionWithoutFilters_topic2,
topic3: selectionWithoutFilters_topic3
};
return [selectionWithoutFilters].concat(selectionsWithFilters);
}
function make(addresses, topicSelections) {
let topicSelections$1 = compressTopicSelections(topicSelections);
return {
addresses: addresses,
topicSelections: topicSelections$1
};
}
let eventBlockRangeSchema = S$RescriptSchema.strict(S$RescriptSchema.object(s => ({
_gte: s.f("_gte", S$RescriptSchema.option(S$RescriptSchema.int))
})));
function extractStartBlock(where, onEventBlockFilterSchema, contractName) {
if (typeof where === "boolean") {
return;
}
try {
let inner = S$RescriptSchema.parseOrThrow(where, onEventBlockFilterSchema);
if (inner !== undefined) {
return S$RescriptSchema.parseOrThrow(Primitive_option.valFromOption(inner), eventBlockRangeSchema)._gte;
} else {
return;
}
} catch (raw_exn) {
let exn = Primitive_exceptions.internalToException(raw_exn);
if (exn.RE_EXN_ID === S$RescriptSchema.Raised) {
return Stdlib_JsError.throwWithMessage(`Invalid where configuration for ` + contractName + `. \`block\` filter is invalid: ` + Utils.prettifyExn(exn._1) + `. Only \`_gte\` is supported on event filters — use \`indexer.onBlock\` for \`_lte\` or \`_every\`.`);
}
throw exn;
}
}
function makeChainArg(contractName, chainId, addresses) {
let chainObj = {};
chainObj["id"] = chainId;
chainObj[contractName] = {
addresses: addresses
};
return chainObj;
}
function makeDetectionChainArg(contractName, chainId, getAddresses) {
let contractObj = Object.create(null);
Object.defineProperty(contractObj, "addresses", {
enumerable: true,
get: getAddresses
});
let chainObj = {};
chainObj["id"] = chainId;
chainObj[contractName] = contractObj;
return chainObj;
}
let makeAddressesProbe = (function (contractName) {
var trap = function () {
throw new Error(
'Invalid where configuration for "' + contractName +
'": chain.' + contractName + '.addresses must be passed directly as an indexed-param ' +
'filter value (e.g. { params: { to: chain.' + contractName + '.addresses } }). ' +
'It cannot be spread, mapped, indexed, or otherwise transformed.'
);
};
return new Proxy([], {get: trap});
});
function extractAddressFilterGroupsOrThrow(result, probe, contractName) {
let groups = [];
let scanGroup = paramsObj => {
let names = [];
Utils.Dict.forEachWithKey(paramsObj, (value, key) => {
if (value === probe) {
names.push(key);
paramsObj[key] = [];
return;
}
});
if (!Utils.$$Array.isEmpty(names)) {
groups.push(names);
return;
}
};
if (typeof result === "object" && result !== null && !Array.isArray(result)) {
let match = result["params"];
if (match !== undefined) {
if (Array.isArray(match)) {
match.forEach(item => {
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
return scanGroup(item);
}
});
} else {
switch (typeof match) {
case "object" :
scanGroup(match);
break;
}
}
}
}
if (Utils.$$Array.isEmpty(groups)) {
Stdlib_JsError.throwWithMessage(`Invalid where configuration for ` + contractName + `. The callback reads \`chain.` + contractName + `.addresses\` but doesn't use it as an indexed-param filter value. Use it directly, e.g. { params: { to: chain.` + contractName + `.addresses } }.`);
}
return groups;
}
let emptyTopics = [];
function noopGetter(param) {
return emptyTopics;
}
function parseEventFiltersOrThrow(eventFilters, sighash, params, contractName, probeChainId, onEventBlockFilterSchema, topic1Opt, topic2Opt, topic3Opt) {
let topic1 = topic1Opt !== undefined ? topic1Opt : noopGetter;
let topic2 = topic2Opt !== undefined ? topic2Opt : noopGetter;
let topic3 = topic3Opt !== undefined ? topic3Opt : noopGetter;
let filterByAddresses = {
contents: false
};
let addressFilterParamGroups = [];
let startBlock;
let topic0 = [sighash];
let $$default = {
topic0: topic0,
topic1: emptyTopics,
topic2: emptyTopics,
topic3: emptyTopics
};
let paramsRecordToTopicSelection = paramsFilter => {
if (Utils.Dict.isEmpty(paramsFilter)) {
return $$default;
} else {
Utils.Dict.forEachWithKey(paramsFilter, (param, key) => {
if (!params.includes(key)) {
return Stdlib_JsError.throwWithMessage(`Invalid where configuration. The event doesn't have an indexed parameter "` + key + `" and can't use it for filtering`);
}
});
return {
topic0: topic0,
topic1: topic1(paramsFilter),
topic2: topic2(paramsFilter),
topic3: topic3(paramsFilter)
};
}
};
let acceptedWhereKeys = [
"params",
"block"
];
let parse = where => {
if (where === true) {
return [$$default];
}
if (where === false) {
return [];
}
if (typeof where !== "object" || where === null || Array.isArray(where)) {
return Stdlib_JsError.throwWithMessage("Invalid where configuration. Expected an object");
}
Utils.Dict.forEachWithKey(where, (param, key) => {
if (!acceptedWhereKeys.includes(key)) {
return Stdlib_JsError.throwWithMessage(`Invalid where configuration. Unknown field "` + key + `". Indexed parameter filters must be nested under \`params\` and block-range filters under \`block\``);
}
});
let match = where["params"];
if (match === undefined) {
return [$$default];
}
if (Array.isArray(match)) {
if (match.length !== 0) {
return match.map(item => {
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
return paramsRecordToTopicSelection(item);
} else {
return Stdlib_JsError.throwWithMessage("Invalid where configuration. Each entry in `params` must be an object");
}
});
} else {
return [$$default];
}
}
if (match === null) {
return Stdlib_JsError.throwWithMessage("Invalid where configuration. Expected `params` to be an object or an array of objects");
}
switch (typeof match) {
case "object" :
return [paramsRecordToTopicSelection(match)];
default:
return Stdlib_JsError.throwWithMessage("Invalid where configuration. Expected `params` to be an object or an array of objects");
}
};
let getEventFiltersOrThrow;
if (eventFilters !== undefined) {
if (typeof eventFilters === "function") {
let addressesProbe = makeAddressesProbe(contractName);
let chain = makeDetectionChainArg(contractName, probeChainId, () => {
filterByAddresses.contents = true;
return addressesProbe;
});
let probedResult = eventFilters({
chain: chain
});
if (filterByAddresses.contents) {
addressFilterParamGroups = extractAddressFilterGroupsOrThrow(probedResult, addressesProbe, contractName);
}
startBlock = extractStartBlock(probedResult, onEventBlockFilterSchema, contractName);
getEventFiltersOrThrow = filterByAddresses.contents ? chain => ({
TAG: "Dynamic",
_0: addresses => {
let chainArg = makeChainArg(contractName, chain, addresses);
return parse(eventFilters({
chain: chainArg
}));
}
}) : chain => {
let chainArg = makeDetectionChainArg(contractName, chain, () => Stdlib_JsError.throwWithMessage(`Invalid where configuration. Event callback for contract "` + contractName + `" read \`chain.` + contractName + `.addresses\` at runtime but the probe didn't detect the access on chainId ` + chain.toString() + `. Move the \`chain.` + contractName + `.addresses\` read above any \`chain.id\` branching so the probe picks up the dependency and switches to the dynamic fetch path.`));
return {
TAG: "Static",
_0: parse(eventFilters({
chain: chainArg
}))
};
};
} else {
startBlock = extractStartBlock(eventFilters, onEventBlockFilterSchema, contractName);
let $$static = {
TAG: "Static",
_0: parse(eventFilters)
};
getEventFiltersOrThrow = param => $$static;
}
} else {
let $$static$1 = {
TAG: "Static",
_0: [$$default]
};
getEventFiltersOrThrow = param => $$static$1;
}
return {
getEventFiltersOrThrow: getEventFiltersOrThrow,
filterByAddresses: filterByAddresses.contents,
addressFilterParamGroups: addressFilterParamGroups,
startBlock: startBlock
};
}
export {
MissingRequiredTopic0,
makeTopicSelection,
hasFilters,
compressTopicSelections,
make,
eventBlockRangeSchema,
extractStartBlock,
makeChainArg,
makeDetectionChainArg,
makeAddressesProbe,
extractAddressFilterGroupsOrThrow,
parseEventFiltersOrThrow,
}
/* eventBlockRangeSchema Not a pure module */