UNPKG

@entangle-labs/udf-sdk

Version:

SDK for interacting with UDF Oracle

101 lines (100 loc) 3.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); class UdfSdk { constructor(baseUrl = "https://udfsnap.ent-dx.com") { this.baseUrl = baseUrl; } bytesToHex(bytes) { return Array.from(bytes) .map((b) => b.toString(16).padStart(2, "0")) .join(""); } decodeVoteValue(base64Value) { const binaryString = atob(base64Value); const bytes = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } const hexString = "0x" + this.bytesToHex(bytes); const value = BigInt(hexString); return value; } processVote(vote) { return { feedKey: vote.FeedKey, value: this.decodeVoteValue(vote.Value), timestamp: vote.Timestamp, publisher: vote.Publisher, signature: vote.Signature, }; } async getCallData(feedKeys) { const response = await this.fetchData(feedKeys); return response.update_call_data; } async getVotes(feedKeys) { const response = await this.fetchData(feedKeys); return response.feeds.flatMap((feed) => feed.votes.map((vote) => this.processVote(vote))); } async getMedian(feedKey) { const votes = await this.getVotes([feedKey]); if (!votes || votes.length === 0) { throw new Error("No votes provided for median calculation"); } const sortedValues = votes .map((v) => v.value) .filter((v) => !isNaN(Number(v)) && isFinite(Number(v))) .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)); if (sortedValues.length === 0) { throw new Error("No valid numerical values found in votes"); } const mid = Math.floor(sortedValues.length / 2); if (sortedValues.length % 2 === 1) { return sortedValues[mid]; } return (sortedValues[mid - 1] + sortedValues[mid]) / 2n; } async fetchData(feedKeys) { const queryParams = new URLSearchParams({ feedKeys: feedKeys.join(",") }); const response = await fetch(`${this.baseUrl}/last_votes?${queryParams}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } async getLastVotes(feedKeys) { const data = await this.fetchData(feedKeys); const processedFeeds = data.feeds.map((feed) => { const processedVotes = feed.votes.map((vote) => this.processVote(vote)); const latestTimestamp = Math.max(...processedVotes.map((v) => v.timestamp)); return { feedKey: feed.feed_key, votes: processedVotes, median: this.calculateMedianForVotes(processedVotes), timestamp: latestTimestamp, }; }); return { feeds: processedFeeds, updateCallData: data.update_call_data, }; } calculateMedianForVotes(votes) { if (!votes || votes.length === 0) { throw new Error("No votes provided for median calculation"); } const sortedValues = votes .map((v) => v.value) .filter((v) => !isNaN(Number(v)) && isFinite(Number(v))) .sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)); if (sortedValues.length === 0) { throw new Error("No valid numerical values found in votes"); } const mid = Math.floor(sortedValues.length / 2); if (sortedValues.length % 2 === 1) { return sortedValues[mid]; } return (sortedValues[mid - 1] + sortedValues[mid]) / 2n; } } exports.default = UdfSdk;