obol-mcp 2.0.0

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 (58) hide show
  1. package/README.md +195 -0
  2. package/dist/app.d.ts +3 -0
  3. package/dist/app.d.ts.map +1 -0
  4. package/dist/app.js +130 -0
  5. package/dist/app.js.map +1 -0
  6. package/dist/config/env.d.ts +47 -0
  7. package/dist/config/env.d.ts.map +1 -0
  8. package/dist/config/env.js +63 -0
  9. package/dist/config/env.js.map +1 -0
  10. package/dist/config/pricing.d.ts +12 -0
  11. package/dist/config/pricing.d.ts.map +1 -0
  12. package/dist/config/pricing.js +99 -0
  13. package/dist/config/pricing.js.map +1 -0
  14. package/dist/mcp.d.ts +35 -0
  15. package/dist/mcp.d.ts.map +1 -0
  16. package/dist/mcp.js +150 -0
  17. package/dist/mcp.js.map +1 -0
  18. package/dist/middleware/validation.d.ts +6 -0
  19. package/dist/middleware/validation.d.ts.map +1 -0
  20. package/dist/middleware/validation.js +40 -0
  21. package/dist/middleware/validation.js.map +1 -0
  22. package/dist/middleware/x402.d.ts +33 -0
  23. package/dist/middleware/x402.d.ts.map +1 -0
  24. package/dist/middleware/x402.js +294 -0
  25. package/dist/middleware/x402.js.map +1 -0
  26. package/dist/plugins/defi/routes.d.ts +12 -0
  27. package/dist/plugins/defi/routes.d.ts.map +1 -0
  28. package/dist/plugins/defi/routes.js +430 -0
  29. package/dist/plugins/defi/routes.js.map +1 -0
  30. package/dist/plugins/token/routes.d.ts +10 -0
  31. package/dist/plugins/token/routes.d.ts.map +1 -0
  32. package/dist/plugins/token/routes.js +111 -0
  33. package/dist/plugins/token/routes.js.map +1 -0
  34. package/dist/plugins/wallet/routes.d.ts +13 -0
  35. package/dist/plugins/wallet/routes.d.ts.map +1 -0
  36. package/dist/plugins/wallet/routes.js +235 -0
  37. package/dist/plugins/wallet/routes.js.map +1 -0
  38. package/dist/server.d.ts +2 -0
  39. package/dist/server.d.ts.map +1 -0
  40. package/dist/server.js +38 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/services/cache.d.ts +25 -0
  43. package/dist/services/cache.d.ts.map +1 -0
  44. package/dist/services/cache.js +82 -0
  45. package/dist/services/cache.js.map +1 -0
  46. package/dist/services/helius.d.ts +102 -0
  47. package/dist/services/helius.d.ts.map +1 -0
  48. package/dist/services/helius.js +456 -0
  49. package/dist/services/helius.js.map +1 -0
  50. package/dist/utils/logger.d.ts +3 -0
  51. package/dist/utils/logger.d.ts.map +1 -0
  52. package/dist/utils/logger.js +15 -0
  53. package/dist/utils/logger.js.map +1 -0
  54. package/dist/utils/retry.d.ts +9 -0
  55. package/dist/utils/retry.d.ts.map +1 -0
  56. package/dist/utils/retry.js +45 -0
  57. package/dist/utils/retry.js.map +1 -0
  58. package/package.json +81 -0
