@general-liquidity/gordon-cli 0.75.4 → 0.75.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gordon.js +1546 -37
- package/package.json +1 -1
package/dist/gordon.js
CHANGED
|
@@ -14414,7 +14414,9 @@ async function checkEnvStatus() {
|
|
|
14414
14414
|
KRAKEN_API_SECRET: process.env.KRAKEN_API_SECRET,
|
|
14415
14415
|
BITFINEX_API_KEY: process.env.BITFINEX_API_KEY,
|
|
14416
14416
|
BITFINEX_API_SECRET: process.env.BITFINEX_API_SECRET,
|
|
14417
|
-
HYPERLIQUID_PRIVATE_KEY: process.env.HYPERLIQUID_PRIVATE_KEY
|
|
14417
|
+
HYPERLIQUID_PRIVATE_KEY: process.env.HYPERLIQUID_PRIVATE_KEY,
|
|
14418
|
+
UNISWAP_API_KEY: process.env.UNISWAP_API_KEY,
|
|
14419
|
+
THEGRAPH_API_KEY: process.env.THEGRAPH_API_KEY
|
|
14418
14420
|
};
|
|
14419
14421
|
return {
|
|
14420
14422
|
fileExists: false,
|
|
@@ -14425,6 +14427,8 @@ async function checkEnvStatus() {
|
|
|
14425
14427
|
hasKrakenKeys: !!(keys2.KRAKEN_API_KEY && keys2.KRAKEN_API_SECRET),
|
|
14426
14428
|
hasBitfinexKeys: !!(keys2.BITFINEX_API_KEY && keys2.BITFINEX_API_SECRET),
|
|
14427
14429
|
hasHyperliquidKey: !!keys2.HYPERLIQUID_PRIVATE_KEY,
|
|
14430
|
+
hasUniswapKey: !!keys2.UNISWAP_API_KEY,
|
|
14431
|
+
hasGraphKey: !!keys2.THEGRAPH_API_KEY,
|
|
14428
14432
|
keys: keys2
|
|
14429
14433
|
};
|
|
14430
14434
|
}
|
|
@@ -14445,7 +14449,9 @@ async function checkEnvStatus() {
|
|
|
14445
14449
|
KRAKEN_API_SECRET: parsed.KRAKEN_API_SECRET || process.env.KRAKEN_API_SECRET,
|
|
14446
14450
|
BITFINEX_API_KEY: parsed.BITFINEX_API_KEY || process.env.BITFINEX_API_KEY,
|
|
14447
14451
|
BITFINEX_API_SECRET: parsed.BITFINEX_API_SECRET || process.env.BITFINEX_API_SECRET,
|
|
14448
|
-
HYPERLIQUID_PRIVATE_KEY: parsed.HYPERLIQUID_PRIVATE_KEY || process.env.HYPERLIQUID_PRIVATE_KEY
|
|
14452
|
+
HYPERLIQUID_PRIVATE_KEY: parsed.HYPERLIQUID_PRIVATE_KEY || process.env.HYPERLIQUID_PRIVATE_KEY,
|
|
14453
|
+
UNISWAP_API_KEY: parsed.UNISWAP_API_KEY || process.env.UNISWAP_API_KEY,
|
|
14454
|
+
THEGRAPH_API_KEY: parsed.THEGRAPH_API_KEY || process.env.THEGRAPH_API_KEY
|
|
14449
14455
|
};
|
|
14450
14456
|
return {
|
|
14451
14457
|
fileExists: true,
|
|
@@ -14456,6 +14462,8 @@ async function checkEnvStatus() {
|
|
|
14456
14462
|
hasKrakenKeys: !!(keys.KRAKEN_API_KEY && keys.KRAKEN_API_SECRET),
|
|
14457
14463
|
hasBitfinexKeys: !!(keys.BITFINEX_API_KEY && keys.BITFINEX_API_SECRET),
|
|
14458
14464
|
hasHyperliquidKey: !!keys.HYPERLIQUID_PRIVATE_KEY,
|
|
14465
|
+
hasUniswapKey: !!keys.UNISWAP_API_KEY,
|
|
14466
|
+
hasGraphKey: !!keys.THEGRAPH_API_KEY,
|
|
14459
14467
|
keys
|
|
14460
14468
|
};
|
|
14461
14469
|
}
|
|
@@ -195777,6 +195785,9 @@ var init_hyperliquid3 = __esm(() => {
|
|
|
195777
195785
|
});
|
|
195778
195786
|
|
|
195779
195787
|
// src/infra/uniswap/types.ts
|
|
195788
|
+
function isUniswapXRouting(routing) {
|
|
195789
|
+
return ["DUTCH_V2", "DUTCH_V3", "DUTCH_LIMIT", "PRIORITY"].includes(routing);
|
|
195790
|
+
}
|
|
195780
195791
|
var NATIVE_TOKEN = "0x0000000000000000000000000000000000000000", GAS_BUFFER_PERCENT = 0.15, WRAPPED_NATIVE, USDC_ADDRESSES, SUPPORTED_CHAIN_IDS, CHAIN_NAMES;
|
|
195781
195792
|
var init_types10 = __esm(() => {
|
|
195782
195793
|
WRAPPED_NATIVE = {
|
|
@@ -195797,13 +195808,14 @@ var init_types10 = __esm(() => {
|
|
|
195797
195808
|
42161: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
|
|
195798
195809
|
43114: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"
|
|
195799
195810
|
};
|
|
195800
|
-
SUPPORTED_CHAIN_IDS = [1, 10, 56, 130, 137, 196, 324, 480, 1868, 8453, 42161, 42220, 43114, 81457, 7777777];
|
|
195811
|
+
SUPPORTED_CHAIN_IDS = [1, 10, 56, 130, 137, 143, 196, 324, 480, 1868, 8453, 42161, 42220, 43114, 81457, 7777777];
|
|
195801
195812
|
CHAIN_NAMES = {
|
|
195802
195813
|
1: "Ethereum",
|
|
195803
195814
|
10: "Optimism",
|
|
195804
195815
|
56: "BNB Chain",
|
|
195805
195816
|
130: "Unichain",
|
|
195806
195817
|
137: "Polygon",
|
|
195818
|
+
143: "Monad",
|
|
195807
195819
|
196: "X Layer",
|
|
195808
195820
|
324: "zkSync",
|
|
195809
195821
|
480: "World Chain",
|
|
@@ -196193,23 +196205,779 @@ var init_client9 = __esm(() => {
|
|
|
196193
196205
|
};
|
|
196194
196206
|
});
|
|
196195
196207
|
|
|
196208
|
+
// src/infra/uniswap/subgraph-types.ts
|
|
196209
|
+
var V3_SUBGRAPH_IDS;
|
|
196210
|
+
var init_subgraph_types = __esm(() => {
|
|
196211
|
+
V3_SUBGRAPH_IDS = {
|
|
196212
|
+
1: "5zvR82QoaXYFyDEKLZ9t6v9adgnptxYpKpSbxtgVENFV",
|
|
196213
|
+
10: "Cghf4LfVqPiFw6fp6Y5X5Ubc8UpmUhSfJL82zwiBFLaj",
|
|
196214
|
+
56: "F85MNzUGYqgSHSHRGgeVMNsdnW1KtZSVgFULumXRZTw2",
|
|
196215
|
+
137: "3hCPRGf4z88VC5rsBKU5AA9FBBq5nF3jbKJG7VZCbhjm",
|
|
196216
|
+
8453: "43Hwfi3dJSoGpyas9VwNoDAv55yjgGrPpNSmbQZArzMG",
|
|
196217
|
+
42161: "FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM",
|
|
196218
|
+
42220: "ESdrTJ3twMwWVoQ1hUE2u7PugEHX3QkenudD6aXCkDQ4",
|
|
196219
|
+
43114: "GVH9h9KZ9CqheUEL93qMbq7QwgoBu32QXQDPR6bev4Eo",
|
|
196220
|
+
81457: "2LHovKznvo8YmKC9ZprPjsYAZDCc4K5q4AYz8s3cnQn1"
|
|
196221
|
+
};
|
|
196222
|
+
});
|
|
196223
|
+
|
|
196224
|
+
// src/infra/uniswap/subgraph.ts
|
|
196225
|
+
class UniswapSubgraph {
|
|
196226
|
+
apiKey;
|
|
196227
|
+
chainId;
|
|
196228
|
+
client;
|
|
196229
|
+
endpointUrl;
|
|
196230
|
+
poolCache = new Cache({ defaultTtl: CACHE_TTL.pool, maxEntries: 100 });
|
|
196231
|
+
dataCache = new Cache({ defaultTtl: CACHE_TTL.candles, maxEntries: 500 });
|
|
196232
|
+
requestCount = 0;
|
|
196233
|
+
lastResetTime = Date.now();
|
|
196234
|
+
throttledCount = 0;
|
|
196235
|
+
circuitState = "closed";
|
|
196236
|
+
consecutiveFailures = 0;
|
|
196237
|
+
circuitOpenedAt = 0;
|
|
196238
|
+
constructor(apiKey, chainId, client) {
|
|
196239
|
+
this.apiKey = apiKey;
|
|
196240
|
+
this.chainId = chainId;
|
|
196241
|
+
this.client = client;
|
|
196242
|
+
const subgraphId = V3_SUBGRAPH_IDS[chainId];
|
|
196243
|
+
this.endpointUrl = subgraphId ? `${GRAPH_GATEWAY}/subgraphs/id/${subgraphId}` : null;
|
|
196244
|
+
}
|
|
196245
|
+
isAvailable() {
|
|
196246
|
+
if (!this.endpointUrl)
|
|
196247
|
+
return false;
|
|
196248
|
+
if (this.circuitState === "open") {
|
|
196249
|
+
if (Date.now() - this.circuitOpenedAt > CIRCUIT_RESET_MS) {
|
|
196250
|
+
this.circuitState = "half-open";
|
|
196251
|
+
return true;
|
|
196252
|
+
}
|
|
196253
|
+
return false;
|
|
196254
|
+
}
|
|
196255
|
+
return true;
|
|
196256
|
+
}
|
|
196257
|
+
async checkRateLimit() {
|
|
196258
|
+
const now2 = Date.now();
|
|
196259
|
+
if (now2 - this.lastResetTime > 60000) {
|
|
196260
|
+
this.requestCount = 0;
|
|
196261
|
+
this.lastResetTime = now2;
|
|
196262
|
+
this.throttledCount = 0;
|
|
196263
|
+
}
|
|
196264
|
+
if (this.requestCount >= RATE_LIMIT.maxPerMinute) {
|
|
196265
|
+
const waitMs = 60000 - (now2 - this.lastResetTime);
|
|
196266
|
+
throw new Error(`Subgraph rate limit reached (${RATE_LIMIT.maxPerMinute}/min). Retry in ${Math.ceil(waitMs / 1000)}s.`);
|
|
196267
|
+
}
|
|
196268
|
+
if (this.requestCount >= RATE_LIMIT.throttleAt) {
|
|
196269
|
+
const delayMs = 500 * (this.requestCount - RATE_LIMIT.throttleAt + 1);
|
|
196270
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
196271
|
+
this.throttledCount++;
|
|
196272
|
+
}
|
|
196273
|
+
}
|
|
196274
|
+
async query(graphql, variables = {}) {
|
|
196275
|
+
if (!this.endpointUrl) {
|
|
196276
|
+
throw new Error(`No V3 subgraph available for chain ${this.chainId}`);
|
|
196277
|
+
}
|
|
196278
|
+
if (this.circuitState === "open" && !this.isAvailable()) {
|
|
196279
|
+
throw new Error("Subgraph circuit breaker is open");
|
|
196280
|
+
}
|
|
196281
|
+
await this.checkRateLimit();
|
|
196282
|
+
this.requestCount++;
|
|
196283
|
+
let lastError = null;
|
|
196284
|
+
for (let attempt = 0;attempt <= MAX_RETRIES3; attempt++) {
|
|
196285
|
+
if (attempt > 0) {
|
|
196286
|
+
const delay5 = BASE_DELAY_MS2 * 2 ** (attempt - 1);
|
|
196287
|
+
await new Promise((r) => setTimeout(r, delay5));
|
|
196288
|
+
}
|
|
196289
|
+
try {
|
|
196290
|
+
const url2 = `${GRAPH_GATEWAY}/${this.apiKey}${this.endpointUrl}`;
|
|
196291
|
+
const res = await fetch(url2, {
|
|
196292
|
+
method: "POST",
|
|
196293
|
+
headers: { "Content-Type": "application/json" },
|
|
196294
|
+
body: JSON.stringify({ query: graphql, variables })
|
|
196295
|
+
});
|
|
196296
|
+
if (res.ok) {
|
|
196297
|
+
const json3 = await res.json();
|
|
196298
|
+
if (json3.errors?.length) {
|
|
196299
|
+
throw new Error(`Subgraph error: ${json3.errors.map((e2) => e2.message).join("; ")}`);
|
|
196300
|
+
}
|
|
196301
|
+
this.consecutiveFailures = 0;
|
|
196302
|
+
if (this.circuitState === "half-open")
|
|
196303
|
+
this.circuitState = "closed";
|
|
196304
|
+
return json3.data;
|
|
196305
|
+
}
|
|
196306
|
+
const errBody = await res.text().catch(() => "");
|
|
196307
|
+
if ([429, 500, 503].includes(res.status) && attempt < MAX_RETRIES3) {
|
|
196308
|
+
if (res.status === 429)
|
|
196309
|
+
this.throttledCount++;
|
|
196310
|
+
lastError = new Error(`Subgraph HTTP ${res.status}: ${errBody}`);
|
|
196311
|
+
continue;
|
|
196312
|
+
}
|
|
196313
|
+
this.onFailure();
|
|
196314
|
+
throw new Error(`Subgraph HTTP ${res.status}: ${errBody}`);
|
|
196315
|
+
} catch (err) {
|
|
196316
|
+
if (err instanceof Error && err.message.startsWith("Subgraph"))
|
|
196317
|
+
throw err;
|
|
196318
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
196319
|
+
if (attempt >= MAX_RETRIES3) {
|
|
196320
|
+
this.onFailure();
|
|
196321
|
+
throw lastError;
|
|
196322
|
+
}
|
|
196323
|
+
}
|
|
196324
|
+
}
|
|
196325
|
+
throw lastError || new Error("Subgraph request failed");
|
|
196326
|
+
}
|
|
196327
|
+
onFailure() {
|
|
196328
|
+
this.consecutiveFailures++;
|
|
196329
|
+
if (this.consecutiveFailures >= CIRCUIT_FAILURE_THRESHOLD) {
|
|
196330
|
+
this.circuitState = "open";
|
|
196331
|
+
this.circuitOpenedAt = Date.now();
|
|
196332
|
+
}
|
|
196333
|
+
}
|
|
196334
|
+
async resolvePool(symbol16) {
|
|
196335
|
+
const cacheKey = `pool:${this.chainId}:${symbol16}`;
|
|
196336
|
+
const cached2 = this.poolCache.get(cacheKey);
|
|
196337
|
+
if (cached2)
|
|
196338
|
+
return cached2;
|
|
196339
|
+
const { tokenIn, tokenOut } = await this.client.resolveSymbol(symbol16);
|
|
196340
|
+
const inLower = tokenIn.toLowerCase();
|
|
196341
|
+
const outLower = tokenOut.toLowerCase();
|
|
196342
|
+
const [t0, t1] = inLower < outLower ? [inLower, outLower] : [outLower, inLower];
|
|
196343
|
+
const isInverted = inLower !== t0;
|
|
196344
|
+
const data = await this.query(`query($t0: String!, $t1: String!) {
|
|
196345
|
+
pools(
|
|
196346
|
+
first: 1
|
|
196347
|
+
where: { token0: $t0, token1: $t1 }
|
|
196348
|
+
orderBy: liquidity
|
|
196349
|
+
orderDirection: desc
|
|
196350
|
+
) {
|
|
196351
|
+
id feeTier liquidity sqrtPrice tick
|
|
196352
|
+
token0Price token1Price
|
|
196353
|
+
totalValueLockedUSD volumeUSD
|
|
196354
|
+
token0 { id symbol name decimals }
|
|
196355
|
+
token1 { id symbol name decimals }
|
|
196356
|
+
}
|
|
196357
|
+
}`, { t0, t1 });
|
|
196358
|
+
if (!data.pools.length) {
|
|
196359
|
+
throw new Error(`No Uniswap V3 pool found for ${symbol16} on chain ${this.chainId}`);
|
|
196360
|
+
}
|
|
196361
|
+
const resolved = { pool: data.pools[0], isInverted };
|
|
196362
|
+
this.poolCache.set(cacheKey, resolved, CACHE_TTL.pool);
|
|
196363
|
+
return resolved;
|
|
196364
|
+
}
|
|
196365
|
+
getPoolPrice(pool, isInverted) {
|
|
196366
|
+
return isInverted ? parseFloat(pool.token1Price) : parseFloat(pool.token0Price);
|
|
196367
|
+
}
|
|
196368
|
+
async getCandles(symbol16, interval, limit) {
|
|
196369
|
+
const { pool, isInverted } = await this.resolvePool(symbol16);
|
|
196370
|
+
const useHourly = ["1m", "5m", "15m", "30m", "1h", "4h"].includes(interval);
|
|
196371
|
+
const intervalSeconds = useHourly ? 3600 : 86400;
|
|
196372
|
+
const start = Math.floor(Date.now() / 1000) - limit * intervalSeconds;
|
|
196373
|
+
const cacheKey = `candle:${this.chainId}:${pool.id}:${interval}:${limit}`;
|
|
196374
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196375
|
+
if (cached2)
|
|
196376
|
+
return cached2;
|
|
196377
|
+
let candles;
|
|
196378
|
+
if (useHourly) {
|
|
196379
|
+
const data = await this.query(`query($pool: String!, $start: Int!, $first: Int!) {
|
|
196380
|
+
poolHourDatas(
|
|
196381
|
+
first: $first
|
|
196382
|
+
where: { pool: $pool, periodStartUnix_gte: $start }
|
|
196383
|
+
orderBy: periodStartUnix
|
|
196384
|
+
orderDirection: asc
|
|
196385
|
+
) {
|
|
196386
|
+
periodStartUnix open high low close
|
|
196387
|
+
volumeUSD volumeToken0 volumeToken1 tvlUSD
|
|
196388
|
+
token0Price token1Price
|
|
196389
|
+
}
|
|
196390
|
+
}`, { pool: pool.id, start, first: Math.min(limit, 1000) });
|
|
196391
|
+
candles = data.poolHourDatas.map((d) => this.mapCandle(d.periodStartUnix, intervalSeconds, d, isInverted));
|
|
196392
|
+
} else {
|
|
196393
|
+
const data = await this.query(`query($pool: String!, $start: Int!, $first: Int!) {
|
|
196394
|
+
poolDayDatas(
|
|
196395
|
+
first: $first
|
|
196396
|
+
where: { pool: $pool, date_gte: $start }
|
|
196397
|
+
orderBy: date
|
|
196398
|
+
orderDirection: asc
|
|
196399
|
+
) {
|
|
196400
|
+
date open high low close
|
|
196401
|
+
volumeUSD volumeToken0 volumeToken1 tvlUSD
|
|
196402
|
+
token0Price token1Price
|
|
196403
|
+
}
|
|
196404
|
+
}`, { pool: pool.id, start, first: Math.min(limit, 1000) });
|
|
196405
|
+
candles = data.poolDayDatas.map((d) => this.mapCandle(d.date, intervalSeconds, d, isInverted));
|
|
196406
|
+
}
|
|
196407
|
+
this.dataCache.set(cacheKey, candles, CACHE_TTL.candles);
|
|
196408
|
+
return candles;
|
|
196409
|
+
}
|
|
196410
|
+
mapCandle(timestamp, intervalSec, d, isInverted) {
|
|
196411
|
+
let open = parseFloat(d.open);
|
|
196412
|
+
let high = parseFloat(d.high);
|
|
196413
|
+
let low = parseFloat(d.low);
|
|
196414
|
+
let close = parseFloat(d.close);
|
|
196415
|
+
if (open === 0 && close === 0) {
|
|
196416
|
+
const price = isInverted ? parseFloat(d.token1Price) : parseFloat(d.token0Price);
|
|
196417
|
+
open = high = low = close = price;
|
|
196418
|
+
} else if (isInverted && open !== 0 && high !== 0 && low !== 0 && close !== 0) {
|
|
196419
|
+
const iOpen = 1 / open;
|
|
196420
|
+
const iHigh = 1 / low;
|
|
196421
|
+
const iLow = 1 / high;
|
|
196422
|
+
const iClose = 1 / close;
|
|
196423
|
+
open = iOpen;
|
|
196424
|
+
high = iHigh;
|
|
196425
|
+
low = iLow;
|
|
196426
|
+
close = iClose;
|
|
196427
|
+
} else if (isInverted) {
|
|
196428
|
+
const price = parseFloat(d.token1Price);
|
|
196429
|
+
if (price !== 0) {
|
|
196430
|
+
open = high = low = close = price;
|
|
196431
|
+
}
|
|
196432
|
+
}
|
|
196433
|
+
return {
|
|
196434
|
+
openTime: timestamp * 1000,
|
|
196435
|
+
open,
|
|
196436
|
+
high,
|
|
196437
|
+
low,
|
|
196438
|
+
close,
|
|
196439
|
+
volume: parseFloat(d.volumeUSD),
|
|
196440
|
+
closeTime: (timestamp + intervalSec) * 1000 - 1
|
|
196441
|
+
};
|
|
196442
|
+
}
|
|
196443
|
+
async get24hrTickers(limit = 100) {
|
|
196444
|
+
const cacheKey = `tickers:${this.chainId}:${limit}`;
|
|
196445
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196446
|
+
if (cached2)
|
|
196447
|
+
return cached2;
|
|
196448
|
+
const fetchLimit = Math.min(limit + 15, 200);
|
|
196449
|
+
const data = await this.query(`query($first: Int!) {
|
|
196450
|
+
tokens(
|
|
196451
|
+
first: $first
|
|
196452
|
+
orderBy: volumeUSD
|
|
196453
|
+
orderDirection: desc
|
|
196454
|
+
where: { volumeUSD_gt: "1000" }
|
|
196455
|
+
) {
|
|
196456
|
+
id symbol name
|
|
196457
|
+
volumeUSD totalValueLockedUSD
|
|
196458
|
+
tokenDayDatas(first: 2, orderBy: date, orderDirection: desc) {
|
|
196459
|
+
date priceUSD volumeUSD
|
|
196460
|
+
open high low close
|
|
196461
|
+
}
|
|
196462
|
+
}
|
|
196463
|
+
}`, { first: fetchLimit });
|
|
196464
|
+
const now2 = Date.now();
|
|
196465
|
+
const tickers = [];
|
|
196466
|
+
for (const token of data.tokens) {
|
|
196467
|
+
if (STABLECOIN_SYMBOLS.has(token.symbol.toUpperCase()))
|
|
196468
|
+
continue;
|
|
196469
|
+
if (token.tokenDayDatas.length === 0)
|
|
196470
|
+
continue;
|
|
196471
|
+
const today = token.tokenDayDatas[0];
|
|
196472
|
+
const yesterday = token.tokenDayDatas[1];
|
|
196473
|
+
const todayPrice = parseFloat(today.priceUSD);
|
|
196474
|
+
const yesterdayPrice = yesterday ? parseFloat(yesterday.priceUSD) : todayPrice;
|
|
196475
|
+
const priceChange = todayPrice - yesterdayPrice;
|
|
196476
|
+
const priceChangePercent = yesterdayPrice !== 0 ? priceChange / yesterdayPrice * 100 : 0;
|
|
196477
|
+
const highPrice = parseFloat(today.high) || todayPrice;
|
|
196478
|
+
const lowPrice = parseFloat(today.low) || todayPrice;
|
|
196479
|
+
tickers.push({
|
|
196480
|
+
symbol: `${token.symbol.toUpperCase()}USDC`,
|
|
196481
|
+
priceChange,
|
|
196482
|
+
priceChangePercent,
|
|
196483
|
+
lastPrice: todayPrice,
|
|
196484
|
+
highPrice,
|
|
196485
|
+
lowPrice,
|
|
196486
|
+
volume: parseFloat(today.volumeUSD),
|
|
196487
|
+
quoteVolume: parseFloat(today.volumeUSD),
|
|
196488
|
+
openTime: today.date * 1000,
|
|
196489
|
+
closeTime: now2
|
|
196490
|
+
});
|
|
196491
|
+
if (tickers.length >= limit)
|
|
196492
|
+
break;
|
|
196493
|
+
}
|
|
196494
|
+
this.dataCache.set(cacheKey, tickers, CACHE_TTL.tickers);
|
|
196495
|
+
return tickers;
|
|
196496
|
+
}
|
|
196497
|
+
async getTopSymbols(n) {
|
|
196498
|
+
const cacheKey = `top:${this.chainId}:${n}`;
|
|
196499
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196500
|
+
if (cached2)
|
|
196501
|
+
return cached2;
|
|
196502
|
+
const fetchN = Math.min(n + 10, 100);
|
|
196503
|
+
const data = await this.query(`query($first: Int!) {
|
|
196504
|
+
tokens(
|
|
196505
|
+
first: $first
|
|
196506
|
+
orderBy: volumeUSD
|
|
196507
|
+
orderDirection: desc
|
|
196508
|
+
where: { volumeUSD_gt: "1000" }
|
|
196509
|
+
) {
|
|
196510
|
+
id symbol
|
|
196511
|
+
}
|
|
196512
|
+
}`, { first: fetchN });
|
|
196513
|
+
const symbols = [];
|
|
196514
|
+
for (const token of data.tokens) {
|
|
196515
|
+
const sym = token.symbol.toUpperCase();
|
|
196516
|
+
if (STABLECOIN_SYMBOLS.has(sym))
|
|
196517
|
+
continue;
|
|
196518
|
+
if (sym === "WETH" || sym === "WBTC") {
|
|
196519
|
+
symbols.push(`${sym.slice(1)}USDC`);
|
|
196520
|
+
} else {
|
|
196521
|
+
symbols.push(`${sym}USDC`);
|
|
196522
|
+
}
|
|
196523
|
+
if (symbols.length >= n)
|
|
196524
|
+
break;
|
|
196525
|
+
}
|
|
196526
|
+
this.dataCache.set(cacheKey, symbols, CACHE_TTL.top);
|
|
196527
|
+
return symbols;
|
|
196528
|
+
}
|
|
196529
|
+
async getTradeHistory(symbol16, limit) {
|
|
196530
|
+
const { pool, isInverted } = await this.resolvePool(symbol16);
|
|
196531
|
+
const cacheKey = `trades:${this.chainId}:${pool.id}:${limit}`;
|
|
196532
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196533
|
+
if (cached2)
|
|
196534
|
+
return cached2;
|
|
196535
|
+
const data = await this.query(`query($pool: String!, $first: Int!) {
|
|
196536
|
+
swaps(
|
|
196537
|
+
first: $first
|
|
196538
|
+
where: { pool: $pool }
|
|
196539
|
+
orderBy: timestamp
|
|
196540
|
+
orderDirection: desc
|
|
196541
|
+
) {
|
|
196542
|
+
id timestamp
|
|
196543
|
+
amount0 amount1 amountUSD
|
|
196544
|
+
sender recipient
|
|
196545
|
+
sqrtPriceX96 tick
|
|
196546
|
+
}
|
|
196547
|
+
}`, { pool: pool.id, first: Math.min(limit, 1000) });
|
|
196548
|
+
const trades = data.swaps.map((swap) => {
|
|
196549
|
+
const amount0 = parseFloat(swap.amount0);
|
|
196550
|
+
const amount1 = parseFloat(swap.amount1);
|
|
196551
|
+
const amountUSD = parseFloat(swap.amountUSD);
|
|
196552
|
+
const baseAmount = isInverted ? amount1 : amount0;
|
|
196553
|
+
const side = baseAmount > 0 ? "SELL" : "BUY";
|
|
196554
|
+
const quantity = Math.abs(baseAmount);
|
|
196555
|
+
const price = amountUSD > 0 && quantity > 0 ? amountUSD / quantity : quantity > 0 ? this.getPoolPrice(pool, isInverted) : 0;
|
|
196556
|
+
return {
|
|
196557
|
+
id: swap.id,
|
|
196558
|
+
orderId: swap.id,
|
|
196559
|
+
symbol: symbol16,
|
|
196560
|
+
side,
|
|
196561
|
+
price,
|
|
196562
|
+
quantity,
|
|
196563
|
+
commission: 0,
|
|
196564
|
+
commissionAsset: "USD",
|
|
196565
|
+
time: parseInt(swap.timestamp, 10) * 1000,
|
|
196566
|
+
isMaker: false
|
|
196567
|
+
};
|
|
196568
|
+
});
|
|
196569
|
+
this.dataCache.set(cacheKey, trades, CACHE_TTL.trades);
|
|
196570
|
+
return trades;
|
|
196571
|
+
}
|
|
196572
|
+
async getPoolData(symbol16) {
|
|
196573
|
+
const { pool, isInverted } = await this.resolvePool(symbol16);
|
|
196574
|
+
const cacheKey = `poolData:${this.chainId}:${pool.id}`;
|
|
196575
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196576
|
+
if (cached2)
|
|
196577
|
+
return cached2;
|
|
196578
|
+
const data = await this.query(`query($id: ID!) {
|
|
196579
|
+
pool(id: $id) {
|
|
196580
|
+
id feeTier liquidity sqrtPrice tick
|
|
196581
|
+
token0Price token1Price
|
|
196582
|
+
totalValueLockedUSD volumeUSD
|
|
196583
|
+
token0 { id symbol name decimals }
|
|
196584
|
+
token1 { id symbol name decimals }
|
|
196585
|
+
}
|
|
196586
|
+
}`, { id: pool.id });
|
|
196587
|
+
if (!data.pool)
|
|
196588
|
+
throw new Error(`Pool ${pool.id} not found`);
|
|
196589
|
+
const result = {
|
|
196590
|
+
price: this.getPoolPrice(data.pool, isInverted),
|
|
196591
|
+
feeTier: parseInt(data.pool.feeTier, 10),
|
|
196592
|
+
tvlUSD: parseFloat(data.pool.totalValueLockedUSD),
|
|
196593
|
+
liquidity: data.pool.liquidity
|
|
196594
|
+
};
|
|
196595
|
+
this.dataCache.set(cacheKey, result, CACHE_TTL.poolData);
|
|
196596
|
+
return result;
|
|
196597
|
+
}
|
|
196598
|
+
async getOrderBook(symbol16) {
|
|
196599
|
+
const { pool, isInverted } = await this.resolvePool(symbol16);
|
|
196600
|
+
const { price, feeTier, tvlUSD } = await this.getPoolData(symbol16);
|
|
196601
|
+
const spreadFraction = feeTier / 1e6;
|
|
196602
|
+
const halfSpread = price * spreadFraction / 2;
|
|
196603
|
+
try {
|
|
196604
|
+
const ticks = await this.getTickLiquidity(symbol16, 10);
|
|
196605
|
+
if (ticks.length > 0) {
|
|
196606
|
+
const freshPool = await this.getPoolData(symbol16);
|
|
196607
|
+
const bids = [];
|
|
196608
|
+
const asks = [];
|
|
196609
|
+
for (const tick of ticks) {
|
|
196610
|
+
const tickIdx = parseInt(tick.tickIdx, 10);
|
|
196611
|
+
const liqNet = parseFloat(tick.liquidityNet);
|
|
196612
|
+
if (liqNet === 0)
|
|
196613
|
+
continue;
|
|
196614
|
+
const tickPrice = isInverted ? parseFloat(tick.price1) : parseFloat(tick.price0);
|
|
196615
|
+
const liquidityScore = Math.abs(liqNet);
|
|
196616
|
+
if (tickPrice <= freshPool.price) {
|
|
196617
|
+
bids.push({ price: tickPrice, quantity: liquidityScore });
|
|
196618
|
+
} else {
|
|
196619
|
+
asks.push({ price: tickPrice, quantity: liquidityScore });
|
|
196620
|
+
}
|
|
196621
|
+
}
|
|
196622
|
+
if (bids.length > 0 || asks.length > 0) {
|
|
196623
|
+
bids.sort((a, b) => b.price - a.price);
|
|
196624
|
+
asks.sort((a, b) => a.price - b.price);
|
|
196625
|
+
return { lastUpdateId: Date.now(), bids, asks };
|
|
196626
|
+
}
|
|
196627
|
+
}
|
|
196628
|
+
} catch {}
|
|
196629
|
+
const depthProxy = tvlUSD / 2;
|
|
196630
|
+
return {
|
|
196631
|
+
lastUpdateId: Date.now(),
|
|
196632
|
+
bids: [{ price: price - halfSpread, quantity: depthProxy / price }],
|
|
196633
|
+
asks: [{ price: price + halfSpread, quantity: depthProxy / price }]
|
|
196634
|
+
};
|
|
196635
|
+
}
|
|
196636
|
+
async getBookTicker(symbol16) {
|
|
196637
|
+
const { price, feeTier, tvlUSD } = await this.getPoolData(symbol16);
|
|
196638
|
+
const spreadFraction = feeTier / 1e6;
|
|
196639
|
+
const halfSpread = price * spreadFraction / 2;
|
|
196640
|
+
const depthProxy = tvlUSD / 2;
|
|
196641
|
+
return {
|
|
196642
|
+
symbol: symbol16,
|
|
196643
|
+
bidPrice: price - halfSpread,
|
|
196644
|
+
bidQty: depthProxy / price,
|
|
196645
|
+
askPrice: price + halfSpread,
|
|
196646
|
+
askQty: depthProxy / price
|
|
196647
|
+
};
|
|
196648
|
+
}
|
|
196649
|
+
async getSpread(symbol16) {
|
|
196650
|
+
const { price, feeTier } = await this.getPoolData(symbol16);
|
|
196651
|
+
const spreadFraction = feeTier / 1e6;
|
|
196652
|
+
const spread = price * spreadFraction;
|
|
196653
|
+
return {
|
|
196654
|
+
spread,
|
|
196655
|
+
spreadPercent: spreadFraction * 100,
|
|
196656
|
+
bidPrice: price - spread / 2,
|
|
196657
|
+
askPrice: price + spread / 2
|
|
196658
|
+
};
|
|
196659
|
+
}
|
|
196660
|
+
async getAvgPrice(symbol16) {
|
|
196661
|
+
const { price } = await this.getPoolData(symbol16);
|
|
196662
|
+
return { mins: 5, price };
|
|
196663
|
+
}
|
|
196664
|
+
async getEthPrice() {
|
|
196665
|
+
const cacheKey = `bundle:${this.chainId}`;
|
|
196666
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196667
|
+
if (cached2 !== undefined)
|
|
196668
|
+
return cached2;
|
|
196669
|
+
const data = await this.query(`{ bundle(id: "1") { id ethPriceUSD } }`);
|
|
196670
|
+
const price = data.bundle ? parseFloat(data.bundle.ethPriceUSD) : NaN;
|
|
196671
|
+
if (isNaN(price) || price <= 0) {
|
|
196672
|
+
throw new Error(`Unable to fetch ETH price from bundle on chain ${this.chainId}`);
|
|
196673
|
+
}
|
|
196674
|
+
this.dataCache.set(cacheKey, price, CACHE_TTL.bundle);
|
|
196675
|
+
return price;
|
|
196676
|
+
}
|
|
196677
|
+
async getFactory() {
|
|
196678
|
+
const cacheKey = `factory:${this.chainId}`;
|
|
196679
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196680
|
+
if (cached2 !== undefined)
|
|
196681
|
+
return cached2;
|
|
196682
|
+
const data = await this.query(`{ factory(id: "1") {
|
|
196683
|
+
id poolCount txCount
|
|
196684
|
+
totalVolumeUSD totalVolumeETH
|
|
196685
|
+
totalFeesUSD totalFeesETH
|
|
196686
|
+
totalValueLockedUSD totalValueLockedETH
|
|
196687
|
+
owner
|
|
196688
|
+
} }`);
|
|
196689
|
+
this.dataCache.set(cacheKey, data.factory, CACHE_TTL.protocol);
|
|
196690
|
+
return data.factory;
|
|
196691
|
+
}
|
|
196692
|
+
async getTokenHourCandles(tokenAddress, limit = 168) {
|
|
196693
|
+
const addr = tokenAddress.toLowerCase();
|
|
196694
|
+
const cacheKey = `tokenHour:${this.chainId}:${addr}:${limit}`;
|
|
196695
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196696
|
+
if (cached2)
|
|
196697
|
+
return cached2;
|
|
196698
|
+
const start = Math.floor(Date.now() / 1000) - limit * 3600;
|
|
196699
|
+
const data = await this.query(`query($token: String!, $start: Int!, $first: Int!) {
|
|
196700
|
+
tokenHourDatas(
|
|
196701
|
+
first: $first
|
|
196702
|
+
where: { token: $token, periodStartUnix_gte: $start }
|
|
196703
|
+
orderBy: periodStartUnix
|
|
196704
|
+
orderDirection: asc
|
|
196705
|
+
) {
|
|
196706
|
+
periodStartUnix
|
|
196707
|
+
open high low close
|
|
196708
|
+
priceUSD volumeUSD feesUSD
|
|
196709
|
+
totalValueLockedUSD
|
|
196710
|
+
token { id }
|
|
196711
|
+
}
|
|
196712
|
+
}`, { token: addr, start, first: Math.min(limit, 1000) });
|
|
196713
|
+
const candles = data.tokenHourDatas.map((d) => {
|
|
196714
|
+
const fallback = parseFloat(d.priceUSD);
|
|
196715
|
+
const openVal = parseFloat(d.open);
|
|
196716
|
+
const highVal = parseFloat(d.high);
|
|
196717
|
+
const lowVal = parseFloat(d.low);
|
|
196718
|
+
const closeVal = parseFloat(d.close);
|
|
196719
|
+
return {
|
|
196720
|
+
openTime: d.periodStartUnix * 1000,
|
|
196721
|
+
open: openVal > 0 ? openVal : fallback,
|
|
196722
|
+
high: highVal > 0 ? highVal : fallback,
|
|
196723
|
+
low: lowVal > 0 ? lowVal : fallback,
|
|
196724
|
+
close: closeVal > 0 ? closeVal : fallback,
|
|
196725
|
+
volume: parseFloat(d.volumeUSD),
|
|
196726
|
+
closeTime: (d.periodStartUnix + 3600) * 1000 - 1
|
|
196727
|
+
};
|
|
196728
|
+
});
|
|
196729
|
+
this.dataCache.set(cacheKey, candles, CACHE_TTL.candles);
|
|
196730
|
+
return candles;
|
|
196731
|
+
}
|
|
196732
|
+
async getTickLiquidity(symbol16, ticksPerSide = 20) {
|
|
196733
|
+
const { pool } = await this.resolvePool(symbol16);
|
|
196734
|
+
const freshData = await this.query(`query($id: ID!) { pool(id: $id) { tick feeTier } }`, { id: pool.id });
|
|
196735
|
+
const currentTick = parseInt(freshData.pool?.tick ?? pool.tick, 10);
|
|
196736
|
+
const feeTier = parseInt(freshData.pool?.feeTier ?? pool.feeTier, 10);
|
|
196737
|
+
const tickSpacing = feeTier === 100 ? 1 : feeTier === 500 ? 10 : feeTier === 3000 ? 60 : feeTier === 1e4 ? 200 : 60;
|
|
196738
|
+
const tickRange = ticksPerSide * tickSpacing;
|
|
196739
|
+
const cacheKey = `ticks:${this.chainId}:${pool.id}:${currentTick}:${ticksPerSide}`;
|
|
196740
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196741
|
+
if (cached2)
|
|
196742
|
+
return cached2;
|
|
196743
|
+
const minTick = currentTick - tickRange;
|
|
196744
|
+
const maxTick = currentTick + tickRange;
|
|
196745
|
+
const data = await this.query(`query($pool: String!, $minTick: BigInt!, $maxTick: BigInt!) {
|
|
196746
|
+
ticks(
|
|
196747
|
+
first: 100
|
|
196748
|
+
where: { pool: $pool, tickIdx_gte: $minTick, tickIdx_lte: $maxTick }
|
|
196749
|
+
orderBy: tickIdx
|
|
196750
|
+
orderDirection: asc
|
|
196751
|
+
) {
|
|
196752
|
+
id tickIdx poolAddress
|
|
196753
|
+
liquidityGross liquidityNet
|
|
196754
|
+
price0 price1
|
|
196755
|
+
volumeToken0 volumeToken1 volumeUSD
|
|
196756
|
+
feesUSD
|
|
196757
|
+
}
|
|
196758
|
+
}`, { pool: pool.id, minTick: minTick.toString(), maxTick: maxTick.toString() });
|
|
196759
|
+
this.dataCache.set(cacheKey, data.ticks, CACHE_TTL.ticks);
|
|
196760
|
+
return data.ticks;
|
|
196761
|
+
}
|
|
196762
|
+
async getMints(symbol16, limit = 50) {
|
|
196763
|
+
const { pool } = await this.resolvePool(symbol16);
|
|
196764
|
+
const cacheKey = `mints:${this.chainId}:${pool.id}:${limit}`;
|
|
196765
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196766
|
+
if (cached2)
|
|
196767
|
+
return cached2;
|
|
196768
|
+
const data = await this.query(`query($pool: String!, $first: Int!) {
|
|
196769
|
+
mints(
|
|
196770
|
+
first: $first
|
|
196771
|
+
where: { pool: $pool }
|
|
196772
|
+
orderBy: timestamp
|
|
196773
|
+
orderDirection: desc
|
|
196774
|
+
) {
|
|
196775
|
+
id timestamp
|
|
196776
|
+
transaction { id timestamp }
|
|
196777
|
+
pool { id }
|
|
196778
|
+
token0 { id symbol name decimals }
|
|
196779
|
+
token1 { id symbol name decimals }
|
|
196780
|
+
owner sender origin
|
|
196781
|
+
amount amount0 amount1 amountUSD
|
|
196782
|
+
tickLower tickUpper logIndex
|
|
196783
|
+
}
|
|
196784
|
+
}`, { pool: pool.id, first: Math.min(limit, 1000) });
|
|
196785
|
+
this.dataCache.set(cacheKey, data.mints, CACHE_TTL.events);
|
|
196786
|
+
return data.mints;
|
|
196787
|
+
}
|
|
196788
|
+
async getBurns(symbol16, limit = 50) {
|
|
196789
|
+
const { pool } = await this.resolvePool(symbol16);
|
|
196790
|
+
const cacheKey = `burns:${this.chainId}:${pool.id}:${limit}`;
|
|
196791
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196792
|
+
if (cached2)
|
|
196793
|
+
return cached2;
|
|
196794
|
+
const data = await this.query(`query($pool: String!, $first: Int!) {
|
|
196795
|
+
burns(
|
|
196796
|
+
first: $first
|
|
196797
|
+
where: { pool: $pool }
|
|
196798
|
+
orderBy: timestamp
|
|
196799
|
+
orderDirection: desc
|
|
196800
|
+
) {
|
|
196801
|
+
id timestamp
|
|
196802
|
+
transaction { id timestamp }
|
|
196803
|
+
pool { id }
|
|
196804
|
+
token0 { id symbol name decimals }
|
|
196805
|
+
token1 { id symbol name decimals }
|
|
196806
|
+
owner origin
|
|
196807
|
+
amount amount0 amount1 amountUSD
|
|
196808
|
+
tickLower tickUpper logIndex
|
|
196809
|
+
}
|
|
196810
|
+
}`, { pool: pool.id, first: Math.min(limit, 1000) });
|
|
196811
|
+
this.dataCache.set(cacheKey, data.burns, CACHE_TTL.events);
|
|
196812
|
+
return data.burns;
|
|
196813
|
+
}
|
|
196814
|
+
async getCollects(symbol16, limit = 50) {
|
|
196815
|
+
const { pool } = await this.resolvePool(symbol16);
|
|
196816
|
+
const cacheKey = `collects:${this.chainId}:${pool.id}:${limit}`;
|
|
196817
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196818
|
+
if (cached2)
|
|
196819
|
+
return cached2;
|
|
196820
|
+
const data = await this.query(`query($pool: String!, $first: Int!) {
|
|
196821
|
+
collects(
|
|
196822
|
+
first: $first
|
|
196823
|
+
where: { pool: $pool }
|
|
196824
|
+
orderBy: timestamp
|
|
196825
|
+
orderDirection: desc
|
|
196826
|
+
) {
|
|
196827
|
+
id timestamp
|
|
196828
|
+
transaction { id timestamp }
|
|
196829
|
+
pool { id }
|
|
196830
|
+
owner
|
|
196831
|
+
amount0 amount1 amountUSD
|
|
196832
|
+
tickLower tickUpper logIndex
|
|
196833
|
+
}
|
|
196834
|
+
}`, { pool: pool.id, first: Math.min(limit, 1000) });
|
|
196835
|
+
this.dataCache.set(cacheKey, data.collects, CACHE_TTL.events);
|
|
196836
|
+
return data.collects;
|
|
196837
|
+
}
|
|
196838
|
+
async getFlashLoans(symbol16, limit = 50) {
|
|
196839
|
+
const { pool } = await this.resolvePool(symbol16);
|
|
196840
|
+
const cacheKey = `flashes:${this.chainId}:${pool.id}:${limit}`;
|
|
196841
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196842
|
+
if (cached2)
|
|
196843
|
+
return cached2;
|
|
196844
|
+
const data = await this.query(`query($pool: String!, $first: Int!) {
|
|
196845
|
+
flashes(
|
|
196846
|
+
first: $first
|
|
196847
|
+
where: { pool: $pool }
|
|
196848
|
+
orderBy: timestamp
|
|
196849
|
+
orderDirection: desc
|
|
196850
|
+
) {
|
|
196851
|
+
id timestamp
|
|
196852
|
+
transaction { id timestamp }
|
|
196853
|
+
pool { id }
|
|
196854
|
+
sender recipient
|
|
196855
|
+
amount0 amount1 amountUSD
|
|
196856
|
+
amount0Paid amount1Paid
|
|
196857
|
+
logIndex
|
|
196858
|
+
}
|
|
196859
|
+
}`, { pool: pool.id, first: Math.min(limit, 1000) });
|
|
196860
|
+
this.dataCache.set(cacheKey, data.flashes, CACHE_TTL.events);
|
|
196861
|
+
return data.flashes;
|
|
196862
|
+
}
|
|
196863
|
+
async getPositions(owner, limit = 50) {
|
|
196864
|
+
const addr = owner.toLowerCase();
|
|
196865
|
+
const cacheKey = `positions:${this.chainId}:${addr}:${limit}`;
|
|
196866
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196867
|
+
if (cached2)
|
|
196868
|
+
return cached2;
|
|
196869
|
+
const data = await this.query(`query($owner: String!, $first: Int!) {
|
|
196870
|
+
positions(
|
|
196871
|
+
first: $first
|
|
196872
|
+
where: { owner: $owner, liquidity_gt: "0" }
|
|
196873
|
+
orderBy: liquidity
|
|
196874
|
+
orderDirection: desc
|
|
196875
|
+
) {
|
|
196876
|
+
id owner
|
|
196877
|
+
pool { id token0 { id symbol name decimals } token1 { id symbol name decimals } }
|
|
196878
|
+
token0 { id symbol name decimals }
|
|
196879
|
+
token1 { id symbol name decimals }
|
|
196880
|
+
tickLower { tickIdx price0 price1 }
|
|
196881
|
+
tickUpper { tickIdx price0 price1 }
|
|
196882
|
+
liquidity
|
|
196883
|
+
depositedToken0 depositedToken1
|
|
196884
|
+
withdrawnToken0 withdrawnToken1
|
|
196885
|
+
collectedFeesToken0 collectedFeesToken1
|
|
196886
|
+
transaction { id timestamp }
|
|
196887
|
+
}
|
|
196888
|
+
}`, { owner: addr, first: Math.min(limit, 1000) });
|
|
196889
|
+
this.dataCache.set(cacheKey, data.positions, CACHE_TTL.positions);
|
|
196890
|
+
return data.positions;
|
|
196891
|
+
}
|
|
196892
|
+
async getPositionSnapshots(positionId, limit = 50) {
|
|
196893
|
+
const cacheKey = `snapshots:${this.chainId}:${positionId}:${limit}`;
|
|
196894
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196895
|
+
if (cached2)
|
|
196896
|
+
return cached2;
|
|
196897
|
+
const data = await this.query(`query($position: String!, $first: Int!) {
|
|
196898
|
+
positionSnapshots(
|
|
196899
|
+
first: $first
|
|
196900
|
+
where: { position: $position }
|
|
196901
|
+
orderBy: timestamp
|
|
196902
|
+
orderDirection: desc
|
|
196903
|
+
) {
|
|
196904
|
+
id owner
|
|
196905
|
+
pool { id }
|
|
196906
|
+
position { id }
|
|
196907
|
+
blockNumber timestamp
|
|
196908
|
+
liquidity
|
|
196909
|
+
depositedToken0 depositedToken1
|
|
196910
|
+
withdrawnToken0 withdrawnToken1
|
|
196911
|
+
collectedFeesToken0 collectedFeesToken1
|
|
196912
|
+
transaction { id }
|
|
196913
|
+
}
|
|
196914
|
+
}`, { position: positionId, first: Math.min(limit, 1000) });
|
|
196915
|
+
this.dataCache.set(cacheKey, data.positionSnapshots, CACHE_TTL.positions);
|
|
196916
|
+
return data.positionSnapshots;
|
|
196917
|
+
}
|
|
196918
|
+
async getProtocolDayData(days = 30) {
|
|
196919
|
+
const cacheKey = `protocol:${this.chainId}:${days}`;
|
|
196920
|
+
const cached2 = this.dataCache.get(cacheKey);
|
|
196921
|
+
if (cached2)
|
|
196922
|
+
return cached2;
|
|
196923
|
+
const start = Math.floor(Date.now() / 1000) - days * 86400;
|
|
196924
|
+
const data = await this.query(`query($start: Int!, $first: Int!) {
|
|
196925
|
+
uniswapDayDatas(
|
|
196926
|
+
first: $first
|
|
196927
|
+
where: { date_gte: $start }
|
|
196928
|
+
orderBy: date
|
|
196929
|
+
orderDirection: asc
|
|
196930
|
+
) {
|
|
196931
|
+
id date
|
|
196932
|
+
volumeETH volumeUSD
|
|
196933
|
+
feesUSD txCount tvlUSD
|
|
196934
|
+
}
|
|
196935
|
+
}`, { start, first: Math.min(days, 1000) });
|
|
196936
|
+
this.dataCache.set(cacheKey, data.uniswapDayDatas, CACHE_TTL.protocol);
|
|
196937
|
+
return data.uniswapDayDatas;
|
|
196938
|
+
}
|
|
196939
|
+
}
|
|
196940
|
+
var GRAPH_GATEWAY = "https://gateway.thegraph.com/api", MAX_RETRIES3 = 3, BASE_DELAY_MS2 = 500, RATE_LIMIT, CIRCUIT_FAILURE_THRESHOLD = 5, CIRCUIT_RESET_MS = 60000, CACHE_TTL, STABLECOIN_SYMBOLS;
|
|
196941
|
+
var init_subgraph = __esm(() => {
|
|
196942
|
+
init_subgraph_types();
|
|
196943
|
+
RATE_LIMIT = { maxPerMinute: 30, throttleAt: 25 };
|
|
196944
|
+
CACHE_TTL = {
|
|
196945
|
+
pool: 30 * 60000,
|
|
196946
|
+
candles: 5 * 60000,
|
|
196947
|
+
tickers: 2 * 60000,
|
|
196948
|
+
top: 5 * 60000,
|
|
196949
|
+
trades: 60000,
|
|
196950
|
+
poolData: 60000,
|
|
196951
|
+
bundle: 60000,
|
|
196952
|
+
ticks: 60000,
|
|
196953
|
+
events: 60000,
|
|
196954
|
+
positions: 5 * 60000,
|
|
196955
|
+
protocol: 5 * 60000
|
|
196956
|
+
};
|
|
196957
|
+
STABLECOIN_SYMBOLS = new Set(["USDC", "USDT", "DAI", "BUSD", "TUSD", "FRAX", "LUSD", "USDP", "GUSD", "PYUSD"]);
|
|
196958
|
+
});
|
|
196959
|
+
|
|
196196
196960
|
// src/infra/uniswap/index.ts
|
|
196197
196961
|
var init_uniswap = __esm(() => {
|
|
196198
196962
|
init_client9();
|
|
196199
196963
|
init_token_list();
|
|
196964
|
+
init_subgraph();
|
|
196965
|
+
init_subgraph_types();
|
|
196200
196966
|
init_types10();
|
|
196201
196967
|
});
|
|
196202
196968
|
|
|
196203
196969
|
// src/infra/exchange/adapters/uniswap.ts
|
|
196204
196970
|
class UniswapAdapter {
|
|
196205
196971
|
client;
|
|
196972
|
+
subgraph;
|
|
196206
196973
|
exchangeId = "uniswap";
|
|
196207
196974
|
displayName = "Uniswap";
|
|
196208
196975
|
localOrders = new Map;
|
|
196209
196976
|
localTrades = new Map;
|
|
196210
196977
|
orderCounter = 0;
|
|
196211
|
-
constructor(apiKey, walletAddress, chainId = 1) {
|
|
196978
|
+
constructor(apiKey, walletAddress, chainId = 1, graphApiKey) {
|
|
196212
196979
|
this.client = new UniswapClient(apiKey, walletAddress, chainId);
|
|
196980
|
+
this.subgraph = graphApiKey ? new UniswapSubgraph(graphApiKey, chainId, this.client) : null;
|
|
196213
196981
|
}
|
|
196214
196982
|
async testConnection() {
|
|
196215
196983
|
return this.client.testConnection();
|
|
@@ -196241,16 +197009,40 @@ class UniswapAdapter {
|
|
|
196241
197009
|
throw new Error("No output amount in quote");
|
|
196242
197010
|
return Number(outputAmount) / 10 ** tokenOutDecimals;
|
|
196243
197011
|
}
|
|
196244
|
-
async getCandles(
|
|
196245
|
-
|
|
197012
|
+
async getCandles(symbol16, interval, limit) {
|
|
197013
|
+
if (!this.subgraph?.isAvailable())
|
|
197014
|
+
return [];
|
|
197015
|
+
try {
|
|
197016
|
+
return await this.subgraph.getCandles(symbol16, interval, limit ?? 50);
|
|
197017
|
+
} catch {
|
|
197018
|
+
return [];
|
|
197019
|
+
}
|
|
196246
197020
|
}
|
|
196247
197021
|
async get24hrTickers() {
|
|
196248
|
-
|
|
197022
|
+
if (!this.subgraph?.isAvailable())
|
|
197023
|
+
return [];
|
|
197024
|
+
try {
|
|
197025
|
+
return await this.subgraph.get24hrTickers();
|
|
197026
|
+
} catch {
|
|
197027
|
+
return [];
|
|
197028
|
+
}
|
|
196249
197029
|
}
|
|
196250
|
-
async getTopSymbols(
|
|
196251
|
-
|
|
197030
|
+
async getTopSymbols(n) {
|
|
197031
|
+
if (!this.subgraph?.isAvailable()) {
|
|
197032
|
+
return ["ETHUSDC", "WBTCUSDC", "ARBUSDC", "LINKUSDC", "UNIUSDC"];
|
|
197033
|
+
}
|
|
197034
|
+
try {
|
|
197035
|
+
return await this.subgraph.getTopSymbols(n);
|
|
197036
|
+
} catch {
|
|
197037
|
+
return ["ETHUSDC", "WBTCUSDC", "ARBUSDC", "LINKUSDC", "UNIUSDC"];
|
|
197038
|
+
}
|
|
196252
197039
|
}
|
|
196253
197040
|
async getOrderBook(symbol16, _limit) {
|
|
197041
|
+
if (this.subgraph?.isAvailable()) {
|
|
197042
|
+
try {
|
|
197043
|
+
return await this.subgraph.getOrderBook(symbol16);
|
|
197044
|
+
} catch {}
|
|
197045
|
+
}
|
|
196254
197046
|
const price = await this.getPrice(symbol16);
|
|
196255
197047
|
const spread = price * 0.003;
|
|
196256
197048
|
return {
|
|
@@ -196260,6 +197052,11 @@ class UniswapAdapter {
|
|
|
196260
197052
|
};
|
|
196261
197053
|
}
|
|
196262
197054
|
async getBookTicker(symbol16) {
|
|
197055
|
+
if (this.subgraph?.isAvailable()) {
|
|
197056
|
+
try {
|
|
197057
|
+
return await this.subgraph.getBookTicker(symbol16);
|
|
197058
|
+
} catch {}
|
|
197059
|
+
}
|
|
196263
197060
|
const price = await this.getPrice(symbol16);
|
|
196264
197061
|
const spread = price * 0.003;
|
|
196265
197062
|
return {
|
|
@@ -196271,6 +197068,11 @@ class UniswapAdapter {
|
|
|
196271
197068
|
};
|
|
196272
197069
|
}
|
|
196273
197070
|
async getSpread(symbol16) {
|
|
197071
|
+
if (this.subgraph?.isAvailable()) {
|
|
197072
|
+
try {
|
|
197073
|
+
return await this.subgraph.getSpread(symbol16);
|
|
197074
|
+
} catch {}
|
|
197075
|
+
}
|
|
196274
197076
|
const price = await this.getPrice(symbol16);
|
|
196275
197077
|
const spread = price * 0.003;
|
|
196276
197078
|
return {
|
|
@@ -196281,6 +197083,11 @@ class UniswapAdapter {
|
|
|
196281
197083
|
};
|
|
196282
197084
|
}
|
|
196283
197085
|
async getAvgPrice(symbol16) {
|
|
197086
|
+
if (this.subgraph?.isAvailable()) {
|
|
197087
|
+
try {
|
|
197088
|
+
return await this.subgraph.getAvgPrice(symbol16);
|
|
197089
|
+
} catch {}
|
|
197090
|
+
}
|
|
196284
197091
|
const price = await this.getPrice(symbol16);
|
|
196285
197092
|
return { mins: 5, price };
|
|
196286
197093
|
}
|
|
@@ -196345,11 +197152,16 @@ class UniswapAdapter {
|
|
|
196345
197152
|
this.localOrders.set(orderId, order);
|
|
196346
197153
|
const meta3 = {
|
|
196347
197154
|
_unsignedTx: swapTx.swap,
|
|
196348
|
-
_quoteTimestamp: quoteTimestamp
|
|
197155
|
+
_quoteTimestamp: quoteTimestamp,
|
|
197156
|
+
_routing: quote.routing
|
|
196349
197157
|
};
|
|
196350
197158
|
if (approvalResult.approval) {
|
|
196351
197159
|
meta3._approvalTx = approvalResult.approval;
|
|
196352
197160
|
}
|
|
197161
|
+
if (isUniswapXRouting(quote.routing) && quote.permitData) {
|
|
197162
|
+
meta3._permitData = quote.permitData;
|
|
197163
|
+
meta3._isUniswapX = true;
|
|
197164
|
+
}
|
|
196353
197165
|
if (swapTx.txFailureReasons?.length) {
|
|
196354
197166
|
meta3._txFailureReasons = swapTx.txFailureReasons;
|
|
196355
197167
|
}
|
|
@@ -196395,8 +197207,18 @@ class UniswapAdapter {
|
|
|
196395
197207
|
return false;
|
|
196396
197208
|
}
|
|
196397
197209
|
}
|
|
196398
|
-
async getTradeHistory(symbol16,
|
|
196399
|
-
|
|
197210
|
+
async getTradeHistory(symbol16, limit) {
|
|
197211
|
+
const local = this.localTrades.get(symbol16) || [];
|
|
197212
|
+
if (!this.subgraph?.isAvailable())
|
|
197213
|
+
return local;
|
|
197214
|
+
try {
|
|
197215
|
+
const onChain = await this.subgraph.getTradeHistory(symbol16, limit ?? 50);
|
|
197216
|
+
const localIds = new Set(local.map((t2) => t2.id));
|
|
197217
|
+
const deduped = onChain.filter((t2) => !localIds.has(t2.id));
|
|
197218
|
+
return [...local, ...deduped].slice(0, limit ?? 50);
|
|
197219
|
+
} catch {
|
|
197220
|
+
return local;
|
|
197221
|
+
}
|
|
196400
197222
|
}
|
|
196401
197223
|
async getOrderHistory(symbol16, _limit) {
|
|
196402
197224
|
return Array.from(this.localOrders.values()).filter((o) => o.symbol === symbol16);
|
|
@@ -196430,6 +197252,7 @@ class UniswapAdapter {
|
|
|
196430
197252
|
}
|
|
196431
197253
|
var init_uniswap2 = __esm(() => {
|
|
196432
197254
|
init_uniswap();
|
|
197255
|
+
init_subgraph();
|
|
196433
197256
|
init_types10();
|
|
196434
197257
|
});
|
|
196435
197258
|
|
|
@@ -196498,7 +197321,7 @@ var init_factory = __esm(() => {
|
|
|
196498
197321
|
if (!credentials.apiKey) {
|
|
196499
197322
|
throw new Error("Uniswap requires an API key from developers.uniswap.org");
|
|
196500
197323
|
}
|
|
196501
|
-
exchange = new UniswapAdapter(credentials.apiKey, credentials.walletPrivateKey || credentials.apiSecret, 1);
|
|
197324
|
+
exchange = new UniswapAdapter(credentials.apiKey, credentials.walletPrivateKey || credentials.apiSecret, 1, process.env.THEGRAPH_API_KEY);
|
|
196502
197325
|
break;
|
|
196503
197326
|
default:
|
|
196504
197327
|
throw new Error(`No adapter available for exchange: ${exchangeId}`);
|
|
@@ -286303,26 +287126,52 @@ async function dexScreenerFetch(path6) {
|
|
|
286303
287126
|
}
|
|
286304
287127
|
return await res.json();
|
|
286305
287128
|
}
|
|
286306
|
-
async function
|
|
286307
|
-
const data = await dexScreenerFetch(`/token-pairs/v1
|
|
286308
|
-
return (data.pairs ?? []).filter((p) => p.chainId ===
|
|
287129
|
+
async function getDexPairs(chain, tokenAddress) {
|
|
287130
|
+
const data = await dexScreenerFetch(`/token-pairs/v1/${chain}/${tokenAddress}`);
|
|
287131
|
+
return (data.pairs ?? []).filter((p) => p.chainId === chain);
|
|
286309
287132
|
}
|
|
286310
|
-
async function
|
|
287133
|
+
async function searchDexPairs(query, chain, dex) {
|
|
286311
287134
|
const data = await dexScreenerFetch(`/latest/dex/search?q=${encodeURIComponent(query)}`);
|
|
286312
|
-
|
|
286313
|
-
|
|
286314
|
-
|
|
287135
|
+
let pairs = data.pairs ?? [];
|
|
287136
|
+
if (chain)
|
|
287137
|
+
pairs = pairs.filter((p) => p.chainId === chain);
|
|
287138
|
+
if (dex)
|
|
287139
|
+
pairs = pairs.filter((p) => p.dexId === dex);
|
|
287140
|
+
return pairs;
|
|
287141
|
+
}
|
|
287142
|
+
async function getDexTokensBatch(chain, addresses) {
|
|
286315
287143
|
if (addresses.length === 0)
|
|
286316
287144
|
return [];
|
|
286317
287145
|
const batch = addresses.slice(0, 30).join(",");
|
|
286318
|
-
const data = await dexScreenerFetch(`/tokens/v1
|
|
286319
|
-
return (data.pairs ?? []).filter((p) => p.chainId ===
|
|
287146
|
+
const data = await dexScreenerFetch(`/tokens/v1/${chain}/${batch}`);
|
|
287147
|
+
return (data.pairs ?? []).filter((p) => p.chainId === chain);
|
|
286320
287148
|
}
|
|
286321
|
-
async function
|
|
287149
|
+
async function getNewTokens(chain) {
|
|
286322
287150
|
const data = await dexScreenerFetch(`/token-profiles/latest/v1`);
|
|
286323
|
-
|
|
287151
|
+
if (!chain)
|
|
287152
|
+
return data ?? [];
|
|
287153
|
+
return (data ?? []).filter((t2) => t2.chainId === chain);
|
|
287154
|
+
}
|
|
287155
|
+
async function getBoostedTokens(chain) {
|
|
287156
|
+
const data = await dexScreenerFetch(`/token-boosts/top/v1`);
|
|
287157
|
+
if (!chain)
|
|
287158
|
+
return data ?? [];
|
|
287159
|
+
return (data ?? []).filter((t2) => t2.chainId === chain);
|
|
287160
|
+
}
|
|
287161
|
+
async function getBasePairs(tokenAddress) {
|
|
287162
|
+
return getDexPairs("base", tokenAddress);
|
|
287163
|
+
}
|
|
287164
|
+
async function searchBasePairs(query) {
|
|
287165
|
+
return searchDexPairs(query, "base");
|
|
287166
|
+
}
|
|
287167
|
+
async function getBaseTokensBatch(addresses) {
|
|
287168
|
+
return getDexTokensBatch("base", addresses);
|
|
287169
|
+
}
|
|
287170
|
+
async function getNewBaseTokens() {
|
|
287171
|
+
return getNewTokens("base");
|
|
286324
287172
|
}
|
|
286325
287173
|
var DEXSCREENER_BASE = "https://api.dexscreener.com";
|
|
287174
|
+
var init_dexscreener = () => {};
|
|
286326
287175
|
|
|
286327
287176
|
// src/infra/base/signals.ts
|
|
286328
287177
|
async function detectWhaleTransfers(opts = {}) {
|
|
@@ -286433,6 +287282,7 @@ async function detectNewListings(opts = {}) {
|
|
|
286433
287282
|
return signals;
|
|
286434
287283
|
}
|
|
286435
287284
|
var init_signals = __esm(() => {
|
|
287285
|
+
init_dexscreener();
|
|
286436
287286
|
init_types14();
|
|
286437
287287
|
});
|
|
286438
287288
|
|
|
@@ -286440,6 +287290,7 @@ var init_signals = __esm(() => {
|
|
|
286440
287290
|
var init_base4 = __esm(() => {
|
|
286441
287291
|
init_registry4();
|
|
286442
287292
|
init_chain2();
|
|
287293
|
+
init_dexscreener();
|
|
286443
287294
|
init_signals();
|
|
286444
287295
|
init_types14();
|
|
286445
287296
|
});
|
|
@@ -1120270,6 +1121121,7 @@ var init_base_signals = __esm(() => {
|
|
|
1120270
1121121
|
init_tools();
|
|
1120271
1121122
|
init_zod();
|
|
1120272
1121123
|
init_signals();
|
|
1121124
|
+
init_dexscreener();
|
|
1120273
1121125
|
scanBaseWhaleTransfersTool = createTool({
|
|
1120274
1121126
|
id: "scan_base_whale_transfers",
|
|
1120275
1121127
|
description: "Scan for large token transfers (whale movements) on Base L2. " + "Detects big USDC, WETH, and other major token movements. " + "Requires BASESCAN_API_KEY. " + "Use when user asks 'any whale activity on Base', 'large transfers', 'who is moving big money on Base'.",
|
|
@@ -1120715,6 +1121567,624 @@ ${formatted.join(`
|
|
|
1120715
1121567
|
};
|
|
1120716
1121568
|
});
|
|
1120717
1121569
|
|
|
1121570
|
+
// src/infra/agents/tools/uniswap-data.ts
|
|
1121571
|
+
function getSubgraph(execContext) {
|
|
1121572
|
+
const ctx = getGordonContext(execContext);
|
|
1121573
|
+
if (!ctx?.exchange)
|
|
1121574
|
+
return { error: "Exchange client not connected." };
|
|
1121575
|
+
if (ctx.exchange.exchangeId !== "uniswap")
|
|
1121576
|
+
return { error: "This tool is only available on Uniswap." };
|
|
1121577
|
+
const subgraph = ctx.exchange.subgraph;
|
|
1121578
|
+
if (!subgraph?.isAvailable())
|
|
1121579
|
+
return { error: "Uniswap subgraph not available. Set THEGRAPH_API_KEY." };
|
|
1121580
|
+
return { subgraph };
|
|
1121581
|
+
}
|
|
1121582
|
+
var getPoolTickLiquidityTool, getLiquidityEventsTool, getPoolFlashEventsTool, getLpPositionsTool, getProtocolOverviewTool, getFeeCollectionsTool, uniswapDataTools;
|
|
1121583
|
+
var init_uniswap_data = __esm(() => {
|
|
1121584
|
+
init_tools();
|
|
1121585
|
+
init_zod();
|
|
1121586
|
+
init_types8();
|
|
1121587
|
+
getPoolTickLiquidityTool = createTool({
|
|
1121588
|
+
id: "get_pool_tick_liquidity",
|
|
1121589
|
+
description: "Get real liquidity distribution around the current price for a Uniswap pool. " + "Shows actual bid/ask depth from on-chain tick data \u2014 much more accurate than TVL proxy. " + "Use for order book depth analysis, slippage estimation, and liquidity gap detection.",
|
|
1121590
|
+
inputSchema: exports_external.object({
|
|
1121591
|
+
symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC', 'UNIUSDC')"),
|
|
1121592
|
+
ticksPerSide: exports_external.number().min(1).max(50).default(20).describe("Number of tick spaces on each side of current price")
|
|
1121593
|
+
}),
|
|
1121594
|
+
outputSchema: exports_external.object({
|
|
1121595
|
+
symbol: exports_external.string().optional(),
|
|
1121596
|
+
currentTick: exports_external.number().optional(),
|
|
1121597
|
+
tickCount: exports_external.number().optional(),
|
|
1121598
|
+
ticks: exports_external.array(exports_external.object({
|
|
1121599
|
+
tickIdx: exports_external.number(),
|
|
1121600
|
+
price: exports_external.number(),
|
|
1121601
|
+
liquidityNet: exports_external.number(),
|
|
1121602
|
+
liquidityGross: exports_external.number(),
|
|
1121603
|
+
volumeUSD: exports_external.number()
|
|
1121604
|
+
})).optional(),
|
|
1121605
|
+
error: exports_external.string().optional()
|
|
1121606
|
+
}),
|
|
1121607
|
+
execute: async ({ symbol: symbol16, ticksPerSide }, execContext) => {
|
|
1121608
|
+
const result = getSubgraph(execContext);
|
|
1121609
|
+
if ("error" in result)
|
|
1121610
|
+
return result;
|
|
1121611
|
+
try {
|
|
1121612
|
+
const pool = await result.subgraph.resolvePool(symbol16);
|
|
1121613
|
+
const ticks = await result.subgraph.getTickLiquidity(symbol16, ticksPerSide);
|
|
1121614
|
+
return {
|
|
1121615
|
+
symbol: symbol16,
|
|
1121616
|
+
currentTick: parseInt(pool.pool.tick, 10),
|
|
1121617
|
+
tickCount: ticks.length,
|
|
1121618
|
+
ticks: ticks.map((t3) => ({
|
|
1121619
|
+
tickIdx: parseInt(t3.tickIdx, 10),
|
|
1121620
|
+
price: parseFloat(pool.isInverted ? t3.price1 : t3.price0),
|
|
1121621
|
+
liquidityNet: parseFloat(t3.liquidityNet),
|
|
1121622
|
+
liquidityGross: parseFloat(t3.liquidityGross),
|
|
1121623
|
+
volumeUSD: parseFloat(t3.volumeUSD)
|
|
1121624
|
+
}))
|
|
1121625
|
+
};
|
|
1121626
|
+
} catch (error48) {
|
|
1121627
|
+
return { error: `Failed to get tick liquidity: ${error48.message}` };
|
|
1121628
|
+
}
|
|
1121629
|
+
}
|
|
1121630
|
+
});
|
|
1121631
|
+
getLiquidityEventsTool = createTool({
|
|
1121632
|
+
id: "get_liquidity_events",
|
|
1121633
|
+
description: "Get recent liquidity additions (mints) and removals (burns) for a Uniswap pool. " + "Large mints signal confidence; large burns may signal exit. " + "Use for detecting smart money flows, liquidity rug risk, and LP sentiment.",
|
|
1121634
|
+
inputSchema: exports_external.object({
|
|
1121635
|
+
symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC', 'UNIUSDC')"),
|
|
1121636
|
+
limit: exports_external.number().min(1).max(100).default(20).describe("Number of events per type")
|
|
1121637
|
+
}),
|
|
1121638
|
+
outputSchema: exports_external.object({
|
|
1121639
|
+
symbol: exports_external.string().optional(),
|
|
1121640
|
+
mints: exports_external.array(exports_external.object({
|
|
1121641
|
+
timestamp: exports_external.number(),
|
|
1121642
|
+
amountUSD: exports_external.number(),
|
|
1121643
|
+
amount0: exports_external.number(),
|
|
1121644
|
+
amount1: exports_external.number(),
|
|
1121645
|
+
owner: exports_external.string(),
|
|
1121646
|
+
tickLower: exports_external.number(),
|
|
1121647
|
+
tickUpper: exports_external.number()
|
|
1121648
|
+
})).optional(),
|
|
1121649
|
+
burns: exports_external.array(exports_external.object({
|
|
1121650
|
+
timestamp: exports_external.number(),
|
|
1121651
|
+
amountUSD: exports_external.number(),
|
|
1121652
|
+
amount0: exports_external.number(),
|
|
1121653
|
+
amount1: exports_external.number(),
|
|
1121654
|
+
owner: exports_external.string(),
|
|
1121655
|
+
tickLower: exports_external.number(),
|
|
1121656
|
+
tickUpper: exports_external.number()
|
|
1121657
|
+
})).optional(),
|
|
1121658
|
+
netFlowUSD: exports_external.number().optional(),
|
|
1121659
|
+
error: exports_external.string().optional()
|
|
1121660
|
+
}),
|
|
1121661
|
+
execute: async ({ symbol: symbol16, limit }, execContext) => {
|
|
1121662
|
+
const result = getSubgraph(execContext);
|
|
1121663
|
+
if ("error" in result)
|
|
1121664
|
+
return result;
|
|
1121665
|
+
try {
|
|
1121666
|
+
const [mints, burns] = await Promise.all([
|
|
1121667
|
+
result.subgraph.getMints(symbol16, limit),
|
|
1121668
|
+
result.subgraph.getBurns(symbol16, limit)
|
|
1121669
|
+
]);
|
|
1121670
|
+
const mintFlow = mints.reduce((sum, m) => sum + parseFloat(m.amountUSD), 0);
|
|
1121671
|
+
const burnFlow = burns.reduce((sum, b) => sum + parseFloat(b.amountUSD), 0);
|
|
1121672
|
+
return {
|
|
1121673
|
+
symbol: symbol16,
|
|
1121674
|
+
mints: mints.map((m) => ({
|
|
1121675
|
+
timestamp: parseInt(m.timestamp, 10) * 1000,
|
|
1121676
|
+
amountUSD: parseFloat(m.amountUSD),
|
|
1121677
|
+
amount0: parseFloat(m.amount0),
|
|
1121678
|
+
amount1: parseFloat(m.amount1),
|
|
1121679
|
+
owner: m.owner,
|
|
1121680
|
+
tickLower: parseInt(m.tickLower, 10),
|
|
1121681
|
+
tickUpper: parseInt(m.tickUpper, 10)
|
|
1121682
|
+
})),
|
|
1121683
|
+
burns: burns.map((b) => ({
|
|
1121684
|
+
timestamp: parseInt(b.timestamp, 10) * 1000,
|
|
1121685
|
+
amountUSD: parseFloat(b.amountUSD),
|
|
1121686
|
+
amount0: parseFloat(b.amount0),
|
|
1121687
|
+
amount1: parseFloat(b.amount1),
|
|
1121688
|
+
owner: b.owner,
|
|
1121689
|
+
tickLower: parseInt(b.tickLower, 10),
|
|
1121690
|
+
tickUpper: parseInt(b.tickUpper, 10)
|
|
1121691
|
+
})),
|
|
1121692
|
+
netFlowUSD: mintFlow - burnFlow
|
|
1121693
|
+
};
|
|
1121694
|
+
} catch (error48) {
|
|
1121695
|
+
return { error: `Failed to get liquidity events: ${error48.message}` };
|
|
1121696
|
+
}
|
|
1121697
|
+
}
|
|
1121698
|
+
});
|
|
1121699
|
+
getPoolFlashEventsTool = createTool({
|
|
1121700
|
+
id: "get_pool_flash_events",
|
|
1121701
|
+
description: "Get recent flash loan events for a Uniswap pool. " + "Flash loans can indicate arbitrage activity or potential manipulation. " + "Large or frequent flash loans around a token may signal price instability.",
|
|
1121702
|
+
inputSchema: exports_external.object({
|
|
1121703
|
+
symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC')"),
|
|
1121704
|
+
limit: exports_external.number().min(1).max(100).default(20).describe("Number of events to return")
|
|
1121705
|
+
}),
|
|
1121706
|
+
outputSchema: exports_external.object({
|
|
1121707
|
+
symbol: exports_external.string().optional(),
|
|
1121708
|
+
count: exports_external.number().optional(),
|
|
1121709
|
+
totalAmountUSD: exports_external.number().optional(),
|
|
1121710
|
+
events: exports_external.array(exports_external.object({
|
|
1121711
|
+
timestamp: exports_external.number(),
|
|
1121712
|
+
amountUSD: exports_external.number(),
|
|
1121713
|
+
amount0: exports_external.number(),
|
|
1121714
|
+
amount1: exports_external.number(),
|
|
1121715
|
+
amount0Paid: exports_external.number(),
|
|
1121716
|
+
amount1Paid: exports_external.number(),
|
|
1121717
|
+
sender: exports_external.string()
|
|
1121718
|
+
})).optional(),
|
|
1121719
|
+
error: exports_external.string().optional()
|
|
1121720
|
+
}),
|
|
1121721
|
+
execute: async ({ symbol: symbol16, limit }, execContext) => {
|
|
1121722
|
+
const result = getSubgraph(execContext);
|
|
1121723
|
+
if ("error" in result)
|
|
1121724
|
+
return result;
|
|
1121725
|
+
try {
|
|
1121726
|
+
const flashes = await result.subgraph.getFlashLoans(symbol16, limit);
|
|
1121727
|
+
const totalUSD = flashes.reduce((sum, f2) => sum + parseFloat(f2.amountUSD), 0);
|
|
1121728
|
+
return {
|
|
1121729
|
+
symbol: symbol16,
|
|
1121730
|
+
count: flashes.length,
|
|
1121731
|
+
totalAmountUSD: totalUSD,
|
|
1121732
|
+
events: flashes.map((f2) => ({
|
|
1121733
|
+
timestamp: parseInt(f2.timestamp, 10) * 1000,
|
|
1121734
|
+
amountUSD: parseFloat(f2.amountUSD),
|
|
1121735
|
+
amount0: parseFloat(f2.amount0),
|
|
1121736
|
+
amount1: parseFloat(f2.amount1),
|
|
1121737
|
+
amount0Paid: parseFloat(f2.amount0Paid),
|
|
1121738
|
+
amount1Paid: parseFloat(f2.amount1Paid),
|
|
1121739
|
+
sender: f2.sender
|
|
1121740
|
+
}))
|
|
1121741
|
+
};
|
|
1121742
|
+
} catch (error48) {
|
|
1121743
|
+
return { error: `Failed to get flash events: ${error48.message}` };
|
|
1121744
|
+
}
|
|
1121745
|
+
}
|
|
1121746
|
+
});
|
|
1121747
|
+
getLpPositionsTool = createTool({
|
|
1121748
|
+
id: "get_lp_positions",
|
|
1121749
|
+
description: "Get active Uniswap V3 LP positions for a wallet address. " + "Shows pools, price ranges, liquidity amounts, deposited/withdrawn tokens, and collected fees. " + "Use for portfolio monitoring of LP positions.",
|
|
1121750
|
+
inputSchema: exports_external.object({
|
|
1121751
|
+
owner: exports_external.string().describe("Wallet address (0x...)"),
|
|
1121752
|
+
limit: exports_external.number().min(1).max(100).default(20).describe("Max positions to return")
|
|
1121753
|
+
}),
|
|
1121754
|
+
outputSchema: exports_external.object({
|
|
1121755
|
+
owner: exports_external.string().optional(),
|
|
1121756
|
+
positionCount: exports_external.number().optional(),
|
|
1121757
|
+
positions: exports_external.array(exports_external.object({
|
|
1121758
|
+
id: exports_external.string(),
|
|
1121759
|
+
pool: exports_external.string(),
|
|
1121760
|
+
token0: exports_external.string(),
|
|
1121761
|
+
token1: exports_external.string(),
|
|
1121762
|
+
tickLower: exports_external.number(),
|
|
1121763
|
+
tickUpper: exports_external.number(),
|
|
1121764
|
+
liquidity: exports_external.string(),
|
|
1121765
|
+
depositedToken0: exports_external.number(),
|
|
1121766
|
+
depositedToken1: exports_external.number(),
|
|
1121767
|
+
withdrawnToken0: exports_external.number(),
|
|
1121768
|
+
withdrawnToken1: exports_external.number(),
|
|
1121769
|
+
collectedFeesToken0: exports_external.number(),
|
|
1121770
|
+
collectedFeesToken1: exports_external.number()
|
|
1121771
|
+
})).optional(),
|
|
1121772
|
+
error: exports_external.string().optional()
|
|
1121773
|
+
}),
|
|
1121774
|
+
execute: async ({ owner, limit }, execContext) => {
|
|
1121775
|
+
const result = getSubgraph(execContext);
|
|
1121776
|
+
if ("error" in result)
|
|
1121777
|
+
return result;
|
|
1121778
|
+
try {
|
|
1121779
|
+
const positions = await result.subgraph.getPositions(owner, limit);
|
|
1121780
|
+
return {
|
|
1121781
|
+
owner,
|
|
1121782
|
+
positionCount: positions.length,
|
|
1121783
|
+
positions: positions.map((p) => ({
|
|
1121784
|
+
id: p.id,
|
|
1121785
|
+
pool: p.pool.id,
|
|
1121786
|
+
token0: `${p.token0.symbol} (${p.token0.id.slice(0, 10)}...)`,
|
|
1121787
|
+
token1: `${p.token1.symbol} (${p.token1.id.slice(0, 10)}...)`,
|
|
1121788
|
+
tickLower: parseInt(p.tickLower.tickIdx, 10),
|
|
1121789
|
+
tickUpper: parseInt(p.tickUpper.tickIdx, 10),
|
|
1121790
|
+
liquidity: p.liquidity,
|
|
1121791
|
+
depositedToken0: parseFloat(p.depositedToken0),
|
|
1121792
|
+
depositedToken1: parseFloat(p.depositedToken1),
|
|
1121793
|
+
withdrawnToken0: parseFloat(p.withdrawnToken0),
|
|
1121794
|
+
withdrawnToken1: parseFloat(p.withdrawnToken1),
|
|
1121795
|
+
collectedFeesToken0: parseFloat(p.collectedFeesToken0),
|
|
1121796
|
+
collectedFeesToken1: parseFloat(p.collectedFeesToken1)
|
|
1121797
|
+
}))
|
|
1121798
|
+
};
|
|
1121799
|
+
} catch (error48) {
|
|
1121800
|
+
return { error: `Failed to get LP positions: ${error48.message}` };
|
|
1121801
|
+
}
|
|
1121802
|
+
}
|
|
1121803
|
+
});
|
|
1121804
|
+
getProtocolOverviewTool = createTool({
|
|
1121805
|
+
id: "get_uniswap_protocol_overview",
|
|
1121806
|
+
description: "Get Uniswap V3 protocol-wide metrics: ETH/USD price, total pools, total volume, " + "total fees, TVL, and recent daily data. Use for protocol health assessment, " + "DeFi market overview, and macro trend analysis.",
|
|
1121807
|
+
inputSchema: exports_external.object({
|
|
1121808
|
+
days: exports_external.number().min(1).max(90).default(7).describe("Number of days of daily data to include")
|
|
1121809
|
+
}),
|
|
1121810
|
+
outputSchema: exports_external.object({
|
|
1121811
|
+
ethPriceUSD: exports_external.number().optional(),
|
|
1121812
|
+
factory: exports_external.object({
|
|
1121813
|
+
poolCount: exports_external.number(),
|
|
1121814
|
+
totalVolumeUSD: exports_external.number(),
|
|
1121815
|
+
totalFeesUSD: exports_external.number(),
|
|
1121816
|
+
totalValueLockedUSD: exports_external.number()
|
|
1121817
|
+
}).optional(),
|
|
1121818
|
+
dailyData: exports_external.array(exports_external.object({
|
|
1121819
|
+
date: exports_external.number(),
|
|
1121820
|
+
volumeUSD: exports_external.number(),
|
|
1121821
|
+
feesUSD: exports_external.number(),
|
|
1121822
|
+
tvlUSD: exports_external.number(),
|
|
1121823
|
+
txCount: exports_external.number()
|
|
1121824
|
+
})).optional(),
|
|
1121825
|
+
error: exports_external.string().optional()
|
|
1121826
|
+
}),
|
|
1121827
|
+
execute: async ({ days }, execContext) => {
|
|
1121828
|
+
const result = getSubgraph(execContext);
|
|
1121829
|
+
if ("error" in result)
|
|
1121830
|
+
return result;
|
|
1121831
|
+
try {
|
|
1121832
|
+
const [ethPrice, factory6, dayData] = await Promise.all([
|
|
1121833
|
+
result.subgraph.getEthPrice(),
|
|
1121834
|
+
result.subgraph.getFactory(),
|
|
1121835
|
+
result.subgraph.getProtocolDayData(days)
|
|
1121836
|
+
]);
|
|
1121837
|
+
return {
|
|
1121838
|
+
ethPriceUSD: ethPrice,
|
|
1121839
|
+
factory: factory6 ? {
|
|
1121840
|
+
poolCount: parseInt(factory6.poolCount, 10),
|
|
1121841
|
+
totalVolumeUSD: parseFloat(factory6.totalVolumeUSD),
|
|
1121842
|
+
totalFeesUSD: parseFloat(factory6.totalFeesUSD),
|
|
1121843
|
+
totalValueLockedUSD: parseFloat(factory6.totalValueLockedUSD)
|
|
1121844
|
+
} : undefined,
|
|
1121845
|
+
dailyData: dayData.map((d) => ({
|
|
1121846
|
+
date: d.date * 1000,
|
|
1121847
|
+
volumeUSD: parseFloat(d.volumeUSD),
|
|
1121848
|
+
feesUSD: parseFloat(d.feesUSD),
|
|
1121849
|
+
tvlUSD: parseFloat(d.tvlUSD),
|
|
1121850
|
+
txCount: parseInt(d.txCount, 10)
|
|
1121851
|
+
}))
|
|
1121852
|
+
};
|
|
1121853
|
+
} catch (error48) {
|
|
1121854
|
+
return { error: `Failed to get protocol overview: ${error48.message}` };
|
|
1121855
|
+
}
|
|
1121856
|
+
}
|
|
1121857
|
+
});
|
|
1121858
|
+
getFeeCollectionsTool = createTool({
|
|
1121859
|
+
id: "get_fee_collections",
|
|
1121860
|
+
description: "Get recent fee collection events for a Uniswap pool. " + "Shows when LPs harvest their earned fees. Useful for tracking LP profitability " + "and identifying wallets actively managing their positions.",
|
|
1121861
|
+
inputSchema: exports_external.object({
|
|
1121862
|
+
symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC')"),
|
|
1121863
|
+
limit: exports_external.number().min(1).max(100).default(20).describe("Number of events to return")
|
|
1121864
|
+
}),
|
|
1121865
|
+
outputSchema: exports_external.object({
|
|
1121866
|
+
symbol: exports_external.string().optional(),
|
|
1121867
|
+
count: exports_external.number().optional(),
|
|
1121868
|
+
totalFeesUSD: exports_external.number().optional(),
|
|
1121869
|
+
events: exports_external.array(exports_external.object({
|
|
1121870
|
+
timestamp: exports_external.number(),
|
|
1121871
|
+
amountUSD: exports_external.number(),
|
|
1121872
|
+
amount0: exports_external.number(),
|
|
1121873
|
+
amount1: exports_external.number(),
|
|
1121874
|
+
owner: exports_external.string()
|
|
1121875
|
+
})).optional(),
|
|
1121876
|
+
error: exports_external.string().optional()
|
|
1121877
|
+
}),
|
|
1121878
|
+
execute: async ({ symbol: symbol16, limit }, execContext) => {
|
|
1121879
|
+
const result = getSubgraph(execContext);
|
|
1121880
|
+
if ("error" in result)
|
|
1121881
|
+
return result;
|
|
1121882
|
+
try {
|
|
1121883
|
+
const collects = await result.subgraph.getCollects(symbol16, limit);
|
|
1121884
|
+
const totalUSD = collects.reduce((sum, c) => sum + parseFloat(c.amountUSD), 0);
|
|
1121885
|
+
return {
|
|
1121886
|
+
symbol: symbol16,
|
|
1121887
|
+
count: collects.length,
|
|
1121888
|
+
totalFeesUSD: totalUSD,
|
|
1121889
|
+
events: collects.map((c) => ({
|
|
1121890
|
+
timestamp: parseInt(c.timestamp, 10) * 1000,
|
|
1121891
|
+
amountUSD: parseFloat(c.amountUSD),
|
|
1121892
|
+
amount0: parseFloat(c.amount0),
|
|
1121893
|
+
amount1: parseFloat(c.amount1),
|
|
1121894
|
+
owner: c.owner
|
|
1121895
|
+
}))
|
|
1121896
|
+
};
|
|
1121897
|
+
} catch (error48) {
|
|
1121898
|
+
return { error: `Failed to get fee collections: ${error48.message}` };
|
|
1121899
|
+
}
|
|
1121900
|
+
}
|
|
1121901
|
+
});
|
|
1121902
|
+
uniswapDataTools = {
|
|
1121903
|
+
get_pool_tick_liquidity: getPoolTickLiquidityTool,
|
|
1121904
|
+
get_liquidity_events: getLiquidityEventsTool,
|
|
1121905
|
+
get_pool_flash_events: getPoolFlashEventsTool,
|
|
1121906
|
+
get_lp_positions: getLpPositionsTool,
|
|
1121907
|
+
get_uniswap_protocol_overview: getProtocolOverviewTool,
|
|
1121908
|
+
get_fee_collections: getFeeCollectionsTool
|
|
1121909
|
+
};
|
|
1121910
|
+
});
|
|
1121911
|
+
|
|
1121912
|
+
// src/infra/agents/tools/dex-search.ts
|
|
1121913
|
+
var searchDexPairsTool, getBoostedTokensTool, dexSearchTools;
|
|
1121914
|
+
var init_dex_search = __esm(() => {
|
|
1121915
|
+
init_tools();
|
|
1121916
|
+
init_zod();
|
|
1121917
|
+
init_dexscreener();
|
|
1121918
|
+
searchDexPairsTool = createTool({
|
|
1121919
|
+
id: "search_dex_pairs",
|
|
1121920
|
+
description: "Search for DEX trading pairs across any chain using DexScreener. " + "Works on Ethereum, Base, Arbitrum, Optimism, Polygon, BSC, Avalanche, and more. " + "Filter by chain and/or DEX. No API key needed. " + "Use when user asks about DEX pairs on chains other than Base, or wants to compare " + "pairs across chains. For Base-only queries, prefer get_base_dex_pairs.",
|
|
1121921
|
+
inputSchema: exports_external.object({
|
|
1121922
|
+
query: exports_external.string().describe("Search term: token symbol (e.g., 'UNI'), pair (e.g., 'WETH/USDC'), or token address (0x...)"),
|
|
1121923
|
+
chain: exports_external.string().optional().describe("DexScreener chain ID: 'ethereum', 'base', 'arbitrum', 'optimism', 'polygon', 'bsc', 'avalanche', 'unichain'. Omit for all chains."),
|
|
1121924
|
+
dex: exports_external.string().optional().describe("DEX filter: 'uniswap', 'sushiswap', 'aerodrome', 'curve', etc. Omit for all DEXs.")
|
|
1121925
|
+
}),
|
|
1121926
|
+
outputSchema: exports_external.object({
|
|
1121927
|
+
pairs: exports_external.array(exports_external.object({
|
|
1121928
|
+
chain: exports_external.string(),
|
|
1121929
|
+
pairAddress: exports_external.string(),
|
|
1121930
|
+
dex: exports_external.string(),
|
|
1121931
|
+
baseToken: exports_external.string(),
|
|
1121932
|
+
quoteToken: exports_external.string(),
|
|
1121933
|
+
priceUsd: exports_external.string(),
|
|
1121934
|
+
volumeH24: exports_external.number(),
|
|
1121935
|
+
liquidityUsd: exports_external.number(),
|
|
1121936
|
+
priceChangeH24: exports_external.number(),
|
|
1121937
|
+
marketCap: exports_external.number().nullable(),
|
|
1121938
|
+
url: exports_external.string()
|
|
1121939
|
+
})).optional(),
|
|
1121940
|
+
count: exports_external.number().optional(),
|
|
1121941
|
+
error: exports_external.string().optional()
|
|
1121942
|
+
}),
|
|
1121943
|
+
execute: async ({ query, chain, dex }) => {
|
|
1121944
|
+
try {
|
|
1121945
|
+
const isAddress4 = /^0x[a-fA-F0-9]{40}$/.test(query);
|
|
1121946
|
+
let pairs;
|
|
1121947
|
+
if (isAddress4 && chain) {
|
|
1121948
|
+
pairs = await getDexPairs(chain, query);
|
|
1121949
|
+
if (dex)
|
|
1121950
|
+
pairs = pairs.filter((p) => p.dexId === dex);
|
|
1121951
|
+
} else {
|
|
1121952
|
+
pairs = await searchDexPairs(query, chain, dex);
|
|
1121953
|
+
}
|
|
1121954
|
+
return {
|
|
1121955
|
+
count: pairs.length,
|
|
1121956
|
+
pairs: pairs.slice(0, 25).map((p) => ({
|
|
1121957
|
+
chain: p.chainId,
|
|
1121958
|
+
pairAddress: p.pairAddress,
|
|
1121959
|
+
dex: p.dexId,
|
|
1121960
|
+
baseToken: `${p.baseToken.symbol} (${p.baseToken.address})`,
|
|
1121961
|
+
quoteToken: `${p.quoteToken.symbol} (${p.quoteToken.address})`,
|
|
1121962
|
+
priceUsd: p.priceUsd,
|
|
1121963
|
+
volumeH24: p.volume?.h24 ?? 0,
|
|
1121964
|
+
liquidityUsd: p.liquidity?.usd ?? 0,
|
|
1121965
|
+
priceChangeH24: p.priceChange?.h24 ?? 0,
|
|
1121966
|
+
marketCap: p.marketCap ?? null,
|
|
1121967
|
+
url: p.url
|
|
1121968
|
+
}))
|
|
1121969
|
+
};
|
|
1121970
|
+
} catch (error48) {
|
|
1121971
|
+
return { error: `Failed to search DEX pairs: ${error48.message}` };
|
|
1121972
|
+
}
|
|
1121973
|
+
}
|
|
1121974
|
+
});
|
|
1121975
|
+
getBoostedTokensTool = createTool({
|
|
1121976
|
+
id: "get_boosted_tokens",
|
|
1121977
|
+
description: "Get currently promoted/boosted tokens from DexScreener across all chains. " + "Shows tokens with active promotions \u2014 can indicate marketing spend or community interest. " + "Optionally filter by chain. No API key needed.",
|
|
1121978
|
+
inputSchema: exports_external.object({
|
|
1121979
|
+
chain: exports_external.string().optional().describe("Filter to a specific chain: 'ethereum', 'base', 'arbitrum', etc. Omit for all chains.")
|
|
1121980
|
+
}),
|
|
1121981
|
+
outputSchema: exports_external.object({
|
|
1121982
|
+
tokens: exports_external.array(exports_external.object({
|
|
1121983
|
+
chain: exports_external.string(),
|
|
1121984
|
+
tokenAddress: exports_external.string(),
|
|
1121985
|
+
url: exports_external.string(),
|
|
1121986
|
+
description: exports_external.string().optional()
|
|
1121987
|
+
})).optional(),
|
|
1121988
|
+
count: exports_external.number().optional(),
|
|
1121989
|
+
error: exports_external.string().optional()
|
|
1121990
|
+
}),
|
|
1121991
|
+
execute: async ({ chain }) => {
|
|
1121992
|
+
try {
|
|
1121993
|
+
const tokens = await getBoostedTokens(chain);
|
|
1121994
|
+
return {
|
|
1121995
|
+
count: tokens.length,
|
|
1121996
|
+
tokens: tokens.slice(0, 30).map((t3) => ({
|
|
1121997
|
+
chain: t3.chainId,
|
|
1121998
|
+
tokenAddress: t3.tokenAddress,
|
|
1121999
|
+
url: t3.url,
|
|
1122000
|
+
description: t3.description
|
|
1122001
|
+
}))
|
|
1122002
|
+
};
|
|
1122003
|
+
} catch (error48) {
|
|
1122004
|
+
return { error: `Failed to get boosted tokens: ${error48.message}` };
|
|
1122005
|
+
}
|
|
1122006
|
+
}
|
|
1122007
|
+
});
|
|
1122008
|
+
dexSearchTools = {
|
|
1122009
|
+
search_dex_pairs: searchDexPairsTool,
|
|
1122010
|
+
get_boosted_tokens: getBoostedTokensTool
|
|
1122011
|
+
};
|
|
1122012
|
+
});
|
|
1122013
|
+
|
|
1122014
|
+
// src/infra/defillama/client.ts
|
|
1122015
|
+
async function llamaFetch(base4, path6) {
|
|
1122016
|
+
const url2 = `${base4}${path6}`;
|
|
1122017
|
+
const res = await fetch(url2, { signal: AbortSignal.timeout(15000) });
|
|
1122018
|
+
if (!res.ok) {
|
|
1122019
|
+
throw new Error(`DefiLlama API error: ${res.status} ${res.statusText}`);
|
|
1122020
|
+
}
|
|
1122021
|
+
return await res.json();
|
|
1122022
|
+
}
|
|
1122023
|
+
async function getAllPools() {
|
|
1122024
|
+
const cached2 = poolsCache.get("all");
|
|
1122025
|
+
if (cached2)
|
|
1122026
|
+
return cached2;
|
|
1122027
|
+
const resp = await llamaFetch(YIELDS_BASE, "/pools");
|
|
1122028
|
+
const pools = resp.data ?? [];
|
|
1122029
|
+
poolsCache.set("all", pools);
|
|
1122030
|
+
return pools;
|
|
1122031
|
+
}
|
|
1122032
|
+
async function getUniswapPoolYields(chain, symbol16) {
|
|
1122033
|
+
const allPools = await getAllPools();
|
|
1122034
|
+
let pools = allPools.filter((p) => p.project === "uniswap-v3" || p.project === "uniswap-v4");
|
|
1122035
|
+
if (chain) {
|
|
1122036
|
+
const defillamaChain = DEFILLAMA_CHAINS[chain.toLowerCase()] ?? chain;
|
|
1122037
|
+
pools = pools.filter((p) => p.chain === defillamaChain);
|
|
1122038
|
+
}
|
|
1122039
|
+
if (symbol16) {
|
|
1122040
|
+
const sym = symbol16.toUpperCase();
|
|
1122041
|
+
pools = pools.filter((p) => p.symbol.toUpperCase().includes(sym));
|
|
1122042
|
+
}
|
|
1122043
|
+
pools.sort((a2, b) => b.tvlUsd - a2.tvlUsd);
|
|
1122044
|
+
return pools;
|
|
1122045
|
+
}
|
|
1122046
|
+
async function getTopYieldPools(chain, limit = 20, minTvl = 1e5) {
|
|
1122047
|
+
const allPools = await getAllPools();
|
|
1122048
|
+
let pools = allPools.filter((p) => p.tvlUsd >= minTvl && p.apy > 0);
|
|
1122049
|
+
if (chain) {
|
|
1122050
|
+
const defillamaChain = DEFILLAMA_CHAINS[chain.toLowerCase()] ?? chain;
|
|
1122051
|
+
pools = pools.filter((p) => p.chain === defillamaChain);
|
|
1122052
|
+
}
|
|
1122053
|
+
pools.sort((a2, b) => b.apy - a2.apy);
|
|
1122054
|
+
return pools.slice(0, limit);
|
|
1122055
|
+
}
|
|
1122056
|
+
var YIELDS_BASE = "https://yields.llama.fi", DEFILLAMA_CHAINS, poolsCache, priceCache;
|
|
1122057
|
+
var init_client11 = __esm(() => {
|
|
1122058
|
+
DEFILLAMA_CHAINS = {
|
|
1122059
|
+
ethereum: "Ethereum",
|
|
1122060
|
+
base: "Base",
|
|
1122061
|
+
arbitrum: "Arbitrum",
|
|
1122062
|
+
optimism: "Optimism",
|
|
1122063
|
+
polygon: "Polygon",
|
|
1122064
|
+
bsc: "BSC",
|
|
1122065
|
+
avalanche: "Avalanche",
|
|
1122066
|
+
celo: "Celo",
|
|
1122067
|
+
blast: "Blast",
|
|
1122068
|
+
unichain: "Unichain"
|
|
1122069
|
+
};
|
|
1122070
|
+
poolsCache = new Cache({ defaultTtl: 5 * 60 * 1000 });
|
|
1122071
|
+
priceCache = new Cache({ defaultTtl: 2 * 60 * 1000 });
|
|
1122072
|
+
});
|
|
1122073
|
+
|
|
1122074
|
+
// src/infra/agents/tools/defillama-yields.ts
|
|
1122075
|
+
var getUniswapYieldsTool, getTopYieldsTool, defillamaYieldTools;
|
|
1122076
|
+
var init_defillama_yields = __esm(() => {
|
|
1122077
|
+
init_tools();
|
|
1122078
|
+
init_zod();
|
|
1122079
|
+
init_client11();
|
|
1122080
|
+
getUniswapYieldsTool = createTool({
|
|
1122081
|
+
id: "get_uniswap_pool_yields",
|
|
1122082
|
+
description: "Get current APY, TVL, and volume data for Uniswap V3/V4 pools from DefiLlama. " + "Shows base APY (fees), reward APY, 7d/30d trends, impermanent loss risk, and pool TVL. " + "Use for yield farming analysis, comparing fee tiers, and LP profitability assessment. " + "Supports all chains: Ethereum, Base, Arbitrum, Optimism, Polygon, etc.",
|
|
1122083
|
+
inputSchema: exports_external.object({
|
|
1122084
|
+
chain: exports_external.string().optional().describe("Chain name (e.g., 'ethereum', 'base', 'arbitrum'). Omit for all chains."),
|
|
1122085
|
+
symbol: exports_external.string().optional().describe("Token pair filter (e.g., 'WETH-USDC', 'USDC'). Partial match."),
|
|
1122086
|
+
limit: exports_external.number().min(1).max(50).default(15).describe("Max pools to return")
|
|
1122087
|
+
}),
|
|
1122088
|
+
outputSchema: exports_external.object({
|
|
1122089
|
+
pools: exports_external.array(exports_external.object({
|
|
1122090
|
+
pool: exports_external.string(),
|
|
1122091
|
+
symbol: exports_external.string(),
|
|
1122092
|
+
chain: exports_external.string(),
|
|
1122093
|
+
tvlUsd: exports_external.number(),
|
|
1122094
|
+
apy: exports_external.number(),
|
|
1122095
|
+
apyBase: exports_external.number().nullable(),
|
|
1122096
|
+
apyReward: exports_external.number().nullable(),
|
|
1122097
|
+
apyPct7D: exports_external.number().nullable(),
|
|
1122098
|
+
apyPct30D: exports_external.number().nullable(),
|
|
1122099
|
+
volumeUsd1d: exports_external.number().nullable(),
|
|
1122100
|
+
volumeUsd7d: exports_external.number().nullable(),
|
|
1122101
|
+
ilRisk: exports_external.string(),
|
|
1122102
|
+
stablecoin: exports_external.boolean(),
|
|
1122103
|
+
poolMeta: exports_external.string().nullable()
|
|
1122104
|
+
})).optional(),
|
|
1122105
|
+
count: exports_external.number().optional(),
|
|
1122106
|
+
error: exports_external.string().optional()
|
|
1122107
|
+
}),
|
|
1122108
|
+
execute: async ({ chain, symbol: symbol16, limit }) => {
|
|
1122109
|
+
try {
|
|
1122110
|
+
const pools = await getUniswapPoolYields(chain, symbol16);
|
|
1122111
|
+
return {
|
|
1122112
|
+
count: Math.min(pools.length, limit),
|
|
1122113
|
+
pools: pools.slice(0, limit).map((p) => ({
|
|
1122114
|
+
pool: p.pool,
|
|
1122115
|
+
symbol: p.symbol,
|
|
1122116
|
+
chain: p.chain,
|
|
1122117
|
+
tvlUsd: Math.round(p.tvlUsd),
|
|
1122118
|
+
apy: Math.round(p.apy * 100) / 100,
|
|
1122119
|
+
apyBase: p.apyBase !== null ? Math.round(p.apyBase * 100) / 100 : null,
|
|
1122120
|
+
apyReward: p.apyReward !== null ? Math.round(p.apyReward * 100) / 100 : null,
|
|
1122121
|
+
apyPct7D: p.apyPct7D !== null ? Math.round(p.apyPct7D * 100) / 100 : null,
|
|
1122122
|
+
apyPct30D: p.apyPct30D !== null ? Math.round(p.apyPct30D * 100) / 100 : null,
|
|
1122123
|
+
volumeUsd1d: p.volumeUsd1d !== null ? Math.round(p.volumeUsd1d) : null,
|
|
1122124
|
+
volumeUsd7d: p.volumeUsd7d !== null ? Math.round(p.volumeUsd7d) : null,
|
|
1122125
|
+
ilRisk: p.ilRisk,
|
|
1122126
|
+
stablecoin: p.stablecoin,
|
|
1122127
|
+
poolMeta: p.poolMeta
|
|
1122128
|
+
}))
|
|
1122129
|
+
};
|
|
1122130
|
+
} catch (error48) {
|
|
1122131
|
+
return { error: `Failed to get Uniswap yields: ${error48.message}` };
|
|
1122132
|
+
}
|
|
1122133
|
+
}
|
|
1122134
|
+
});
|
|
1122135
|
+
getTopYieldsTool = createTool({
|
|
1122136
|
+
id: "get_top_defi_yields",
|
|
1122137
|
+
description: "Get the highest-yielding DeFi pools across all protocols from DefiLlama. " + "Includes Uniswap, Aave, Compound, Aerodrome, Curve, and all tracked protocols. " + "Use for finding the best yield opportunities, comparing protocols, and yield farming research.",
|
|
1122138
|
+
inputSchema: exports_external.object({
|
|
1122139
|
+
chain: exports_external.string().optional().describe("Chain name (e.g., 'ethereum', 'base', 'arbitrum'). Omit for all chains."),
|
|
1122140
|
+
limit: exports_external.number().min(1).max(50).default(20).describe("Max pools to return"),
|
|
1122141
|
+
minTvl: exports_external.number().default(1e5).describe("Minimum TVL in USD (default: 100000)")
|
|
1122142
|
+
}),
|
|
1122143
|
+
outputSchema: exports_external.object({
|
|
1122144
|
+
pools: exports_external.array(exports_external.object({
|
|
1122145
|
+
pool: exports_external.string(),
|
|
1122146
|
+
project: exports_external.string(),
|
|
1122147
|
+
symbol: exports_external.string(),
|
|
1122148
|
+
chain: exports_external.string(),
|
|
1122149
|
+
tvlUsd: exports_external.number(),
|
|
1122150
|
+
apy: exports_external.number(),
|
|
1122151
|
+
apyBase: exports_external.number().nullable(),
|
|
1122152
|
+
apyReward: exports_external.number().nullable(),
|
|
1122153
|
+
stablecoin: exports_external.boolean(),
|
|
1122154
|
+
ilRisk: exports_external.string()
|
|
1122155
|
+
})).optional(),
|
|
1122156
|
+
count: exports_external.number().optional(),
|
|
1122157
|
+
error: exports_external.string().optional()
|
|
1122158
|
+
}),
|
|
1122159
|
+
execute: async ({ chain, limit, minTvl }) => {
|
|
1122160
|
+
try {
|
|
1122161
|
+
const pools = await getTopYieldPools(chain, limit, minTvl);
|
|
1122162
|
+
return {
|
|
1122163
|
+
count: pools.length,
|
|
1122164
|
+
pools: pools.map((p) => ({
|
|
1122165
|
+
pool: p.pool,
|
|
1122166
|
+
project: p.project,
|
|
1122167
|
+
symbol: p.symbol,
|
|
1122168
|
+
chain: p.chain,
|
|
1122169
|
+
tvlUsd: Math.round(p.tvlUsd),
|
|
1122170
|
+
apy: Math.round(p.apy * 100) / 100,
|
|
1122171
|
+
apyBase: p.apyBase !== null ? Math.round(p.apyBase * 100) / 100 : null,
|
|
1122172
|
+
apyReward: p.apyReward !== null ? Math.round(p.apyReward * 100) / 100 : null,
|
|
1122173
|
+
stablecoin: p.stablecoin,
|
|
1122174
|
+
ilRisk: p.ilRisk
|
|
1122175
|
+
}))
|
|
1122176
|
+
};
|
|
1122177
|
+
} catch (error48) {
|
|
1122178
|
+
return { error: `Failed to get top yields: ${error48.message}` };
|
|
1122179
|
+
}
|
|
1122180
|
+
}
|
|
1122181
|
+
});
|
|
1122182
|
+
defillamaYieldTools = {
|
|
1122183
|
+
get_uniswap_pool_yields: getUniswapYieldsTool,
|
|
1122184
|
+
get_top_defi_yields: getTopYieldsTool
|
|
1122185
|
+
};
|
|
1122186
|
+
});
|
|
1122187
|
+
|
|
1120718
1122188
|
// src/infra/agents/tools/position-tracking.ts
|
|
1120719
1122189
|
async function getManager() {
|
|
1120720
1122190
|
return getPositionManager(getEventBus());
|
|
@@ -1127074,6 +1128544,9 @@ var init_tools3 = __esm(async () => {
|
|
|
1127074
1128544
|
init_agentkit_defi();
|
|
1127075
1128545
|
init_base_signals();
|
|
1127076
1128546
|
init_base_indexers();
|
|
1128547
|
+
init_uniswap_data();
|
|
1128548
|
+
init_dex_search();
|
|
1128549
|
+
init_defillama_yields();
|
|
1127077
1128550
|
init_position_tracking();
|
|
1127078
1128551
|
init_risk_gate();
|
|
1127079
1128552
|
init_memory_tools();
|
|
@@ -1127125,6 +1128598,9 @@ var init_tools3 = __esm(async () => {
|
|
|
1127125
1128598
|
init_agentkit_defi();
|
|
1127126
1128599
|
init_base_signals();
|
|
1127127
1128600
|
init_base_indexers();
|
|
1128601
|
+
init_uniswap_data();
|
|
1128602
|
+
init_dex_search();
|
|
1128603
|
+
init_defillama_yields();
|
|
1127128
1128604
|
init_position_tracking();
|
|
1127129
1128605
|
init_risk_gate();
|
|
1127130
1128606
|
init_memory_tools();
|
|
@@ -1127180,6 +1128656,9 @@ var init_tools3 = __esm(async () => {
|
|
|
1127180
1128656
|
...agentKitDefiTools,
|
|
1127181
1128657
|
...baseSignalTools,
|
|
1127182
1128658
|
...baseIndexerTools,
|
|
1128659
|
+
...uniswapDataTools,
|
|
1128660
|
+
...dexSearchTools,
|
|
1128661
|
+
...defillamaYieldTools,
|
|
1127183
1128662
|
...multiModalChartTools,
|
|
1127184
1128663
|
...evalTools,
|
|
1127185
1128664
|
...positionTrackingTools,
|
|
@@ -1127226,6 +1128705,9 @@ var init_tools3 = __esm(async () => {
|
|
|
1127226
1128705
|
agentKitDefi: Object.keys(agentKitDefiTools).length,
|
|
1127227
1128706
|
baseSignals: Object.keys(baseSignalTools).length,
|
|
1127228
1128707
|
baseIndexers: Object.keys(baseIndexerTools).length,
|
|
1128708
|
+
uniswapData: Object.keys(uniswapDataTools).length,
|
|
1128709
|
+
dexSearch: Object.keys(dexSearchTools).length,
|
|
1128710
|
+
defillamaYields: Object.keys(defillamaYieldTools).length,
|
|
1127229
1128711
|
multiModalCharts: Object.keys(multiModalChartTools).length,
|
|
1127230
1128712
|
evals: Object.keys(evalTools).length,
|
|
1127231
1128713
|
positionTracking: Object.keys(positionTrackingTools).length,
|
|
@@ -1140867,7 +1142349,7 @@ class ExperimentalClientTasks {
|
|
|
1140867
1142349
|
return this._client.requestStream(request, resultSchema, options);
|
|
1140868
1142350
|
}
|
|
1140869
1142351
|
}
|
|
1140870
|
-
var
|
|
1142352
|
+
var init_client12 = __esm(() => {
|
|
1140871
1142353
|
init_types19();
|
|
1140872
1142354
|
});
|
|
1140873
1142355
|
|
|
@@ -1140949,12 +1142431,12 @@ function getSupportedElicitationModes(capabilities) {
|
|
|
1140949
1142431
|
return { supportsFormMode, supportsUrlMode };
|
|
1140950
1142432
|
}
|
|
1140951
1142433
|
var Client2;
|
|
1140952
|
-
var
|
|
1142434
|
+
var init_client13 = __esm(() => {
|
|
1140953
1142435
|
init_protocol3();
|
|
1140954
1142436
|
init_types19();
|
|
1140955
1142437
|
init_ajv_provider();
|
|
1140956
1142438
|
init_zod_compat();
|
|
1140957
|
-
|
|
1142439
|
+
init_client12();
|
|
1140958
1142440
|
Client2 = class Client2 extends Protocol {
|
|
1140959
1142441
|
constructor(_clientInfo, options) {
|
|
1140960
1142442
|
super(options);
|
|
@@ -1148833,7 +1150315,7 @@ var init_dist18 = __esm(() => {
|
|
|
1148833
1150315
|
init_error();
|
|
1148834
1150316
|
init_tools();
|
|
1148835
1150317
|
init_utils();
|
|
1148836
|
-
|
|
1150318
|
+
init_client13();
|
|
1148837
1150319
|
init_sse();
|
|
1148838
1150320
|
init_stdio2();
|
|
1148839
1150321
|
init_streamableHttp();
|
|
@@ -1150405,7 +1151887,7 @@ function disableMCPHotReload() {
|
|
|
1150405
1151887
|
}
|
|
1150406
1151888
|
}
|
|
1150407
1151889
|
var _mcpClient = null, _mcpTools = null, _initPromise = null, _hotReloadTimer = null, _lastPluginFingerprint = null;
|
|
1150408
|
-
var
|
|
1151890
|
+
var init_client14 = __esm(() => {
|
|
1150409
1151891
|
init_dist18();
|
|
1150410
1151892
|
init_installer();
|
|
1150411
1151893
|
init_credentials();
|
|
@@ -1150499,6 +1151981,10 @@ function getScannerAgent() {
|
|
|
1150499
1151981
|
defillama_search_protocols: instrumentedAgentKitDefiTools.defillama_search_protocols,
|
|
1150500
1151982
|
indexer_top_pools: instrumentedBaseIndexerTools.indexer_top_pools,
|
|
1150501
1151983
|
indexer_aerodrome_pools: instrumentedBaseIndexerTools.indexer_aerodrome_pools,
|
|
1151984
|
+
search_dex_pairs: instrumentedDexSearchTools.search_dex_pairs,
|
|
1151985
|
+
get_boosted_tokens: instrumentedDexSearchTools.get_boosted_tokens,
|
|
1151986
|
+
get_uniswap_protocol_overview: instrumentedUniswapDataTools.get_uniswap_protocol_overview,
|
|
1151987
|
+
get_liquidity_events: instrumentedUniswapDataTools.get_liquidity_events,
|
|
1150502
1151988
|
report_setup: instrumentedPositionTrackingTools.report_setup,
|
|
1150503
1151989
|
...instrumentedMemoryTools,
|
|
1150504
1151990
|
...instrumentedPlaybookTools,
|
|
@@ -1150542,6 +1152028,14 @@ function getAnalystAgent() {
|
|
|
1150542
1152028
|
defillama_get_protocol: instrumentedAgentKitDefiTools.defillama_get_protocol,
|
|
1150543
1152029
|
defillama_get_token_prices: instrumentedAgentKitDefiTools.defillama_get_token_prices,
|
|
1150544
1152030
|
indexer_pool_stats: instrumentedBaseIndexerTools.indexer_pool_stats,
|
|
1152031
|
+
get_pool_tick_liquidity: instrumentedUniswapDataTools.get_pool_tick_liquidity,
|
|
1152032
|
+
get_liquidity_events: instrumentedUniswapDataTools.get_liquidity_events,
|
|
1152033
|
+
get_pool_flash_events: instrumentedUniswapDataTools.get_pool_flash_events,
|
|
1152034
|
+
get_fee_collections: instrumentedUniswapDataTools.get_fee_collections,
|
|
1152035
|
+
get_uniswap_protocol_overview: instrumentedUniswapDataTools.get_uniswap_protocol_overview,
|
|
1152036
|
+
get_uniswap_pool_yields: instrumentedDefillamaYieldTools.get_uniswap_pool_yields,
|
|
1152037
|
+
get_top_defi_yields: instrumentedDefillamaYieldTools.get_top_defi_yields,
|
|
1152038
|
+
search_dex_pairs: instrumentedDexSearchTools.search_dex_pairs,
|
|
1150545
1152039
|
track_base_wallet: instrumentedBaseSignalTools.track_base_wallet,
|
|
1150546
1152040
|
get_base_token_holders: instrumentedBaseSignalTools.get_base_token_holders,
|
|
1150547
1152041
|
get_base_dex_pairs: instrumentedBaseSignalTools.get_base_dex_pairs,
|
|
@@ -1150684,6 +1152178,8 @@ function getMonitorAgent() {
|
|
|
1150684
1152178
|
agentkit_get_wallet: instrumentedAgentKitOnchainTools.agentkit_get_wallet,
|
|
1150685
1152179
|
agentkit_get_balance: instrumentedAgentKitOnchainTools.agentkit_get_balance,
|
|
1150686
1152180
|
agentkit_erc20_balance: instrumentedAgentKitOnchainTools.agentkit_erc20_balance,
|
|
1152181
|
+
get_lp_positions: instrumentedUniswapDataTools.get_lp_positions,
|
|
1152182
|
+
get_fee_collections: instrumentedUniswapDataTools.get_fee_collections,
|
|
1150687
1152183
|
...instrumentedSharedContextTools,
|
|
1150688
1152184
|
record_trade_outcome: instrumentedEvalTools.record_trade_outcome,
|
|
1150689
1152185
|
get_performance_report: instrumentedEvalTools.get_performance_report,
|
|
@@ -1150796,7 +1152292,7 @@ function resetAgents() {
|
|
|
1150796
1152292
|
_agents = {};
|
|
1150797
1152293
|
_subAgentMemory = null;
|
|
1150798
1152294
|
}
|
|
1150799
|
-
var DEFAULT_MEMORY_CONFIG, _memoryConfig, instrumentedIndicatorTools, instrumentedExplainTools, instrumentedMarketTools, instrumentedPositionTools, instrumentedSchedulerTools, instrumentedSystemTools, instrumentedEarnTools, instrumentedChartTools, instrumentedOrderbookTools, instrumentedWalletTools, instrumentedDiscoveryTools, instrumentedHistoryTools, instrumentedAccountTools, instrumentedTradingTools, instrumentedMarketAnalysisTools, instrumentedLiquidationIntelligenceTools, instrumentedRiskManagementTools, instrumentedStrategyTools, instrumentedMetricsTools, instrumentedCompositionTools, instrumentedBacktestTools, instrumentedSharedContextTools, instrumentedParallelAnalysisTools, instrumentedStrategyGenerationTools, instrumentedMultiModalChartTools, instrumentedMarketDataTools, instrumentedPairAnalysisTools, instrumentedAutonomousTools, instrumentedBaseOnchainTools, instrumentedAgentKitOnchainTools, instrumentedAgentKitDefiTools, instrumentedBaseSignalTools, instrumentedBaseIndexerTools, instrumentedEvalTools, instrumentedPositionTrackingTools, instrumentedMemoryTools, instrumentedPlaybookTools, instrumentedPlaybookBacktestTools, instrumentedAuditTools, instrumentedProtocolTools, instrumentedRegimeTools, instrumentedRuntimeTools, instrumentedAdvancedTools, instrumentedCheckRiskTool, WORKING_MEMORY_TEMPLATE = `
|
|
1152295
|
+
var DEFAULT_MEMORY_CONFIG, _memoryConfig, instrumentedIndicatorTools, instrumentedExplainTools, instrumentedMarketTools, instrumentedPositionTools, instrumentedSchedulerTools, instrumentedSystemTools, instrumentedEarnTools, instrumentedChartTools, instrumentedOrderbookTools, instrumentedWalletTools, instrumentedDiscoveryTools, instrumentedHistoryTools, instrumentedAccountTools, instrumentedTradingTools, instrumentedMarketAnalysisTools, instrumentedLiquidationIntelligenceTools, instrumentedRiskManagementTools, instrumentedStrategyTools, instrumentedMetricsTools, instrumentedCompositionTools, instrumentedBacktestTools, instrumentedSharedContextTools, instrumentedParallelAnalysisTools, instrumentedStrategyGenerationTools, instrumentedMultiModalChartTools, instrumentedMarketDataTools, instrumentedPairAnalysisTools, instrumentedAutonomousTools, instrumentedBaseOnchainTools, instrumentedAgentKitOnchainTools, instrumentedAgentKitDefiTools, instrumentedBaseSignalTools, instrumentedBaseIndexerTools, instrumentedUniswapDataTools, instrumentedDexSearchTools, instrumentedDefillamaYieldTools, instrumentedEvalTools, instrumentedPositionTrackingTools, instrumentedMemoryTools, instrumentedPlaybookTools, instrumentedPlaybookBacktestTools, instrumentedAuditTools, instrumentedProtocolTools, instrumentedRegimeTools, instrumentedRuntimeTools, instrumentedAdvancedTools, instrumentedCheckRiskTool, WORKING_MEMORY_TEMPLATE = `
|
|
1150800
1152296
|
# Trader Profile
|
|
1150801
1152297
|
|
|
1150802
1152298
|
## Personal Info
|
|
@@ -1151402,7 +1152898,7 @@ var init_agents = __esm(async () => {
|
|
|
1151402
1152898
|
init_registry2();
|
|
1151403
1152899
|
init_shared_context();
|
|
1151404
1152900
|
init_evals2();
|
|
1151405
|
-
|
|
1152901
|
+
init_client14();
|
|
1151406
1152902
|
await init_tools3();
|
|
1151407
1152903
|
DEFAULT_MEMORY_CONFIG = {
|
|
1151408
1152904
|
lastMessages: 20,
|
|
@@ -1151443,6 +1152939,9 @@ var init_agents = __esm(async () => {
|
|
|
1151443
1152939
|
instrumentedAgentKitDefiTools = withToolsMetrics(agentKitDefiTools);
|
|
1151444
1152940
|
instrumentedBaseSignalTools = withToolsMetrics(baseSignalTools);
|
|
1151445
1152941
|
instrumentedBaseIndexerTools = withToolsMetrics(baseIndexerTools);
|
|
1152942
|
+
instrumentedUniswapDataTools = withToolsMetrics(uniswapDataTools);
|
|
1152943
|
+
instrumentedDexSearchTools = withToolsMetrics(dexSearchTools);
|
|
1152944
|
+
instrumentedDefillamaYieldTools = withToolsMetrics(defillamaYieldTools);
|
|
1151446
1152945
|
instrumentedEvalTools = withToolsMetrics(evalTools);
|
|
1151447
1152946
|
instrumentedPositionTrackingTools = withToolsMetrics(positionTrackingTools);
|
|
1151448
1152947
|
instrumentedMemoryTools = withToolsMetrics(memoryTools);
|
|
@@ -1153279,6 +1154778,16 @@ var init_orchestrator = __esm(async () => {
|
|
|
1153279
1154778
|
indexer_top_pools: "Scanner",
|
|
1153280
1154779
|
indexer_pool_stats: "Analyst",
|
|
1153281
1154780
|
indexer_aerodrome_pools: "Scanner",
|
|
1154781
|
+
get_pool_tick_liquidity: "Analyst",
|
|
1154782
|
+
get_liquidity_events: "Scanner",
|
|
1154783
|
+
get_pool_flash_events: "Analyst",
|
|
1154784
|
+
get_lp_positions: "Monitor",
|
|
1154785
|
+
get_uniswap_protocol_overview: "Scanner",
|
|
1154786
|
+
get_fee_collections: "Monitor",
|
|
1154787
|
+
search_dex_pairs: "Scanner",
|
|
1154788
|
+
get_boosted_tokens: "Scanner",
|
|
1154789
|
+
get_uniswap_pool_yields: "Analyst",
|
|
1154790
|
+
get_top_defi_yields: "Analyst",
|
|
1153282
1154791
|
scan_base_whale_transfers: "Scanner",
|
|
1153283
1154792
|
scan_base_volume_spikes: "Scanner",
|
|
1153284
1154793
|
scan_base_new_tokens: "Scanner",
|
|
@@ -1155427,7 +1156936,7 @@ async function checkOrphanedOrders(exchange, activeTrades, result) {
|
|
|
1155427
1156936
|
}
|
|
1155428
1156937
|
|
|
1155429
1156938
|
// src/gateway/runtime/gateway-runtime.ts
|
|
1155430
|
-
|
|
1156939
|
+
init_client14();
|
|
1155431
1156940
|
|
|
1155432
1156941
|
// src/gateway/scheduler/local-cron.ts
|
|
1155433
1156942
|
init_logger2();
|
|
@@ -1156281,7 +1157790,7 @@ class ReconciliationLoop {
|
|
|
1156281
1157790
|
}
|
|
1156282
1157791
|
}
|
|
1156283
1157792
|
// src/gateway/daemon/process.ts
|
|
1156284
|
-
|
|
1157793
|
+
init_client14();
|
|
1156285
1157794
|
init_engine();
|
|
1156286
1157795
|
var logger116 = createModuleLogger("gateway-daemon");
|
|
1156287
1157796
|
async function startGatewayDaemonProcess() {
|
|
@@ -1162414,7 +1163923,7 @@ var import_react64 = __toESM(require_react(), 1);
|
|
|
1162414
1163923
|
// package.json
|
|
1162415
1163924
|
var package_default2 = {
|
|
1162416
1163925
|
name: "@general-liquidity/gordon-cli",
|
|
1162417
|
-
version: "0.75.
|
|
1163926
|
+
version: "0.75.6",
|
|
1162418
1163927
|
description: "The Frontier Trading Agent",
|
|
1162419
1163928
|
author: "General Liquidity, Inc.",
|
|
1162420
1163929
|
license: "MIT",
|
|
@@ -1164542,7 +1166051,7 @@ async function ensureThreadRegistered() {
|
|
|
1164542
1166051
|
|
|
1164543
1166052
|
// src/infra/agents/index.ts
|
|
1164544
1166053
|
init_memory3();
|
|
1164545
|
-
|
|
1166054
|
+
init_client14();
|
|
1164546
1166055
|
init_reflection();
|
|
1164547
1166056
|
|
|
1164548
1166057
|
// src/app/SetupWizard.tsx
|
|
@@ -1166459,7 +1167968,7 @@ function useTheme() {
|
|
|
1166459
1167968
|
}
|
|
1166460
1167969
|
|
|
1166461
1167970
|
// src/app/App.tsx
|
|
1166462
|
-
|
|
1167971
|
+
init_client14();
|
|
1166463
1167972
|
init_llm();
|
|
1166464
1167973
|
init_binance2();
|
|
1166465
1167974
|
init_exchange();
|
|
@@ -1172691,7 +1174200,7 @@ async function checkForUpdates() {
|
|
|
1172691
1174200
|
|
|
1172692
1174201
|
// src/index.tsx
|
|
1172693
1174202
|
init_telemetry2();
|
|
1172694
|
-
|
|
1174203
|
+
init_client14();
|
|
1172695
1174204
|
var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
|
|
1172696
1174205
|
var flags = parseFlags();
|
|
1172697
1174206
|
var command = parseCommand();
|