@elizaos/plugin-wallet 2.0.0-beta.1

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 (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -0
  3. package/auto-enable.ts +76 -0
  4. package/dist/LpManagementService-BWrQ5-cO.mjs +353 -0
  5. package/dist/MockLpService-D_Apn4Fd.mjs +99 -0
  6. package/dist/aerodrome-CfnESC32.mjs +890 -0
  7. package/dist/chunk-hT5z_Zn9.mjs +35 -0
  8. package/dist/index.d.mts +34727 -0
  9. package/dist/index.mjs +21590 -0
  10. package/dist/lib/server-wallet-trade.d.mts +34 -0
  11. package/dist/lib/server-wallet-trade.mjs +306 -0
  12. package/dist/meteora-BPX39hZo.mjs +22640 -0
  13. package/dist/orca-Bybp1HXO.mjs +249 -0
  14. package/dist/pancakeswp-CkEXlXti.mjs +604 -0
  15. package/dist/plugin-ZO_MTyd0.mjs +529 -0
  16. package/dist/raydium-rfaM9yEf.mjs +539 -0
  17. package/dist/sdk/index.d.mts +32492 -0
  18. package/dist/sdk/index.mjs +6415 -0
  19. package/dist/types-D5252NZk.mjs +487 -0
  20. package/dist/uniswap-CReXgXVN.mjs +573 -0
  21. package/dist/wallet-action.d.mts +6 -0
  22. package/dist/wallet-action.mjs +820 -0
  23. package/package.json +152 -0
  24. package/src/actions/failure-codes.ts +79 -0
  25. package/src/actions/index.ts +1 -0
  26. package/src/analytics/birdeye/actions/wallet-search-address.ts +9 -0
  27. package/src/analytics/birdeye/birdeye-task.ts +175 -0
  28. package/src/analytics/birdeye/birdeye.ts +813 -0
  29. package/src/analytics/birdeye/constants.ts +74 -0
  30. package/src/analytics/birdeye/providers/agent-portfolio-provider.ts +18 -0
  31. package/src/analytics/birdeye/providers/market.ts +227 -0
  32. package/src/analytics/birdeye/providers/portfolio-factory.test.ts +138 -0
  33. package/src/analytics/birdeye/providers/portfolio-factory.ts +252 -0
  34. package/src/analytics/birdeye/providers/trending.ts +365 -0
  35. package/src/analytics/birdeye/providers/wallet.ts +14 -0
  36. package/src/analytics/birdeye/search-category.test.ts +207 -0
  37. package/src/analytics/birdeye/search-category.ts +506 -0
  38. package/src/analytics/birdeye/service.ts +992 -0
  39. package/src/analytics/birdeye/tasks/birdeye.ts +232 -0
  40. package/src/analytics/birdeye/types/api/common.ts +305 -0
  41. package/src/analytics/birdeye/types/api/defi.ts +220 -0
  42. package/src/analytics/birdeye/types/api/pair.ts +200 -0
  43. package/src/analytics/birdeye/types/api/search.ts +86 -0
  44. package/src/analytics/birdeye/types/api/token.ts +635 -0
  45. package/src/analytics/birdeye/types/api/trader.ts +76 -0
  46. package/src/analytics/birdeye/types/api/wallet.ts +181 -0
  47. package/src/analytics/birdeye/types/shared.ts +106 -0
  48. package/src/analytics/birdeye/utils.ts +700 -0
  49. package/src/analytics/dexscreener/errors.ts +28 -0
  50. package/src/analytics/dexscreener/index.ts +3 -0
  51. package/src/analytics/dexscreener/search-category.test.ts +49 -0
  52. package/src/analytics/dexscreener/search-category.ts +42 -0
  53. package/src/analytics/dexscreener/service.ts +595 -0
  54. package/src/analytics/dexscreener/types.ts +128 -0
  55. package/src/analytics/lpinfo/index.d.ts +7 -0
  56. package/src/analytics/lpinfo/index.ts +52 -0
  57. package/src/analytics/lpinfo/kamino/README.md +102 -0
  58. package/src/analytics/lpinfo/kamino/index.ts +24 -0
  59. package/src/analytics/lpinfo/kamino/providers/kaminoLiquidityProvider.ts +422 -0
  60. package/src/analytics/lpinfo/kamino/providers/kaminoPoolProvider.ts +365 -0
  61. package/src/analytics/lpinfo/kamino/providers/kaminoProvider.ts +496 -0
  62. package/src/analytics/lpinfo/kamino/services/kaminoLiquidityService.ts +1123 -0
  63. package/src/analytics/lpinfo/kamino/services/kaminoService.ts +758 -0
  64. package/src/analytics/lpinfo/steer/README.md +169 -0
  65. package/src/analytics/lpinfo/steer/index.ts +23 -0
  66. package/src/analytics/lpinfo/steer/providers/steerLiquidityProvider.ts +544 -0
  67. package/src/analytics/lpinfo/steer/services/steerLiquidityService.ts +1690 -0
  68. package/src/analytics/lpinfo/steer/steer-display-types.ts +99 -0
  69. package/src/analytics/news/index.ts +52 -0
  70. package/src/analytics/news/interfaces/types.ts +222 -0
  71. package/src/analytics/news/providers/defiNewsProvider.ts +734 -0
  72. package/src/analytics/news/services/newsDataService.ts +332 -0
  73. package/src/analytics/news/utils/formatters.ts +151 -0
  74. package/src/analytics/token-info/action.ts +240 -0
  75. package/src/analytics/token-info/index.ts +3 -0
  76. package/src/analytics/token-info/params.ts +215 -0
  77. package/src/analytics/token-info/providers.ts +681 -0
  78. package/src/analytics/token-info/service.ts +168 -0
  79. package/src/analytics/token-info/types.ts +74 -0
  80. package/src/audit/audit-log.ts +45 -0
  81. package/src/browser-shim/build-shim.ts +123 -0
  82. package/src/browser-shim/index.ts +5 -0
  83. package/src/browser-shim/shim.template.js +563 -0
  84. package/src/chains/evm/.github/workflows/npm-deploy.yml +112 -0
  85. package/src/chains/evm/LICENSE +21 -0
  86. package/src/chains/evm/README.md +106 -0
  87. package/src/chains/evm/actions/helpers.ts +147 -0
  88. package/src/chains/evm/actions/swap.ts +839 -0
  89. package/src/chains/evm/actions/transfer.ts +254 -0
  90. package/src/chains/evm/biome.json +61 -0
  91. package/src/chains/evm/bridge-router.ts +660 -0
  92. package/src/chains/evm/build.ts +89 -0
  93. package/src/chains/evm/chain-handler.ts +416 -0
  94. package/src/chains/evm/constants.ts +23 -0
  95. package/src/chains/evm/contracts/artifacts/OZGovernor.json +1707 -0
  96. package/src/chains/evm/contracts/artifacts/TimelockController.json +1007 -0
  97. package/src/chains/evm/contracts/artifacts/VoteToken.json +895 -0
  98. package/src/chains/evm/dex/aerodrome/index.ts +34 -0
  99. package/src/chains/evm/dex/aerodrome/services/AerodromeLpService.ts +558 -0
  100. package/src/chains/evm/dex/aerodrome/types.ts +318 -0
  101. package/src/chains/evm/dex/pancakeswp/index.ts +35 -0
  102. package/src/chains/evm/dex/pancakeswp/services/PancakeSwapV3LpService.ts +743 -0
  103. package/src/chains/evm/dex/pancakeswp/types.ts +65 -0
  104. package/src/chains/evm/dex/uniswap/index.ts +35 -0
  105. package/src/chains/evm/dex/uniswap/services/UniswapV3LpService.ts +759 -0
  106. package/src/chains/evm/dex/uniswap/types.ts +390 -0
  107. package/src/chains/evm/generated/specs/spec-helpers.ts +73 -0
  108. package/src/chains/evm/generated/specs/specs.ts +151 -0
  109. package/src/chains/evm/gov-router.ts +250 -0
  110. package/src/chains/evm/index.browser.ts +16 -0
  111. package/src/chains/evm/index.ts +31 -0
  112. package/src/chains/evm/prompts.ts +193 -0
  113. package/src/chains/evm/providers/get-balance.ts +123 -0
  114. package/src/chains/evm/providers/wallet.ts +715 -0
  115. package/src/chains/evm/routes/sign.ts +333 -0
  116. package/src/chains/evm/rpc-providers.ts +410 -0
  117. package/src/chains/evm/service.ts +140 -0
  118. package/src/chains/evm/templates/index.ts +10 -0
  119. package/src/chains/evm/types/index.ts +432 -0
  120. package/src/chains/evm/vitest.config.ts +18 -0
  121. package/src/chains/registry.ts +668 -0
  122. package/src/chains/solana/README.md +367 -0
  123. package/src/chains/wallet-action.ts +533 -0
  124. package/src/chains/wallet-router.test.ts +296 -0
  125. package/src/contracts.ts +65 -0
  126. package/src/core-augmentation.ts +10 -0
  127. package/src/index.ts +71 -0
  128. package/src/lib/server-wallet-trade.ts +192 -0
  129. package/src/lib/wallet-export-guard.ts +330 -0
  130. package/src/lp/actions/liquidity.ts +827 -0
  131. package/src/lp/e2e/real-token-tests.ts +428 -0
  132. package/src/lp/e2e/scenarios.ts +470 -0
  133. package/src/lp/e2e/test-utils.ts +145 -0
  134. package/src/lp/lp-manager-entry.ts +303 -0
  135. package/src/lp/services/ConcentratedLiquidityService.ts +120 -0
  136. package/src/lp/services/DexInteractionService.ts +226 -0
  137. package/src/lp/services/LpManagementService.test.ts +148 -0
  138. package/src/lp/services/LpManagementService.ts +632 -0
  139. package/src/lp/services/UserLpProfileService.ts +163 -0
  140. package/src/lp/services/VaultService.ts +153 -0
  141. package/src/lp/services/YieldOptimizationService.ts +344 -0
  142. package/src/lp/services/__tests__/MockLpService.ts +146 -0
  143. package/src/lp/tasks/LpAutoRebalanceTask.ts +117 -0
  144. package/src/lp/tasks/__tests__/LpAutoRebalanceTask.test.ts +370 -0
  145. package/src/lp/types.ts +582 -0
  146. package/src/lp/utils/solanaClient.ts +143 -0
  147. package/src/plugin.ts +125 -0
  148. package/src/policy/policy.ts +19 -0
  149. package/src/providers/canonical-provider.ts +27 -0
  150. package/src/providers/unified-wallet-provider.ts +79 -0
  151. package/src/register-routes.ts +11 -0
  152. package/src/routes/plugin.ts +47 -0
  153. package/src/routes/wallet-market-overview-route.ts +869 -0
  154. package/src/sdk/abi.ts +258 -0
  155. package/src/sdk/bridge/abis.ts +126 -0
  156. package/src/sdk/bridge/client.ts +518 -0
  157. package/src/sdk/bridge/index.ts +56 -0
  158. package/src/sdk/bridge/solana.ts +604 -0
  159. package/src/sdk/bridge/types.ts +202 -0
  160. package/src/sdk/convenience.ts +347 -0
  161. package/src/sdk/escrow/MutualStakeEscrow.ts +480 -0
  162. package/src/sdk/escrow/types.ts +64 -0
  163. package/src/sdk/escrow/verifiers.ts +73 -0
  164. package/src/sdk/identity/erc8004.ts +692 -0
  165. package/src/sdk/identity/reputation.ts +449 -0
  166. package/src/sdk/identity/uaid.ts +497 -0
  167. package/src/sdk/identity/validation.ts +372 -0
  168. package/src/sdk/index.ts +763 -0
  169. package/src/sdk/policy/SpendingPolicy.ts +260 -0
  170. package/src/sdk/policy/UptoBillingPolicy.ts +320 -0
  171. package/src/sdk/router/PaymentRouter.ts +215 -0
  172. package/src/sdk/router/index.ts +8 -0
  173. package/src/sdk/swap/SwapModule.ts +310 -0
  174. package/src/sdk/swap/abi.ts +117 -0
  175. package/src/sdk/swap/index.ts +34 -0
  176. package/src/sdk/swap/types.ts +135 -0
  177. package/src/sdk/tokens/decimals.ts +140 -0
  178. package/src/sdk/tokens/registry.ts +911 -0
  179. package/src/sdk/tokens/solana.ts +419 -0
  180. package/src/sdk/tokens/transfers.ts +327 -0
  181. package/src/sdk/types.ts +158 -0
  182. package/src/sdk/wallet-core.ts +115 -0
  183. package/src/sdk/x402/budget.ts +168 -0
  184. package/src/sdk/x402/chains/abstract/index.ts +280 -0
  185. package/src/sdk/x402/client.ts +320 -0
  186. package/src/sdk/x402/index.ts +46 -0
  187. package/src/sdk/x402/middleware.ts +92 -0
  188. package/src/sdk/x402/multi-asset.ts +144 -0
  189. package/src/sdk/x402/types.ts +156 -0
  190. package/src/services/wallet-backend-service.ts +328 -0
  191. package/src/types/wallet-router.ts +227 -0
  192. package/src/utils/intent-trajectory.ts +106 -0
  193. package/src/wallet/backend.ts +62 -0
  194. package/src/wallet/errors.ts +49 -0
  195. package/src/wallet/index.ts +27 -0
  196. package/src/wallet/local-eoa-backend.ts +201 -0
  197. package/src/wallet/pending.ts +60 -0
  198. package/src/wallet/select-backend.ts +47 -0
  199. package/src/wallet/steward-backend.ts +161 -0
  200. package/src/wallet-action.ts +1 -0
@@ -0,0 +1,595 @@
1
+ // @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
2
+
3
+ import {
4
+ cloudServiceApisBaseUrl,
5
+ toRuntimeSettings,
6
+ } from "@elizaos/cloud-routing";
7
+ import { type IAgentRuntime, Service } from "@elizaos/core";
8
+ import { dexScreenerErrorMessage } from "./errors";
9
+ import type {
10
+ DexScreenerBoostedToken,
11
+ DexScreenerChainParams,
12
+ DexScreenerConfig,
13
+ DexScreenerNewPairsParams,
14
+ DexScreenerOrder,
15
+ DexScreenerPair,
16
+ DexScreenerPairParams,
17
+ DexScreenerProfile,
18
+ DexScreenerSearchParams,
19
+ DexScreenerServiceResponse,
20
+ DexScreenerTokenParams,
21
+ DexScreenerTrendingParams,
22
+ } from "./types";
23
+
24
+ type DexScreenerBoostedWire = DexScreenerBoostedToken & {
25
+ labels?: string[];
26
+ };
27
+
28
+ type TokensV1Wire = DexScreenerPair | DexScreenerPair[];
29
+
30
+ export class DexScreenerService extends Service {
31
+ static serviceType = "dexscreener" as const;
32
+ private baseUrl!: string;
33
+ private defaultHeaders!: Record<string, string>;
34
+ private dexConfig!: DexScreenerConfig;
35
+ private lastRequestTime = 0;
36
+ public capabilityDescription =
37
+ "Provides DEX analytics and token information from DexScreener";
38
+
39
+ static async start(runtime: IAgentRuntime): Promise<Service> {
40
+ const service = new DexScreenerService(runtime);
41
+
42
+ const customBase = String(
43
+ runtime.getSetting("DEXSCREENER_API_URL") ?? "",
44
+ ).trim();
45
+ const delayRaw = runtime.getSetting("DEXSCREENER_RATE_LIMIT_DELAY");
46
+ const delayParsed = Number.parseInt(
47
+ typeof delayRaw === "number"
48
+ ? String(delayRaw)
49
+ : String(delayRaw ?? "100"),
50
+ 10,
51
+ );
52
+ const rateLimitDelay = Number.isFinite(delayParsed) ? delayParsed : 100;
53
+
54
+ let apiUrl: string;
55
+ const authHeaders: Record<string, string> = {};
56
+
57
+ if (customBase.length > 0) {
58
+ apiUrl = customBase.replace(/\/+$/, "");
59
+ } else {
60
+ const cloud = cloudServiceApisBaseUrl(
61
+ toRuntimeSettings(runtime),
62
+ "dexscreener",
63
+ );
64
+ if (cloud !== null) {
65
+ apiUrl = cloud.baseUrl;
66
+ Object.assign(authHeaders, cloud.headers);
67
+ } else {
68
+ apiUrl = "https://api.dexscreener.com";
69
+ }
70
+ }
71
+
72
+ service.dexConfig = {
73
+ apiUrl,
74
+ rateLimitDelay,
75
+ };
76
+
77
+ service.baseUrl = apiUrl;
78
+ service.defaultHeaders = {
79
+ Accept: "application/json",
80
+ "User-Agent": "ElizaOS-DexScreener-Plugin/1.0",
81
+ ...authHeaders,
82
+ };
83
+
84
+ return service;
85
+ }
86
+
87
+ async stop(): Promise<void> {
88
+ // Cleanup if needed
89
+ console.log("DexScreener service stopped");
90
+ }
91
+
92
+ private async get<T>(
93
+ path: string,
94
+ params?: Record<string, string>,
95
+ ): Promise<T> {
96
+ let url = `${this.baseUrl}${path}`;
97
+ if (params && Object.keys(params).length > 0) {
98
+ url += `?${new URLSearchParams(params).toString()}`;
99
+ }
100
+ const response = await fetch(url, { headers: this.defaultHeaders });
101
+ if (!response.ok) {
102
+ const errData = await response.json().catch(() => ({}));
103
+ throw Object.assign(
104
+ new Error(errData?.message || `HTTP ${response.status}`),
105
+ {
106
+ response: { data: errData },
107
+ },
108
+ );
109
+ }
110
+ return response.json() as Promise<T>;
111
+ }
112
+
113
+ private async rateLimit(): Promise<void> {
114
+ const delayMs = this.dexConfig.rateLimitDelay ?? 100;
115
+ const now = Date.now();
116
+ const timeSinceLastRequest = now - this.lastRequestTime;
117
+ if (timeSinceLastRequest < delayMs) {
118
+ await new Promise((resolve) =>
119
+ setTimeout(resolve, delayMs - timeSinceLastRequest),
120
+ );
121
+ }
122
+ this.lastRequestTime = Date.now();
123
+ }
124
+
125
+ async search(
126
+ params: DexScreenerSearchParams,
127
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
128
+ try {
129
+ await this.rateLimit();
130
+ const data = await this.get<{ pairs?: DexScreenerPair[] }>(
131
+ `/latest/dex/search`,
132
+ { q: params.query },
133
+ );
134
+
135
+ return {
136
+ success: true,
137
+ data: data.pairs || [],
138
+ };
139
+ } catch (caught: unknown) {
140
+ console.error("DexScreener search error:", caught);
141
+ return {
142
+ success: false,
143
+ error: dexScreenerErrorMessage(caught) || "Failed to search tokens",
144
+ };
145
+ }
146
+ }
147
+
148
+ async getTokenPairs(
149
+ params: DexScreenerTokenParams,
150
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
151
+ try {
152
+ await this.rateLimit();
153
+ const data = await this.get<{ pairs?: DexScreenerPair[] }>(
154
+ `/latest/dex/tokens/${params.tokenAddress}`,
155
+ );
156
+
157
+ return {
158
+ success: true,
159
+ data: data.pairs || [],
160
+ };
161
+ } catch (caught: unknown) {
162
+ console.error("DexScreener getTokenPairs error:", caught);
163
+ return {
164
+ success: false,
165
+ error: dexScreenerErrorMessage(caught) || "Failed to get token pairs",
166
+ };
167
+ }
168
+ }
169
+
170
+ async getPair(
171
+ params: DexScreenerPairParams,
172
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair>> {
173
+ try {
174
+ await this.rateLimit();
175
+ const data = await this.get<{ pair?: DexScreenerPair }>(
176
+ `/latest/dex/pairs/${params.pairAddress}`,
177
+ );
178
+
179
+ if (!data.pair) {
180
+ return {
181
+ success: false,
182
+ error: "Pair not found",
183
+ };
184
+ }
185
+
186
+ return {
187
+ success: true,
188
+ data: data.pair,
189
+ };
190
+ } catch (caught: unknown) {
191
+ console.error("DexScreener getPair error:", caught);
192
+ return {
193
+ success: false,
194
+ error: dexScreenerErrorMessage(caught) || "Failed to get pair",
195
+ };
196
+ }
197
+ }
198
+
199
+ async getTrending(
200
+ params: DexScreenerTrendingParams = {},
201
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
202
+ try {
203
+ await this.rateLimit();
204
+
205
+ // DexScreener doesn't have a direct trending endpoint
206
+ // We'll use the boosted tokens endpoint as a proxy for trending
207
+ const responseData = await this.get<
208
+ DexScreenerBoostedToken[] | DexScreenerBoostedToken
209
+ >(`/token-boosts/top/v1`);
210
+
211
+ // The boosted tokens response is an array of boosted tokens
212
+ const boostedTokens = Array.isArray(responseData)
213
+ ? responseData
214
+ : [responseData];
215
+
216
+ // For each boosted token, we need to get the actual pair data
217
+ const pairPromises = boostedTokens
218
+ .slice(0, params.limit || 10)
219
+ .map(async (token) => {
220
+ try {
221
+ const pairData = await this.get<TokensV1Wire>(
222
+ `/tokens/v1/${token.chainId}/${token.tokenAddress}`,
223
+ );
224
+ return Array.isArray(pairData) ? pairData[0] : null;
225
+ } catch (error) {
226
+ console.error(
227
+ `Failed to get pair data for ${token.tokenAddress}:`,
228
+ error,
229
+ );
230
+ return null;
231
+ }
232
+ });
233
+
234
+ const pairs = (await Promise.all(pairPromises)).filter(
235
+ (pair) => pair !== null,
236
+ );
237
+
238
+ return {
239
+ success: true,
240
+ data: pairs,
241
+ };
242
+ } catch (caught: unknown) {
243
+ console.error("DexScreener getTrending error:", caught);
244
+ return {
245
+ success: false,
246
+ error:
247
+ dexScreenerErrorMessage(caught) || "Failed to get trending pairs",
248
+ };
249
+ }
250
+ }
251
+
252
+ async getPairsByChain(
253
+ params: DexScreenerChainParams,
254
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
255
+ try {
256
+ await this.rateLimit();
257
+
258
+ // Use search API with chain filter
259
+ const data = await this.get<{ pairs?: DexScreenerPair[] }>(
260
+ `/latest/dex/search`,
261
+ { q: params.chain },
262
+ );
263
+
264
+ let pairs: DexScreenerPair[] = data.pairs || [];
265
+
266
+ // Filter to only include pairs from the specified chain
267
+ pairs = pairs.filter(
268
+ (pair) => pair.chainId.toLowerCase() === params.chain.toLowerCase(),
269
+ );
270
+
271
+ // Sort by specified criteria
272
+ if (params.sortBy) {
273
+ pairs.sort((a, b) => {
274
+ switch (params.sortBy) {
275
+ case "volume":
276
+ return (b.volume?.h24 || 0) - (a.volume?.h24 || 0);
277
+ case "liquidity":
278
+ return (b.liquidity?.usd || 0) - (a.liquidity?.usd || 0);
279
+ case "priceChange":
280
+ return (b.priceChange?.h24 || 0) - (a.priceChange?.h24 || 0);
281
+ case "txns":
282
+ return (
283
+ (b.txns?.h24.buys + b.txns?.h24.sells || 0) -
284
+ (a.txns?.h24.buys + a.txns?.h24.sells || 0)
285
+ );
286
+ default:
287
+ return 0;
288
+ }
289
+ });
290
+ }
291
+
292
+ // Limit results
293
+ const limitedPairs = params.limit
294
+ ? pairs.slice(0, params.limit)
295
+ : pairs.slice(0, 20);
296
+
297
+ return {
298
+ success: true,
299
+ data: limitedPairs,
300
+ };
301
+ } catch (caught: unknown) {
302
+ console.error("DexScreener getPairsByChain error:", caught);
303
+ return {
304
+ success: false,
305
+ error:
306
+ dexScreenerErrorMessage(caught) || "Failed to get pairs by chain",
307
+ };
308
+ }
309
+ }
310
+
311
+ async getNewPairs(
312
+ params: DexScreenerNewPairsParams = {},
313
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
314
+ try {
315
+ await this.rateLimit();
316
+
317
+ // DexScreener doesn't have a direct new pairs endpoint
318
+ // We'll use the latest token profiles as a proxy for new tokens
319
+ const responseData = await this.get<
320
+ DexScreenerProfile[] | DexScreenerProfile
321
+ >(`/token-profiles/latest/v1`);
322
+
323
+ // The latest token profiles response is an array of profiles
324
+ const profiles = Array.isArray(responseData)
325
+ ? responseData
326
+ : [responseData];
327
+
328
+ // Filter by chain if specified
329
+ const filteredProfiles = params.chain
330
+ ? profiles.filter(
331
+ (p) => p.chainId?.toLowerCase() === params.chain?.toLowerCase(),
332
+ )
333
+ : profiles;
334
+
335
+ // For each profile, we need to get the actual pair data
336
+ const pairPromises = filteredProfiles
337
+ .slice(0, params.limit || 10)
338
+ .map(async (profile) => {
339
+ try {
340
+ const pairData = await this.get<TokensV1Wire>(
341
+ `/tokens/v1/${profile.chainId}/${profile.tokenAddress}`,
342
+ );
343
+ const pairs = Array.isArray(pairData) ? pairData : [];
344
+ // Return the first pair with 'new' label
345
+ if (pairs.length > 0) {
346
+ return {
347
+ ...pairs[0],
348
+ labels: pairs[0].labels?.includes("new")
349
+ ? pairs[0].labels
350
+ : [...(pairs[0].labels || []), "new"],
351
+ };
352
+ }
353
+ return null;
354
+ } catch (error) {
355
+ console.error(
356
+ `Failed to get pair data for ${profile.tokenAddress}:`,
357
+ error,
358
+ );
359
+ return null;
360
+ }
361
+ });
362
+
363
+ const pairs = (await Promise.all(pairPromises)).filter(
364
+ (pair) => pair !== null,
365
+ );
366
+
367
+ return {
368
+ success: true,
369
+ data: pairs,
370
+ };
371
+ } catch (caught: unknown) {
372
+ console.error("DexScreener getNewPairs error:", caught);
373
+ return {
374
+ success: false,
375
+ error: dexScreenerErrorMessage(caught) || "Failed to get new pairs",
376
+ };
377
+ }
378
+ }
379
+
380
+ async getTokenProfile(
381
+ tokenAddress: string,
382
+ ): Promise<DexScreenerServiceResponse<DexScreenerProfile>> {
383
+ try {
384
+ await this.rateLimit();
385
+ // Token profiles are available through the latest profiles endpoint
386
+ // We need to fetch all and find the matching one
387
+ const responseData = await this.get<
388
+ DexScreenerProfile[] | DexScreenerProfile
389
+ >(`/token-profiles/latest/v1`);
390
+ const profiles = Array.isArray(responseData)
391
+ ? responseData
392
+ : [responseData];
393
+
394
+ const profile = profiles.find(
395
+ (p) => p.tokenAddress?.toLowerCase() === tokenAddress.toLowerCase(),
396
+ );
397
+
398
+ if (!profile) {
399
+ return {
400
+ success: false,
401
+ error: "Token profile not found",
402
+ };
403
+ }
404
+
405
+ return {
406
+ success: true,
407
+ data: profile,
408
+ };
409
+ } catch (caught: unknown) {
410
+ console.error("DexScreener getTokenProfile error:", caught);
411
+ return {
412
+ success: false,
413
+ error: dexScreenerErrorMessage(caught) || "Failed to get token profile",
414
+ };
415
+ }
416
+ }
417
+
418
+ formatPrice(price: string | number): string {
419
+ const numPrice = typeof price === "string" ? parseFloat(price) : price;
420
+ if (numPrice >= 1) {
421
+ return numPrice.toFixed(2);
422
+ } else if (numPrice >= 0.01) {
423
+ return numPrice.toFixed(4);
424
+ } else {
425
+ return numPrice.toFixed(8);
426
+ }
427
+ }
428
+
429
+ formatPriceChange(change: number): string {
430
+ const sign = change >= 0 ? "+" : "";
431
+ return `${sign}${change.toFixed(2)}%`;
432
+ }
433
+
434
+ formatUsdValue(value: number): string {
435
+ if (value >= 1000000) {
436
+ return `$${(value / 1000000).toFixed(2)}M`;
437
+ } else if (value >= 1000) {
438
+ return `$${(value / 1000).toFixed(2)}K`;
439
+ } else {
440
+ return `$${value.toFixed(2)}`;
441
+ }
442
+ }
443
+
444
+ async getMultipleTokens(
445
+ chainId: string,
446
+ tokenAddresses: string[],
447
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
448
+ try {
449
+ if (tokenAddresses.length > 30) {
450
+ return {
451
+ success: false,
452
+ error: "Maximum 30 token addresses allowed",
453
+ };
454
+ }
455
+
456
+ await this.rateLimit();
457
+ const addresses = tokenAddresses.join(",");
458
+ const data = await this.get<DexScreenerPair[] | DexScreenerPair>(
459
+ `/tokens/v1/${chainId}/${addresses}`,
460
+ );
461
+
462
+ return {
463
+ success: true,
464
+ data: Array.isArray(data) ? data : data ? [data] : [],
465
+ };
466
+ } catch (caught: unknown) {
467
+ console.error("DexScreener getMultipleTokens error:", caught);
468
+ return {
469
+ success: false,
470
+ error:
471
+ dexScreenerErrorMessage(caught) || "Failed to get multiple tokens",
472
+ };
473
+ }
474
+ }
475
+
476
+ async getLatestTokenProfiles(): Promise<
477
+ DexScreenerServiceResponse<DexScreenerProfile[]>
478
+ > {
479
+ try {
480
+ await this.rateLimit();
481
+ const data = await this.get<DexScreenerProfile[] | DexScreenerProfile>(
482
+ `/token-profiles/latest/v1`,
483
+ );
484
+
485
+ return {
486
+ success: true,
487
+ data: Array.isArray(data) ? data : [data],
488
+ };
489
+ } catch (caught: unknown) {
490
+ console.error("DexScreener getLatestTokenProfiles error:", caught);
491
+ return {
492
+ success: false,
493
+ error:
494
+ dexScreenerErrorMessage(caught) ||
495
+ "Failed to get latest token profiles",
496
+ };
497
+ }
498
+ }
499
+
500
+ async getLatestBoostedTokens(): Promise<
501
+ DexScreenerServiceResponse<DexScreenerBoostedWire[]>
502
+ > {
503
+ try {
504
+ await this.rateLimit();
505
+ const data = await this.get<
506
+ DexScreenerBoostedWire[] | DexScreenerBoostedWire
507
+ >(`/token-boosts/latest/v1`);
508
+
509
+ return {
510
+ success: true,
511
+ data: Array.isArray(data) ? data : [data],
512
+ };
513
+ } catch (caught: unknown) {
514
+ console.error("DexScreener getLatestBoostedTokens error:", caught);
515
+ return {
516
+ success: false,
517
+ error:
518
+ dexScreenerErrorMessage(caught) ||
519
+ "Failed to get latest boosted tokens",
520
+ };
521
+ }
522
+ }
523
+
524
+ async getTopBoostedTokens(): Promise<
525
+ DexScreenerServiceResponse<DexScreenerBoostedWire[]>
526
+ > {
527
+ try {
528
+ await this.rateLimit();
529
+ const data = await this.get<
530
+ DexScreenerBoostedWire[] | DexScreenerBoostedWire
531
+ >(`/token-boosts/top/v1`);
532
+
533
+ return {
534
+ success: true,
535
+ data: Array.isArray(data) ? data : [data],
536
+ };
537
+ } catch (caught: unknown) {
538
+ console.error("DexScreener getTopBoostedTokens error:", caught);
539
+ return {
540
+ success: false,
541
+ error:
542
+ dexScreenerErrorMessage(caught) || "Failed to get top boosted tokens",
543
+ };
544
+ }
545
+ }
546
+
547
+ async checkOrderStatus(
548
+ chainId: string,
549
+ tokenAddress: string,
550
+ ): Promise<DexScreenerServiceResponse<DexScreenerOrder[]>> {
551
+ try {
552
+ await this.rateLimit();
553
+ const data = await this.get<DexScreenerOrder[] | DexScreenerOrder>(
554
+ `/orders/v1/${chainId}/${tokenAddress}`,
555
+ );
556
+
557
+ return {
558
+ success: true,
559
+ data: Array.isArray(data) ? data : data ? [data] : [],
560
+ };
561
+ } catch (caught: unknown) {
562
+ console.error("DexScreener checkOrderStatus error:", caught);
563
+ return {
564
+ success: false,
565
+ error:
566
+ dexScreenerErrorMessage(caught) || "Failed to check order status",
567
+ };
568
+ }
569
+ }
570
+
571
+ async getTokenPairsByChain(
572
+ chainId: string,
573
+ tokenAddress: string,
574
+ ): Promise<DexScreenerServiceResponse<DexScreenerPair[]>> {
575
+ try {
576
+ await this.rateLimit();
577
+ const data = await this.get<DexScreenerPair[] | DexScreenerPair>(
578
+ `/token-pairs/v1/${chainId}/${tokenAddress}`,
579
+ );
580
+
581
+ return {
582
+ success: true,
583
+ data: Array.isArray(data) ? data : data ? [data] : [],
584
+ };
585
+ } catch (caught: unknown) {
586
+ console.error("DexScreener getTokenPairsByChain error:", caught);
587
+ return {
588
+ success: false,
589
+ error:
590
+ dexScreenerErrorMessage(caught) ||
591
+ "Failed to get token pairs by chain",
592
+ };
593
+ }
594
+ }
595
+ }
@@ -0,0 +1,128 @@
1
+ // @ts-nocheck — legacy code from absorbed plugins (lp-manager, lpinfo, dexscreener, defi-news, birdeye); strict types pending cleanup
2
+ // DexScreener API Types
3
+
4
+ export interface DexScreenerTokenInfo {
5
+ address: string;
6
+ name: string;
7
+ symbol: string;
8
+ decimals: number;
9
+ }
10
+
11
+ export interface DexScreenerPair {
12
+ chainId: string;
13
+ dexId: string;
14
+ url: string;
15
+ pairAddress: string;
16
+ labels?: string[];
17
+ baseToken: DexScreenerTokenInfo;
18
+ quoteToken: DexScreenerTokenInfo;
19
+ priceNative: string;
20
+ priceUsd?: string;
21
+ txns: {
22
+ m5: { buys: number; sells: number };
23
+ h1: { buys: number; sells: number };
24
+ h6: { buys: number; sells: number };
25
+ h24: { buys: number; sells: number };
26
+ };
27
+ volume: {
28
+ h24: number;
29
+ h6: number;
30
+ h1: number;
31
+ m5: number;
32
+ };
33
+ priceChange: {
34
+ m5: number;
35
+ h1: number;
36
+ h6: number;
37
+ h24: number;
38
+ };
39
+ liquidity?: {
40
+ usd?: number;
41
+ base: number;
42
+ quote: number;
43
+ };
44
+ fdv?: number;
45
+ marketCap?: number;
46
+ pairCreatedAt?: number;
47
+ info?: {
48
+ imageUrl?: string;
49
+ websites?: { label: string; url: string }[];
50
+ socials?: { type: string; url: string }[];
51
+ };
52
+ }
53
+
54
+ export interface DexScreenerSearchParams {
55
+ query: string;
56
+ }
57
+
58
+ export interface DexScreenerTokenParams {
59
+ tokenAddress: string;
60
+ }
61
+
62
+ export interface DexScreenerPairParams {
63
+ pairAddress: string;
64
+ }
65
+
66
+ export interface DexScreenerTrendingParams {
67
+ timeframe?: "1h" | "6h" | "24h";
68
+ limit?: number;
69
+ }
70
+
71
+ export interface DexScreenerChainParams {
72
+ chain: string;
73
+ sortBy?: "volume" | "liquidity" | "priceChange" | "txns";
74
+ limit?: number;
75
+ }
76
+
77
+ export interface DexScreenerNewPairsParams {
78
+ chain?: string;
79
+ limit?: number;
80
+ }
81
+
82
+ export interface DexScreenerProfile {
83
+ url: string;
84
+ chainId: string;
85
+ tokenAddress: string;
86
+ icon?: string;
87
+ header?: string;
88
+ openGraph?: string;
89
+ description?: string;
90
+ links?: Array<{
91
+ label: string;
92
+ type: string;
93
+ url: string;
94
+ }>;
95
+ }
96
+
97
+ export interface DexScreenerServiceResponse<T> {
98
+ success: boolean;
99
+ data?: T;
100
+ error?: string;
101
+ }
102
+
103
+ export interface DexScreenerConfig {
104
+ apiUrl?: string;
105
+ rateLimitDelay?: number;
106
+ }
107
+
108
+ export interface DexScreenerBoostedToken {
109
+ url: string;
110
+ chainId: string;
111
+ tokenAddress: string;
112
+ amount: number;
113
+ totalAmount: number;
114
+ icon?: string;
115
+ header?: string;
116
+ description?: string;
117
+ links?: Array<{
118
+ type: string;
119
+ label: string;
120
+ url: string;
121
+ }>;
122
+ }
123
+
124
+ export interface DexScreenerOrder {
125
+ type: "tokenProfile" | "boost" | string;
126
+ status: "processing" | "completed" | "failed" | string;
127
+ paymentTimestamp: number;
128
+ }