openoracle-sdk-js
Version:
OpenOracle Node.js SDK - Intelligent Oracle Routing with Multiple LLM Providers
1,505 lines • 97.8 kB
JavaScript
import Te from "axios";
import { config as Re } from "dotenv";
import { format as E, transports as Ce, createLogger as Oe } from "winston";
class y extends Error {
code;
severity;
context;
constructor(e, t = "ORACLE_ERROR", r = "error", s) {
super(e), this.name = this.constructor.name, this.code = t, this.severity = r, this.context = s, Error.captureStackTrace(this, this.constructor);
}
toJSON() {
return {
name: this.name,
message: this.message,
code: this.code,
severity: this.severity,
context: this.context,
stack: this.stack
};
}
}
class U extends y {
constructor(e, t) {
super(e, "ROUTING_ERROR", "error", t);
}
}
class f extends y {
constructor(e, t) {
super(e, "VALIDATION_ERROR", "error", t);
}
}
class P extends y {
constructor(e, t) {
super(e, "CONFIGURATION_ERROR", "error", t);
}
}
class A extends y {
provider;
constructor(e, t, r) {
super(e, "PROVIDER_ERROR", "error", { ...r, provider: t }), this.provider = t;
}
}
class Ae extends y {
statusCode;
response;
constructor(e, t, r, s) {
super(e, "NETWORK_ERROR", "error", { ...s, statusCode: t, response: r }), this.statusCode = t, this.response = r;
}
}
class L extends y {
constructor(e, t) {
super(e, "AUTHENTICATION_ERROR", "error", t);
}
}
class Se extends y {
retryAfter;
constructor(e, t, r) {
super(e, "RATE_LIMIT_ERROR", "warning", { ...r, retryAfter: t }), this.retryAfter = t;
}
}
class H extends y {
timeoutMs;
constructor(e, t, r) {
super(e, "TIMEOUT_ERROR", "error", { ...r, timeoutMs: t }), this.timeoutMs = t;
}
}
class ze extends y {
expectedValue;
actualValue;
constructor(e, t, r, s) {
super(e, "DATA_INTEGRITY_ERROR", "critical", {
...s,
expectedValue: t,
actualValue: r
}), this.expectedValue = t, this.actualValue = r;
}
}
class Ge extends y {
operation;
provider;
constructor(e, t, r) {
const s = t ? `Operation '${e}' is not supported by provider '${t}'` : `Operation '${e}' is not supported`;
super(s, "UNSUPPORTED_OPERATION_ERROR", "error", {
...r,
operation: e,
provider: t
}), this.operation = e, this.provider = t;
}
}
class je extends y {
constructor(e, t) {
super(e, "CACHE_ERROR", "warning", t);
}
}
class Je extends y {
providers;
values;
constructor(e, t, r, s) {
super(e, "CONSENSUS_ERROR", "error", { ...s, providers: t, values: r }), this.providers = t, this.values = r;
}
}
function _e(i) {
return i instanceof y;
}
function Ze(i, e) {
return i instanceof e;
}
function Xe(i) {
return _e(i) ? i : i instanceof Error ? new y(i.message, "UNKNOWN_ERROR", "error", {
originalError: i.name,
stack: i.stack
}) : new y(
String(i),
"UNKNOWN_ERROR",
"error",
{ originalError: i }
);
}
let Me = class {
axios;
config;
requestCount = 0;
lastRequestTime = 0;
constructor(e, t) {
this.config = e, this.axios = Te.create({
baseURL: (t == null ? void 0 : t.baseURL) || "http://localhost:8000",
timeout: (t == null ? void 0 : t.timeout) || e.network.timeouts.request,
headers: {
"Content-Type": "application/json",
"User-Agent": "openoracle-sdk-node/0.1.0",
...t == null ? void 0 : t.headers
}
}), this.setupInterceptors();
}
setupInterceptors() {
this.axios.interceptors.request.use(
(e) => (this.requestCount++, this.lastRequestTime = Date.now(), this.config.apiKeys.openai && (e.headers = e.headers || {}, e.headers.Authorization = `Bearer ${this.config.apiKeys.openai}`), e),
(e) => Promise.reject(this.normalizeError(e))
), this.axios.interceptors.response.use(
(e) => e,
(e) => Promise.reject(this.normalizeError(e))
);
}
normalizeError(e) {
var t, r, s, a, n, o, d, h, m, w, T, R, I, b, O, S;
if (Te.isAxiosError(e)) {
const _ = (t = e.response) == null ? void 0 : t.status, v = ((s = (r = e.response) == null ? void 0 : r.data) == null ? void 0 : s.message) || e.message;
switch (_) {
case 401:
return new L(v, {
url: (a = e.config) == null ? void 0 : a.url,
method: (n = e.config) == null ? void 0 : n.method
});
case 429:
const M = (o = e.response) == null ? void 0 : o.headers["retry-after"];
return new Se(v, M ? parseInt(M) : void 0, {
url: (d = e.config) == null ? void 0 : d.url,
method: (h = e.config) == null ? void 0 : h.method
});
case 400:
return new f(v, {
url: (m = e.config) == null ? void 0 : m.url,
method: (w = e.config) == null ? void 0 : w.method,
data: (T = e.config) == null ? void 0 : T.data
});
default:
return e.code === "ECONNABORTED" || e.code === "ETIMEDOUT" ? new H(
v,
this.config.network.timeouts.request,
{
url: (R = e.config) == null ? void 0 : R.url,
method: (I = e.config) == null ? void 0 : I.method
}
) : new Ae(
v,
_,
(b = e.response) == null ? void 0 : b.data,
{
url: (O = e.config) == null ? void 0 : O.url,
method: (S = e.config) == null ? void 0 : S.method
}
);
}
}
return e;
}
async get(e, t) {
return (await this.axios.get(e, t)).data;
}
async post(e, t, r) {
return (await this.axios.post(e, t, r)).data;
}
async put(e, t, r) {
return (await this.axios.put(e, t, r)).data;
}
async patch(e, t, r) {
return (await this.axios.patch(e, t, r)).data;
}
async delete(e, t) {
return (await this.axios.delete(e, t)).data;
}
async request(e) {
return (await this.axios.request(e)).data;
}
// Health check endpoint
async healthCheck() {
try {
return await this.get("/health"), !0;
} catch {
return !1;
}
}
// Get client statistics
getStats() {
return {
requestCount: this.requestCount,
lastRequestTime: this.lastRequestTime
};
}
// Update configuration
updateConfig(e) {
this.axios.defaults.timeout = e.network.timeouts.request, e.apiKeys.openai && (this.axios.defaults.headers.common.Authorization = `Bearer ${e.apiKeys.openai}`);
}
// Retry mechanism with exponential backoff
async withRetry(e, t = this.config.network.retries.maxAttempts) {
let r;
for (let s = 1; s <= t; s++)
try {
return await e();
} catch (a) {
if (r = a, s === t)
throw r;
if (a instanceof L || a instanceof f)
throw a;
const n = Math.min(
this.config.network.retries.backoffMs * Math.pow(2, s - 1),
this.config.network.retries.maxBackoffMs
);
await new Promise((o) => setTimeout(o, n));
}
throw r;
}
// Batch requests
async batch(e) {
return Promise.all(e.map((t) => t()));
}
// Stream support for real-time data
createEventStream(e, t) {
const r = new EventSource(e);
return t != null && t.onData && (r.onmessage = (s) => {
var a;
try {
const n = JSON.parse(s.data);
t.onData(n);
} catch (n) {
(a = t.onError) == null || a.call(t, n);
}
}), t != null && t.onError && (r.onerror = (s) => {
t.onError(new Ae("EventSource error", void 0, s));
}), t != null && t.onClose && r.addEventListener("close", t.onClose), r;
}
// WebSocket support
createWebSocket(e, t) {
const r = new WebSocket(e, t);
return r.onerror = (s) => {
console.error("WebSocket error:", s);
}, r;
}
// Cleanup
destroy() {
}
};
var c = /* @__PURE__ */ ((i) => (i.CHAINLINK = "chainlink", i.PYTH = "pyth", i.UMA = "uma", i.BAND = "band", i.API3 = "api3", i.DIA = "dia", i.TELLOR = "tellor", i.SUPRA = "supra", i.FLUX = "flux", i.REDSTONE = "redstone", i))(c || {}), u = /* @__PURE__ */ ((i) => (i.PRICE = "price", i.SPORTS = "sports", i.WEATHER = "weather", i.ECONOMIC = "economic", i.NFT = "nft", i.SOCIAL = "social", i.NEWS = "news", i.CRYPTO = "crypto", i.STOCKS = "stocks", i.COMMODITIES = "commodities", i.FOREX = "forex", i.DEFI = "defi", i.CUSTOM = "custom", i))(u || {}), D = /* @__PURE__ */ ((i) => (i.REALTIME = "realtime", i.SECOND = "second", i.MINUTE = "minute", i.HOUR = "hour", i.DAILY = "daily", i.WEEKLY = "weekly", i.MONTHLY = "monthly", i.ON_DEMAND = "on_demand", i))(D || {}), De = /* @__PURE__ */ ((i) => (i.AUTOMATED = "automated", i.MANUAL = "manual", i.VOTING = "voting", i.CONSENSUS = "consensus", i.OPTIMISTIC = "optimistic", i.CHALLENGE = "challenge", i))(De || {}), g = /* @__PURE__ */ ((i) => (i.PRICE_FEEDS = "price_feeds", i.VRF = "vrf", i.AUTOMATION = "automation", i.EXTERNAL_ADAPTERS = "external_adapters", i.PROOF_OF_RESERVE = "proof_of_reserve", i.CCIP = "ccip", i.FUNCTIONS = "functions", i.SPORTS_DATA = "sports_data", i.WEATHER_DATA = "weather_data", i.ECONOMIC_DATA = "economic_data", i.NFT_DATA = "nft_data", i))(g || {}), l = /* @__PURE__ */ ((i) => (i.VERY_LOW = "very_low", i.LOW = "low", i.MEDIUM = "medium", i.HIGH = "high", i.VERY_HIGH = "very_high", i))(l || {}), ke = /* @__PURE__ */ ((i) => (i.INFO = "info", i.WARNING = "warning", i.ERROR = "error", i.CRITICAL = "critical", i))(ke || {}), C = /* @__PURE__ */ ((i) => (i.COST_OPTIMIZED = "cost_optimized", i.SPEED_OPTIMIZED = "speed_optimized", i.ACCURACY_OPTIMIZED = "accuracy_optimized", i.BALANCED = "balanced", i.REDUNDANT = "redundant", i))(C || {}), Ne = /* @__PURE__ */ ((i) => (i.ONLINE = "online", i.OFFLINE = "offline", i.DEGRADED = "degraded", i.MAINTENANCE = "maintenance", i))(Ne || {}), Ie = /* @__PURE__ */ ((i) => (i.NO_CACHE = "no_cache", i.MEMORY_ONLY = "memory_only", i.PERSISTENT = "persistent", i.HYBRID = "hybrid", i))(Ie || {}), p = /* @__PURE__ */ ((i) => (i[i.ETHEREUM = 1] = "ETHEREUM", i[i.POLYGON = 137] = "POLYGON", i[i.BSC = 56] = "BSC", i[i.AVALANCHE = 43114] = "AVALANCHE", i[i.ARBITRUM = 42161] = "ARBITRUM", i[i.OPTIMISM = 10] = "OPTIMISM", i[i.FANTOM = 250] = "FANTOM", i[i.FLOW_EVM = 545] = "FLOW_EVM", i[i.FLOW_TESTNET = 646] = "FLOW_TESTNET", i))(p || {});
const tt = [
1,
137,
56,
43114,
42161,
10,
545,
646
/* FLOW_TESTNET */
];
function rt(i) {
return i && typeof i == "object" && "value" in i && "timestamp" in i && "source" in i && "confidence" in i;
}
function st(i) {
return i && typeof i == "object" && typeof i.query == "string" && Object.values(u).includes(i.category);
}
function it(i) {
return i && typeof i == "object" && Object.values(c).includes(i.oracleProvider) && Object.values(l).includes(i.confidence) && Array.isArray(i.data);
}
function $e(i) {
const e = [], t = [];
i.query ? i.query.length < 3 && e.push("Query must be at least 3 characters long") : e.push("Query is required"), i.category ? Object.values(u).includes(i.category) || e.push("Invalid category") : e.push("Category is required"), i.maxProviders && i.maxProviders < 1 && e.push("Max providers must be at least 1"), i.consensusThreshold && (i.consensusThreshold < 0 || i.consensusThreshold > 1) && e.push("Consensus threshold must be between 0 and 1"), i.timeoutMs && i.timeoutMs < 1e3 && t.push("Timeout less than 1 second may cause failures");
const r = e.length === 0 ? t.length === 0 ? l.VERY_HIGH : l.HIGH : l.LOW;
return {
isValid: e.length === 0,
errors: e,
warnings: t,
confidence: r
};
}
function xe(i) {
const e = [], t = [];
i.provider ? Object.values(c).includes(i.provider) || e.push("Invalid provider") : e.push("Provider is required"), i.timeout && i.timeout < 1e3 && t.push("Timeout less than 1 second may cause failures"), i.retryAttempts && i.retryAttempts < 0 && e.push("Retry attempts must be non-negative"), i.rateLimit && i.rateLimit < 1 && e.push("Rate limit must be at least 1");
const r = e.length === 0 ? t.length === 0 ? l.VERY_HIGH : l.HIGH : l.LOW;
return {
isValid: e.length === 0,
errors: e,
warnings: t,
confidence: r
};
}
let at = class {
config;
client;
providerMetrics = /* @__PURE__ */ new Map();
cache = /* @__PURE__ */ new Map();
constructor(e, t) {
this.config = e, this.client = t || new Me(e), this.initializeProviderMetrics();
}
initializeProviderMetrics() {
Object.values(c).forEach((e) => {
this.providerMetrics.set(e, {
providerId: e,
requestCount: 0,
successCount: 0,
errorCount: 0,
averageResponseTime: 0,
lastUsed: /* @__PURE__ */ new Date(0),
cost: 0,
reliability: 1
});
});
}
/**
* Route a question to the optimal oracle provider(s)
*/
async routeQuestion(e, t, r = {}) {
const s = {
query: e,
category: t,
maxProviders: r.maxProviders || this.config.routing.maxProviders,
consensusThreshold: r.consensusThreshold || this.config.routing.consensusThreshold,
timeoutMs: r.timeoutMs || this.config.network.timeouts.request,
cacheEnabled: r.enableCaching ?? this.config.cache.strategy !== "no_cache"
}, a = $e(s);
if (!a.isValid)
throw new f(`Invalid routing request: ${a.errors.join(", ")}`);
if (s.cacheEnabled) {
const o = this.getCachedResponse(s);
if (o)
return o;
}
const n = Date.now();
try {
const o = await this.selectProviders(s, r.strategy);
if (o.length === 0)
throw new U("No suitable providers found for the query");
const d = await this.executeQueries(s, o), h = this.aggregateResponses(d, s), m = {
oracleProvider: h.primaryProvider,
confidence: h.confidence,
data: h.data,
reasoning: h.reasoning,
alternativeProviders: o.filter((w) => w !== h.primaryProvider),
executionTimeMs: Date.now() - n,
cached: !1,
metadata: {
totalProviders: o.length,
consensus: h.consensus,
strategy: r.strategy || this.config.routing.strategy
}
};
return s.cacheEnabled && this.cacheResponse(s, m), m;
} catch (o) {
if (r.fallbackEnabled && this.config.routing.fallbackProviders.length > 0)
return this.executeFallback(s, o);
throw o;
}
}
/**
* Select optimal providers based on routing strategy
*/
async selectProviders(e, t) {
const r = this.getAvailableProviders(e);
switch (t || this.config.routing.strategy) {
case C.COST_OPTIMIZED:
return this.selectByCost(r, e.maxProviders);
case C.SPEED_OPTIMIZED:
return this.selectBySpeed(r, e.maxProviders);
case C.ACCURACY_OPTIMIZED:
return this.selectByAccuracy(r, e.maxProviders);
case C.REDUNDANT:
return this.selectForRedundancy(r, e.maxProviders);
case C.BALANCED:
default:
return this.selectBalanced(r, e.maxProviders);
}
}
getAvailableProviders(e) {
let t = Object.values(c);
return e.requiredProviders && e.requiredProviders.length > 0 && (t = t.filter((r) => e.requiredProviders.includes(r))), e.excludedProviders && e.excludedProviders.length > 0 && (t = t.filter((r) => !e.excludedProviders.includes(r))), t.filter((r) => this.config.hasApiKey(r) || this.isPublicProvider(r));
}
isPublicProvider(e) {
return [c.PYTH].includes(e);
}
selectByCost(e, t) {
return e.sort((r, s) => this.getProviderCost(r) - this.getProviderCost(s)).slice(0, t);
}
selectBySpeed(e, t) {
return e.sort((r, s) => {
const a = this.providerMetrics.get(r), n = this.providerMetrics.get(s);
return a.averageResponseTime - n.averageResponseTime;
}).slice(0, t);
}
selectByAccuracy(e, t) {
return e.sort((r, s) => {
const a = this.providerMetrics.get(r).reliability;
return this.providerMetrics.get(s).reliability - a;
}).slice(0, t);
}
selectForRedundancy(e, t) {
return [
c.CHAINLINK,
c.PYTH,
c.UMA,
c.BAND,
c.API3
].filter((s) => e.includes(s)).slice(0, t);
}
selectBalanced(e, t) {
return e.map((s) => {
const a = this.providerMetrics.get(s), n = this.getProviderCost(s), o = this.config.routing.speedWeighting * (1 / (a.averageResponseTime + 1)) + this.config.routing.accuracyWeighting * a.reliability + this.config.routing.costWeighting * (1 / (n + 1));
return { provider: s, score: o };
}).sort((s, a) => a.score - s.score).slice(0, t).map((s) => s.provider);
}
getProviderCost(e) {
return {
[c.CHAINLINK]: 0.01,
[c.PYTH]: 5e-3,
[c.UMA]: 0.02,
[c.BAND]: 0.015,
[c.API3]: 0.01
}[e] || 0.01;
}
/**
* Execute queries across selected providers
*/
async executeQueries(e, t) {
const r = t.map(async (s) => {
const a = Date.now();
try {
const n = await this.queryProvider(s, e);
return this.updateProviderMetrics(s, {
success: !0,
responseTime: Date.now() - a
}), { provider: s, data: n };
} catch (n) {
return this.updateProviderMetrics(s, {
success: !1,
responseTime: Date.now() - a
}), { provider: s, data: [], error: n };
}
});
return Promise.all(r);
}
async queryProvider(e, t) {
try {
return (await this.client.post(`/api/oracle/${e}/query`, {
query: t.query,
category: t.category,
metadata: t.metadata
})).data || [];
} catch (r) {
throw new A(
`Provider ${e} query failed`,
e,
{ originalError: r.message }
);
}
}
aggregateResponses(e, t) {
const r = e.filter((o) => !o.error && o.data.length > 0);
if (r.length === 0)
throw new U("All providers failed to return data");
const s = r[0];
let a = !0;
r.length > 1 && (a = this.checkConsensus(r, t.consensusThreshold));
const n = this.calculateConfidence(r, a);
return {
primaryProvider: s.provider,
confidence: n,
data: s.data,
reasoning: this.generateReasoning(r, a),
consensus: a
};
}
checkConsensus(e, t) {
if (e.length < 2) return !0;
const r = e.map((a) => {
var n;
return (n = a.data[0]) == null ? void 0 : n.value;
}).filter((a) => a !== void 0);
if (r.length < 2) return !0;
if (typeof r[0] == "number") {
const a = r, n = a.reduce((h, m) => h + m, 0) / a.length, o = a.reduce((h, m) => h + Math.pow(m - n, 2), 0) / a.length;
return Math.sqrt(o) / Math.abs(n) < 1 - t;
}
return new Set(r).size === 1;
}
calculateConfidence(e, t) {
if (e.length === 0) return l.VERY_LOW;
if (e.length === 1) {
const r = this.providerMetrics.get(e[0].provider).reliability;
return r > 0.9 ? l.HIGH : r > 0.7 ? l.MEDIUM : l.LOW;
}
return t ? e.length >= 3 ? l.VERY_HIGH : l.HIGH : l.MEDIUM;
}
generateReasoning(e, t) {
const r = e.map((s) => s.provider).join(", ");
return e.length === 1 ? `Single provider response from ${r}` : t ? `Consensus achieved across ${e.length} providers: ${r}` : `Mixed results from ${e.length} providers: ${r}. Using primary provider result.`;
}
async executeFallback(e, t) {
const r = this.config.routing.fallbackProviders;
try {
const s = await this.executeQueries(e, r), a = this.aggregateResponses(s, e);
return {
oracleProvider: a.primaryProvider,
confidence: l.LOW,
// Fallback always has lower confidence
data: a.data,
reasoning: `Fallback execution after primary failure: ${t.message}`,
alternativeProviders: [],
executionTimeMs: 0,
cached: !1,
metadata: { fallback: !0, originalError: t.message }
};
} catch (s) {
throw new U(
"Both primary and fallback routing failed",
{
originalError: t.message,
fallbackError: s.message
}
);
}
}
updateProviderMetrics(e, t) {
const r = this.providerMetrics.get(e);
r.requestCount++, r.lastUsed = /* @__PURE__ */ new Date(), t.success ? r.successCount++ : r.errorCount++, r.averageResponseTime = (r.averageResponseTime * (r.requestCount - 1) + t.responseTime) / r.requestCount, r.reliability = r.successCount / r.requestCount;
}
getCachedResponse(e) {
const t = this.getCacheKey(e), r = this.cache.get(t);
return r ? Date.now() - r.timestamp > r.ttl ? (this.cache.delete(t), null) : { ...r.data, cached: !0 } : null;
}
cacheResponse(e, t) {
const r = this.getCacheKey(e);
if (this.cache.set(r, {
data: t,
timestamp: Date.now(),
ttl: this.config.cache.ttlSeconds * 1e3
}), this.cache.size > this.config.cache.maxSize) {
const s = this.cache.keys().next().value;
this.cache.delete(s);
}
}
getCacheKey(e) {
return `${e.query}:${e.category}:${JSON.stringify(e.metadata || {})}`;
}
/**
* Get routing metrics for all providers
*/
getMetrics() {
return new Map(this.providerMetrics);
}
/**
* Clear cache
*/
clearCache() {
this.cache.clear();
}
/**
* Health check for all configured providers
*/
async healthCheck() {
const e = Object.values(c), t = {};
return await Promise.all(
e.map(async (r) => {
try {
await this.client.get(`/api/oracle/${r}/health`), t[r] = !0;
} catch {
t[r] = !1;
}
})
), t;
}
}, Ue = class k {
apiKeys;
network;
cache;
routing;
logging;
environment;
constructor(e = {}) {
var t, r, s, a, n, o, d, h, m, w, T, R, I, b, O, S, _, v, M, W, Y, B, V, Q, z, G, j, J, Z, X, ee, te, re, se, ie, ae, ne, oe, ce, le, ue, de, he, me, ge, pe, fe, ye, we, Pe, ve, Ee;
this.environment = e.environment || "production", this.apiKeys = {
openai: ((t = e.apiKeys) == null ? void 0 : t.openai) || process.env.OPENAI_API_KEY,
chainlink: ((r = e.apiKeys) == null ? void 0 : r.chainlink) || process.env.CHAINLINK_API_KEY,
pyth: ((s = e.apiKeys) == null ? void 0 : s.pyth) || process.env.PYTH_API_KEY,
uma: ((a = e.apiKeys) == null ? void 0 : a.uma) || process.env.UMA_API_KEY,
band: ((n = e.apiKeys) == null ? void 0 : n.band) || process.env.BAND_API_KEY,
api3: ((o = e.apiKeys) == null ? void 0 : o.api3) || process.env.API3_API_KEY,
twitter: {
bearerToken: ((h = (d = e.apiKeys) == null ? void 0 : d.twitter) == null ? void 0 : h.bearerToken) || process.env.TWITTER_BEARER_TOKEN,
apiKey: ((w = (m = e.apiKeys) == null ? void 0 : m.twitter) == null ? void 0 : w.apiKey) || process.env.TWITTER_API_KEY,
apiSecret: ((R = (T = e.apiKeys) == null ? void 0 : T.twitter) == null ? void 0 : R.apiSecret) || process.env.TWITTER_API_SECRET,
accessToken: ((b = (I = e.apiKeys) == null ? void 0 : I.twitter) == null ? void 0 : b.accessToken) || process.env.TWITTER_ACCESS_TOKEN,
accessTokenSecret: ((S = (O = e.apiKeys) == null ? void 0 : O.twitter) == null ? void 0 : S.accessTokenSecret) || process.env.TWITTER_ACCESS_TOKEN_SECRET
},
polygon: ((_ = e.apiKeys) == null ? void 0 : _.polygon) || process.env.POLYGON_API_KEY,
etherscan: ((v = e.apiKeys) == null ? void 0 : v.etherscan) || process.env.ETHERSCAN_API_KEY,
moralis: ((M = e.apiKeys) == null ? void 0 : M.moralis) || process.env.MORALIS_API_KEY,
alchemy: ((W = e.apiKeys) == null ? void 0 : W.alchemy) || process.env.ALCHEMY_API_KEY,
...e.apiKeys
}, this.network = {
defaultChain: ((Y = e.network) == null ? void 0 : Y.defaultChain) || p.ETHEREUM,
rpcs: {
[p.ETHEREUM]: process.env.ETHEREUM_RPC || "https://eth.llamarpc.com",
[p.POLYGON]: process.env.POLYGON_RPC || "https://polygon.llamarpc.com",
[p.BSC]: process.env.BSC_RPC || "https://bsc.llamarpc.com",
[p.ARBITRUM]: process.env.ARBITRUM_RPC || "https://arbitrum.llamarpc.com",
[p.OPTIMISM]: process.env.OPTIMISM_RPC || "https://optimism.llamarpc.com",
[p.FLOW_EVM]: process.env.FLOW_EVM_RPC || "https://mainnet.evm.nodes.onflow.org",
[p.FLOW_TESTNET]: process.env.FLOW_TESTNET_RPC || "https://testnet.evm.nodes.onflow.org",
...(B = e.network) == null ? void 0 : B.rpcs
},
timeouts: {
connection: ((Q = (V = e.network) == null ? void 0 : V.timeouts) == null ? void 0 : Q.connection) || 1e4,
request: ((G = (z = e.network) == null ? void 0 : z.timeouts) == null ? void 0 : G.request) || 3e4,
retry: ((J = (j = e.network) == null ? void 0 : j.timeouts) == null ? void 0 : J.retry) || 5e3
},
retries: {
maxAttempts: ((X = (Z = e.network) == null ? void 0 : Z.retries) == null ? void 0 : X.maxAttempts) || 3,
backoffMs: ((te = (ee = e.network) == null ? void 0 : ee.retries) == null ? void 0 : te.backoffMs) || 1e3,
maxBackoffMs: ((se = (re = e.network) == null ? void 0 : re.retries) == null ? void 0 : se.maxBackoffMs) || 1e4
}
}, this.cache = {
strategy: ((ie = e.cache) == null ? void 0 : ie.strategy) || Ie.MEMORY_ONLY,
ttlSeconds: ((ae = e.cache) == null ? void 0 : ae.ttlSeconds) || 300,
// 5 minutes
maxSize: ((ne = e.cache) == null ? void 0 : ne.maxSize) || 1e3,
persistPath: ((oe = e.cache) == null ? void 0 : oe.persistPath) || "./cache",
...e.cache
}, this.routing = {
strategy: ((ce = e.routing) == null ? void 0 : ce.strategy) || C.BALANCED,
preferredProviders: ((le = e.routing) == null ? void 0 : le.preferredProviders) || [
c.CHAINLINK,
c.PYTH
],
fallbackProviders: ((ue = e.routing) == null ? void 0 : ue.fallbackProviders) || [
c.UMA,
c.BAND,
c.API3
],
consensusThreshold: ((de = e.routing) == null ? void 0 : de.consensusThreshold) || 0.8,
maxProviders: ((he = e.routing) == null ? void 0 : he.maxProviders) || 3,
costWeighting: ((me = e.routing) == null ? void 0 : me.costWeighting) || 0.3,
speedWeighting: ((ge = e.routing) == null ? void 0 : ge.speedWeighting) || 0.4,
accuracyWeighting: ((pe = e.routing) == null ? void 0 : pe.accuracyWeighting) || 0.3,
...e.routing
}, this.logging = {
level: ((fe = e.logging) == null ? void 0 : fe.level) || (this.environment === "production" ? "error" : "info"),
format: ((ye = e.logging) == null ? void 0 : ye.format) || "text",
destination: ((we = e.logging) == null ? void 0 : we.destination) || "console",
filePath: ((Pe = e.logging) == null ? void 0 : Pe.filePath) || "./logs/openoracle.log",
maxFileSize: ((ve = e.logging) == null ? void 0 : ve.maxFileSize) || "10m",
maxFiles: ((Ee = e.logging) == null ? void 0 : Ee.maxFiles) || 5,
...e.logging
}, this.validateConfig();
}
/**
* Create configuration from environment variables
*/
static fromEnv(e) {
return e ? Re({ path: e }) : Re(), new k();
}
/**
* Create configuration from JSON object
*/
static fromJSON(e) {
const t = typeof e == "string" ? JSON.parse(e) : e;
return new k(t);
}
/**
* Create configuration from file
*/
static async fromFile(e) {
try {
const r = await (await import("./__vite-browser-external-DYxpcVy9.mjs")).readFile(e, "utf-8");
return k.fromJSON(r);
} catch (t) {
throw new P(`Failed to load config from file: ${e}`, {
filePath: e,
error: t instanceof Error ? t.message : String(t)
});
}
}
/**
* Validate configuration values
*/
validateConfig() {
if (!this.apiKeys.openai && this.environment === "production")
throw new P("OpenAI API key is required for production");
if (this.network.timeouts.connection <= 0)
throw new P("Connection timeout must be positive");
if (this.network.retries.maxAttempts < 1)
throw new P("Max retry attempts must be at least 1");
if (this.routing.consensusThreshold < 0 || this.routing.consensusThreshold > 1)
throw new P("Consensus threshold must be between 0 and 1");
const e = this.routing.costWeighting + this.routing.speedWeighting + this.routing.accuracyWeighting;
if (Math.abs(e - 1) > 0.01)
throw new P("Routing weightings must sum to 1.0");
if (this.cache.ttlSeconds <= 0)
throw new P("Cache TTL must be positive");
if (this.cache.maxSize <= 0)
throw new P("Cache max size must be positive");
}
/**
* Get RPC URL for specific chain
*/
getRpcUrl(e) {
const t = this.network.rpcs[e];
if (!t)
throw new P(`No RPC URL configured for chain ${e}`);
return t;
}
/**
* Check if API key is available for provider
*/
hasApiKey(e) {
switch (e) {
case c.CHAINLINK:
return !!this.apiKeys.chainlink;
case c.PYTH:
return !!this.apiKeys.pyth;
case c.UMA:
return !!this.apiKeys.uma;
case c.BAND:
return !!this.apiKeys.band;
case c.API3:
return !!this.apiKeys.api3;
default:
return !1;
}
}
/**
* Export configuration as JSON
*/
toJSON() {
return {
apiKeys: this.apiKeys,
network: this.network,
cache: this.cache,
routing: this.routing,
logging: this.logging,
environment: this.environment
};
}
/**
* Create a copy of the configuration with modifications
*/
withOptions(e) {
return new k({
...this.toJSON(),
...e
});
}
}, x = null;
function ot() {
return x || (x = Ue.fromEnv()), x;
}
function ct(i) {
x = i;
}
let lt = class {
client;
config;
constructor(e, t) {
this.client = e, this.config = t;
}
/**
* Query price data from oracle providers
*/
async getPrice(e) {
if (!e.symbol)
throw new f("Symbol is required for price queries");
return (await this.client.get("/api/oracle/price", {
params: {
symbol: e.symbol,
currency: e.currency || "USD",
provider: e.provider,
max_age: e.maxAge,
include_fees: e.includeFees
}
})).data || [];
}
/**
* Query general data from oracle providers
*/
async queryData(e) {
const t = {
query: e.query,
category: e.category,
requiredProviders: e.providers,
maxProviders: e.maxProviders,
consensusThreshold: e.consensusRequired ? 0.8 : 0.5,
timeoutMs: e.timeoutMs || this.config.network.timeouts.request
};
return await this.client.post("/api/oracle/query", t);
}
/**
* Get Chainlink price feeds
*/
async getChainlinkFeed(e, t) {
return (await this.client.get(`/api/oracle/chainlink/feed/${e}`, {
params: { chain_id: t }
})).data;
}
/**
* Get Pyth price feeds
*/
async getPythFeed(e) {
return (await this.client.get(`/api/oracle/pyth/price/${e}`)).data;
}
/**
* List available Chainlink price feeds
*/
async listChainlinkFeeds(e) {
return (await this.client.get("/api/oracle/chainlink/feeds", {
params: { chain_id: e }
})).data || [];
}
/**
* List available Pyth price feeds
*/
async listPythFeeds() {
return (await this.client.get("/api/oracle/pyth/feeds")).data || [];
}
/**
* Get provider capabilities
*/
async getProviderCapabilities(e) {
return (await this.client.get(`/api/oracle/providers/${e}/capabilities`)).data;
}
/**
* List all available providers
*/
async listProviders() {
return (await this.client.get("/api/oracle/providers")).data || [];
}
/**
* Health check for specific provider
*/
async checkProviderHealth(e) {
try {
return await this.client.get(`/api/oracle/providers/${e}/health`), !0;
} catch {
return !1;
}
}
/**
* Aggregate data from multiple providers
*/
async aggregateData(e, t, r) {
return (await this.client.post("/api/oracle/aggregate", {
query: e,
category: t,
providers: r
})).data;
}
/**
* Subscribe to real-time price updates
*/
subscribeToPriceUpdates(e, t, r) {
const s = new URLSearchParams({
symbol: e,
...(r == null ? void 0 : r.provider) && { provider: r.provider },
...(r == null ? void 0 : r.interval) && { interval: r.interval.toString() },
...(r == null ? void 0 : r.currency) && { currency: r.currency }
});
return this.client.createEventStream(`/api/oracle/price/stream?${s}`, {
onData: t,
onError: (a) => {
console.error("Price stream error:", a);
}
});
}
/**
* Subscribe to general data updates
*/
subscribeToDataUpdates(e, t, r, s) {
const a = new URLSearchParams({
query: e,
category: t,
...(s == null ? void 0 : s.providers) && { providers: s.providers.join(",") },
...(s == null ? void 0 : s.interval) && { interval: s.interval.toString() }
});
return this.client.createEventStream(`/api/oracle/data/stream?${a}`, {
onData: r,
onError: (n) => {
console.error("Data stream error:", n);
}
});
}
/**
* Create a custom oracle feed
*/
async createCustomFeed(e) {
return (await this.client.post("/api/oracle/feeds/custom", e)).data;
}
/**
* Get custom feed data
*/
async getCustomFeedData(e) {
return (await this.client.get(`/api/oracle/feeds/custom/${e}`)).data || [];
}
/**
* List user's custom feeds
*/
async listCustomFeeds() {
return (await this.client.get("/api/oracle/feeds/custom")).data || [];
}
/**
* Delete a custom feed
*/
async deleteCustomFeed(e) {
try {
return await this.client.delete(`/api/oracle/feeds/custom/${e}`), !0;
} catch {
return !1;
}
}
/**
* Batch query multiple data points
*/
async batchQuery(e) {
return (await this.client.post("/api/oracle/batch", { queries: e })).data || [];
}
/**
* Get historical data
*/
async getHistoricalData(e, t, r, s) {
return (await this.client.get("/api/oracle/historical", {
params: {
query: e,
category: t,
from: r.from.toISOString(),
to: r.to.toISOString(),
interval: r.interval || "1h",
provider: s
}
})).data || [];
}
/**
* Get provider statistics
*/
async getProviderStats(e, t) {
const r = { provider: e };
return t && (r.from = t.from.toISOString(), r.to = t.to.toISOString()), (await this.client.get("/api/oracle/providers/stats", { params: r })).data;
}
}, dt = class {
client;
config;
constructor(e, t) {
this.client = e, this.config = t, this.validateTwitterConfig();
}
validateTwitterConfig() {
var e, t;
if (!((e = this.config.apiKeys.twitter) != null && e.bearerToken) && !((t = this.config.apiKeys.twitter) != null && t.apiKey))
throw new L("Twitter API credentials are required");
}
/**
* Search tweets for oracle data
*/
async searchTweets(e) {
var r, s, a;
if (!e.query)
throw new f("Search query is required");
return ((a = (await this.client.post("/api/twitter/search", {
query: e.query,
max_results: e.maxResults || 100,
tweet_fields: e.tweetFields || ["public_metrics", "created_at", "context_annotations"],
user_fields: e.userFields || ["public_metrics", "verified_type"],
expansions: e.expansions || ["author_id"],
start_time: (r = e.startTime) == null ? void 0 : r.toISOString(),
end_time: (s = e.endTime) == null ? void 0 : s.toISOString(),
lang: e.lang || "en"
})).data) == null ? void 0 : a.tweets) || [];
}
/**
* Analyze sentiment from tweets
*/
async analyzeSentiment(e, t) {
var s, a, n, o;
return (await this.client.post("/api/twitter/sentiment", {
query: e,
max_tweets: (t == null ? void 0 : t.maxTweets) || 500,
start_time: (a = (s = t == null ? void 0 : t.timeRange) == null ? void 0 : s.from) == null ? void 0 : a.toISOString(),
end_time: (o = (n = t == null ? void 0 : t.timeRange) == null ? void 0 : n.to) == null ? void 0 : o.toISOString(),
include_retweets: (t == null ? void 0 : t.includeRetweets) ?? !1,
lang: (t == null ? void 0 : t.lang) || "en"
})).data;
}
/**
* Extract prediction markets from tweets
*/
async extractPredictions(e, t, r) {
return (await this.client.post("/api/twitter/predictions", {
query: e,
category: t,
timeframe: r == null ? void 0 : r.timeframe,
min_confidence: (r == null ? void 0 : r.confidence) || 0.6,
max_tweets: (r == null ? void 0 : r.maxTweets) || 200
})).data || [];
}
/**
* Create prediction market from tweet
*/
async createPredictionFromTweet(e) {
if (!e.tweetId && !e.query)
throw new f("Either tweet ID or query is required");
return (await this.client.post("/api/twitter/create-prediction", e)).data;
}
/**
* Get trending topics relevant to oracle queries
*/
async getTrendingTopics(e, t) {
return (await this.client.get("/api/twitter/trends", {
params: {
location: e || "worldwide",
category: t
}
})).data || [];
}
/**
* Analyze user influence and credibility
*/
async analyzeUser(e) {
return (await this.client.get(`/api/twitter/users/${e}/analysis`)).data;
}
/**
* Monitor real-time mentions and hashtags
*/
async monitorMentions(e, t, r) {
const s = new URLSearchParams({
keywords: e.join(","),
include_retweets: ((r == null ? void 0 : r.includeRetweets) ?? !1).toString(),
lang: (r == null ? void 0 : r.lang) || "en",
sentiment: ((r == null ? void 0 : r.sentiment) ?? !0).toString()
});
return this.client.createEventStream(`/api/twitter/stream/mentions?${s}`, {
onData: t,
onError: (a) => {
console.error("Twitter stream error:", a);
}
});
}
/**
* Get Twitter-based market confidence indicators
*/
async getMarketConfidence(e, t) {
return (await this.client.post("/api/twitter/market-confidence", {
query: e,
start_time: t.from.toISOString(),
end_time: t.to.toISOString()
})).data;
}
/**
* Extract numeric predictions from tweets
*/
async extractNumericPredictions(e, t, r) {
return (await this.client.post("/api/twitter/numeric-predictions", {
query: e,
target_metric: t,
timeframe: r == null ? void 0 : r.timeframe,
currency: r == null ? void 0 : r.currency,
unit: r == null ? void 0 : r.unit,
min_confidence: (r == null ? void 0 : r.minConfidence) || 0.5
})).data || [];
}
/**
* Get Twitter-based event predictions
*/
async getEventPredictions(e, t, r) {
return (await this.client.post("/api/twitter/event-predictions", {
event_query: e,
category: t,
time_horizon: r
})).data;
}
/**
* Create custom Twitter-based oracle feed
*/
async createTwitterFeed(e) {
return (await this.client.post("/api/twitter/feeds", e)).data;
}
/**
* Get historical Twitter sentiment data
*/
async getHistoricalSentiment(e, t, r = "1d") {
return (await this.client.get("/api/twitter/historical-sentiment", {
params: {
query: e,
from: t.from.toISOString(),
to: t.to.toISOString(),
interval: r
}
})).data || [];
}
}, mt = class {
client;
config;
constructor(e, t) {
this.client = e, this.config = t;
}
/**
* Create a new prediction poll
*/
async createPoll(e) {
const t = this.validatePollRequest(e);
if (!t.isValid)
throw new f(`Invalid poll request: ${t.errors.join(", ")}`);
return (await this.client.post("/api/polls", {
question: e.question,
description: e.description,
category: e.category,
options: e.options,
end_time: e.endTime.toISOString(),
resolution_method: e.resolutionMethod,
minimum_stake: e.minimumStake,
maximum_stake: e.maximumStake,
creator_stake: e.creatorStake,
tags: e.tags,
metadata: e.metadata
})).data;
}
/**
* Get poll details
*/
async getPoll(e) {
return (await this.client.get(`/api/polls/${e}`)).data;
}
/**
* List polls with filtering options
*/
async listPolls(e) {
var r;
return (await this.client.get("/api/polls", {
params: {
category: e == null ? void 0 : e.category,
status: e == null ? void 0 : e.status,
creator: e == null ? void 0 : e.creator,
tags: (r = e == null ? void 0 : e.tags) == null ? void 0 : r.join(","),
limit: (e == null ? void 0 : e.limit) || 50,
offset: (e == null ? void 0 : e.offset) || 0,
sort_by: (e == null ? void 0 : e.sortBy) || "created_time",
sort_order: (e == null ? void 0 : e.sortOrder) || "desc"
}
})).data;
}
/**
* Vote on a poll
*/
async vote(e, t, r, s, a) {
if (r <= 0)
throw new f("Stake must be positive");
if (t < 0)
throw new f("Option index must be non-negative");
return (await this.client.post(`/api/polls/${e}/vote`, {
option_index: t,
stake: r,
confidence: s || l.MEDIUM,
reasoning: a
})).data;
}
/**
* Get poll statistics
*/
async getPollStatistics(e) {
return (await this.client.get(`/api/polls/${e}/statistics`)).data;
}
/**
* Get user's voting history
*/
async getUserActivity(e) {
return (await this.client.get(`/api/polls/users/${e}/activity`)).data;
}
/**
* Resolve a poll (for authorized resolvers)
*/
async resolvePoll(e, t, r, s) {
return (await this.client.post(`/api/polls/${e}/resolve`, {
winning_option: t,
resolution_data: r,
resolution_source: s
})).data;
}
/**
* Get poll resolution details
*/
async getPollResolution(e) {
return (await this.client.get(`/api/polls/${e}/resolution`)).data;
}
/**
* Get trending polls
*/
async getTrendingPolls(e = "1d", t) {
return (await this.client.get("/api/polls/trending", {
params: {
timeframe: e,
category: t
}
})).data || [];
}
/**
* Search polls by keywords
*/
async searchPolls(e, t) {
return (await this.client.get("/api/polls/search", {
params: {
q: e,
category: t == null ? void 0 : t.category,
status: t == null ? void 0 : t.status,
limit: (t == null ? void 0 : t.limit) || 50,
include_content: (t == null ? void 0 : t.includeContent) ?? !0
}
})).data || [];
}
/**
* Get poll recommendations for user
*/
async getRecommendations(e, t = 10) {
return (await this.client.get(`/api/polls/users/${e}/recommendations`, {
params: { limit: t }
})).data || [];
}
/**
* Subscribe to poll updates
*/
subscribeToPollUpdates(e, t) {
return this.client.createEventStream(`/api/polls/${e}/stream`, {
onData: t,
onError: (r) => {
console.error("Poll stream error:", r);
}
});
}
/**
* Subscribe to new polls in category
*/
subscribeToNewPolls(e, t) {
return this.client.createEventStream(`/api/polls/stream/new?category=${e}`, {
onData: t,
onError: (r) => {
console.error("New polls stream error:", r);
}
});
}
/**
* Get market maker opportunities
*/
async getMarketMakerOpportunities(e, t, r) {
return (await this.client.get("/api/polls/market-maker/opportunities", {
params: {
min_liquidity: e,
max_risk: t,
categories: r == null ? void 0 : r.join(",")
}
})).data || [];
}
/**
* Create automated poll resolution
*/
async createAutomatedResolution(e, t) {
return (await this.client.post(`/api/polls/${e}/automated-resolution`, t)).data;
}
/**
* Get poll analytics
*/
async getPollAnalytics(e) {
return (await this.client.get(`/api/polls/${e}/analytics`)).data;
}
validatePollRequest(e) {
const t = [], r = [];
(!e.question || e.question.trim().length < 10) && t.push("Question must be at least 10 characters long"), (!e.options || e.options.length < 2) && t.push("Poll must have at least 2 options"), e.options && e.options.length > 10 && r.push("Polls with more than 10 options may be difficult to manage"), (!e.endTime || e.endTime <= /* @__PURE__ */ new Date()) && t.push("End time must be in the future"), e.endTime && e.endTime.getTime() - Date.now() < 36e5 && r.push("Polls ending in less than 1 hour may not get enough participation"), e.minimumStake && e.maximumStake && e.minimumStake >= e.maximumStake && t.push("Minimum stake must be less than maximum stake"), e.minimumStake && e.minimumStake <= 0 && t.push("Minimum stake must be positive");
const s = t.length === 0 ? r.length === 0 ? l.VERY_HIGH : l.HIGH : l.LOW;
return {
isValid: t.length === 0,
errors: t,
warnings: r,
confidence: s
};
}
}, $ = class {
config;
client;
providerConfig;
capabilities;
supportedCategories;
requestCount = 0;
lastRequestTime = 0;
rateLimitQueue = [];
constructor(e, t, r) {
this.config = e, this.client = t, this.providerConfig = r, this.capabilities = this.getProviderCapabilities(), this.supportedCategories = this.getSupportedCategories(), this.validateConfiguration();
}
// Optional methods that can be overridden
getDefaultTimeout() {
return this.providerConfig.timeout || 3e4;
}
getDefaultRetries() {
return this.providerConfig.retryAttempts || 3;
}
getCostPerQuery() {
return 0.01;
}
/**
* Main query method with built-in retries, rate limiting, and error handling
*/
async query(e, t = {}) {
if (this.validateRequest(e), !this.supportedCategories.includes(e.category))
throw new A(
`Category ${e.category} is not supported by ${this.getProviderName()}`,
this.getProviderName()
);
await this.applyRateLimit();
const r = Date.now(), s = t.retryAttempts ?? this.getDefaultRetries();
for (let a = 1; a <= s; a++)
try {
const n = await this.executeQueryWithTimeout(e, t);
return this.updateMetrics(!0, Date.now() - r), n;
} catch (n) {
if (a === s)
throw this.updateMetrics(!1, Date.now() - r), n;
if (n instanceof f)
throw n;
const o = Math.min(1e3 * Math.pow(2, a - 1), 1e4);
await new Promise((d) => setTimeout(d, o));
}
throw new A(`All retry attempts failed for ${this.getProviderName()}`, this.getProviderName());
}
/**
* Execute query with timeout protection
*/
async executeQueryWithTimeout(e, t) {
const r = t.timeout ?? this.getDefaultTimeout();
return Promise.race([
this.queryData(e, t),
new Promise((s, a) => {
setTimeout(
() => a(new H(`Query timeout after ${r}ms`, r)),
r
);
})
]);
}
/**
* Health check for the provider
*/
async healthCheck() {
try {
const e = {
query: "health_check",
category: u.CUSTOM
};
return await this.query(e, { timeout: 5e3 }), !0;
} catch {
return !1;
}
}
/**
* Get provider capabilities information
*/
getCapabilities() {
return {
provider: this.getProviderName(),
capabilities: this.capabilities,
supportedCategories: this.supportedCategories,
updateFrequencies: this.getSupportedUpdateFrequencies(),
costPerQuery: this.getCostPerQuery(),
averageResponseTimeMs: this.getAverageResponseTime(),
reliability: this.getReliability(),
accuracy: this.getAccuracy()
};
}
/**
* Get supported update frequencies
*/
getSupportedUpdateFrequencies() {
return [
D.ON_DEMAND,
D.MINUTE,
D.HOUR,
D.DAILY
];
}
/**
* Get provider statistics
*/
getStats() {
return {
requestCount: this.requestCount,
lastRequestTime: this.lastRequestTime,
averageResponseTime: this.getAverageResponseTime(),
reliability: this.getReliability()
};
}
/**
* Test provider connectivity
*/
async testConnection() {
const e = Date.now();
try {
const t = await this.client.get(this.getEndpointUrl(), {
timeout: 5e3
});
return {
connected: !0,
responseTime: Date.now() - e
};
} catch (t) {
return {
connected: !1,
error: t instanceof Error ? t.message : String(t)
};
}
}
/**
* Create standardized oracle data point
*/
createDataPoint(e, t, r = l.MEDIUM, s) {
return {
value: e,
timestamp: /* @__PURE__ */ new Date(),
source: `${this.getProviderName()}:${t}`,
confidence: r,
metadata: {
provider: this.getProviderName(),
...s
}
};
}
/**
* Parse and normalize response data
*/
normalizeResponse(e, t, r, s = !1) {
return {
data: (Array.isArray(e) ? e : [e]).map(
(n) => this.createDataPoint(n, "api", l.MEDIUM)
),
metadata: {
provider: this.getProviderName(),
responseTime: r,
cached: s,
confidence: l.MEDIUM,
cost: this.getCostPerQuery()
}
};
}
/**
* Validate request before processing
*/
validateRequest(e) {
if (!e.query || e.query.trim().length === 0)
throw new f("Query cannot be empty");
if (!Object.values(u).includes(e.category))
throw new f("Invalid data category");
}
/**
* Validate provider configuration
*/
validateConfiguration() {
const e = xe(this.providerConfig);
if (!e.isValid)
throw new f(
`Invalid provider configuration: ${e.errors.join(", ")}`
);
}
/**
* Apply rate limiting
*/
async applyRateLimit() {
if (!this.providerConfig.rateLimit) return;
const t = Date.now() - this.lastRequestTime, r = 60 * 1e3 / this.providerConfig.rateLimit;
if (t < r) {
const s = r - t;
await new Promise((a) => setTimeout(a, s));
}
}
/**
* Update request metrics
*/
updateMetrics(e, t) {
this.requestCount++, this.lastRequestTime = Date.now()