Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 3x 3x 3x 3x 3x 3x 3x 3x 3x | import { MathUtils, RedstoneTypes } from "@redstone-finance/utils";
import axios from "axios";
import { resolveDataServiceUrls } from "./data-services-urls";
export interface GetDataFeedValuesInput {
aggregationAlgorithm?: "median" | "min" | "max"; // median by default
dataServiceId?: string; // "redstone-main-demo" by default
gatewayUrls?: string[]; // if not specified, use default for dataServiceId
}
export type GetDataFeedValuesOutput = Record<string, number | undefined>;
type GatewayResponse = RedstoneTypes.DataPackageFromGatewayResponse;
const DEFAULT_DATA_SERVICE_ID = "redstone-main-demo";
const DEFAULT_AGGREGATION_ALGORITHM = "median";
export const getDataFeedValues = async (
args: GetDataFeedValuesInput = {}
): Promise<GetDataFeedValuesOutput> => {
const dataServiceId = args.dataServiceId ?? DEFAULT_DATA_SERVICE_ID;
const aggregationAlgorithm =
args.aggregationAlgorithm ?? DEFAULT_AGGREGATION_ALGORITHM;
const gatewayUrls = args.gatewayUrls ?? resolveDataServiceUrls(dataServiceId);
const dataPackagesPerFeed = await Promise.any<GatewayResponse>(
gatewayUrls.map((url) => getDataPackagesFromGateway(url, dataServiceId))
);
const result: GetDataFeedValuesOutput = {};
for (const [dataPackageId, dataPackages] of Object.entries(
dataPackagesPerFeed
)) {
Iif (isMultiPointDataPackageId(dataPackageId)) {
continue;
}
const dataFeedId = dataPackageId;
const plainValues = dataPackages!.map((dp) =>
Number(dp.dataPoints[0].value)
);
result[dataFeedId] = aggregateValues(plainValues, aggregationAlgorithm);
}
return result;
};
const isMultiPointDataPackageId = (dataPackageId: string) =>
dataPackageId.startsWith("__") && dataPackageId.endsWith("__");
const getDataPackagesFromGateway = async (
url: string,
dataServiceId: string
): Promise<GatewayResponse> => {
const response = await axios.get<GatewayResponse>(
`${url}/data-packages/latest/${dataServiceId}`
);
Iif (typeof response.data === "string") {
throw new Error(
`Failed to fetch data package from ${url}. Data service ID responded with: ${String(
response.data
)}`
);
}
return response.data;
};
export const aggregateValues = (
plainValues: number[],
aggregationAlgorithm: "median" | "min" | "max"
) => {
switch (aggregationAlgorithm) {
case "max":
return Math.max(...plainValues);
case "min":
return Math.min(...plainValues);
case "median":
return MathUtils.getMedian(plainValues);
default:
throw new Error(
`Unsupported aggregationAlgorithm ${String(aggregationAlgorithm)}`
);
}
};
|