@general-liquidity/gordon-cli 0.75.3 → 0.75.5

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.
Files changed (2) hide show
  1. package/dist/gordon.js +1937 -81
  2. 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
  }
@@ -14715,7 +14723,7 @@ var init_config = __esm(() => {
14715
14723
  apiSecret: exports_external.string(),
14716
14724
  permissions: ExchangePermissionsSchema
14717
14725
  });
14718
- ExchangeTypeSchema = exports_external.enum(["binance", "binance_us", "coinbase", "kraken", "bitfinex", "hyperliquid"]);
14726
+ ExchangeTypeSchema = exports_external.enum(["binance", "binance_us", "coinbase", "kraken", "bitfinex", "hyperliquid", "uniswap"]);
14719
14727
  MultiExchangeConfigSchema = exports_external.object({
14720
14728
  id: exports_external.string(),
14721
14729
  type: ExchangeTypeSchema,
@@ -195776,9 +195784,1472 @@ var init_hyperliquid3 = __esm(() => {
195776
195784
  init_errors3();
195777
195785
  });
195778
195786
 
195787
+ // src/infra/uniswap/types.ts
195788
+ var NATIVE_TOKEN = "0x0000000000000000000000000000000000000000", GAS_BUFFER_PERCENT = 0.15, WRAPPED_NATIVE, USDC_ADDRESSES, SUPPORTED_CHAIN_IDS, CHAIN_NAMES;
195789
+ var init_types10 = __esm(() => {
195790
+ WRAPPED_NATIVE = {
195791
+ 1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
195792
+ 10: "0x4200000000000000000000000000000000000006",
195793
+ 56: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
195794
+ 137: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
195795
+ 8453: "0x4200000000000000000000000000000000000006",
195796
+ 42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
195797
+ 43114: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7"
195798
+ };
195799
+ USDC_ADDRESSES = {
195800
+ 1: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
195801
+ 10: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
195802
+ 56: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
195803
+ 137: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
195804
+ 8453: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
195805
+ 42161: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
195806
+ 43114: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"
195807
+ };
195808
+ SUPPORTED_CHAIN_IDS = [1, 10, 56, 130, 137, 196, 324, 480, 1868, 8453, 42161, 42220, 43114, 81457, 7777777];
195809
+ CHAIN_NAMES = {
195810
+ 1: "Ethereum",
195811
+ 10: "Optimism",
195812
+ 56: "BNB Chain",
195813
+ 130: "Unichain",
195814
+ 137: "Polygon",
195815
+ 196: "X Layer",
195816
+ 324: "zkSync",
195817
+ 480: "World Chain",
195818
+ 1868: "Soneium",
195819
+ 8453: "Base",
195820
+ 42161: "Arbitrum",
195821
+ 42220: "Celo",
195822
+ 43114: "Avalanche",
195823
+ 81457: "Blast",
195824
+ 7777777: "Zora"
195825
+ };
195826
+ });
195827
+
195828
+ // src/infra/uniswap/token-list.ts
195829
+ class UniswapTokenList {
195830
+ bySymbol = new Map;
195831
+ byAddress = new Map;
195832
+ cache = new Cache({ defaultTtl: CACHE_TTL_MS2, maxEntries: 1 });
195833
+ fetchPromise = null;
195834
+ isLoaded() {
195835
+ return this.cache.has("loaded");
195836
+ }
195837
+ async ensureLoaded() {
195838
+ if (this.isLoaded())
195839
+ return;
195840
+ if (this.fetchPromise)
195841
+ return this.fetchPromise;
195842
+ this.fetchPromise = this.fetchList();
195843
+ try {
195844
+ await this.fetchPromise;
195845
+ } finally {
195846
+ this.fetchPromise = null;
195847
+ }
195848
+ }
195849
+ async fetchList() {
195850
+ try {
195851
+ const res = await fetch(TOKEN_LIST_URL);
195852
+ if (!res.ok)
195853
+ throw new Error(`Token list fetch failed: ${res.status}`);
195854
+ const data = await res.json();
195855
+ this.buildMaps(data.tokens);
195856
+ this.cache.set("loaded", true, CACHE_TTL_MS2);
195857
+ } catch {
195858
+ if (this.bySymbol.size === 0) {
195859
+ this.buildHardcodedFallback();
195860
+ }
195861
+ }
195862
+ }
195863
+ buildMaps(tokens) {
195864
+ this.bySymbol.clear();
195865
+ this.byAddress.clear();
195866
+ const supportedChains = new Set(SUPPORTED_CHAIN_IDS);
195867
+ for (const raw of tokens) {
195868
+ if (supportedChains.has(raw.chainId)) {
195869
+ this.addToken({
195870
+ chainId: raw.chainId,
195871
+ address: raw.address,
195872
+ symbol: raw.symbol,
195873
+ name: raw.name,
195874
+ decimals: raw.decimals,
195875
+ logoURI: raw.logoURI
195876
+ });
195877
+ }
195878
+ if (raw.extensions?.bridgeInfo) {
195879
+ for (const [chainIdStr, bridge] of Object.entries(raw.extensions.bridgeInfo)) {
195880
+ const bridgeChainId = Number(chainIdStr);
195881
+ if (supportedChains.has(bridgeChainId)) {
195882
+ this.addToken({
195883
+ chainId: bridgeChainId,
195884
+ address: bridge.tokenAddress,
195885
+ symbol: raw.symbol,
195886
+ name: raw.name,
195887
+ decimals: raw.decimals,
195888
+ logoURI: raw.logoURI
195889
+ });
195890
+ }
195891
+ }
195892
+ }
195893
+ }
195894
+ }
195895
+ buildHardcodedFallback() {
195896
+ for (const [chainIdStr, address] of Object.entries(WRAPPED_NATIVE)) {
195897
+ const chainId = Number(chainIdStr);
195898
+ const symbol16 = chainId === 56 ? "WBNB" : chainId === 137 ? "WMATIC" : chainId === 43114 ? "WAVAX" : "WETH";
195899
+ this.addToken({ chainId, address, symbol: symbol16, name: `Wrapped Native (${symbol16})`, decimals: 18 });
195900
+ }
195901
+ for (const [chainIdStr, address] of Object.entries(USDC_ADDRESSES)) {
195902
+ const chainId = Number(chainIdStr);
195903
+ this.addToken({ chainId, address, symbol: "USDC", name: "USD Coin", decimals: 6 });
195904
+ }
195905
+ this.cache.set("loaded", true, CACHE_TTL_MS2);
195906
+ }
195907
+ addToken(token) {
195908
+ const key = `${token.symbol.toUpperCase()}:${token.chainId}`;
195909
+ const existing = this.bySymbol.get(key) || [];
195910
+ if (!existing.some((t2) => t2.address.toLowerCase() === token.address.toLowerCase())) {
195911
+ existing.push(token);
195912
+ this.bySymbol.set(key, existing);
195913
+ }
195914
+ this.byAddress.set(token.address.toLowerCase(), token);
195915
+ }
195916
+ async resolve(symbol16, chainId) {
195917
+ await this.ensureLoaded();
195918
+ const sym = symbol16.toUpperCase();
195919
+ const exact = this.bySymbol.get(`${sym}:${chainId}`);
195920
+ if (exact && exact.length > 0)
195921
+ return exact[0].address;
195922
+ const mainnet = this.bySymbol.get(`${sym}:1`);
195923
+ if (mainnet && mainnet.length > 0) {
195924
+ return mainnet[0].address;
195925
+ }
195926
+ for (const [key, tokens] of this.bySymbol) {
195927
+ if (key.startsWith(`${sym}:`)) {
195928
+ return tokens[0].address;
195929
+ }
195930
+ }
195931
+ return null;
195932
+ }
195933
+ async getToken(symbol16, chainId) {
195934
+ await this.ensureLoaded();
195935
+ const sym = symbol16.toUpperCase();
195936
+ const exact = this.bySymbol.get(`${sym}:${chainId}`);
195937
+ if (exact && exact.length > 0)
195938
+ return exact[0];
195939
+ const mainnet = this.bySymbol.get(`${sym}:1`);
195940
+ if (mainnet && mainnet.length > 0)
195941
+ return mainnet[0];
195942
+ return null;
195943
+ }
195944
+ async getTokenByAddress(address) {
195945
+ await this.ensureLoaded();
195946
+ return this.byAddress.get(address.toLowerCase()) || null;
195947
+ }
195948
+ }
195949
+ var TOKEN_LIST_URL = "https://tokens.uniswap.org", CACHE_TTL_MS2;
195950
+ var init_token_list = __esm(() => {
195951
+ init_types10();
195952
+ CACHE_TTL_MS2 = 24 * 60 * 60 * 1000;
195953
+ });
195954
+
195955
+ // src/infra/uniswap/client.ts
195956
+ class UniswapClient {
195957
+ apiKey;
195958
+ walletAddress;
195959
+ chainId;
195960
+ rateLimitState;
195961
+ circuitState = "closed";
195962
+ consecutiveFailures = 0;
195963
+ tokenList = new UniswapTokenList;
195964
+ constructor(apiKey, walletAddress, chainId = 1) {
195965
+ this.apiKey = apiKey;
195966
+ this.walletAddress = walletAddress;
195967
+ this.chainId = chainId;
195968
+ this.rateLimitState = {
195969
+ requestCount: 0,
195970
+ lastReset: Date.now(),
195971
+ throttledCount: 0
195972
+ };
195973
+ }
195974
+ get address() {
195975
+ return this.walletAddress;
195976
+ }
195977
+ get chain() {
195978
+ return this.chainId;
195979
+ }
195980
+ checkRateLimit() {
195981
+ const now2 = Date.now();
195982
+ if (now2 - this.rateLimitState.lastReset > 60000) {
195983
+ this.rateLimitState.requestCount = 0;
195984
+ this.rateLimitState.lastReset = now2;
195985
+ this.rateLimitState.throttledCount = 0;
195986
+ }
195987
+ }
195988
+ shouldThrottle() {
195989
+ this.checkRateLimit();
195990
+ return this.circuitState === "open" || this.rateLimitState.requestCount > RATE_LIMIT_CONFIG6.throttleThreshold;
195991
+ }
195992
+ getRateLimitStatus() {
195993
+ this.checkRateLimit();
195994
+ const usagePercent = this.rateLimitState.requestCount / RATE_LIMIT_CONFIG6.maxRequestsPerMinute * 100;
195995
+ return {
195996
+ currentRequests: this.rateLimitState.requestCount,
195997
+ maxRequests: RATE_LIMIT_CONFIG6.maxRequestsPerMinute,
195998
+ usagePercent: Math.round(usagePercent),
195999
+ isThrottling: this.shouldThrottle(),
196000
+ throttledCount: this.rateLimitState.throttledCount,
196001
+ timeUntilReset: Math.max(0, 60000 - (Date.now() - this.rateLimitState.lastReset))
196002
+ };
196003
+ }
196004
+ getCircuitBreakerState() {
196005
+ return this.circuitState;
196006
+ }
196007
+ resetCircuitBreaker() {
196008
+ this.circuitState = "closed";
196009
+ this.consecutiveFailures = 0;
196010
+ }
196011
+ getUsdcAddress() {
196012
+ return USDC_ADDRESSES[this.chainId] || USDC_ADDRESSES[1];
196013
+ }
196014
+ getWrappedNative() {
196015
+ return WRAPPED_NATIVE[this.chainId] || WRAPPED_NATIVE[1];
196016
+ }
196017
+ isNativeToken(token) {
196018
+ return token.toLowerCase() === NATIVE_TOKEN.toLowerCase();
196019
+ }
196020
+ async resolveSymbol(symbol16) {
196021
+ const s = symbol16.toUpperCase().replace(/[_\-/]/g, "");
196022
+ if (s.startsWith("0X") && s.includes("0X", 3)) {
196023
+ const parts = symbol16.split(/[_\-/]/);
196024
+ if (parts.length === 2) {
196025
+ const inToken = await this.tokenList.getTokenByAddress(parts[0]);
196026
+ const outToken = await this.tokenList.getTokenByAddress(parts[1]);
196027
+ return {
196028
+ tokenIn: parts[0],
196029
+ tokenOut: parts[1],
196030
+ tokenInDecimals: inToken?.decimals ?? 18,
196031
+ tokenOutDecimals: outToken?.decimals ?? 18
196032
+ };
196033
+ }
196034
+ }
196035
+ const quotePatterns = [
196036
+ [/USDC$/, "USDC", () => this.getUsdcAddress(), 6],
196037
+ [/USDT$/, "USDT", () => this.getUsdcAddress(), 6],
196038
+ [/ETH$/, "ETH", () => this.getWrappedNative(), 18],
196039
+ [/WETH$/, "WETH", () => this.getWrappedNative(), 18]
196040
+ ];
196041
+ for (const [pattern2, _quoteName, getQuoteAddress, quoteDecimals] of quotePatterns) {
196042
+ if (pattern2.test(s)) {
196043
+ const base2 = s.replace(pattern2, "");
196044
+ if (!base2)
196045
+ continue;
196046
+ if (base2 === "ETH" || base2 === "WETH") {
196047
+ return {
196048
+ tokenIn: this.getWrappedNative(),
196049
+ tokenOut: getQuoteAddress(),
196050
+ tokenInDecimals: 18,
196051
+ tokenOutDecimals: quoteDecimals
196052
+ };
196053
+ }
196054
+ const baseToken = await this.tokenList.getToken(base2, this.chainId);
196055
+ if (baseToken) {
196056
+ return {
196057
+ tokenIn: baseToken.address,
196058
+ tokenOut: getQuoteAddress(),
196059
+ tokenInDecimals: baseToken.decimals,
196060
+ tokenOutDecimals: quoteDecimals
196061
+ };
196062
+ }
196063
+ throw new Error(`Unknown token "${base2}" \u2014 not found in Uniswap token list for chain ${this.chainId}. ` + `Use a token address directly (e.g., "0x1234.../0xABCD...").`);
196064
+ }
196065
+ }
196066
+ throw new Error(`Cannot resolve symbol "${symbol16}" to token addresses. ` + `Use a supported pair like "UNIUSDC", "LINKETH", or raw addresses "0xABC.../0xDEF...".`);
196067
+ }
196068
+ async request(path5, body, extraHeaders) {
196069
+ this.checkRateLimit();
196070
+ this.rateLimitState.requestCount++;
196071
+ const url2 = `${BASE_URL4}${path5}`;
196072
+ const headers = {
196073
+ "Content-Type": "application/json",
196074
+ "x-api-key": this.apiKey,
196075
+ "x-universal-router-version": "2.0",
196076
+ ...extraHeaders
196077
+ };
196078
+ let lastError = null;
196079
+ for (let attempt = 0;attempt <= MAX_RETRIES2; attempt++) {
196080
+ if (attempt > 0) {
196081
+ const delay5 = BASE_DELAY_MS * 2 ** (attempt - 1);
196082
+ await new Promise((r) => setTimeout(r, delay5));
196083
+ }
196084
+ try {
196085
+ const res = await fetch(url2, {
196086
+ method: "POST",
196087
+ headers,
196088
+ body: JSON.stringify(body)
196089
+ });
196090
+ if (res.ok) {
196091
+ this.consecutiveFailures = 0;
196092
+ if (this.circuitState === "half-open")
196093
+ this.circuitState = "closed";
196094
+ return res.json();
196095
+ }
196096
+ const errorBody = await res.text().catch(() => "");
196097
+ if ([429, 500, 503].includes(res.status) && attempt < MAX_RETRIES2) {
196098
+ if (res.status === 429)
196099
+ this.rateLimitState.throttledCount++;
196100
+ lastError = new Error(`Uniswap API error ${res.status}: ${errorBody}`);
196101
+ continue;
196102
+ }
196103
+ this.consecutiveFailures++;
196104
+ if (this.consecutiveFailures >= 5)
196105
+ this.circuitState = "open";
196106
+ throw new Error(`Uniswap API error ${res.status}: ${errorBody}`);
196107
+ } catch (err) {
196108
+ if (err instanceof Error && err.message.startsWith("Uniswap API error")) {
196109
+ throw err;
196110
+ }
196111
+ lastError = err instanceof Error ? err : new Error(String(err));
196112
+ if (attempt >= MAX_RETRIES2) {
196113
+ this.consecutiveFailures++;
196114
+ if (this.consecutiveFailures >= 5)
196115
+ this.circuitState = "open";
196116
+ throw lastError;
196117
+ }
196118
+ }
196119
+ }
196120
+ throw lastError || new Error("Uniswap request failed");
196121
+ }
196122
+ async testConnection() {
196123
+ try {
196124
+ const weth = this.getWrappedNative();
196125
+ const usdc = this.getUsdcAddress();
196126
+ await this.getQuote(weth, usdc, "1000000000000000");
196127
+ return true;
196128
+ } catch {
196129
+ return false;
196130
+ }
196131
+ }
196132
+ async getQuote(tokenIn, tokenOut, amount, options = {}) {
196133
+ const tokenOutChainId = options.tokenOutChainId ?? this.chainId;
196134
+ const isCrossChain = tokenOutChainId !== this.chainId;
196135
+ const body = {
196136
+ type: options.type ?? "EXACT_INPUT",
196137
+ amount,
196138
+ tokenInChainId: this.chainId,
196139
+ tokenOutChainId,
196140
+ tokenIn,
196141
+ tokenOut,
196142
+ swapper: this.walletAddress,
196143
+ routingPreference: options.routingPreference ?? "BEST_PRICE"
196144
+ };
196145
+ if (options.slippageTolerance) {
196146
+ body.slippageTolerance = options.slippageTolerance;
196147
+ } else {
196148
+ body.autoSlippage = "DEFAULT";
196149
+ }
196150
+ if (options.permitAmount) {
196151
+ body.permitAmount = options.permitAmount;
196152
+ }
196153
+ const extraHeaders = isCrossChain ? { "x-chained-actions-enabled": "true" } : undefined;
196154
+ return this.request("/quote", body, extraHeaders);
196155
+ }
196156
+ async getSwapTransaction(quote, permit, deadline) {
196157
+ const body = {
196158
+ quote: quote.quote,
196159
+ refreshGasPrice: true,
196160
+ deadline: deadline ?? Math.floor(Date.now() / 1000) + 120
196161
+ };
196162
+ if (permit) {
196163
+ body.signature = permit.signature;
196164
+ body.permitData = permit.permitData;
196165
+ }
196166
+ const resp = await this.request("/swap", body);
196167
+ if (resp.swap.gasLimit) {
196168
+ const buffered = Math.ceil(Number(resp.swap.gasLimit) * (1 + GAS_BUFFER_PERCENT));
196169
+ resp.swap.gasLimit = buffered.toString();
196170
+ }
196171
+ return resp;
196172
+ }
196173
+ async checkApproval(token, amount) {
196174
+ if (this.isNativeToken(token)) {
196175
+ return { approval: null };
196176
+ }
196177
+ return this.request("/check_approval", {
196178
+ walletAddress: this.walletAddress,
196179
+ token,
196180
+ amount,
196181
+ chainId: this.chainId,
196182
+ includeGasInfo: true
196183
+ });
196184
+ }
196185
+ static validateSwapTransaction(data) {
196186
+ if (!data || data === "" || data === "0x")
196187
+ return false;
196188
+ return /^0x[0-9a-fA-F]+$/.test(data);
196189
+ }
196190
+ static isQuoteFresh(quoteTimestamp) {
196191
+ return Date.now() - quoteTimestamp < QUOTE_MAX_AGE_MS;
196192
+ }
196193
+ }
196194
+ var BASE_URL4 = "https://trade-api.gateway.uniswap.org/v1", MAX_RETRIES2 = 3, BASE_DELAY_MS = 500, QUOTE_MAX_AGE_MS = 30000, RATE_LIMIT_CONFIG6;
196195
+ var init_client9 = __esm(() => {
196196
+ init_types10();
196197
+ init_token_list();
196198
+ RATE_LIMIT_CONFIG6 = {
196199
+ maxRequestsPerMinute: 60,
196200
+ throttleThreshold: 50
196201
+ };
196202
+ });
196203
+
196204
+ // src/infra/uniswap/subgraph-types.ts
196205
+ var V3_SUBGRAPH_IDS;
196206
+ var init_subgraph_types = __esm(() => {
196207
+ V3_SUBGRAPH_IDS = {
196208
+ 1: "5zvR82QoaXYFyDEKLZ9t6v9adgnptxYpKpSbxtgVENFV",
196209
+ 10: "Cghf4LfVqPiFw6fp6Y5X5Ubc8UpmUhSfJL82zwiBFLaj",
196210
+ 56: "F85MNzUGYqgSHSHRGgeVMNsdnW1KtZSVgFULumXRZTw2",
196211
+ 137: "3hCPRGf4z88VC5rsBKU5AA9FBBq5nF3jbKJG7VZCbhjm",
196212
+ 8453: "43Hwfi3dJSoGpyas9VwNoDAv55yjgGrPpNSmbQZArzMG",
196213
+ 42161: "FbCGRftH4a3yZugY7TnbYgPJVEv2LvMT6oF1fxPe9aJM",
196214
+ 42220: "ESdrTJ3twMwWVoQ1hUE2u7PugEHX3QkenudD6aXCkDQ4",
196215
+ 43114: "GVH9h9KZ9CqheUEL93qMbq7QwgoBu32QXQDPR6bev4Eo",
196216
+ 81457: "2LHovKznvo8YmKC9ZprPjsYAZDCc4K5q4AYz8s3cnQn1"
196217
+ };
196218
+ });
196219
+
196220
+ // src/infra/uniswap/subgraph.ts
196221
+ class UniswapSubgraph {
196222
+ apiKey;
196223
+ chainId;
196224
+ client;
196225
+ endpointUrl;
196226
+ poolCache = new Cache({ defaultTtl: CACHE_TTL.pool, maxEntries: 100 });
196227
+ dataCache = new Cache({ defaultTtl: CACHE_TTL.candles, maxEntries: 500 });
196228
+ requestCount = 0;
196229
+ lastResetTime = Date.now();
196230
+ throttledCount = 0;
196231
+ circuitState = "closed";
196232
+ consecutiveFailures = 0;
196233
+ circuitOpenedAt = 0;
196234
+ constructor(apiKey, chainId, client) {
196235
+ this.apiKey = apiKey;
196236
+ this.chainId = chainId;
196237
+ this.client = client;
196238
+ const subgraphId = V3_SUBGRAPH_IDS[chainId];
196239
+ this.endpointUrl = subgraphId ? `${GRAPH_GATEWAY}/subgraphs/id/${subgraphId}` : null;
196240
+ }
196241
+ isAvailable() {
196242
+ if (!this.endpointUrl)
196243
+ return false;
196244
+ if (this.circuitState === "open") {
196245
+ if (Date.now() - this.circuitOpenedAt > CIRCUIT_RESET_MS) {
196246
+ this.circuitState = "half-open";
196247
+ return true;
196248
+ }
196249
+ return false;
196250
+ }
196251
+ return true;
196252
+ }
196253
+ async checkRateLimit() {
196254
+ const now2 = Date.now();
196255
+ if (now2 - this.lastResetTime > 60000) {
196256
+ this.requestCount = 0;
196257
+ this.lastResetTime = now2;
196258
+ this.throttledCount = 0;
196259
+ }
196260
+ if (this.requestCount >= RATE_LIMIT.maxPerMinute) {
196261
+ const waitMs = 60000 - (now2 - this.lastResetTime);
196262
+ throw new Error(`Subgraph rate limit reached (${RATE_LIMIT.maxPerMinute}/min). Retry in ${Math.ceil(waitMs / 1000)}s.`);
196263
+ }
196264
+ if (this.requestCount >= RATE_LIMIT.throttleAt) {
196265
+ const delayMs = 500 * (this.requestCount - RATE_LIMIT.throttleAt + 1);
196266
+ await new Promise((r) => setTimeout(r, delayMs));
196267
+ this.throttledCount++;
196268
+ }
196269
+ }
196270
+ async query(graphql, variables = {}) {
196271
+ if (!this.endpointUrl) {
196272
+ throw new Error(`No V3 subgraph available for chain ${this.chainId}`);
196273
+ }
196274
+ if (this.circuitState === "open" && !this.isAvailable()) {
196275
+ throw new Error("Subgraph circuit breaker is open");
196276
+ }
196277
+ await this.checkRateLimit();
196278
+ this.requestCount++;
196279
+ let lastError = null;
196280
+ for (let attempt = 0;attempt <= MAX_RETRIES3; attempt++) {
196281
+ if (attempt > 0) {
196282
+ const delay5 = BASE_DELAY_MS2 * 2 ** (attempt - 1);
196283
+ await new Promise((r) => setTimeout(r, delay5));
196284
+ }
196285
+ try {
196286
+ const url2 = `${GRAPH_GATEWAY}/${this.apiKey}${this.endpointUrl}`;
196287
+ const res = await fetch(url2, {
196288
+ method: "POST",
196289
+ headers: { "Content-Type": "application/json" },
196290
+ body: JSON.stringify({ query: graphql, variables })
196291
+ });
196292
+ if (res.ok) {
196293
+ const json3 = await res.json();
196294
+ if (json3.errors?.length) {
196295
+ throw new Error(`Subgraph error: ${json3.errors.map((e2) => e2.message).join("; ")}`);
196296
+ }
196297
+ this.consecutiveFailures = 0;
196298
+ if (this.circuitState === "half-open")
196299
+ this.circuitState = "closed";
196300
+ return json3.data;
196301
+ }
196302
+ const errBody = await res.text().catch(() => "");
196303
+ if ([429, 500, 503].includes(res.status) && attempt < MAX_RETRIES3) {
196304
+ if (res.status === 429)
196305
+ this.throttledCount++;
196306
+ lastError = new Error(`Subgraph HTTP ${res.status}: ${errBody}`);
196307
+ continue;
196308
+ }
196309
+ this.onFailure();
196310
+ throw new Error(`Subgraph HTTP ${res.status}: ${errBody}`);
196311
+ } catch (err) {
196312
+ if (err instanceof Error && err.message.startsWith("Subgraph"))
196313
+ throw err;
196314
+ lastError = err instanceof Error ? err : new Error(String(err));
196315
+ if (attempt >= MAX_RETRIES3) {
196316
+ this.onFailure();
196317
+ throw lastError;
196318
+ }
196319
+ }
196320
+ }
196321
+ throw lastError || new Error("Subgraph request failed");
196322
+ }
196323
+ onFailure() {
196324
+ this.consecutiveFailures++;
196325
+ if (this.consecutiveFailures >= CIRCUIT_FAILURE_THRESHOLD) {
196326
+ this.circuitState = "open";
196327
+ this.circuitOpenedAt = Date.now();
196328
+ }
196329
+ }
196330
+ async resolvePool(symbol16) {
196331
+ const cacheKey = `pool:${this.chainId}:${symbol16}`;
196332
+ const cached2 = this.poolCache.get(cacheKey);
196333
+ if (cached2)
196334
+ return cached2;
196335
+ const { tokenIn, tokenOut } = await this.client.resolveSymbol(symbol16);
196336
+ const inLower = tokenIn.toLowerCase();
196337
+ const outLower = tokenOut.toLowerCase();
196338
+ const [t0, t1] = inLower < outLower ? [inLower, outLower] : [outLower, inLower];
196339
+ const isInverted = inLower !== t0;
196340
+ const data = await this.query(`query($t0: String!, $t1: String!) {
196341
+ pools(
196342
+ first: 1
196343
+ where: { token0: $t0, token1: $t1 }
196344
+ orderBy: liquidity
196345
+ orderDirection: desc
196346
+ ) {
196347
+ id feeTier liquidity sqrtPrice tick
196348
+ token0Price token1Price
196349
+ totalValueLockedUSD volumeUSD
196350
+ token0 { id symbol name decimals }
196351
+ token1 { id symbol name decimals }
196352
+ }
196353
+ }`, { t0, t1 });
196354
+ if (!data.pools.length) {
196355
+ throw new Error(`No Uniswap V3 pool found for ${symbol16} on chain ${this.chainId}`);
196356
+ }
196357
+ const resolved = { pool: data.pools[0], isInverted };
196358
+ this.poolCache.set(cacheKey, resolved, CACHE_TTL.pool);
196359
+ return resolved;
196360
+ }
196361
+ getPoolPrice(pool, isInverted) {
196362
+ return isInverted ? parseFloat(pool.token1Price) : parseFloat(pool.token0Price);
196363
+ }
196364
+ async getCandles(symbol16, interval, limit) {
196365
+ const { pool, isInverted } = await this.resolvePool(symbol16);
196366
+ const useHourly = ["1m", "5m", "15m", "30m", "1h", "4h"].includes(interval);
196367
+ const intervalSeconds = useHourly ? 3600 : 86400;
196368
+ const start = Math.floor(Date.now() / 1000) - limit * intervalSeconds;
196369
+ const cacheKey = `candle:${this.chainId}:${pool.id}:${interval}:${limit}`;
196370
+ const cached2 = this.dataCache.get(cacheKey);
196371
+ if (cached2)
196372
+ return cached2;
196373
+ let candles;
196374
+ if (useHourly) {
196375
+ const data = await this.query(`query($pool: String!, $start: Int!, $first: Int!) {
196376
+ poolHourDatas(
196377
+ first: $first
196378
+ where: { pool: $pool, periodStartUnix_gte: $start }
196379
+ orderBy: periodStartUnix
196380
+ orderDirection: asc
196381
+ ) {
196382
+ periodStartUnix open high low close
196383
+ volumeUSD volumeToken0 volumeToken1 tvlUSD
196384
+ token0Price token1Price
196385
+ }
196386
+ }`, { pool: pool.id, start, first: Math.min(limit, 1000) });
196387
+ candles = data.poolHourDatas.map((d) => this.mapCandle(d.periodStartUnix, intervalSeconds, d, isInverted));
196388
+ } else {
196389
+ const data = await this.query(`query($pool: String!, $start: Int!, $first: Int!) {
196390
+ poolDayDatas(
196391
+ first: $first
196392
+ where: { pool: $pool, date_gte: $start }
196393
+ orderBy: date
196394
+ orderDirection: asc
196395
+ ) {
196396
+ date open high low close
196397
+ volumeUSD volumeToken0 volumeToken1 tvlUSD
196398
+ token0Price token1Price
196399
+ }
196400
+ }`, { pool: pool.id, start, first: Math.min(limit, 1000) });
196401
+ candles = data.poolDayDatas.map((d) => this.mapCandle(d.date, intervalSeconds, d, isInverted));
196402
+ }
196403
+ this.dataCache.set(cacheKey, candles, CACHE_TTL.candles);
196404
+ return candles;
196405
+ }
196406
+ mapCandle(timestamp, intervalSec, d, isInverted) {
196407
+ let open = parseFloat(d.open);
196408
+ let high = parseFloat(d.high);
196409
+ let low = parseFloat(d.low);
196410
+ let close = parseFloat(d.close);
196411
+ if (open === 0 && close === 0) {
196412
+ const price = isInverted ? parseFloat(d.token1Price) : parseFloat(d.token0Price);
196413
+ open = high = low = close = price;
196414
+ } else if (isInverted && open !== 0 && high !== 0 && low !== 0 && close !== 0) {
196415
+ const iOpen = 1 / open;
196416
+ const iHigh = 1 / low;
196417
+ const iLow = 1 / high;
196418
+ const iClose = 1 / close;
196419
+ open = iOpen;
196420
+ high = iHigh;
196421
+ low = iLow;
196422
+ close = iClose;
196423
+ } else if (isInverted) {
196424
+ const price = parseFloat(d.token1Price);
196425
+ if (price !== 0) {
196426
+ open = high = low = close = price;
196427
+ }
196428
+ }
196429
+ return {
196430
+ openTime: timestamp * 1000,
196431
+ open,
196432
+ high,
196433
+ low,
196434
+ close,
196435
+ volume: parseFloat(d.volumeUSD),
196436
+ closeTime: (timestamp + intervalSec) * 1000 - 1
196437
+ };
196438
+ }
196439
+ async get24hrTickers(limit = 100) {
196440
+ const cacheKey = `tickers:${this.chainId}:${limit}`;
196441
+ const cached2 = this.dataCache.get(cacheKey);
196442
+ if (cached2)
196443
+ return cached2;
196444
+ const fetchLimit = Math.min(limit + 15, 200);
196445
+ const data = await this.query(`query($first: Int!) {
196446
+ tokens(
196447
+ first: $first
196448
+ orderBy: volumeUSD
196449
+ orderDirection: desc
196450
+ where: { volumeUSD_gt: "1000" }
196451
+ ) {
196452
+ id symbol name
196453
+ volumeUSD totalValueLockedUSD
196454
+ tokenDayDatas(first: 2, orderBy: date, orderDirection: desc) {
196455
+ date priceUSD volumeUSD
196456
+ open high low close
196457
+ }
196458
+ }
196459
+ }`, { first: fetchLimit });
196460
+ const now2 = Date.now();
196461
+ const tickers = [];
196462
+ for (const token of data.tokens) {
196463
+ if (STABLECOIN_SYMBOLS.has(token.symbol.toUpperCase()))
196464
+ continue;
196465
+ if (token.tokenDayDatas.length === 0)
196466
+ continue;
196467
+ const today = token.tokenDayDatas[0];
196468
+ const yesterday = token.tokenDayDatas[1];
196469
+ const todayPrice = parseFloat(today.priceUSD);
196470
+ const yesterdayPrice = yesterday ? parseFloat(yesterday.priceUSD) : todayPrice;
196471
+ const priceChange = todayPrice - yesterdayPrice;
196472
+ const priceChangePercent = yesterdayPrice !== 0 ? priceChange / yesterdayPrice * 100 : 0;
196473
+ const highPrice = parseFloat(today.high) || todayPrice;
196474
+ const lowPrice = parseFloat(today.low) || todayPrice;
196475
+ tickers.push({
196476
+ symbol: `${token.symbol.toUpperCase()}USDC`,
196477
+ priceChange,
196478
+ priceChangePercent,
196479
+ lastPrice: todayPrice,
196480
+ highPrice,
196481
+ lowPrice,
196482
+ volume: parseFloat(today.volumeUSD),
196483
+ quoteVolume: parseFloat(today.volumeUSD),
196484
+ openTime: today.date * 1000,
196485
+ closeTime: now2
196486
+ });
196487
+ if (tickers.length >= limit)
196488
+ break;
196489
+ }
196490
+ this.dataCache.set(cacheKey, tickers, CACHE_TTL.tickers);
196491
+ return tickers;
196492
+ }
196493
+ async getTopSymbols(n) {
196494
+ const cacheKey = `top:${this.chainId}:${n}`;
196495
+ const cached2 = this.dataCache.get(cacheKey);
196496
+ if (cached2)
196497
+ return cached2;
196498
+ const fetchN = Math.min(n + 10, 100);
196499
+ const data = await this.query(`query($first: Int!) {
196500
+ tokens(
196501
+ first: $first
196502
+ orderBy: volumeUSD
196503
+ orderDirection: desc
196504
+ where: { volumeUSD_gt: "1000" }
196505
+ ) {
196506
+ id symbol
196507
+ }
196508
+ }`, { first: fetchN });
196509
+ const symbols = [];
196510
+ for (const token of data.tokens) {
196511
+ const sym = token.symbol.toUpperCase();
196512
+ if (STABLECOIN_SYMBOLS.has(sym))
196513
+ continue;
196514
+ if (sym === "WETH" || sym === "WBTC") {
196515
+ symbols.push(`${sym.slice(1)}USDC`);
196516
+ } else {
196517
+ symbols.push(`${sym}USDC`);
196518
+ }
196519
+ if (symbols.length >= n)
196520
+ break;
196521
+ }
196522
+ this.dataCache.set(cacheKey, symbols, CACHE_TTL.top);
196523
+ return symbols;
196524
+ }
196525
+ async getTradeHistory(symbol16, limit) {
196526
+ const { pool, isInverted } = await this.resolvePool(symbol16);
196527
+ const cacheKey = `trades:${this.chainId}:${pool.id}:${limit}`;
196528
+ const cached2 = this.dataCache.get(cacheKey);
196529
+ if (cached2)
196530
+ return cached2;
196531
+ const data = await this.query(`query($pool: String!, $first: Int!) {
196532
+ swaps(
196533
+ first: $first
196534
+ where: { pool: $pool }
196535
+ orderBy: timestamp
196536
+ orderDirection: desc
196537
+ ) {
196538
+ id timestamp
196539
+ amount0 amount1 amountUSD
196540
+ sender recipient
196541
+ sqrtPriceX96 tick
196542
+ }
196543
+ }`, { pool: pool.id, first: Math.min(limit, 1000) });
196544
+ const trades = data.swaps.map((swap) => {
196545
+ const amount0 = parseFloat(swap.amount0);
196546
+ const amount1 = parseFloat(swap.amount1);
196547
+ const amountUSD = parseFloat(swap.amountUSD);
196548
+ const baseAmount = isInverted ? amount1 : amount0;
196549
+ const side = baseAmount > 0 ? "SELL" : "BUY";
196550
+ const quantity = Math.abs(baseAmount);
196551
+ const price = amountUSD > 0 && quantity > 0 ? amountUSD / quantity : quantity > 0 ? this.getPoolPrice(pool, isInverted) : 0;
196552
+ return {
196553
+ id: swap.id,
196554
+ orderId: swap.id,
196555
+ symbol: symbol16,
196556
+ side,
196557
+ price,
196558
+ quantity,
196559
+ commission: 0,
196560
+ commissionAsset: "USD",
196561
+ time: parseInt(swap.timestamp, 10) * 1000,
196562
+ isMaker: false
196563
+ };
196564
+ });
196565
+ this.dataCache.set(cacheKey, trades, CACHE_TTL.trades);
196566
+ return trades;
196567
+ }
196568
+ async getPoolData(symbol16) {
196569
+ const { pool, isInverted } = await this.resolvePool(symbol16);
196570
+ const cacheKey = `poolData:${this.chainId}:${pool.id}`;
196571
+ const cached2 = this.dataCache.get(cacheKey);
196572
+ if (cached2)
196573
+ return cached2;
196574
+ const data = await this.query(`query($id: ID!) {
196575
+ pool(id: $id) {
196576
+ id feeTier liquidity sqrtPrice tick
196577
+ token0Price token1Price
196578
+ totalValueLockedUSD volumeUSD
196579
+ token0 { id symbol name decimals }
196580
+ token1 { id symbol name decimals }
196581
+ }
196582
+ }`, { id: pool.id });
196583
+ if (!data.pool)
196584
+ throw new Error(`Pool ${pool.id} not found`);
196585
+ const result = {
196586
+ price: this.getPoolPrice(data.pool, isInverted),
196587
+ feeTier: parseInt(data.pool.feeTier, 10),
196588
+ tvlUSD: parseFloat(data.pool.totalValueLockedUSD),
196589
+ liquidity: data.pool.liquidity
196590
+ };
196591
+ this.dataCache.set(cacheKey, result, CACHE_TTL.poolData);
196592
+ return result;
196593
+ }
196594
+ async getOrderBook(symbol16) {
196595
+ const { pool, isInverted } = await this.resolvePool(symbol16);
196596
+ const { price, feeTier, tvlUSD } = await this.getPoolData(symbol16);
196597
+ const spreadFraction = feeTier / 1e6;
196598
+ const halfSpread = price * spreadFraction / 2;
196599
+ try {
196600
+ const ticks = await this.getTickLiquidity(symbol16, 10);
196601
+ if (ticks.length > 0) {
196602
+ const freshPool = await this.getPoolData(symbol16);
196603
+ const bids = [];
196604
+ const asks = [];
196605
+ for (const tick of ticks) {
196606
+ const tickIdx = parseInt(tick.tickIdx, 10);
196607
+ const liqNet = parseFloat(tick.liquidityNet);
196608
+ if (liqNet === 0)
196609
+ continue;
196610
+ const tickPrice = isInverted ? parseFloat(tick.price1) : parseFloat(tick.price0);
196611
+ const liquidityScore = Math.abs(liqNet);
196612
+ if (tickPrice <= freshPool.price) {
196613
+ bids.push({ price: tickPrice, quantity: liquidityScore });
196614
+ } else {
196615
+ asks.push({ price: tickPrice, quantity: liquidityScore });
196616
+ }
196617
+ }
196618
+ if (bids.length > 0 || asks.length > 0) {
196619
+ bids.sort((a, b) => b.price - a.price);
196620
+ asks.sort((a, b) => a.price - b.price);
196621
+ return { lastUpdateId: Date.now(), bids, asks };
196622
+ }
196623
+ }
196624
+ } catch {}
196625
+ const depthProxy = tvlUSD / 2;
196626
+ return {
196627
+ lastUpdateId: Date.now(),
196628
+ bids: [{ price: price - halfSpread, quantity: depthProxy / price }],
196629
+ asks: [{ price: price + halfSpread, quantity: depthProxy / price }]
196630
+ };
196631
+ }
196632
+ async getBookTicker(symbol16) {
196633
+ const { price, feeTier, tvlUSD } = await this.getPoolData(symbol16);
196634
+ const spreadFraction = feeTier / 1e6;
196635
+ const halfSpread = price * spreadFraction / 2;
196636
+ const depthProxy = tvlUSD / 2;
196637
+ return {
196638
+ symbol: symbol16,
196639
+ bidPrice: price - halfSpread,
196640
+ bidQty: depthProxy / price,
196641
+ askPrice: price + halfSpread,
196642
+ askQty: depthProxy / price
196643
+ };
196644
+ }
196645
+ async getSpread(symbol16) {
196646
+ const { price, feeTier } = await this.getPoolData(symbol16);
196647
+ const spreadFraction = feeTier / 1e6;
196648
+ const spread = price * spreadFraction;
196649
+ return {
196650
+ spread,
196651
+ spreadPercent: spreadFraction * 100,
196652
+ bidPrice: price - spread / 2,
196653
+ askPrice: price + spread / 2
196654
+ };
196655
+ }
196656
+ async getAvgPrice(symbol16) {
196657
+ const { price } = await this.getPoolData(symbol16);
196658
+ return { mins: 5, price };
196659
+ }
196660
+ async getEthPrice() {
196661
+ const cacheKey = `bundle:${this.chainId}`;
196662
+ const cached2 = this.dataCache.get(cacheKey);
196663
+ if (cached2 !== undefined)
196664
+ return cached2;
196665
+ const data = await this.query(`{ bundle(id: "1") { id ethPriceUSD } }`);
196666
+ const price = data.bundle ? parseFloat(data.bundle.ethPriceUSD) : NaN;
196667
+ if (isNaN(price) || price <= 0) {
196668
+ throw new Error(`Unable to fetch ETH price from bundle on chain ${this.chainId}`);
196669
+ }
196670
+ this.dataCache.set(cacheKey, price, CACHE_TTL.bundle);
196671
+ return price;
196672
+ }
196673
+ async getFactory() {
196674
+ const cacheKey = `factory:${this.chainId}`;
196675
+ const cached2 = this.dataCache.get(cacheKey);
196676
+ if (cached2 !== undefined)
196677
+ return cached2;
196678
+ const data = await this.query(`{ factory(id: "1") {
196679
+ id poolCount txCount
196680
+ totalVolumeUSD totalVolumeETH
196681
+ totalFeesUSD totalFeesETH
196682
+ totalValueLockedUSD totalValueLockedETH
196683
+ owner
196684
+ } }`);
196685
+ this.dataCache.set(cacheKey, data.factory, CACHE_TTL.protocol);
196686
+ return data.factory;
196687
+ }
196688
+ async getTokenHourCandles(tokenAddress, limit = 168) {
196689
+ const addr = tokenAddress.toLowerCase();
196690
+ const cacheKey = `tokenHour:${this.chainId}:${addr}:${limit}`;
196691
+ const cached2 = this.dataCache.get(cacheKey);
196692
+ if (cached2)
196693
+ return cached2;
196694
+ const start = Math.floor(Date.now() / 1000) - limit * 3600;
196695
+ const data = await this.query(`query($token: String!, $start: Int!, $first: Int!) {
196696
+ tokenHourDatas(
196697
+ first: $first
196698
+ where: { token: $token, periodStartUnix_gte: $start }
196699
+ orderBy: periodStartUnix
196700
+ orderDirection: asc
196701
+ ) {
196702
+ periodStartUnix
196703
+ open high low close
196704
+ priceUSD volumeUSD feesUSD
196705
+ totalValueLockedUSD
196706
+ token { id }
196707
+ }
196708
+ }`, { token: addr, start, first: Math.min(limit, 1000) });
196709
+ const candles = data.tokenHourDatas.map((d) => {
196710
+ const fallback = parseFloat(d.priceUSD);
196711
+ const openVal = parseFloat(d.open);
196712
+ const highVal = parseFloat(d.high);
196713
+ const lowVal = parseFloat(d.low);
196714
+ const closeVal = parseFloat(d.close);
196715
+ return {
196716
+ openTime: d.periodStartUnix * 1000,
196717
+ open: openVal > 0 ? openVal : fallback,
196718
+ high: highVal > 0 ? highVal : fallback,
196719
+ low: lowVal > 0 ? lowVal : fallback,
196720
+ close: closeVal > 0 ? closeVal : fallback,
196721
+ volume: parseFloat(d.volumeUSD),
196722
+ closeTime: (d.periodStartUnix + 3600) * 1000 - 1
196723
+ };
196724
+ });
196725
+ this.dataCache.set(cacheKey, candles, CACHE_TTL.candles);
196726
+ return candles;
196727
+ }
196728
+ async getTickLiquidity(symbol16, ticksPerSide = 20) {
196729
+ const { pool } = await this.resolvePool(symbol16);
196730
+ const freshData = await this.query(`query($id: ID!) { pool(id: $id) { tick feeTier } }`, { id: pool.id });
196731
+ const currentTick = parseInt(freshData.pool?.tick ?? pool.tick, 10);
196732
+ const feeTier = parseInt(freshData.pool?.feeTier ?? pool.feeTier, 10);
196733
+ const tickSpacing = feeTier === 100 ? 1 : feeTier === 500 ? 10 : feeTier === 3000 ? 60 : feeTier === 1e4 ? 200 : 60;
196734
+ const tickRange = ticksPerSide * tickSpacing;
196735
+ const cacheKey = `ticks:${this.chainId}:${pool.id}:${currentTick}:${ticksPerSide}`;
196736
+ const cached2 = this.dataCache.get(cacheKey);
196737
+ if (cached2)
196738
+ return cached2;
196739
+ const minTick = currentTick - tickRange;
196740
+ const maxTick = currentTick + tickRange;
196741
+ const data = await this.query(`query($pool: String!, $minTick: BigInt!, $maxTick: BigInt!) {
196742
+ ticks(
196743
+ first: 100
196744
+ where: { pool: $pool, tickIdx_gte: $minTick, tickIdx_lte: $maxTick }
196745
+ orderBy: tickIdx
196746
+ orderDirection: asc
196747
+ ) {
196748
+ id tickIdx poolAddress
196749
+ liquidityGross liquidityNet
196750
+ price0 price1
196751
+ volumeToken0 volumeToken1 volumeUSD
196752
+ feesUSD
196753
+ }
196754
+ }`, { pool: pool.id, minTick: minTick.toString(), maxTick: maxTick.toString() });
196755
+ this.dataCache.set(cacheKey, data.ticks, CACHE_TTL.ticks);
196756
+ return data.ticks;
196757
+ }
196758
+ async getMints(symbol16, limit = 50) {
196759
+ const { pool } = await this.resolvePool(symbol16);
196760
+ const cacheKey = `mints:${this.chainId}:${pool.id}:${limit}`;
196761
+ const cached2 = this.dataCache.get(cacheKey);
196762
+ if (cached2)
196763
+ return cached2;
196764
+ const data = await this.query(`query($pool: String!, $first: Int!) {
196765
+ mints(
196766
+ first: $first
196767
+ where: { pool: $pool }
196768
+ orderBy: timestamp
196769
+ orderDirection: desc
196770
+ ) {
196771
+ id timestamp
196772
+ transaction { id timestamp }
196773
+ pool { id }
196774
+ token0 { id symbol name decimals }
196775
+ token1 { id symbol name decimals }
196776
+ owner sender origin
196777
+ amount amount0 amount1 amountUSD
196778
+ tickLower tickUpper logIndex
196779
+ }
196780
+ }`, { pool: pool.id, first: Math.min(limit, 1000) });
196781
+ this.dataCache.set(cacheKey, data.mints, CACHE_TTL.events);
196782
+ return data.mints;
196783
+ }
196784
+ async getBurns(symbol16, limit = 50) {
196785
+ const { pool } = await this.resolvePool(symbol16);
196786
+ const cacheKey = `burns:${this.chainId}:${pool.id}:${limit}`;
196787
+ const cached2 = this.dataCache.get(cacheKey);
196788
+ if (cached2)
196789
+ return cached2;
196790
+ const data = await this.query(`query($pool: String!, $first: Int!) {
196791
+ burns(
196792
+ first: $first
196793
+ where: { pool: $pool }
196794
+ orderBy: timestamp
196795
+ orderDirection: desc
196796
+ ) {
196797
+ id timestamp
196798
+ transaction { id timestamp }
196799
+ pool { id }
196800
+ token0 { id symbol name decimals }
196801
+ token1 { id symbol name decimals }
196802
+ owner origin
196803
+ amount amount0 amount1 amountUSD
196804
+ tickLower tickUpper logIndex
196805
+ }
196806
+ }`, { pool: pool.id, first: Math.min(limit, 1000) });
196807
+ this.dataCache.set(cacheKey, data.burns, CACHE_TTL.events);
196808
+ return data.burns;
196809
+ }
196810
+ async getCollects(symbol16, limit = 50) {
196811
+ const { pool } = await this.resolvePool(symbol16);
196812
+ const cacheKey = `collects:${this.chainId}:${pool.id}:${limit}`;
196813
+ const cached2 = this.dataCache.get(cacheKey);
196814
+ if (cached2)
196815
+ return cached2;
196816
+ const data = await this.query(`query($pool: String!, $first: Int!) {
196817
+ collects(
196818
+ first: $first
196819
+ where: { pool: $pool }
196820
+ orderBy: timestamp
196821
+ orderDirection: desc
196822
+ ) {
196823
+ id timestamp
196824
+ transaction { id timestamp }
196825
+ pool { id }
196826
+ owner
196827
+ amount0 amount1 amountUSD
196828
+ tickLower tickUpper logIndex
196829
+ }
196830
+ }`, { pool: pool.id, first: Math.min(limit, 1000) });
196831
+ this.dataCache.set(cacheKey, data.collects, CACHE_TTL.events);
196832
+ return data.collects;
196833
+ }
196834
+ async getFlashLoans(symbol16, limit = 50) {
196835
+ const { pool } = await this.resolvePool(symbol16);
196836
+ const cacheKey = `flashes:${this.chainId}:${pool.id}:${limit}`;
196837
+ const cached2 = this.dataCache.get(cacheKey);
196838
+ if (cached2)
196839
+ return cached2;
196840
+ const data = await this.query(`query($pool: String!, $first: Int!) {
196841
+ flashes(
196842
+ first: $first
196843
+ where: { pool: $pool }
196844
+ orderBy: timestamp
196845
+ orderDirection: desc
196846
+ ) {
196847
+ id timestamp
196848
+ transaction { id timestamp }
196849
+ pool { id }
196850
+ sender recipient
196851
+ amount0 amount1 amountUSD
196852
+ amount0Paid amount1Paid
196853
+ logIndex
196854
+ }
196855
+ }`, { pool: pool.id, first: Math.min(limit, 1000) });
196856
+ this.dataCache.set(cacheKey, data.flashes, CACHE_TTL.events);
196857
+ return data.flashes;
196858
+ }
196859
+ async getPositions(owner, limit = 50) {
196860
+ const addr = owner.toLowerCase();
196861
+ const cacheKey = `positions:${this.chainId}:${addr}:${limit}`;
196862
+ const cached2 = this.dataCache.get(cacheKey);
196863
+ if (cached2)
196864
+ return cached2;
196865
+ const data = await this.query(`query($owner: String!, $first: Int!) {
196866
+ positions(
196867
+ first: $first
196868
+ where: { owner: $owner, liquidity_gt: "0" }
196869
+ orderBy: liquidity
196870
+ orderDirection: desc
196871
+ ) {
196872
+ id owner
196873
+ pool { id token0 { id symbol name decimals } token1 { id symbol name decimals } }
196874
+ token0 { id symbol name decimals }
196875
+ token1 { id symbol name decimals }
196876
+ tickLower { tickIdx price0 price1 }
196877
+ tickUpper { tickIdx price0 price1 }
196878
+ liquidity
196879
+ depositedToken0 depositedToken1
196880
+ withdrawnToken0 withdrawnToken1
196881
+ collectedFeesToken0 collectedFeesToken1
196882
+ transaction { id timestamp }
196883
+ }
196884
+ }`, { owner: addr, first: Math.min(limit, 1000) });
196885
+ this.dataCache.set(cacheKey, data.positions, CACHE_TTL.positions);
196886
+ return data.positions;
196887
+ }
196888
+ async getPositionSnapshots(positionId, limit = 50) {
196889
+ const cacheKey = `snapshots:${this.chainId}:${positionId}:${limit}`;
196890
+ const cached2 = this.dataCache.get(cacheKey);
196891
+ if (cached2)
196892
+ return cached2;
196893
+ const data = await this.query(`query($position: String!, $first: Int!) {
196894
+ positionSnapshots(
196895
+ first: $first
196896
+ where: { position: $position }
196897
+ orderBy: timestamp
196898
+ orderDirection: desc
196899
+ ) {
196900
+ id owner
196901
+ pool { id }
196902
+ position { id }
196903
+ blockNumber timestamp
196904
+ liquidity
196905
+ depositedToken0 depositedToken1
196906
+ withdrawnToken0 withdrawnToken1
196907
+ collectedFeesToken0 collectedFeesToken1
196908
+ transaction { id }
196909
+ }
196910
+ }`, { position: positionId, first: Math.min(limit, 1000) });
196911
+ this.dataCache.set(cacheKey, data.positionSnapshots, CACHE_TTL.positions);
196912
+ return data.positionSnapshots;
196913
+ }
196914
+ async getProtocolDayData(days = 30) {
196915
+ const cacheKey = `protocol:${this.chainId}:${days}`;
196916
+ const cached2 = this.dataCache.get(cacheKey);
196917
+ if (cached2)
196918
+ return cached2;
196919
+ const start = Math.floor(Date.now() / 1000) - days * 86400;
196920
+ const data = await this.query(`query($start: Int!, $first: Int!) {
196921
+ uniswapDayDatas(
196922
+ first: $first
196923
+ where: { date_gte: $start }
196924
+ orderBy: date
196925
+ orderDirection: asc
196926
+ ) {
196927
+ id date
196928
+ volumeETH volumeUSD
196929
+ feesUSD txCount tvlUSD
196930
+ }
196931
+ }`, { start, first: Math.min(days, 1000) });
196932
+ this.dataCache.set(cacheKey, data.uniswapDayDatas, CACHE_TTL.protocol);
196933
+ return data.uniswapDayDatas;
196934
+ }
196935
+ }
196936
+ 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;
196937
+ var init_subgraph = __esm(() => {
196938
+ init_subgraph_types();
196939
+ RATE_LIMIT = { maxPerMinute: 30, throttleAt: 25 };
196940
+ CACHE_TTL = {
196941
+ pool: 30 * 60000,
196942
+ candles: 5 * 60000,
196943
+ tickers: 2 * 60000,
196944
+ top: 5 * 60000,
196945
+ trades: 60000,
196946
+ poolData: 60000,
196947
+ bundle: 60000,
196948
+ ticks: 60000,
196949
+ events: 60000,
196950
+ positions: 5 * 60000,
196951
+ protocol: 5 * 60000
196952
+ };
196953
+ STABLECOIN_SYMBOLS = new Set(["USDC", "USDT", "DAI", "BUSD", "TUSD", "FRAX", "LUSD", "USDP", "GUSD", "PYUSD"]);
196954
+ });
196955
+
196956
+ // src/infra/uniswap/index.ts
196957
+ var init_uniswap = __esm(() => {
196958
+ init_client9();
196959
+ init_token_list();
196960
+ init_subgraph();
196961
+ init_subgraph_types();
196962
+ init_types10();
196963
+ });
196964
+
196965
+ // src/infra/exchange/adapters/uniswap.ts
196966
+ class UniswapAdapter {
196967
+ client;
196968
+ subgraph;
196969
+ exchangeId = "uniswap";
196970
+ displayName = "Uniswap";
196971
+ localOrders = new Map;
196972
+ localTrades = new Map;
196973
+ orderCounter = 0;
196974
+ constructor(apiKey, walletAddress, chainId = 1, graphApiKey) {
196975
+ this.client = new UniswapClient(apiKey, walletAddress, chainId);
196976
+ this.subgraph = graphApiKey ? new UniswapSubgraph(graphApiKey, chainId, this.client) : null;
196977
+ }
196978
+ async testConnection() {
196979
+ return this.client.testConnection();
196980
+ }
196981
+ async getExchangeInfo() {
196982
+ const symbols = SUPPORTED_CHAIN_IDS.map((cid) => ({
196983
+ symbol: `${CHAIN_NAMES[cid] || `Chain${cid}`}`,
196984
+ status: "TRADING",
196985
+ baseAsset: "ETH",
196986
+ quoteAsset: "USDC",
196987
+ baseAssetPrecision: 18,
196988
+ quoteAssetPrecision: 6,
196989
+ orderTypes: ["MARKET"],
196990
+ isSpotTradingAllowed: true,
196991
+ filters: []
196992
+ }));
196993
+ return {
196994
+ timezone: "UTC",
196995
+ serverTime: Date.now(),
196996
+ symbols
196997
+ };
196998
+ }
196999
+ async getPrice(symbol16) {
197000
+ const { tokenIn, tokenOut, tokenInDecimals, tokenOutDecimals } = await this.client.resolveSymbol(symbol16);
197001
+ const oneUnit = "1" + "0".repeat(tokenInDecimals);
197002
+ const quote = await this.client.getQuote(tokenIn, tokenOut, oneUnit);
197003
+ const outputAmount = quote.quote.output?.amount || quote.quote.amountOut;
197004
+ if (!outputAmount)
197005
+ throw new Error("No output amount in quote");
197006
+ return Number(outputAmount) / 10 ** tokenOutDecimals;
197007
+ }
197008
+ async getCandles(symbol16, interval, limit) {
197009
+ if (!this.subgraph?.isAvailable())
197010
+ return [];
197011
+ try {
197012
+ return await this.subgraph.getCandles(symbol16, interval, limit ?? 50);
197013
+ } catch {
197014
+ return [];
197015
+ }
197016
+ }
197017
+ async get24hrTickers() {
197018
+ if (!this.subgraph?.isAvailable())
197019
+ return [];
197020
+ try {
197021
+ return await this.subgraph.get24hrTickers();
197022
+ } catch {
197023
+ return [];
197024
+ }
197025
+ }
197026
+ async getTopSymbols(n) {
197027
+ if (!this.subgraph?.isAvailable()) {
197028
+ return ["ETHUSDC", "WBTCUSDC", "ARBUSDC", "LINKUSDC", "UNIUSDC"];
197029
+ }
197030
+ try {
197031
+ return await this.subgraph.getTopSymbols(n);
197032
+ } catch {
197033
+ return ["ETHUSDC", "WBTCUSDC", "ARBUSDC", "LINKUSDC", "UNIUSDC"];
197034
+ }
197035
+ }
197036
+ async getOrderBook(symbol16, _limit) {
197037
+ if (this.subgraph?.isAvailable()) {
197038
+ try {
197039
+ return await this.subgraph.getOrderBook(symbol16);
197040
+ } catch {}
197041
+ }
197042
+ const price = await this.getPrice(symbol16);
197043
+ const spread = price * 0.003;
197044
+ return {
197045
+ lastUpdateId: Date.now(),
197046
+ bids: [{ price: price - spread / 2, quantity: 0 }],
197047
+ asks: [{ price: price + spread / 2, quantity: 0 }]
197048
+ };
197049
+ }
197050
+ async getBookTicker(symbol16) {
197051
+ if (this.subgraph?.isAvailable()) {
197052
+ try {
197053
+ return await this.subgraph.getBookTicker(symbol16);
197054
+ } catch {}
197055
+ }
197056
+ const price = await this.getPrice(symbol16);
197057
+ const spread = price * 0.003;
197058
+ return {
197059
+ symbol: symbol16,
197060
+ bidPrice: price - spread / 2,
197061
+ bidQty: 0,
197062
+ askPrice: price + spread / 2,
197063
+ askQty: 0
197064
+ };
197065
+ }
197066
+ async getSpread(symbol16) {
197067
+ if (this.subgraph?.isAvailable()) {
197068
+ try {
197069
+ return await this.subgraph.getSpread(symbol16);
197070
+ } catch {}
197071
+ }
197072
+ const price = await this.getPrice(symbol16);
197073
+ const spread = price * 0.003;
197074
+ return {
197075
+ spread,
197076
+ spreadPercent: 0.3,
197077
+ bidPrice: price - spread / 2,
197078
+ askPrice: price + spread / 2
197079
+ };
197080
+ }
197081
+ async getAvgPrice(symbol16) {
197082
+ if (this.subgraph?.isAvailable()) {
197083
+ try {
197084
+ return await this.subgraph.getAvgPrice(symbol16);
197085
+ } catch {}
197086
+ }
197087
+ const price = await this.getPrice(symbol16);
197088
+ return { mins: 5, price };
197089
+ }
197090
+ async getAccountInfo() {
197091
+ return {
197092
+ canTrade: true,
197093
+ canWithdraw: true,
197094
+ canDeposit: true,
197095
+ accountType: "DEX",
197096
+ balances: [],
197097
+ updateTime: Date.now()
197098
+ };
197099
+ }
197100
+ async getBalance(_asset) {
197101
+ return 0;
197102
+ }
197103
+ async getAllBalances() {
197104
+ return [];
197105
+ }
197106
+ async getFullAccountDetails() {
197107
+ return {
197108
+ accountInfo: await this.getAccountInfo(),
197109
+ totalUsdtValue: 0,
197110
+ nonZeroBalances: []
197111
+ };
197112
+ }
197113
+ async placeOrder(params) {
197114
+ const { tokenIn, tokenOut, tokenInDecimals, tokenOutDecimals } = await this.client.resolveSymbol(params.symbol);
197115
+ const isBuy = params.side === "BUY";
197116
+ const amount = params.quantity || params.quoteOrderQty || 0;
197117
+ const inputDecimals = isBuy ? tokenOutDecimals : tokenInDecimals;
197118
+ const rawAmount = Math.floor(amount * 10 ** inputDecimals).toString();
197119
+ const swapTokenIn = isBuy ? tokenOut : tokenIn;
197120
+ const swapTokenOut = isBuy ? tokenIn : tokenOut;
197121
+ let quote = await this.client.getQuote(swapTokenIn, swapTokenOut, rawAmount);
197122
+ let quoteTimestamp = Date.now();
197123
+ const approvalResult = await this.client.checkApproval(swapTokenIn, rawAmount);
197124
+ if (!UniswapClient.isQuoteFresh(quoteTimestamp)) {
197125
+ quote = await this.client.getQuote(swapTokenIn, swapTokenOut, rawAmount);
197126
+ quoteTimestamp = Date.now();
197127
+ }
197128
+ const deadline = Math.floor(Date.now() / 1000) + 120;
197129
+ const swapTx = await this.client.getSwapTransaction(quote, undefined, deadline);
197130
+ if (!UniswapClient.validateSwapTransaction(swapTx.swap.data)) {
197131
+ throw new Error("Invalid swap transaction data \u2014 cannot execute");
197132
+ }
197133
+ const orderId = `uniswap-${++this.orderCounter}-${Date.now()}`;
197134
+ const order = {
197135
+ orderId,
197136
+ clientOrderId: quote.requestId,
197137
+ symbol: params.symbol,
197138
+ side: params.side,
197139
+ type: "MARKET",
197140
+ status: "NEW",
197141
+ price: await this.getPrice(params.symbol),
197142
+ quantity: amount,
197143
+ executedQty: 0,
197144
+ cummulativeQuoteQty: 0,
197145
+ time: Date.now(),
197146
+ updateTime: Date.now()
197147
+ };
197148
+ this.localOrders.set(orderId, order);
197149
+ const meta3 = {
197150
+ _unsignedTx: swapTx.swap,
197151
+ _quoteTimestamp: quoteTimestamp
197152
+ };
197153
+ if (approvalResult.approval) {
197154
+ meta3._approvalTx = approvalResult.approval;
197155
+ }
197156
+ if (swapTx.txFailureReasons?.length) {
197157
+ meta3._txFailureReasons = swapTx.txFailureReasons;
197158
+ }
197159
+ Object.assign(order, meta3);
197160
+ return order;
197161
+ }
197162
+ async cancelOrder(_symbol2, orderId) {
197163
+ const order = this.localOrders.get(orderId);
197164
+ if (order && order.status === "NEW") {
197165
+ order.status = "CANCELED";
197166
+ order.updateTime = Date.now();
197167
+ }
197168
+ }
197169
+ async cancelAllOrders(symbol16) {
197170
+ const cancelled = [];
197171
+ for (const order of this.localOrders.values()) {
197172
+ if (order.symbol === symbol16 && order.status === "NEW") {
197173
+ order.status = "CANCELED";
197174
+ order.updateTime = Date.now();
197175
+ cancelled.push(order);
197176
+ }
197177
+ }
197178
+ return cancelled;
197179
+ }
197180
+ async getOpenOrders(symbol16) {
197181
+ const orders = Array.from(this.localOrders.values());
197182
+ return orders.filter((o) => o.status === "NEW" && (!symbol16 || o.symbol === symbol16));
197183
+ }
197184
+ async getOrderStatus(_symbol2, orderId) {
197185
+ const order = this.localOrders.get(String(orderId));
197186
+ if (!order)
197187
+ throw new Error(`Order ${orderId} not found`);
197188
+ return order;
197189
+ }
197190
+ async testOrder(params) {
197191
+ try {
197192
+ const { tokenIn, tokenOut, tokenInDecimals } = await this.client.resolveSymbol(params.symbol);
197193
+ const amount = params.quantity || params.quoteOrderQty || 0;
197194
+ const rawAmount = Math.floor(amount * 10 ** tokenInDecimals).toString();
197195
+ await this.client.getQuote(tokenIn, tokenOut, rawAmount);
197196
+ return true;
197197
+ } catch {
197198
+ return false;
197199
+ }
197200
+ }
197201
+ async getTradeHistory(symbol16, limit) {
197202
+ const local = this.localTrades.get(symbol16) || [];
197203
+ if (!this.subgraph?.isAvailable())
197204
+ return local;
197205
+ try {
197206
+ const onChain = await this.subgraph.getTradeHistory(symbol16, limit ?? 50);
197207
+ const localIds = new Set(local.map((t2) => t2.id));
197208
+ const deduped = onChain.filter((t2) => !localIds.has(t2.id));
197209
+ return [...local, ...deduped].slice(0, limit ?? 50);
197210
+ } catch {
197211
+ return local;
197212
+ }
197213
+ }
197214
+ async getOrderHistory(symbol16, _limit) {
197215
+ return Array.from(this.localOrders.values()).filter((o) => o.symbol === symbol16);
197216
+ }
197217
+ async getDepositHistory(_limit) {
197218
+ return [];
197219
+ }
197220
+ async getWithdrawalHistory(_limit) {
197221
+ return [];
197222
+ }
197223
+ shouldThrottle() {
197224
+ return this.client.shouldThrottle();
197225
+ }
197226
+ getRateLimitStatus() {
197227
+ const status = this.client.getRateLimitStatus();
197228
+ return {
197229
+ currentWeight: status.currentRequests,
197230
+ maxWeight: status.maxRequests,
197231
+ usagePercent: status.usagePercent,
197232
+ isThrottling: status.isThrottling,
197233
+ throttledCount: status.throttledCount,
197234
+ timeUntilReset: status.timeUntilReset
197235
+ };
197236
+ }
197237
+ getCircuitBreakerState() {
197238
+ return this.client.getCircuitBreakerState();
197239
+ }
197240
+ resetCircuitBreaker() {
197241
+ this.client.resetCircuitBreaker();
197242
+ }
197243
+ }
197244
+ var init_uniswap2 = __esm(() => {
197245
+ init_uniswap();
197246
+ init_subgraph();
197247
+ init_types10();
197248
+ });
197249
+
195779
197250
  // src/infra/exchange/factory.ts
195780
197251
  function getCacheKey(exchangeId, credentials) {
195781
- const key = exchangeId === "hyperliquid" ? credentials.walletPrivateKey || "" : credentials.apiKey;
197252
+ const key = exchangeId === "hyperliquid" || exchangeId === "uniswap" ? credentials.walletPrivateKey || credentials.apiKey : credentials.apiKey;
195782
197253
  const keyPrefix = key.substring(0, 8);
195783
197254
  return `${exchangeId}:${keyPrefix}`;
195784
197255
  }
@@ -195790,13 +197261,15 @@ var init_factory = __esm(() => {
195790
197261
  init_kraken3();
195791
197262
  init_bitfinex3();
195792
197263
  init_hyperliquid3();
197264
+ init_uniswap2();
195793
197265
  SUPPORTED_EXCHANGES = [
195794
197266
  "binance",
195795
197267
  "binance_us",
195796
197268
  "coinbase",
195797
197269
  "kraken",
195798
197270
  "bitfinex",
195799
- "hyperliquid"
197271
+ "hyperliquid",
197272
+ "uniswap"
195800
197273
  ];
195801
197274
  ExchangeFactory = class ExchangeFactory {
195802
197275
  static instanceCache = new Map;
@@ -195835,6 +197308,12 @@ var init_factory = __esm(() => {
195835
197308
  }
195836
197309
  exchange = new HyperliquidAdapter(credentials.walletPrivateKey);
195837
197310
  break;
197311
+ case "uniswap":
197312
+ if (!credentials.apiKey) {
197313
+ throw new Error("Uniswap requires an API key from developers.uniswap.org");
197314
+ }
197315
+ exchange = new UniswapAdapter(credentials.apiKey, credentials.walletPrivateKey || credentials.apiSecret, 1, process.env.THEGRAPH_API_KEY);
197316
+ break;
195838
197317
  default:
195839
197318
  throw new Error(`No adapter available for exchange: ${exchangeId}`);
195840
197319
  }
@@ -195872,6 +197351,7 @@ var init_exchange = __esm(() => {
195872
197351
  init_kraken3();
195873
197352
  init_bitfinex3();
195874
197353
  init_hyperliquid3();
197354
+ init_uniswap2();
195875
197355
  });
195876
197356
 
195877
197357
  // src/core/validator.ts
@@ -265114,7 +266594,7 @@ var init_iceberg = __esm(() => {
265114
266594
 
265115
266595
  // src/core/execution/algorithms/types.ts
265116
266596
  var ExecutionAlgorithmSchema, DEFAULT_TWAP_CONFIG, DEFAULT_VWAP_CONFIG, DEFAULT_ICEBERG_CONFIG;
265117
- var init_types10 = __esm(() => {
266597
+ var init_types11 = __esm(() => {
265118
266598
  init_zod();
265119
266599
  ExecutionAlgorithmSchema = exports_external.enum(["TWAP", "VWAP", "ICEBERG"]);
265120
266600
  DEFAULT_TWAP_CONFIG = {
@@ -265255,7 +266735,7 @@ var init_session_manager = __esm(() => {
265255
266735
  init_twap();
265256
266736
  init_vwap();
265257
266737
  init_iceberg();
265258
- init_types10();
266738
+ init_types11();
265259
266739
  logger69 = createModuleLogger("execution-session-manager");
265260
266740
  });
265261
266741
 
@@ -265352,7 +266832,7 @@ function describeIntent(intent2) {
265352
266832
  }
265353
266833
  var DURATION_PATTERNS;
265354
266834
  var init_intent_parser = __esm(() => {
265355
- init_types10();
266835
+ init_types11();
265356
266836
  DURATION_PATTERNS = [
265357
266837
  { pattern: /(\d+)\s*h(?:ours?)?/i, toMs: (m) => parseInt(m[1], 10) * 60 * 60 * 1000 },
265358
266838
  { pattern: /(\d+)\s*m(?:in(?:utes?)?)?/i, toMs: (m) => parseInt(m[1], 10) * 60 * 1000 },
@@ -267536,7 +269016,7 @@ var init_risk_management2 = __esm(() => {
267536
269016
  });
267537
269017
 
267538
269018
  // src/strategies/types.ts
267539
- var init_types11 = () => {};
269019
+ var init_types12 = () => {};
267540
269020
 
267541
269021
  // src/strategies/registry.ts
267542
269022
  class StrategyRegistry {
@@ -275860,7 +277340,7 @@ var init_dsl = __esm(() => {
275860
277340
 
275861
277341
  // src/strategies/index.ts
275862
277342
  var init_strategies = __esm(() => {
275863
- init_types11();
277343
+ init_types12();
275864
277344
  init_registry3();
275865
277345
  init_base_strategy();
275866
277346
  init_ensemble();
@@ -276380,7 +277860,7 @@ var init_strategies2 = __esm(() => {
276380
277860
 
276381
277861
  // src/backtest/types.ts
276382
277862
  var DEFAULT_BACKTEST_CONFIG, DEFAULT_BACKTEST_PARAMS;
276383
- var init_types12 = __esm(() => {
277863
+ var init_types13 = __esm(() => {
276384
277864
  DEFAULT_BACKTEST_CONFIG = {
276385
277865
  timeframe: "4h",
276386
277866
  days: 90,
@@ -277348,7 +278828,7 @@ function runBacktest(strategy, data, params, strategyParams) {
277348
278828
  return engine.run(strategy, data, strategyParams);
277349
278829
  }
277350
278830
  var init_engine2 = __esm(() => {
277351
- init_types12();
278831
+ init_types13();
277352
278832
  init_indicators();
277353
278833
  });
277354
278834
 
@@ -277356,7 +278836,7 @@ var init_engine2 = __esm(() => {
277356
278836
  function getCachedData(symbol16, timeframe, startTime, endTime) {
277357
278837
  const db = getDatabase();
277358
278838
  const now2 = Date.now();
277359
- const ttl = CACHE_TTL_MS2[timeframe] ?? CACHE_TTL_MS2["1h"];
278839
+ const ttl = CACHE_TTL_MS3[timeframe] ?? CACHE_TTL_MS3["1h"];
277360
278840
  const minFetchedAt = now2 - ttl;
277361
278841
  const query = db.prepare(`
277362
278842
  SELECT timestamp, open, high, low, close, volume
@@ -277536,7 +279016,7 @@ async function fetchHistoricalDataRange(exchange, symbol16, timeframe, startTime
277536
279016
  `);
277537
279017
  const cachedRows = query.all(upperSymbol, timeframe, startTime, endTime);
277538
279018
  const now2 = Date.now();
277539
- const ttl = CACHE_TTL_MS2[timeframe] ?? CACHE_TTL_MS2["1h"];
279019
+ const ttl = CACHE_TTL_MS3[timeframe] ?? CACHE_TTL_MS3["1h"];
277540
279020
  const cachedMap = new Map;
277541
279021
  for (const row of cachedRows) {
277542
279022
  cachedMap.set(row.timestamp, {
@@ -277586,7 +279066,7 @@ async function fetchHistoricalDataRange(exchange, symbol16, timeframe, startTime
277586
279066
  }
277587
279067
  return result;
277588
279068
  }
277589
- var logger74, BINANCE_KLINE_LIMIT = 1000, TIMEFRAME_MS, CACHE_TTL_MS2;
279069
+ var logger74, BINANCE_KLINE_LIMIT = 1000, TIMEFRAME_MS, CACHE_TTL_MS3;
277590
279070
  var init_historical = __esm(() => {
277591
279071
  init_storage();
277592
279072
  init_logger2();
@@ -277608,7 +279088,7 @@ var init_historical = __esm(() => {
277608
279088
  "1w": 7 * 24 * 60 * 60 * 1000,
277609
279089
  "1M": 30 * 24 * 60 * 60 * 1000
277610
279090
  };
277611
- CACHE_TTL_MS2 = {
279091
+ CACHE_TTL_MS3 = {
277612
279092
  "1m": 5 * 60 * 1000,
277613
279093
  "3m": 10 * 60 * 1000,
277614
279094
  "5m": 30 * 60 * 1000,
@@ -280361,7 +281841,7 @@ function standardDeviation(values) {
280361
281841
  }
280362
281842
  var logger77, DEFAULT_WALK_FORWARD_CONFIG;
280363
281843
  var init_walk_forward = __esm(() => {
280364
- init_types12();
281844
+ init_types13();
280365
281845
  init_engine2();
280366
281846
  init_logger2();
280367
281847
  logger77 = createModuleLogger("walk-forward");
@@ -281029,7 +282509,7 @@ var init_backtest = __esm(async () => {
281029
282509
  init_tools();
281030
282510
  init_zod();
281031
282511
  init_strategies();
281032
- init_types12();
282512
+ init_types13();
281033
282513
  init_engine2();
281034
282514
  init_historical();
281035
282515
  init_export();
@@ -284002,7 +285482,7 @@ var init_market_data = __esm(() => {
284002
285482
  // src/infra/agents/tools/liquidation-intelligence.ts
284003
285483
  async function fetchMarketData() {
284004
285484
  const now2 = Date.now();
284005
- if (_cache && now2 - _cache.timestamp < CACHE_TTL_MS3) {
285485
+ if (_cache && now2 - _cache.timestamp < CACHE_TTL_MS4) {
284006
285486
  return { meta: _cache.meta, assetCtxs: _cache.assetCtxs };
284007
285487
  }
284008
285488
  const controller = new AbortController;
@@ -284122,7 +285602,7 @@ function analyzeCrowding(ctx) {
284122
285602
  implication = "Balanced positioning \u2014 no significant crowd";
284123
285603
  return { direction, crowdingScore, implication };
284124
285604
  }
284125
- var HL_INFO_API = "https://api.hyperliquid.xyz/info", REQUEST_TIMEOUT_MS = 1e4, CACHE_TTL_MS3 = 1e4, _cache = null, getCascadeRiskTool, getLiquidationPressureTool, getCrowdingAnalysisTool, getSqueezeCandidatesTool, liquidationIntelligenceTools;
285605
+ var HL_INFO_API = "https://api.hyperliquid.xyz/info", REQUEST_TIMEOUT_MS = 1e4, CACHE_TTL_MS4 = 1e4, _cache = null, getCascadeRiskTool, getLiquidationPressureTool, getCrowdingAnalysisTool, getSqueezeCandidatesTool, liquidationIntelligenceTools;
284126
285606
  var init_liquidation_intelligence = __esm(() => {
284127
285607
  init_tools();
284128
285608
  init_zod();
@@ -285389,7 +286869,7 @@ var init_autonomous = __esm(() => {
285389
286869
 
285390
286870
  // src/infra/base/types.ts
285391
286871
  var BASE_CHAIN_CONFIG, BASE_TOKENS, REGISTRY_API_BASE = "https://base.org/api/registry";
285392
- var init_types13 = __esm(() => {
286872
+ var init_types14 = __esm(() => {
285393
286873
  BASE_CHAIN_CONFIG = {
285394
286874
  mainnet: {
285395
286875
  chainId: 8453,
@@ -285475,7 +286955,7 @@ function formatRegistryEntry(entry) {
285475
286955
  };
285476
286956
  }
285477
286957
  var init_registry4 = __esm(() => {
285478
- init_types13();
286958
+ init_types14();
285479
286959
  });
285480
286960
 
285481
286961
  // src/infra/base/chain.ts
@@ -285544,7 +287024,7 @@ async function getBaseTokenBalance(tokenAddress, walletAddress, decimals = 18, n
285544
287024
  return parseFloat(`${intPart}.${fracPart}`);
285545
287025
  }
285546
287026
  var init_chain2 = __esm(() => {
285547
- init_types13();
287027
+ init_types14();
285548
287028
  });
285549
287029
 
285550
287030
  // src/infra/base/basescan.ts
@@ -285767,7 +287247,7 @@ async function detectNewListings(opts = {}) {
285767
287247
  return signals;
285768
287248
  }
285769
287249
  var init_signals = __esm(() => {
285770
- init_types13();
287250
+ init_types14();
285771
287251
  });
285772
287252
 
285773
287253
  // src/infra/base/index.ts
@@ -285775,7 +287255,7 @@ var init_base4 = __esm(() => {
285775
287255
  init_registry4();
285776
287256
  init_chain2();
285777
287257
  init_signals();
285778
- init_types13();
287258
+ init_types14();
285779
287259
  });
285780
287260
 
285781
287261
  // src/infra/agents/tools/base-onchain.ts
@@ -286010,7 +287490,7 @@ var init_base_onchain = __esm(() => {
286010
287490
 
286011
287491
  // src/infra/agentkit/types.ts
286012
287492
  var CDP_ENV_KEYS;
286013
- var init_types14 = __esm(() => {
287493
+ var init_types15 = __esm(() => {
286014
287494
  CDP_ENV_KEYS = {
286015
287495
  API_KEY_ID: "CDP_API_KEY_ID",
286016
287496
  API_KEY_SECRET: "CDP_API_KEY_SECRET",
@@ -727995,7 +729475,7 @@ function createAcrossClient(options) {
727995
729475
  return AcrossClient.create(options);
727996
729476
  }
727997
729477
  var CLIENT_DEFAULTS;
727998
- var init_client9 = __esm(() => {
729478
+ var init_client10 = __esm(() => {
727999
729479
  init__esm();
728000
729480
  init_actions();
728001
729481
  init_constants2();
@@ -728009,7 +729489,7 @@ var init_client9 = __esm(() => {
728009
729489
  });
728010
729490
 
728011
729491
  // node_modules/@across-protocol/app-sdk/dist/types/index.js
728012
- var init_types15 = () => {};
729492
+ var init_types16 = () => {};
728013
729493
 
728014
729494
  // node_modules/@across-protocol/app-sdk/dist/index.js
728015
729495
  var exports_dist = {};
@@ -728076,8 +729556,8 @@ __export(exports_dist, {
728076
729556
  AcrossApiError: () => AcrossApiError
728077
729557
  });
728078
729558
  var init_dist15 = __esm(() => {
728079
- init_client9();
728080
- init_types15();
729559
+ init_client10();
729560
+ init_types16();
728081
729561
  init_actions();
728082
729562
  init_errors14();
728083
729563
  init_utils11();
@@ -880324,7 +881804,7 @@ var require_token_security = __commonJS((exports) => {
880324
881804
  Object.defineProperty(exports, "__esModule", { value: true });
880325
881805
  exports.isTokenSecurityChainId = exports.TokenSecurityChainIds = undefined;
880326
881806
  var index_js_1 = require_chain7();
880327
- var SUPPORTED_CHAIN_IDS = [
881807
+ var SUPPORTED_CHAIN_IDS2 = [
880328
881808
  index_js_1.EvmChainId.AVALANCHE,
880329
881809
  index_js_1.EvmChainId.BSC,
880330
881810
  index_js_1.EvmChainId.FANTOM,
@@ -880344,8 +881824,8 @@ var require_token_security = __commonJS((exports) => {
880344
881824
  index_js_1.EvmChainId.MANTA,
880345
881825
  index_js_1.EvmChainId.ZKLINK
880346
881826
  ];
880347
- exports.TokenSecurityChainIds = SUPPORTED_CHAIN_IDS;
880348
- var isTokenSecurityChainId = (chainId) => SUPPORTED_CHAIN_IDS.includes(chainId);
881827
+ exports.TokenSecurityChainIds = SUPPORTED_CHAIN_IDS2;
881828
+ var isTokenSecurityChainId = (chainId) => SUPPORTED_CHAIN_IDS2.includes(chainId);
880349
881829
  exports.isTokenSecurityChainId = isTokenSecurityChainId;
880350
881830
  });
880351
881831
 
@@ -1048457,11 +1049937,11 @@ var require_cjs8 = __commonJS((exports, module) => {
1048457
1049937
  wrapFetchWithPayment: () => wrapFetchWithPayment
1048458
1049938
  });
1048459
1049939
  module.exports = __toCommonJS2(src_exports);
1048460
- var import_types47 = require_types26();
1048461
- var import_client16 = require_client4();
1049940
+ var import_types51 = require_types26();
1049941
+ var import_client17 = require_client4();
1048462
1049942
  var import_shared = require_shared();
1048463
1049943
  var import_types210 = require_types26();
1048464
- function wrapFetchWithPayment(fetch3, walletClient, maxValue2 = BigInt(0.1 * 10 ** 6), paymentRequirementsSelector = import_client16.selectPaymentRequirements, config4) {
1049944
+ function wrapFetchWithPayment(fetch3, walletClient, maxValue2 = BigInt(0.1 * 10 ** 6), paymentRequirementsSelector = import_client17.selectPaymentRequirements, config4) {
1048465
1049945
  return async (input, init2) => {
1048466
1049946
  var _a16;
1048467
1049947
  const response = await fetch3(input, init2);
@@ -1048469,13 +1049949,13 @@ var require_cjs8 = __commonJS((exports, module) => {
1048469
1049949
  return response;
1048470
1049950
  }
1048471
1049951
  const { x402Version, accepts } = await response.json();
1048472
- const parsedPaymentRequirements = accepts.map((x) => import_types47.PaymentRequirementsSchema.parse(x));
1048473
- const network = (0, import_types47.isMultiNetworkSigner)(walletClient) ? undefined : import_types47.evm.isSignerWallet(walletClient) ? import_types47.ChainIdToNetwork[(_a16 = walletClient.chain) == null ? undefined : _a16.id] : (0, import_types47.isSvmSignerWallet)(walletClient) ? ["solana", "solana-devnet"] : undefined;
1049952
+ const parsedPaymentRequirements = accepts.map((x) => import_types51.PaymentRequirementsSchema.parse(x));
1049953
+ const network = (0, import_types51.isMultiNetworkSigner)(walletClient) ? undefined : import_types51.evm.isSignerWallet(walletClient) ? import_types51.ChainIdToNetwork[(_a16 = walletClient.chain) == null ? undefined : _a16.id] : (0, import_types51.isSvmSignerWallet)(walletClient) ? ["solana", "solana-devnet"] : undefined;
1048474
1049954
  const selectedPaymentRequirements = paymentRequirementsSelector(parsedPaymentRequirements, network, "exact");
1048475
1049955
  if (BigInt(selectedPaymentRequirements.maxAmountRequired) > maxValue2) {
1048476
1049956
  throw new Error("Payment amount exceeds maximum allowed");
1048477
1049957
  }
1048478
- const paymentHeader = await (0, import_client16.createPaymentHeader)(walletClient, x402Version, selectedPaymentRequirements, config4);
1049958
+ const paymentHeader = await (0, import_client17.createPaymentHeader)(walletClient, x402Version, selectedPaymentRequirements, config4);
1048479
1049959
  if (!init2) {
1048480
1049960
  throw new Error("Missing fetch request configuration");
1048481
1049961
  }
@@ -1050399,11 +1051879,11 @@ var require_cjs9 = __commonJS((exports, module) => {
1050399
1051879
  x402HTTPClient: () => import_client22.x402HTTPClient
1050400
1051880
  });
1050401
1051881
  module.exports = __toCommonJS2(src_exports);
1050402
- var import_client16 = require_client6();
1051882
+ var import_client17 = require_client6();
1050403
1051883
  var import_client22 = require_client6();
1050404
1051884
  var import_http6 = require_http10();
1050405
1051885
  function wrapFetchWithPayment(fetch3, client2) {
1050406
- const httpClient = client2 instanceof import_client16.x402HTTPClient ? client2 : new import_client16.x402HTTPClient(client2);
1051886
+ const httpClient = client2 instanceof import_client17.x402HTTPClient ? client2 : new import_client17.x402HTTPClient(client2);
1050407
1051887
  return async (input, init2) => {
1050408
1051888
  const request = new Request(input, init2);
1050409
1051889
  const clonedRequest = request.clone();
@@ -1050455,7 +1051935,7 @@ var require_cjs9 = __commonJS((exports, module) => {
1050455
1051935
  };
1050456
1051936
  }
1050457
1051937
  function wrapFetchWithPaymentFromConfig(fetch3, config4) {
1050458
- const client2 = import_client16.x402Client.fromConfig(config4);
1051938
+ const client2 = import_client17.x402Client.fromConfig(config4);
1050459
1051939
  return wrapFetchWithPayment(fetch3, client2);
1050460
1051940
  }
1050461
1051941
  });
@@ -1094875,7 +1096355,7 @@ var require_yelayActionProvider = __commonJS((exports) => {
1094875
1096355
  var constants_1 = require_constants39();
1094876
1096356
  var viem_1 = require__cjs();
1094877
1096357
  var utils_1 = require_utils25();
1094878
- var SUPPORTED_CHAIN_IDS = ["1", "146", "8453", "42161", "43114"];
1096358
+ var SUPPORTED_CHAIN_IDS2 = ["1", "146", "8453", "42161", "43114"];
1094879
1096359
 
1094880
1096360
  class YelayActionProvider extends actionProvider_1.ActionProvider {
1094881
1096361
  constructor() {
@@ -1095030,7 +1096510,7 @@ APY: ${vault.apy}%
1095030
1096510
  }
1095031
1096511
  }
1095032
1096512
  supportsNetwork(network) {
1095033
- return network.protocolFamily === "evm" && (network.chainId ? SUPPORTED_CHAIN_IDS.includes(network.chainId) : false);
1096513
+ return network.protocolFamily === "evm" && (network.chainId ? SUPPORTED_CHAIN_IDS2.includes(network.chainId) : false);
1095034
1096514
  }
1095035
1096515
  }
1095036
1096516
  exports.YelayActionProvider = YelayActionProvider;
@@ -1119289,14 +1120769,14 @@ function getAvailableActionNames() {
1119289
1120769
  }
1119290
1120770
  var import_agentkit, _agentKit = null, _actions = null;
1119291
1120771
  var init_provider3 = __esm(() => {
1119292
- init_types14();
1120772
+ init_types15();
1119293
1120773
  import_agentkit = __toESM(require_dist25(), 1);
1119294
1120774
  });
1119295
1120775
 
1119296
1120776
  // src/infra/agentkit/index.ts
1119297
1120777
  var init_agentkit = __esm(() => {
1119298
1120778
  init_provider3();
1119299
- init_types14();
1120779
+ init_types15();
1119300
1120780
  });
1119301
1120781
 
1119302
1120782
  // src/infra/agents/tools/agentkit-onchain.ts
@@ -1120049,6 +1121529,348 @@ ${formatted.join(`
1120049
1121529
  };
1120050
1121530
  });
1120051
1121531
 
1121532
+ // src/infra/agents/tools/uniswap-data.ts
1121533
+ function getSubgraph(execContext) {
1121534
+ const ctx = getGordonContext(execContext);
1121535
+ if (!ctx?.exchange)
1121536
+ return { error: "Exchange client not connected." };
1121537
+ if (ctx.exchange.exchangeId !== "uniswap")
1121538
+ return { error: "This tool is only available on Uniswap." };
1121539
+ const subgraph = ctx.exchange.subgraph;
1121540
+ if (!subgraph?.isAvailable())
1121541
+ return { error: "Uniswap subgraph not available. Set THEGRAPH_API_KEY." };
1121542
+ return { subgraph };
1121543
+ }
1121544
+ var getPoolTickLiquidityTool, getLiquidityEventsTool, getPoolFlashEventsTool, getLpPositionsTool, getProtocolOverviewTool, getFeeCollectionsTool, uniswapDataTools;
1121545
+ var init_uniswap_data = __esm(() => {
1121546
+ init_tools();
1121547
+ init_zod();
1121548
+ init_types8();
1121549
+ getPoolTickLiquidityTool = createTool({
1121550
+ id: "get_pool_tick_liquidity",
1121551
+ 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.",
1121552
+ inputSchema: exports_external.object({
1121553
+ symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC', 'UNIUSDC')"),
1121554
+ ticksPerSide: exports_external.number().min(1).max(50).default(20).describe("Number of tick spaces on each side of current price")
1121555
+ }),
1121556
+ outputSchema: exports_external.object({
1121557
+ symbol: exports_external.string().optional(),
1121558
+ currentTick: exports_external.number().optional(),
1121559
+ tickCount: exports_external.number().optional(),
1121560
+ ticks: exports_external.array(exports_external.object({
1121561
+ tickIdx: exports_external.number(),
1121562
+ price: exports_external.number(),
1121563
+ liquidityNet: exports_external.number(),
1121564
+ liquidityGross: exports_external.number(),
1121565
+ volumeUSD: exports_external.number()
1121566
+ })).optional(),
1121567
+ error: exports_external.string().optional()
1121568
+ }),
1121569
+ execute: async ({ symbol: symbol16, ticksPerSide }, execContext) => {
1121570
+ const result = getSubgraph(execContext);
1121571
+ if ("error" in result)
1121572
+ return result;
1121573
+ try {
1121574
+ const pool = await result.subgraph.resolvePool(symbol16);
1121575
+ const ticks = await result.subgraph.getTickLiquidity(symbol16, ticksPerSide);
1121576
+ return {
1121577
+ symbol: symbol16,
1121578
+ currentTick: parseInt(pool.pool.tick, 10),
1121579
+ tickCount: ticks.length,
1121580
+ ticks: ticks.map((t3) => ({
1121581
+ tickIdx: parseInt(t3.tickIdx, 10),
1121582
+ price: parseFloat(pool.isInverted ? t3.price1 : t3.price0),
1121583
+ liquidityNet: parseFloat(t3.liquidityNet),
1121584
+ liquidityGross: parseFloat(t3.liquidityGross),
1121585
+ volumeUSD: parseFloat(t3.volumeUSD)
1121586
+ }))
1121587
+ };
1121588
+ } catch (error48) {
1121589
+ return { error: `Failed to get tick liquidity: ${error48.message}` };
1121590
+ }
1121591
+ }
1121592
+ });
1121593
+ getLiquidityEventsTool = createTool({
1121594
+ id: "get_liquidity_events",
1121595
+ 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.",
1121596
+ inputSchema: exports_external.object({
1121597
+ symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC', 'UNIUSDC')"),
1121598
+ limit: exports_external.number().min(1).max(100).default(20).describe("Number of events per type")
1121599
+ }),
1121600
+ outputSchema: exports_external.object({
1121601
+ symbol: exports_external.string().optional(),
1121602
+ mints: exports_external.array(exports_external.object({
1121603
+ timestamp: exports_external.number(),
1121604
+ amountUSD: exports_external.number(),
1121605
+ amount0: exports_external.number(),
1121606
+ amount1: exports_external.number(),
1121607
+ owner: exports_external.string(),
1121608
+ tickLower: exports_external.number(),
1121609
+ tickUpper: exports_external.number()
1121610
+ })).optional(),
1121611
+ burns: exports_external.array(exports_external.object({
1121612
+ timestamp: exports_external.number(),
1121613
+ amountUSD: exports_external.number(),
1121614
+ amount0: exports_external.number(),
1121615
+ amount1: exports_external.number(),
1121616
+ owner: exports_external.string(),
1121617
+ tickLower: exports_external.number(),
1121618
+ tickUpper: exports_external.number()
1121619
+ })).optional(),
1121620
+ netFlowUSD: exports_external.number().optional(),
1121621
+ error: exports_external.string().optional()
1121622
+ }),
1121623
+ execute: async ({ symbol: symbol16, limit }, execContext) => {
1121624
+ const result = getSubgraph(execContext);
1121625
+ if ("error" in result)
1121626
+ return result;
1121627
+ try {
1121628
+ const [mints, burns] = await Promise.all([
1121629
+ result.subgraph.getMints(symbol16, limit),
1121630
+ result.subgraph.getBurns(symbol16, limit)
1121631
+ ]);
1121632
+ const mintFlow = mints.reduce((sum, m) => sum + parseFloat(m.amountUSD), 0);
1121633
+ const burnFlow = burns.reduce((sum, b) => sum + parseFloat(b.amountUSD), 0);
1121634
+ return {
1121635
+ symbol: symbol16,
1121636
+ mints: mints.map((m) => ({
1121637
+ timestamp: parseInt(m.timestamp, 10) * 1000,
1121638
+ amountUSD: parseFloat(m.amountUSD),
1121639
+ amount0: parseFloat(m.amount0),
1121640
+ amount1: parseFloat(m.amount1),
1121641
+ owner: m.owner,
1121642
+ tickLower: parseInt(m.tickLower, 10),
1121643
+ tickUpper: parseInt(m.tickUpper, 10)
1121644
+ })),
1121645
+ burns: burns.map((b) => ({
1121646
+ timestamp: parseInt(b.timestamp, 10) * 1000,
1121647
+ amountUSD: parseFloat(b.amountUSD),
1121648
+ amount0: parseFloat(b.amount0),
1121649
+ amount1: parseFloat(b.amount1),
1121650
+ owner: b.owner,
1121651
+ tickLower: parseInt(b.tickLower, 10),
1121652
+ tickUpper: parseInt(b.tickUpper, 10)
1121653
+ })),
1121654
+ netFlowUSD: mintFlow - burnFlow
1121655
+ };
1121656
+ } catch (error48) {
1121657
+ return { error: `Failed to get liquidity events: ${error48.message}` };
1121658
+ }
1121659
+ }
1121660
+ });
1121661
+ getPoolFlashEventsTool = createTool({
1121662
+ id: "get_pool_flash_events",
1121663
+ 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.",
1121664
+ inputSchema: exports_external.object({
1121665
+ symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC')"),
1121666
+ limit: exports_external.number().min(1).max(100).default(20).describe("Number of events to return")
1121667
+ }),
1121668
+ outputSchema: exports_external.object({
1121669
+ symbol: exports_external.string().optional(),
1121670
+ count: exports_external.number().optional(),
1121671
+ totalAmountUSD: exports_external.number().optional(),
1121672
+ events: exports_external.array(exports_external.object({
1121673
+ timestamp: exports_external.number(),
1121674
+ amountUSD: exports_external.number(),
1121675
+ amount0: exports_external.number(),
1121676
+ amount1: exports_external.number(),
1121677
+ amount0Paid: exports_external.number(),
1121678
+ amount1Paid: exports_external.number(),
1121679
+ sender: exports_external.string()
1121680
+ })).optional(),
1121681
+ error: exports_external.string().optional()
1121682
+ }),
1121683
+ execute: async ({ symbol: symbol16, limit }, execContext) => {
1121684
+ const result = getSubgraph(execContext);
1121685
+ if ("error" in result)
1121686
+ return result;
1121687
+ try {
1121688
+ const flashes = await result.subgraph.getFlashLoans(symbol16, limit);
1121689
+ const totalUSD = flashes.reduce((sum, f2) => sum + parseFloat(f2.amountUSD), 0);
1121690
+ return {
1121691
+ symbol: symbol16,
1121692
+ count: flashes.length,
1121693
+ totalAmountUSD: totalUSD,
1121694
+ events: flashes.map((f2) => ({
1121695
+ timestamp: parseInt(f2.timestamp, 10) * 1000,
1121696
+ amountUSD: parseFloat(f2.amountUSD),
1121697
+ amount0: parseFloat(f2.amount0),
1121698
+ amount1: parseFloat(f2.amount1),
1121699
+ amount0Paid: parseFloat(f2.amount0Paid),
1121700
+ amount1Paid: parseFloat(f2.amount1Paid),
1121701
+ sender: f2.sender
1121702
+ }))
1121703
+ };
1121704
+ } catch (error48) {
1121705
+ return { error: `Failed to get flash events: ${error48.message}` };
1121706
+ }
1121707
+ }
1121708
+ });
1121709
+ getLpPositionsTool = createTool({
1121710
+ id: "get_lp_positions",
1121711
+ 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.",
1121712
+ inputSchema: exports_external.object({
1121713
+ owner: exports_external.string().describe("Wallet address (0x...)"),
1121714
+ limit: exports_external.number().min(1).max(100).default(20).describe("Max positions to return")
1121715
+ }),
1121716
+ outputSchema: exports_external.object({
1121717
+ owner: exports_external.string().optional(),
1121718
+ positionCount: exports_external.number().optional(),
1121719
+ positions: exports_external.array(exports_external.object({
1121720
+ id: exports_external.string(),
1121721
+ pool: exports_external.string(),
1121722
+ token0: exports_external.string(),
1121723
+ token1: exports_external.string(),
1121724
+ tickLower: exports_external.number(),
1121725
+ tickUpper: exports_external.number(),
1121726
+ liquidity: exports_external.string(),
1121727
+ depositedToken0: exports_external.number(),
1121728
+ depositedToken1: exports_external.number(),
1121729
+ withdrawnToken0: exports_external.number(),
1121730
+ withdrawnToken1: exports_external.number(),
1121731
+ collectedFeesToken0: exports_external.number(),
1121732
+ collectedFeesToken1: exports_external.number()
1121733
+ })).optional(),
1121734
+ error: exports_external.string().optional()
1121735
+ }),
1121736
+ execute: async ({ owner, limit }, execContext) => {
1121737
+ const result = getSubgraph(execContext);
1121738
+ if ("error" in result)
1121739
+ return result;
1121740
+ try {
1121741
+ const positions = await result.subgraph.getPositions(owner, limit);
1121742
+ return {
1121743
+ owner,
1121744
+ positionCount: positions.length,
1121745
+ positions: positions.map((p) => ({
1121746
+ id: p.id,
1121747
+ pool: p.pool.id,
1121748
+ token0: `${p.token0.symbol} (${p.token0.id.slice(0, 10)}...)`,
1121749
+ token1: `${p.token1.symbol} (${p.token1.id.slice(0, 10)}...)`,
1121750
+ tickLower: parseInt(p.tickLower.tickIdx, 10),
1121751
+ tickUpper: parseInt(p.tickUpper.tickIdx, 10),
1121752
+ liquidity: p.liquidity,
1121753
+ depositedToken0: parseFloat(p.depositedToken0),
1121754
+ depositedToken1: parseFloat(p.depositedToken1),
1121755
+ withdrawnToken0: parseFloat(p.withdrawnToken0),
1121756
+ withdrawnToken1: parseFloat(p.withdrawnToken1),
1121757
+ collectedFeesToken0: parseFloat(p.collectedFeesToken0),
1121758
+ collectedFeesToken1: parseFloat(p.collectedFeesToken1)
1121759
+ }))
1121760
+ };
1121761
+ } catch (error48) {
1121762
+ return { error: `Failed to get LP positions: ${error48.message}` };
1121763
+ }
1121764
+ }
1121765
+ });
1121766
+ getProtocolOverviewTool = createTool({
1121767
+ id: "get_uniswap_protocol_overview",
1121768
+ 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.",
1121769
+ inputSchema: exports_external.object({
1121770
+ days: exports_external.number().min(1).max(90).default(7).describe("Number of days of daily data to include")
1121771
+ }),
1121772
+ outputSchema: exports_external.object({
1121773
+ ethPriceUSD: exports_external.number().optional(),
1121774
+ factory: exports_external.object({
1121775
+ poolCount: exports_external.number(),
1121776
+ totalVolumeUSD: exports_external.number(),
1121777
+ totalFeesUSD: exports_external.number(),
1121778
+ totalValueLockedUSD: exports_external.number()
1121779
+ }).optional(),
1121780
+ dailyData: exports_external.array(exports_external.object({
1121781
+ date: exports_external.number(),
1121782
+ volumeUSD: exports_external.number(),
1121783
+ feesUSD: exports_external.number(),
1121784
+ tvlUSD: exports_external.number(),
1121785
+ txCount: exports_external.number()
1121786
+ })).optional(),
1121787
+ error: exports_external.string().optional()
1121788
+ }),
1121789
+ execute: async ({ days }, execContext) => {
1121790
+ const result = getSubgraph(execContext);
1121791
+ if ("error" in result)
1121792
+ return result;
1121793
+ try {
1121794
+ const [ethPrice, factory6, dayData] = await Promise.all([
1121795
+ result.subgraph.getEthPrice(),
1121796
+ result.subgraph.getFactory(),
1121797
+ result.subgraph.getProtocolDayData(days)
1121798
+ ]);
1121799
+ return {
1121800
+ ethPriceUSD: ethPrice,
1121801
+ factory: factory6 ? {
1121802
+ poolCount: parseInt(factory6.poolCount, 10),
1121803
+ totalVolumeUSD: parseFloat(factory6.totalVolumeUSD),
1121804
+ totalFeesUSD: parseFloat(factory6.totalFeesUSD),
1121805
+ totalValueLockedUSD: parseFloat(factory6.totalValueLockedUSD)
1121806
+ } : undefined,
1121807
+ dailyData: dayData.map((d) => ({
1121808
+ date: d.date * 1000,
1121809
+ volumeUSD: parseFloat(d.volumeUSD),
1121810
+ feesUSD: parseFloat(d.feesUSD),
1121811
+ tvlUSD: parseFloat(d.tvlUSD),
1121812
+ txCount: parseInt(d.txCount, 10)
1121813
+ }))
1121814
+ };
1121815
+ } catch (error48) {
1121816
+ return { error: `Failed to get protocol overview: ${error48.message}` };
1121817
+ }
1121818
+ }
1121819
+ });
1121820
+ getFeeCollectionsTool = createTool({
1121821
+ id: "get_fee_collections",
1121822
+ 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.",
1121823
+ inputSchema: exports_external.object({
1121824
+ symbol: exports_external.string().describe("Trading pair (e.g., 'ETHUSDC')"),
1121825
+ limit: exports_external.number().min(1).max(100).default(20).describe("Number of events to return")
1121826
+ }),
1121827
+ outputSchema: exports_external.object({
1121828
+ symbol: exports_external.string().optional(),
1121829
+ count: exports_external.number().optional(),
1121830
+ totalFeesUSD: exports_external.number().optional(),
1121831
+ events: exports_external.array(exports_external.object({
1121832
+ timestamp: exports_external.number(),
1121833
+ amountUSD: exports_external.number(),
1121834
+ amount0: exports_external.number(),
1121835
+ amount1: exports_external.number(),
1121836
+ owner: exports_external.string()
1121837
+ })).optional(),
1121838
+ error: exports_external.string().optional()
1121839
+ }),
1121840
+ execute: async ({ symbol: symbol16, limit }, execContext) => {
1121841
+ const result = getSubgraph(execContext);
1121842
+ if ("error" in result)
1121843
+ return result;
1121844
+ try {
1121845
+ const collects = await result.subgraph.getCollects(symbol16, limit);
1121846
+ const totalUSD = collects.reduce((sum, c) => sum + parseFloat(c.amountUSD), 0);
1121847
+ return {
1121848
+ symbol: symbol16,
1121849
+ count: collects.length,
1121850
+ totalFeesUSD: totalUSD,
1121851
+ events: collects.map((c) => ({
1121852
+ timestamp: parseInt(c.timestamp, 10) * 1000,
1121853
+ amountUSD: parseFloat(c.amountUSD),
1121854
+ amount0: parseFloat(c.amount0),
1121855
+ amount1: parseFloat(c.amount1),
1121856
+ owner: c.owner
1121857
+ }))
1121858
+ };
1121859
+ } catch (error48) {
1121860
+ return { error: `Failed to get fee collections: ${error48.message}` };
1121861
+ }
1121862
+ }
1121863
+ });
1121864
+ uniswapDataTools = {
1121865
+ get_pool_tick_liquidity: getPoolTickLiquidityTool,
1121866
+ get_liquidity_events: getLiquidityEventsTool,
1121867
+ get_pool_flash_events: getPoolFlashEventsTool,
1121868
+ get_lp_positions: getLpPositionsTool,
1121869
+ get_uniswap_protocol_overview: getProtocolOverviewTool,
1121870
+ get_fee_collections: getFeeCollectionsTool
1121871
+ };
1121872
+ });
1121873
+
1120052
1121874
  // src/infra/agents/tools/position-tracking.ts
1120053
1121875
  async function getManager() {
1120054
1121876
  return getPositionManager(getEventBus());
@@ -1121457,7 +1123279,7 @@ var init_runtime_tools = __esm(() => {
1121457
1123279
 
1121458
1123280
  // src/core/regime/types.ts
1121459
1123281
  var MarketRegimeSchema, RegimeMetricsSchema, RegimeSignalSchema, RegimeSpanSchema, RegimeHistorySchema, MultiTimeframeRegimeSchema;
1121460
- var init_types16 = __esm(() => {
1123282
+ var init_types17 = __esm(() => {
1121461
1123283
  init_zod();
1121462
1123284
  MarketRegimeSchema = exports_external.enum([
1121463
1123285
  "trending_up",
@@ -1121685,7 +1123507,7 @@ var init_watcher = __esm(() => {
1121685
1123507
 
1121686
1123508
  // src/core/regime/index.ts
1121687
1123509
  var init_regime = __esm(() => {
1121688
- init_types16();
1123510
+ init_types17();
1121689
1123511
  init_classifier();
1121690
1123512
  init_detector();
1121691
1123513
  init_watcher();
@@ -1121697,7 +1123519,7 @@ var init_regime_tools = __esm(() => {
1121697
1123519
  init_tools();
1121698
1123520
  init_zod();
1121699
1123521
  init_regime();
1121700
- init_types16();
1123522
+ init_types17();
1121701
1123523
  init_types8();
1121702
1123524
  init_logger2();
1121703
1123525
  logger92 = createModuleLogger("regime-tools");
@@ -1122374,7 +1124196,7 @@ var init_advanced_tools = __esm(() => {
1122374
1124196
 
1122375
1124197
  // src/core/genome/types.ts
1122376
1124198
  var MutationSchema2, GenomeSchema, ExperimentSchema, MutationSuggestionSchema;
1122377
- var init_types17 = __esm(() => {
1124199
+ var init_types18 = __esm(() => {
1122378
1124200
  init_zod();
1122379
1124201
  MutationSchema2 = exports_external.object({
1122380
1124202
  mutation_id: exports_external.string().uuid(),
@@ -1122901,7 +1124723,7 @@ __export(exports_genome, {
1122901
1124723
  EvolutionLoop: () => EvolutionLoop
1122902
1124724
  });
1122903
1124725
  var init_genome = __esm(() => {
1122904
- init_types17();
1124726
+ init_types18();
1122905
1124727
  init_manager3();
1122906
1124728
  init_mutator();
1122907
1124729
  init_fitness();
@@ -1126408,6 +1128230,7 @@ var init_tools3 = __esm(async () => {
1126408
1128230
  init_agentkit_defi();
1126409
1128231
  init_base_signals();
1126410
1128232
  init_base_indexers();
1128233
+ init_uniswap_data();
1126411
1128234
  init_position_tracking();
1126412
1128235
  init_risk_gate();
1126413
1128236
  init_memory_tools();
@@ -1126459,6 +1128282,7 @@ var init_tools3 = __esm(async () => {
1126459
1128282
  init_agentkit_defi();
1126460
1128283
  init_base_signals();
1126461
1128284
  init_base_indexers();
1128285
+ init_uniswap_data();
1126462
1128286
  init_position_tracking();
1126463
1128287
  init_risk_gate();
1126464
1128288
  init_memory_tools();
@@ -1126514,6 +1128338,7 @@ var init_tools3 = __esm(async () => {
1126514
1128338
  ...agentKitDefiTools,
1126515
1128339
  ...baseSignalTools,
1126516
1128340
  ...baseIndexerTools,
1128341
+ ...uniswapDataTools,
1126517
1128342
  ...multiModalChartTools,
1126518
1128343
  ...evalTools,
1126519
1128344
  ...positionTrackingTools,
@@ -1126560,6 +1128385,7 @@ var init_tools3 = __esm(async () => {
1126560
1128385
  agentKitDefi: Object.keys(agentKitDefiTools).length,
1126561
1128386
  baseSignals: Object.keys(baseSignalTools).length,
1126562
1128387
  baseIndexers: Object.keys(baseIndexerTools).length,
1128388
+ uniswapData: Object.keys(uniswapDataTools).length,
1126563
1128389
  multiModalCharts: Object.keys(multiModalChartTools).length,
1126564
1128390
  evals: Object.keys(evalTools).length,
1126565
1128391
  positionTracking: Object.keys(positionTrackingTools).length,
@@ -1131950,7 +1133776,7 @@ var init_zod_compat = __esm(() => {
1131950
1133776
 
1131951
1133777
  // node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
1131952
1133778
  var LATEST_PROTOCOL_VERSION = "2025-11-25", SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task", JSONRPC_VERSION4 = "2.0", AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams = (value) => TaskAugmentedRequestParamsSchema.safeParse(value).success, RequestSchema4, NotificationsParamsSchema, NotificationSchema, ResultSchema4, RequestIdSchema, JSONRPCRequestSchema4, isJSONRPCRequest = (value) => JSONRPCRequestSchema4.safeParse(value).success, JSONRPCNotificationSchema4, isJSONRPCNotification = (value) => JSONRPCNotificationSchema4.safeParse(value).success, JSONRPCResultResponseSchema, isJSONRPCResultResponse = (value) => JSONRPCResultResponseSchema.safeParse(value).success, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse = (value) => JSONRPCErrorResponseSchema.safeParse(value).success, JSONRPCMessageSchema, JSONRPCResponseSchema4, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, ServerCapabilitiesSchema4, InitializeResultSchema, InitializedNotificationSchema, isInitializedNotification = (value) => InitializedNotificationSchema.safeParse(value).success, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema4, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema4, TextResourceContentsSchema4, Base64Schema, BlobResourceContentsSchema4, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema4, ImageContentSchema4, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema4, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema4, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError;
1131953
- var init_types18 = __esm(() => {
1133779
+ var init_types19 = __esm(() => {
1131954
1133780
  init_v42();
1131955
1133781
  SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
1131956
1133782
  AssertObjectSchema = custom((v) => v !== null && (typeof v === "object" || typeof v === "function"));
@@ -1133626,7 +1135452,7 @@ function mergeCapabilities(base4, additional) {
1133626
1135452
  var DEFAULT_REQUEST_TIMEOUT_MSEC = 60000;
1133627
1135453
  var init_protocol3 = __esm(() => {
1133628
1135454
  init_zod_compat();
1133629
- init_types18();
1135455
+ init_types19();
1133630
1135456
  init_zod_json_schema_compat();
1133631
1135457
  });
1133632
1135458
 
@@ -1140201,8 +1142027,8 @@ class ExperimentalClientTasks {
1140201
1142027
  return this._client.requestStream(request, resultSchema, options);
1140202
1142028
  }
1140203
1142029
  }
1140204
- var init_client10 = __esm(() => {
1140205
- init_types18();
1142030
+ var init_client11 = __esm(() => {
1142031
+ init_types19();
1140206
1142032
  });
1140207
1142033
 
1140208
1142034
  // node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
@@ -1140283,12 +1142109,12 @@ function getSupportedElicitationModes(capabilities) {
1140283
1142109
  return { supportsFormMode, supportsUrlMode };
1140284
1142110
  }
1140285
1142111
  var Client2;
1140286
- var init_client11 = __esm(() => {
1142112
+ var init_client12 = __esm(() => {
1140287
1142113
  init_protocol3();
1140288
- init_types18();
1142114
+ init_types19();
1140289
1142115
  init_ajv_provider();
1140290
1142116
  init_zod_compat();
1140291
- init_client10();
1142117
+ init_client11();
1140292
1142118
  Client2 = class Client2 extends Protocol {
1140293
1142119
  constructor(_clientInfo, options) {
1140294
1142120
  super(options);
@@ -1141700,7 +1143526,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
1141700
1143526
  var UnauthorizedError2, AUTHORIZATION_CODE_RESPONSE_TYPE = "code", AUTHORIZATION_CODE_CHALLENGE_METHOD = "S256";
1141701
1143527
  var init_auth2 = __esm(() => {
1141702
1143528
  init_index_node2();
1141703
- init_types18();
1143529
+ init_types19();
1141704
1143530
  init_auth();
1141705
1143531
  init_auth();
1141706
1143532
  init_errors18();
@@ -1141893,7 +1143719,7 @@ class SSEClientTransport {
1141893
1143719
  var SseError;
1141894
1143720
  var init_sse = __esm(() => {
1141895
1143721
  init_dist16();
1141896
- init_types18();
1143722
+ init_types19();
1141897
1143723
  init_auth2();
1141898
1143724
  SseError = class SseError extends Error {
1141899
1143725
  constructor(code, message4, event2) {
@@ -1142390,7 +1144216,7 @@ function serializeMessage2(message4) {
1142390
1144216
  `;
1142391
1144217
  }
1142392
1144218
  var init_stdio = __esm(() => {
1142393
- init_types18();
1144219
+ init_types19();
1142394
1144220
  });
1142395
1144221
 
1142396
1144222
  // node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js
@@ -1142899,7 +1144725,7 @@ class StreamableHTTPClientTransport {
1142899
1144725
  }
1142900
1144726
  var DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS, StreamableHTTPError;
1142901
1144727
  var init_streamableHttp = __esm(() => {
1142902
- init_types18();
1144728
+ init_types19();
1142903
1144729
  init_auth2();
1142904
1144730
  init_stream();
1142905
1144731
  DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS = {
@@ -1143048,7 +1144874,7 @@ var init_exit_hook = __esm(() => {
1143048
1144874
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
1143049
1144875
  var init_server = __esm(() => {
1143050
1144876
  init_protocol3();
1143051
- init_types18();
1144877
+ init_types19();
1143052
1144878
  init_ajv_provider();
1143053
1144879
  init_zod_compat();
1143054
1144880
  });
@@ -1147801,7 +1149627,7 @@ var require_content_type = __commonJS((exports) => {
1147801
1149627
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/sse.js
1147802
1149628
  var import_raw_body, import_content_type;
1147803
1149629
  var init_sse2 = __esm(() => {
1147804
- init_types18();
1149630
+ init_types19();
1147805
1149631
  import_raw_body = __toESM(require_raw_body(), 1);
1147806
1149632
  import_content_type = __toESM(require_content_type(), 1);
1147807
1149633
  });
@@ -1148013,7 +1149839,7 @@ var init_dist17 = __esm(() => {
1148013
1149839
 
1148014
1149840
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js
1148015
1149841
  var init_webStandardStreamableHttp = __esm(() => {
1148016
- init_types18();
1149842
+ init_types19();
1148017
1149843
  });
1148018
1149844
 
1148019
1149845
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js
@@ -1148167,12 +1149993,12 @@ var init_dist18 = __esm(() => {
1148167
1149993
  init_error();
1148168
1149994
  init_tools();
1148169
1149995
  init_utils();
1148170
- init_client11();
1149996
+ init_client12();
1148171
1149997
  init_sse();
1148172
1149998
  init_stdio2();
1148173
1149999
  init_streamableHttp();
1148174
1150000
  init_protocol3();
1148175
- init_types18();
1150001
+ init_types19();
1148176
1150002
  init_exit_hook();
1148177
1150003
  init_zod();
1148178
1150004
  init_dist6();
@@ -1149739,7 +1151565,7 @@ function disableMCPHotReload() {
1149739
1151565
  }
1149740
1151566
  }
1149741
1151567
  var _mcpClient = null, _mcpTools = null, _initPromise = null, _hotReloadTimer = null, _lastPluginFingerprint = null;
1149742
- var init_client12 = __esm(() => {
1151568
+ var init_client13 = __esm(() => {
1149743
1151569
  init_dist18();
1149744
1151570
  init_installer();
1149745
1151571
  init_credentials();
@@ -1149833,6 +1151659,8 @@ function getScannerAgent() {
1149833
1151659
  defillama_search_protocols: instrumentedAgentKitDefiTools.defillama_search_protocols,
1149834
1151660
  indexer_top_pools: instrumentedBaseIndexerTools.indexer_top_pools,
1149835
1151661
  indexer_aerodrome_pools: instrumentedBaseIndexerTools.indexer_aerodrome_pools,
1151662
+ get_uniswap_protocol_overview: instrumentedUniswapDataTools.get_uniswap_protocol_overview,
1151663
+ get_liquidity_events: instrumentedUniswapDataTools.get_liquidity_events,
1149836
1151664
  report_setup: instrumentedPositionTrackingTools.report_setup,
1149837
1151665
  ...instrumentedMemoryTools,
1149838
1151666
  ...instrumentedPlaybookTools,
@@ -1149876,6 +1151704,11 @@ function getAnalystAgent() {
1149876
1151704
  defillama_get_protocol: instrumentedAgentKitDefiTools.defillama_get_protocol,
1149877
1151705
  defillama_get_token_prices: instrumentedAgentKitDefiTools.defillama_get_token_prices,
1149878
1151706
  indexer_pool_stats: instrumentedBaseIndexerTools.indexer_pool_stats,
1151707
+ get_pool_tick_liquidity: instrumentedUniswapDataTools.get_pool_tick_liquidity,
1151708
+ get_liquidity_events: instrumentedUniswapDataTools.get_liquidity_events,
1151709
+ get_pool_flash_events: instrumentedUniswapDataTools.get_pool_flash_events,
1151710
+ get_fee_collections: instrumentedUniswapDataTools.get_fee_collections,
1151711
+ get_uniswap_protocol_overview: instrumentedUniswapDataTools.get_uniswap_protocol_overview,
1149879
1151712
  track_base_wallet: instrumentedBaseSignalTools.track_base_wallet,
1149880
1151713
  get_base_token_holders: instrumentedBaseSignalTools.get_base_token_holders,
1149881
1151714
  get_base_dex_pairs: instrumentedBaseSignalTools.get_base_dex_pairs,
@@ -1150018,6 +1151851,8 @@ function getMonitorAgent() {
1150018
1151851
  agentkit_get_wallet: instrumentedAgentKitOnchainTools.agentkit_get_wallet,
1150019
1151852
  agentkit_get_balance: instrumentedAgentKitOnchainTools.agentkit_get_balance,
1150020
1151853
  agentkit_erc20_balance: instrumentedAgentKitOnchainTools.agentkit_erc20_balance,
1151854
+ get_lp_positions: instrumentedUniswapDataTools.get_lp_positions,
1151855
+ get_fee_collections: instrumentedUniswapDataTools.get_fee_collections,
1150021
1151856
  ...instrumentedSharedContextTools,
1150022
1151857
  record_trade_outcome: instrumentedEvalTools.record_trade_outcome,
1150023
1151858
  get_performance_report: instrumentedEvalTools.get_performance_report,
@@ -1150130,7 +1151965,7 @@ function resetAgents() {
1150130
1151965
  _agents = {};
1150131
1151966
  _subAgentMemory = null;
1150132
1151967
  }
1150133
- 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 = `
1151968
+ 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, instrumentedEvalTools, instrumentedPositionTrackingTools, instrumentedMemoryTools, instrumentedPlaybookTools, instrumentedPlaybookBacktestTools, instrumentedAuditTools, instrumentedProtocolTools, instrumentedRegimeTools, instrumentedRuntimeTools, instrumentedAdvancedTools, instrumentedCheckRiskTool, WORKING_MEMORY_TEMPLATE = `
1150134
1151969
  # Trader Profile
1150135
1151970
 
1150136
1151971
  ## Personal Info
@@ -1150736,7 +1152571,7 @@ var init_agents = __esm(async () => {
1150736
1152571
  init_registry2();
1150737
1152572
  init_shared_context();
1150738
1152573
  init_evals2();
1150739
- init_client12();
1152574
+ init_client13();
1150740
1152575
  await init_tools3();
1150741
1152576
  DEFAULT_MEMORY_CONFIG = {
1150742
1152577
  lastMessages: 20,
@@ -1150777,6 +1152612,7 @@ var init_agents = __esm(async () => {
1150777
1152612
  instrumentedAgentKitDefiTools = withToolsMetrics(agentKitDefiTools);
1150778
1152613
  instrumentedBaseSignalTools = withToolsMetrics(baseSignalTools);
1150779
1152614
  instrumentedBaseIndexerTools = withToolsMetrics(baseIndexerTools);
1152615
+ instrumentedUniswapDataTools = withToolsMetrics(uniswapDataTools);
1150780
1152616
  instrumentedEvalTools = withToolsMetrics(evalTools);
1150781
1152617
  instrumentedPositionTrackingTools = withToolsMetrics(positionTrackingTools);
1150782
1152618
  instrumentedMemoryTools = withToolsMetrics(memoryTools);
@@ -1152613,6 +1154449,12 @@ var init_orchestrator = __esm(async () => {
1152613
1154449
  indexer_top_pools: "Scanner",
1152614
1154450
  indexer_pool_stats: "Analyst",
1152615
1154451
  indexer_aerodrome_pools: "Scanner",
1154452
+ get_pool_tick_liquidity: "Analyst",
1154453
+ get_liquidity_events: "Scanner",
1154454
+ get_pool_flash_events: "Analyst",
1154455
+ get_lp_positions: "Monitor",
1154456
+ get_uniswap_protocol_overview: "Scanner",
1154457
+ get_fee_collections: "Monitor",
1152616
1154458
  scan_base_whale_transfers: "Scanner",
1152617
1154459
  scan_base_volume_spikes: "Scanner",
1152618
1154460
  scan_base_new_tokens: "Scanner",
@@ -1154761,7 +1156603,7 @@ async function checkOrphanedOrders(exchange, activeTrades, result) {
1154761
1156603
  }
1154762
1156604
 
1154763
1156605
  // src/gateway/runtime/gateway-runtime.ts
1154764
- init_client12();
1156606
+ init_client13();
1154765
1156607
 
1154766
1156608
  // src/gateway/scheduler/local-cron.ts
1154767
1156609
  init_logger2();
@@ -1155615,7 +1157457,7 @@ class ReconciliationLoop {
1155615
1157457
  }
1155616
1157458
  }
1155617
1157459
  // src/gateway/daemon/process.ts
1155618
- init_client12();
1157460
+ init_client13();
1155619
1157461
  init_engine();
1155620
1157462
  var logger116 = createModuleLogger("gateway-daemon");
1155621
1157463
  async function startGatewayDaemonProcess() {
@@ -1161748,7 +1163590,7 @@ var import_react64 = __toESM(require_react(), 1);
1161748
1163590
  // package.json
1161749
1163591
  var package_default2 = {
1161750
1163592
  name: "@general-liquidity/gordon-cli",
1161751
- version: "0.75.3",
1163593
+ version: "0.75.5",
1161752
1163594
  description: "The Frontier Trading Agent",
1161753
1163595
  author: "General Liquidity, Inc.",
1161754
1163596
  license: "MIT",
@@ -1163876,7 +1165718,7 @@ async function ensureThreadRegistered() {
1163876
1165718
 
1163877
1165719
  // src/infra/agents/index.ts
1163878
1165720
  init_memory3();
1163879
- init_client12();
1165721
+ init_client13();
1163880
1165722
  init_reflection();
1163881
1165723
 
1163882
1165724
  // src/app/SetupWizard.tsx
@@ -1163893,7 +1165735,8 @@ var EXCHANGE_LABELS = {
1163893
1165735
  coinbase: "Coinbase",
1163894
1165736
  kraken: "Kraken",
1163895
1165737
  bitfinex: "Bitfinex",
1163896
- hyperliquid: "Hyperliquid"
1165738
+ hyperliquid: "Hyperliquid",
1165739
+ uniswap: "Uniswap"
1163897
1165740
  };
1163898
1165741
  var EXCHANGE_PASSPHRASE_REQUIRED = {
1163899
1165742
  binance: false,
@@ -1163901,7 +1165744,8 @@ var EXCHANGE_PASSPHRASE_REQUIRED = {
1163901
1165744
  coinbase: true,
1163902
1165745
  kraken: false,
1163903
1165746
  bitfinex: false,
1163904
- hyperliquid: false
1165747
+ hyperliquid: false,
1165748
+ uniswap: false
1163905
1165749
  };
1163906
1165750
  var EXCHANGE_WALLET_AUTH = {
1163907
1165751
  binance: false,
@@ -1163909,7 +1165753,8 @@ var EXCHANGE_WALLET_AUTH = {
1163909
1165753
  coinbase: false,
1163910
1165754
  kraken: false,
1163911
1165755
  bitfinex: false,
1163912
- hyperliquid: true
1165756
+ hyperliquid: true,
1165757
+ uniswap: true
1163913
1165758
  };
1163914
1165759
  var EXCHANGE_INSTRUCTIONS = {
1163915
1165760
  binance: [
@@ -1163949,6 +1165794,12 @@ var EXCHANGE_INSTRUCTIONS = {
1163949
1165794
  "IMPORTANT: Use a dedicated wallet with limited funds for trading",
1163950
1165795
  "Never use your main wallet's private key",
1163951
1165796
  "Fund your Hyperliquid account by depositing USDC on Arbitrum"
1165797
+ ],
1165798
+ uniswap: [
1165799
+ "Get an API key from developers.uniswap.org",
1165800
+ "Provide your wallet address (the address that will execute swaps)",
1165801
+ "Ensure your wallet has ETH for gas and tokens to trade",
1165802
+ "Supports 15+ chains: Ethereum, Base, Arbitrum, Polygon, Optimism, etc."
1163952
1165803
  ]
1163953
1165804
  };
1163954
1165805
  function maskSecret(value) {
@@ -1165784,7 +1167635,7 @@ function useTheme() {
1165784
1167635
  }
1165785
1167636
 
1165786
1167637
  // src/app/App.tsx
1165787
- init_client12();
1167638
+ init_client13();
1165788
1167639
  init_llm();
1165789
1167640
  init_binance2();
1165790
1167641
  init_exchange();
@@ -1168039,7 +1169890,7 @@ async function exchangeCompare(symbol16) {
1168039
1169890
  }
1168040
1169891
  }
1168041
1169892
  function isWalletBasedExchange(type2) {
1168042
- return type2 === "hyperliquid";
1169893
+ return type2 === "hyperliquid" || type2 === "uniswap";
1168043
1169894
  }
1168044
1169895
  function getExchangeSetupInstructions(type2) {
1168045
1169896
  const instructions = {
@@ -1168073,7 +1169924,12 @@ function getExchangeSetupInstructions(type2) {
1168073
1169924
  2. Export the private key from your wallet (MetaMask: Account Details > Export Private Key)
1168074
1169925
  3. IMPORTANT: Use a DEDICATED trading wallet with limited funds
1168075
1169926
  4. Fund your Hyperliquid account by depositing USDC on Arbitrum
1168076
- 5. Note: Hyperliquid uses wallet-based auth (no API key needed)`
1169927
+ 5. Note: Hyperliquid uses wallet-based auth (no API key needed)`,
1169928
+ uniswap: `
1169929
+ 1. Get an API key from developers.uniswap.org
1169930
+ 2. Provide your wallet address (the address that will execute swaps)
1169931
+ 3. Ensure your wallet has ETH for gas and tokens to trade
1169932
+ 4. Supports 15+ chains: Ethereum, Base, Arbitrum, Polygon, Optimism, etc.`
1168077
1169933
  };
1168078
1169934
  return instructions[type2] || "Follow the exchange documentation to create API keys.";
1168079
1169935
  }
@@ -1172011,7 +1173867,7 @@ async function checkForUpdates() {
1172011
1173867
 
1172012
1173868
  // src/index.tsx
1172013
1173869
  init_telemetry2();
1172014
- init_client12();
1173870
+ init_client13();
1172015
1173871
  var jsx_dev_runtime26 = __toESM(require_jsx_dev_runtime(), 1);
1172016
1173872
  var flags = parseFlags();
1172017
1173873
  var command = parseCommand();