@@ -0,0 +1,456 @@
1
+ import { Connection, PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';
2
+ import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token';
3
+ import { config } from '../config/env.js';
4
+ import { cache } from './cache.js';
5
+ import { logger } from '../utils/logger.js';
6
+ import { withRetry } from '../utils/retry.js';
7
+ // ──────────────────────────────────────────────
8
+ // Helius Service
9
+ // ──────────────────────────────────────────────
10
+ class HeliusService {
11
+ connection = null;
12
+ apiKey;
13
+ baseUrl;
14
+ constructor() {
15
+ this.apiKey = config.solana.heliusApiKey;
16
+ this.baseUrl = config.solana.network === 'mainnet-beta'
17
+ ? 'https://mainnet.helius-rpc.com'
18
+ : 'https://devnet.helius-rpc.com';
19
+ }
20
+ getConnection() {
21
+ if (!this.connection) {
22
+ if (!config.solana.rpcUrl) {
23
+ throw new Error('Helius RPC URL not configured');
24
+ }
25
+ this.connection = new Connection(config.solana.rpcUrl, 'confirmed');
26
+ }
27
+ return this.connection;
28
+ }
29
+ get rpcUrl() {
30
+ return `${this.baseUrl}/?api-key=${this.apiKey}`;
31
+ }
32
+ /** DAS API call helper */
33
+ async dasCall(method, params) {
34
+ const response = await fetch(this.rpcUrl, {
35
+ method: 'POST',
36
+ headers: { 'Content-Type': 'application/json' },
37
+ body: JSON.stringify({ jsonrpc: '2.0', id: method, method, params }),
38
+ });
39
+ const data = await response.json();
40
+ if (data.error)
41
+ throw new Error(`Helius ${method}: ${data.error.message}`);
42
+ return data.result;
43
+ }
44
+ // ── SOL ──
45
+ async getSOLBalance(address) {
46
+ return withRetry(async () => {
47
+ const balance = await this.getConnection().getBalance(new PublicKey(address));
48
+ return balance / LAMPORTS_PER_SOL;
49
+ }, { maxRetries: 2 }, `SOL balance ${address}`);
50
+ }
51
+ async getSOLPrice() {
52
+ const cached = await cache.get('price:SOL');
53
+ if (cached !== null)
54
+ return cached;
55
+ try {
56
+ const solMint = 'So11111111111111111111111111111111111111112';
57
+ const response = await fetch(`https://lite-api.jup.ag/price/v3?ids=${solMint}`);
58
+ const data = await response.json();
59
+ const price = data[solMint]?.usdPrice ?? 0;
60
+ await cache.set('price:SOL', price, 120);
61
+ return price;
62
+ }
63
+ catch (error) {
64
+ logger.warn({ error }, 'Failed to fetch SOL price');
65
+ return 0;
66
+ }
67
+ }
68
+ // ── Tokens ──
69
+ async getTokenAccounts(address) {
70
+ const cacheKey = `tokens:${address}`;
71
+ const cached = await cache.get(cacheKey);
72
+ if (cached)
73
+ return cached;
74
+ const pubkey = new PublicKey(address);
75
+ const conn = this.getConnection();
76
+ const [splAccounts, t22Accounts] = await Promise.all([
77
+ conn.getParsedTokenAccountsByOwner(pubkey, { programId: TOKEN_PROGRAM_ID }),
78
+ conn.getParsedTokenAccountsByOwner(pubkey, { programId: TOKEN_2022_PROGRAM_ID }),
79
+ ]);
80
+ const allAccounts = [...splAccounts.value, ...t22Accounts.value];
81
+ const tokens = allAccounts
82
+ .map(acct => {
83
+ const info = acct.account.data.parsed.info;
84
+ const amt = info.tokenAmount;
85
+ return {
86
+ mint: info.mint,
87
+ address: acct.pubkey.toString(),
88
+ owner: info.owner,
89
+ amount: amt.amount,
90
+ decimals: amt.decimals,
91
+ uiAmount: amt.uiAmount || 0,
92
+ };
93
+ })
94
+ .filter(t => t.uiAmount > 0);
95
+ // Enrich with metadata
96
+ await this.enrichTokenMetadata(tokens);
97
+ await cache.set(cacheKey, tokens, 300);
98
+ return tokens;
99
+ }
100
+ async enrichTokenMetadata(tokens) {
101
+ if (tokens.length === 0)
102
+ return;
103
+ try {
104
+ const result = await this.dasCall('getAssetBatch', {
105
+ ids: tokens.map(t => t.mint),
106
+ });
107
+ if (result) {
108
+ const metaMap = new Map(result.map(a => [a.id, a]));
109
+ for (const token of tokens) {
110
+ const meta = metaMap.get(token.mint);
111
+ if (meta?.content) {
112
+ token.name = meta.content.metadata?.name;
113
+ token.symbol = meta.content.metadata?.symbol;
114
+ token.logoURI = meta.content.links?.image || meta.content.files?.[0]?.uri;
115
+ }
116
+ }
117
+ }
118
+ }
119
+ catch (error) {
120
+ logger.warn({ error }, 'Token metadata enrichment failed (non-critical)');
121
+ }
122
+ }
123
+ async getTokenPrices(mints) {
124
+ if (mints.length === 0)
125
+ return new Map();
126
+ const cacheKey = `prices:${mints.sort().join(',')}`;
127
+ const cached = await cache.get(cacheKey);
128
+ if (cached)
129
+ return new Map(Object.entries(cached));
130
+ try {
131
+ const response = await fetch(`https://lite-api.jup.ag/price/v3?ids=${mints.join(',')}`);
132
+ const data = await response.json();
133
+ const priceMap = new Map();
134
+ for (const [mint, info] of Object.entries(data)) {
135
+ if (info?.usdPrice)
136
+ priceMap.set(mint, info.usdPrice);
137
+ }
138
+ await cache.set(cacheKey, Object.fromEntries(priceMap), 120);
139
+ return priceMap;
140
+ }
141
+ catch (error) {
142
+ logger.warn({ error }, 'Jupiter price fetch failed');
143
+ return new Map();
144
+ }
145
+ }
146
+ // ── NFTs ──
147
+ async getNFTCount(address) {
148
+ const cacheKey = `nft-count:${address}`;
149
+ const cached = await cache.get(cacheKey);
150
+ if (cached !== null)
151
+ return cached;
152
+ try {
153
+ const result = await this.dasCall('getAssetsByOwner', {
154
+ ownerAddress: address, page: 1, limit: 1,
155
+ displayOptions: { showFungible: false },
156
+ });
157
+ const count = result?.total ?? 0;
158
+ await cache.set(cacheKey, count, 600);
159
+ return count;
160
+ }
161
+ catch (error) {
162
+ logger.warn({ error, address }, 'NFT count failed');
163
+ return 0;
164
+ }
165
+ }
166
+ async getNFTs(address, limit = 50) {
167
+ const cacheKey = `nfts:${address}:${limit}`;
168
+ const cached = await cache.get(cacheKey);
169
+ if (cached)
170
+ return cached;
171
+ try {
172
+ const result = await this.dasCall('getAssetsByOwner', {
173
+ ownerAddress: address, page: 1, limit,
174
+ displayOptions: { showFungible: false, showCollectionMetadata: true },
175
+ });
176
+ const nfts = (result?.items ?? []).map((asset) => {
177
+ const content = asset.content;
178
+ const metadata = content?.metadata;
179
+ const links = content?.links;
180
+ const files = content?.files;
181
+ const grouping = asset.grouping;
182
+ const creators = asset.creators;
183
+ return {
184
+ mint: asset.id,
185
+ name: metadata?.name,
186
+ symbol: metadata?.symbol,
187
+ collection: grouping?.find(g => g.group_key === 'collection')?.group_value,
188
+ imageUrl: links?.image || files?.[0]?.uri,
189
+ verified: creators?.some(c => c.verified) ?? false,
190
+ };
191
+ });
192
+ await cache.set(cacheKey, nfts, 600);
193
+ return nfts;
194
+ }
195
+ catch (error) {
196
+ logger.warn({ error, address }, 'NFT fetch failed');
197
+ return [];
198
+ }
199
+ }
200
+ // ── Activity ──
201
+ async isWalletActive(address) {
202
+ try {
203
+ const sigs = await this.getConnection().getSignaturesForAddress(new PublicKey(address), { limit: 1 });
204
+ if (sigs.length === 0)
205
+ return false;
206
+ const lastTxTime = sigs[0]?.blockTime;
207
+ if (!lastTxTime)
208
+ return false;
209
+ const thirtyDaysAgo = Math.floor(Date.now() / 1000) - 30 * 86400;
210
+ return lastTxTime > thirtyDaysAgo;
211
+ }
212
+ catch {
213
+ return false;
214
+ }
215
+ }
216
+ async getWalletActivity(address, limit = 50) {
217
+ const cacheKey = `activity:${address}:${limit}`;
218
+ const cached = await cache.get(cacheKey);
219
+ if (cached)
220
+ return cached;
221
+ const pubkey = new PublicKey(address);
222
+ const conn = this.getConnection();
223
+ const signatures = await conn.getSignaturesForAddress(pubkey, { limit });
224
+ if (signatures.length === 0) {
225
+ const empty = { address, transactionCount: 0, recentTransactions: [] };
226
+ await cache.set(cacheKey, empty, 300);
227
+ return empty;
228
+ }
229
+ // Fetch parsed transactions individually (not batched — v1 had a bug here)
230
+ const txPromises = signatures.slice(0, 10).map(async (sig) => {
231
+ try {
232
+ const tx = await conn.getParsedTransaction(sig.signature, {
233
+ maxSupportedTransactionVersion: 0,
234
+ commitment: 'confirmed',
235
+ });
236
+ return { sig, tx };
237
+ }
238
+ catch {
239
+ return { sig, tx: null };
240
+ }
241
+ });
242
+ const results = await Promise.all(txPromises);
243
+ const recentTransactions = results.map(({ sig, tx }) => ({
244
+ signature: sig.signature,
245
+ timestamp: sig.blockTime ?? 0,
246
+ type: inferTxType(tx),
247
+ status: sig.err ? 'failed' : 'success',
248
+ fee: tx?.meta?.fee ? tx.meta.fee / LAMPORTS_PER_SOL : 0,
249
+ description: describeTx(tx),
250
+ }));
251
+ const activity = {
252
+ address,
253
+ transactionCount: signatures.length,
254
+ firstTransaction: signatures.length > 0
255
+ ? new Date((signatures[signatures.length - 1]?.blockTime ?? 0) * 1000).toISOString()
256
+ : undefined,
257
+ lastTransaction: signatures.length > 0
258
+ ? new Date((signatures[0]?.blockTime ?? 0) * 1000).toISOString()
259
+ : undefined,
260
+ recentTransactions,
261
+ };
262
+ await cache.set(cacheKey, activity, 300);
263
+ return activity;
264
+ }
265
+ // ── Composites ──
266
+ async getWalletOverview(address) {
267
+ const cacheKey = `overview:${address}`;
268
+ const cached = await cache.get(cacheKey);
269
+ if (cached)
270
+ return cached;
271
+ const [solBalance, tokens, nftCount, isActive, solPrice] = await Promise.all([
272
+ this.getSOLBalance(address),
273
+ this.getTokenAccounts(address),
274
+ this.getNFTCount(address),
275
+ this.isWalletActive(address),
276
+ this.getSOLPrice(),
277
+ ]);
278
+ const prices = await this.getTokenPrices(tokens.map(t => t.mint));
279
+ for (const token of tokens) {
280
+ const price = prices.get(token.mint);
281
+ if (price) {
282
+ token.priceUSD = price;
283
+ token.valueUSD = token.uiAmount * price;
284
+ }
285
+ }
286
+ const solBalanceUSD = solBalance * solPrice;
287
+ const tokenValueUSD = tokens.reduce((sum, t) => sum + (t.valueUSD ?? 0), 0);
288
+ const topTokens = [...tokens]
289
+ .filter(t => t.valueUSD && t.valueUSD > 0)
290
+ .sort((a, b) => (b.valueUSD ?? 0) - (a.valueUSD ?? 0))
291
+ .slice(0, 5);
292
+ const overview = {
293
+ address,
294
+ solBalance,
295
+ solBalanceUSD,
296
+ totalValueUSD: solBalanceUSD + tokenValueUSD,
297
+ tokenCount: tokens.length,
298
+ nftCount,
299
+ isActive,
300
+ topTokens,
301
+ };
302
+ await cache.set(cacheKey, overview, 300);
303
+ return overview;
304
+ }
305
+ async getWalletPortfolio(address) {
306
+ const cacheKey = `portfolio:${address}`;
307
+ const cached = await cache.get(cacheKey);
308
+ if (cached)
309
+ return cached;
310
+ const [solBalance, tokens, nfts, solPrice] = await Promise.all([
311
+ this.getSOLBalance(address),
312
+ this.getTokenAccounts(address),
313
+ this.getNFTs(address, 100),
314
+ this.getSOLPrice(),
315
+ ]);
316
+ const prices = await this.getTokenPrices(tokens.map(t => t.mint));
317
+ for (const token of tokens) {
318
+ const price = prices.get(token.mint);
319
+ if (price) {
320
+ token.priceUSD = price;
321
+ token.valueUSD = token.uiAmount * price;
322
+ }
323
+ }
324
+ const solBalanceUSD = solBalance * solPrice;
325
+ const tokensValueUSD = tokens.reduce((sum, t) => sum + (t.valueUSD ?? 0), 0);
326
+ const portfolio = {
327
+ address,
328
+ totalValueUSD: solBalanceUSD + tokensValueUSD,
329
+ solBalance,
330
+ solBalanceUSD,
331
+ tokens: tokens.sort((a, b) => (b.valueUSD ?? 0) - (a.valueUSD ?? 0)),
332
+ nfts,
333
+ breakdown: { sol: solBalanceUSD, tokens: tokensValueUSD, nfts: 0 },
334
+ };
335
+ await cache.set(cacheKey, portfolio, 300);
336
+ return portfolio;
337
+ }
338
+ async getWalletRisk(address) {
339
+ const cacheKey = `risk:${address}`;
340
+ const cached = await cache.get(cacheKey);
341
+ if (cached)
342
+ return cached;
343
+ const pubkey = new PublicKey(address);
344
+ const conn = this.getConnection();
345
+ const [overview, recentSigs] = await Promise.all([
346
+ this.getWalletOverview(address),
347
+ conn.getSignaturesForAddress(pubkey, { limit: 100 }),
348
+ ]);
349
+ // Find wallet age by paginating to first tx
350
+ const firstTx = await this.getFirstTransaction(pubkey);
351
+ const factors = [];
352
+ const warnings = [];
353
+ let score = 0;
354
+ // Wallet age
355
+ if (firstTx?.blockTime) {
356
+ const ageDays = Math.floor((Date.now() - firstTx.blockTime * 1000) / 86400000);
357
+ if (ageDays < 7) {
358
+ factors.push({ type: 'wallet_age', severity: 'high', description: `Very new wallet (${ageDays} days)`, impact: 30 });
359
+ score += 30;
360
+ warnings.push('Newly created wallet');
361
+ }
362
+ else if (ageDays < 30) {
363
+ factors.push({ type: 'wallet_age', severity: 'medium', description: `New wallet (${ageDays} days)`, impact: 15 });
364
+ score += 15;
365
+ }
366
+ else {
367
+ factors.push({ type: 'wallet_age', severity: 'low', description: `Wallet age: ${ageDays} days`, impact: 0 });
368
+ }
369
+ }
370
+ // Activity level
371
+ const txCount = recentSigs.length;
372
+ if (txCount < 5) {
373
+ factors.push({ type: 'low_activity', severity: 'medium', description: `Very low activity (${txCount} recent txs)`, impact: 20 });
374
+ score += 20;
375
+ warnings.push('Low transaction history');
376
+ }
377
+ // Portfolio concentration
378
+ if (overview.tokenCount === 0 && overview.solBalance < 0.1) {
379
+ factors.push({ type: 'empty_wallet', severity: 'high', description: 'Minimal or no holdings', impact: 25 });
380
+ score += 25;
381
+ warnings.push('Empty or nearly empty wallet');
382
+ }
383
+ // Inactivity
384
+ if (!overview.isActive) {
385
+ factors.push({ type: 'inactive', severity: 'low', description: 'No activity in 30+ days', impact: 10 });
386
+ score += 10;
387
+ }
388
+ const riskScore = Math.min(score, 100);
389
+ const riskLevel = riskScore < 30 ? 'low' : riskScore < 60 ? 'medium' : 'high';
390
+ const risk = { address, riskScore, riskLevel, factors, warnings };
391
+ await cache.set(cacheKey, risk, 600);
392
+ return risk;
393
+ }
394
+ async getFirstTransaction(pubkey) {
395
+ let oldest = null;
396
+ let before;
397
+ const conn = this.getConnection();
398
+ for (let i = 0; i < 10; i++) {
399
+ const sigs = await conn.getSignaturesForAddress(pubkey, { limit: 1000, before });
400
+ if (sigs.length === 0)
401
+ break;
402
+ const last = sigs[sigs.length - 1];
403
+ if (last)
404
+ oldest = { blockTime: last.blockTime ?? null, signature: last.signature };
405
+ if (sigs.length < 1000)
406
+ break;
407
+ if (oldest)
408
+ before = oldest.signature;
409
+ }
410
+ return oldest;
411
+ }
412
+ /** Warmup connections and caches */
413
+ async warmup() {
414
+ try {
415
+ const conn = this.getConnection();
416
+ await conn.getVersion();
417
+ await this.getSOLPrice();
418
+ logger.info('Helius service warmed up');
419
+ }
420
+ catch (error) {
421
+ logger.warn({ error }, 'Warmup failed (non-critical)');
422
+ }
423
+ }
424
+ }
425
+ // ── Helpers ──
426
+ function inferTxType(tx) {
427
+ const t = tx;
428
+ const instructions = t?.transaction?.message?.instructions ?? [];
429
+ for (const ix of instructions) {
430
+ const pid = ix.programId?.toString() ?? '';
431
+ if (pid === 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')
432
+ return 'Token Transfer';
433
+ if (pid === '11111111111111111111111111111111')
434
+ return 'SOL Transfer';
435
+ if (pid.includes('Swap') || pid.includes('whirl') || pid.includes('JUP'))
436
+ return 'Swap';
437
+ if (pid.includes('Stake'))
438
+ return 'Staking';
439
+ }
440
+ return 'Transaction';
441
+ }
442
+ function describeTx(tx) {
443
+ const t = tx;
444
+ const instructions = t?.transaction?.message?.instructions ?? [];
445
+ if (instructions.length === 0)
446
+ return 'Transaction';
447
+ const pid = instructions[0]?.programId?.toString() ?? '';
448
+ if (pid === 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA')
449
+ return 'Token operation';
450
+ if (pid === '11111111111111111111111111111111')
451
+ return 'SOL transfer';
452
+ return `Program interaction (${instructions.length} instruction${instructions.length > 1 ? 's' : ''})`;
453
+ }
454
+ /** Singleton */
455
+ export const helius = new HeliusService();
456
+ //# sourceMappingURL=helius.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helius.js","sourceRoot":"","sources":["../../src/services/helius.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import pino from 'pino';
2
+ export declare const logger: pino.Logger<never, boolean>;
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,eAAO,MAAM,MAAM,6BAWjB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import pino from 'pino';
2
+ import { config } from '../config/env.js';
3
+ export const logger = pino({
4
+ level: config.logging.level,
5
+ transport: config.server.isDevelopment
6
+ ? {
7
+ target: 'pino-pretty',
8
+ options: {
9
+ translateTime: 'HH:MM:ss',
10
+ ignore: 'pid,hostname',
11
+ },
12
+ }
13
+ : undefined,
14
+ });
15
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK;IAC3B,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa;QACpC,CAAC,CAAC;YACE,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU;gBACzB,MAAM,EAAE,cAAc;aACvB;SACF;QACH,CAAC,CAAC,SAAS;CACd,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface RetryOptions {
2
+ maxRetries?: number;
3
+ initialDelayMs?: number;
4
+ maxDelayMs?: number;
5
+ backoffMultiplier?: number;
6
+ }
7
+ /** Retry an async operation with exponential backoff */
8
+ export declare function withRetry<T>(operation: () => Promise<T>, options?: RetryOptions, context?: string): Promise<T>;
9
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AASD,wDAAwD;AACxD,wBAAsB,SAAS,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,GAAE,YAAiB,EAC1B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC,CAuBZ"}
@@ -0,0 +1,45 @@
1
+ import { logger } from './logger.js';
2
+ const DEFAULTS = {
3
+ maxRetries: 3,
4
+ initialDelayMs: 1000,
5
+ maxDelayMs: 10000,
6
+ backoffMultiplier: 2,
7
+ };
8
+ /** Retry an async operation with exponential backoff */
9
+ export async function withRetry(operation, options = {}, context) {
10
+ const opts = { ...DEFAULTS, ...options };
11
+ let delay = opts.initialDelayMs;
12
+ for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {
13
+ try {
14
+ return await operation();
15
+ }
16
+ catch (error) {
17
+ const isLast = attempt === opts.maxRetries;
18
+ const msg = error instanceof Error ? error.message : String(error);
19
+ if (isLast || !isRetryable(error)) {
20
+ logger.error({ context, attempt: attempt + 1, error: msg }, 'Operation failed');
21
+ throw error;
22
+ }
23
+ logger.warn({ context, attempt: attempt + 1, nextRetryMs: delay, error: msg }, 'Retrying');
24
+ await sleep(delay);
25
+ delay = Math.min(delay * opts.backoffMultiplier, opts.maxDelayMs);
26
+ }
27
+ }
28
+ throw new Error('Unreachable');
29
+ }
30
+ function isRetryable(error) {
31
+ if (!(error instanceof Error))
32
+ return false;
33
+ const msg = error.message.toLowerCase();
34
+ return (msg.includes('timeout') ||
35
+ msg.includes('enotfound') ||
36
+ msg.includes('econnrefused') ||
37
+ msg.includes('fetch failed') ||
38
+ msg.includes('429') ||
39
+ msg.includes('rate limit') ||
40
+ /5\d{2}/.test(msg));
41
+ }
42
+ function sleep(ms) {
43
+ return new Promise(resolve => setTimeout(resolve, ms));
44
+ }
45
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AASrC,MAAM,QAAQ,GAA2B;IACvC,UAAU,EAAE,CAAC;IACb,cAAc,EAAE,IAAI;IACpB,UAAU,EAAE,KAAK;IACjB,iBAAiB,EAAE,CAAC;CACrB,CAAC;AAEF,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,SAA2B,EAC3B,UAAwB,EAAE,EAC1B,OAAgB;IAEhB,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;IACzC,IAAI,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;IAEhC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QAC5D,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC;YAC3C,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEnE,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;gBAChF,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;YAC3F,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACnB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IACxC,OAAO,CACL,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;QACvB,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC;QACzB,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC5B,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;QAC5B,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACnB,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CACnB,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "obol-mcp",
3
+ "version": "2.0.0",
4
+ "description": "Pay the ferryman. Solana agent gateway via x402. MCP server for AI agents.",
5
+ "main": "dist/server.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "dev": "tsx watch src/server.ts",
9
+ "build": "tsc",
10
+ "start": "node dist/server.js",
11
+ "test": "vitest",
12
+ "test:coverage": "vitest --coverage",
13
+ "lint": "eslint src --ext .ts",
14
+ "lint:fix": "eslint src --ext .ts --fix",
15
+ "format": "prettier --write \"src/**/*.ts\"",
16
+ "typecheck": "tsc --noEmit",
17
+ "mcp": "tsx src/mcp.ts",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "bin": {
21
+ "obol-mcp": "./dist/mcp.js"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "LICENSE"
27
+ ],
28
+ "keywords": [
29
+ "solana",
30
+ "x402",
31
+ "api",
32
+ "gateway",
33
+ "micropayments",
34
+ "agent",
35
+ "obol",
36
+ "mcp",
37
+ "model-context-protocol",
38
+ "ai-agent",
39
+ "usdc",
40
+ "defi"
41
+ ],
42
+ "author": "halfkey",
43
+ "license": "MIT",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/halfkey/obol.git"
47
+ },
48
+ "homepage": "https://github.com/halfkey/obol",
49
+ "dependencies": {
50
+ "@fastify/cors": "^10.0.1",
51
+ "@fastify/helmet": "^12.0.1",
52
+ "@fastify/rate-limit": "^10.1.1",
53
+ "@modelcontextprotocol/sdk": "^1.29.0",
54
+ "@solana/spl-token": "^0.4.9",
55
+ "@solana/web3.js": "^1.95.8",
56
+ "@upstash/redis": "^1.35.6",
57
+ "@x402/core": "^2.6.0",
58
+ "@x402/svm": "^2.6.0",
59
+ "bs58": "^6.0.0",
60
+ "dotenv": "^16.4.7",
61
+ "fastify": "^5.2.0",
62
+ "pino": "^9.6.0",
63
+ "pino-pretty": "^13.0.0",
64
+ "zod": "^3.24.1"
65
+ },
66
+ "devDependencies": {
67
+ "@types/node": "^22.10.2",
68
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
69
+ "@typescript-eslint/parser": "^8.19.1",
70
+ "@vitest/coverage-v8": "^2.1.8",
71
+ "eslint": "^9.17.0",
72
+ "eslint-config-prettier": "^9.1.0",
73
+ "prettier": "^3.4.2",
74
+ "tsx": "^4.19.2",
75
+ "typescript": "^5.7.2",
76
+ "vitest": "^2.1.8"
77
+ },
78
+ "engines": {
79
+ "node": ">=20.0.0"
80
+ }
81
+ }