UNPKG

@superfluid-finance/sdk-core

Version:
107 lines 4.47 kB
import { ethers } from "ethers"; import _ from "lodash"; import { listAllResults } from "../Query"; import { createPagedResult, createSkipPaging, isAllPaging, isPageNumberPaging, takePlusOne, } from "../pagination"; import { typeGuard } from "../utils"; import { normalizeSubgraphFilter } from "./normalizeSubgraphFilter"; /** * A base class to handle common Subgraph query logic. */ export class SubgraphQueryHandler { constructor() { /** * For every primary address field key there are more fields generated which it should look for addresses. * NOTE: The implementation is a bit "magical" but it rids of a bunch of boilerplate and creates a single point for editing. */ this.getRelevantAddressesFromFilterByAddressFieldKeys = (filter, addressFieldKeys) => addressFieldKeys .map((key) => [ filter[key], filter[`${String(key)}_in`], filter[`${String(key)}_not`], filter[`${String(key)}_not_in`], ] .filter((x) => typeof x !== "undefined") .flat() .filter((x) => !!x)) .flat(); } getRelevantAddressesFromFilter(filter) { if (!filter) { return { tokens: [], accounts: [], }; } const addressFieldKeys = this.getAddressFieldKeysFromFilter(); const tokenAddresses = this.getRelevantAddressesFromFilterByAddressFieldKeys(filter, addressFieldKeys.tokenKeys); const accountAddresses = this.getRelevantAddressesFromFilterByAddressFieldKeys(filter, addressFieldKeys.accountKeys); return { tokens: _.uniq(tokenAddresses), accounts: _.uniq(accountAddresses), }; } getRelevantAddressesFromResult(result) { if (!result) { return { tokens: [], accounts: [], }; } const intermediate = this.getRelevantAddressesFromResultCore(result); return { tokens: _.uniq(intermediate.tokens.flat().filter((x) => !!x)), accounts: _.uniq(intermediate.accounts.flat().filter((x) => !!x)), }; } async get(subgraphClient, query) { var _a; if (!query.id) { return null; } const response = await this.querySubgraph(subgraphClient, { where: { id: ethers.utils.isAddress(query.id) ? query.id.toLowerCase() : query.id, }, skip: 0, take: 1, block: query.block, }); return (_a = this.mapFromSubgraphResponse(response)[0]) !== null && _a !== void 0 ? _a : null; } async list(subgraphClient, query) { var _a; // Note: Could possibly optimize here to not create a new internal function every time. const queryFunction = async (paging) => { var _a, _b, _c; const subgraphFilter = typeGuard(normalizeSubgraphFilter({ ...((_a = query.filter) !== null && _a !== void 0 ? _a : {}), id_gt: paging.lastId, })); const subgraphQueryVariables = typeGuard({ where: normalizeSubgraphFilter(subgraphFilter), orderBy: (_b = query.order) === null || _b === void 0 ? void 0 : _b.orderBy, orderDirection: (_c = query.order) === null || _c === void 0 ? void 0 : _c.orderDirection, first: takePlusOne(paging), skip: isPageNumberPaging(paging) ? (paging.pageNumber - 1) * paging.take : paging.skip, block: query.block, }); const subgraphResponse = await this.querySubgraph(subgraphClient, subgraphQueryVariables); const mappedResult = this.mapFromSubgraphResponse(subgraphResponse); return createPagedResult(mappedResult, paging); }; if (isAllPaging(query.pagination)) { return createPagedResult(await listAllResults(queryFunction), query.pagination); } else { return queryFunction((_a = query.pagination) !== null && _a !== void 0 ? _a : createSkipPaging()); } } async querySubgraph(subgraphClient, variables) { return await subgraphClient.request(this.requestDocument, variables); } } //# sourceMappingURL=subgraphQueryHandler.js.map