@superfluid-finance/sdk-core
Version:
SDK Core for building with Superfluid Protocol
107 lines • 4.47 kB
JavaScript
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