teleton 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,7 @@
6
6
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
7
7
  <a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen" alt="Node.js"></a>
8
8
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.7-blue" alt="TypeScript"></a>
9
+ <a href="https://ai.resistance.dog"><img src="https://img.shields.io/badge/Website-ai.resistance.dog-ff6600" alt="Website"></a>
9
10
  </p>
10
11
 
11
12
  ---
@@ -3,10 +3,9 @@ import {
3
3
  ContextBuilder,
4
4
  MessageStore,
5
5
  UserStore,
6
- fetchWithTimeout,
7
6
  getDatabase,
8
7
  initializeMemory
9
- } from "./chunk-PMX75DTX.js";
8
+ } from "./chunk-JDPS46IZ.js";
10
9
  import {
11
10
  ALLOWED_EXTENSIONS,
12
11
  MAX_FILE_SIZES,
@@ -20,10 +19,10 @@ import {
20
19
  GECKOTERMINAL_API_URL,
21
20
  OPENAI_TTS_URL,
22
21
  STONFI_API_BASE_URL,
23
- TONAPI_BASE_URL,
22
+ fetchWithTimeout,
24
23
  setTonapiKey,
25
- tonapiHeaders
26
- } from "./chunk-ST5CO7TV.js";
24
+ tonapiFetch
25
+ } from "./chunk-WMIN6AGX.js";
27
26
  import {
28
27
  COMPACTION_KEEP_RECENT,
29
28
  COMPACTION_MAX_MESSAGES,
@@ -3192,6 +3191,18 @@ function maskOldToolResults(messages, config = DEFAULT_MASKING_CONFIG, toolRegis
3192
3191
  return result;
3193
3192
  }
3194
3193
 
3194
+ // src/utils/logger.ts
3195
+ var _verbose = process.env.TELETON_LOG === "verbose";
3196
+ function verbose(...args) {
3197
+ if (_verbose) console.log(...args);
3198
+ }
3199
+ function setVerbose(v) {
3200
+ _verbose = v;
3201
+ }
3202
+ function isVerbose() {
3203
+ return _verbose;
3204
+ }
3205
+
3195
3206
  // src/agent/runtime.ts
3196
3207
  function isContextOverflowError(errorMessage) {
3197
3208
  if (!errorMessage) return false;
@@ -3327,9 +3338,14 @@ var AgentRuntime = class {
3327
3338
  formattedMessage = `${pendingContext}
3328
3339
 
3329
3340
  ${formattedMessage}`;
3330
- console.log(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
3331
- }
3332
- console.log(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
3341
+ verbose(`\u{1F4CB} Including ${pendingContext.split("\n").length - 1} pending messages`);
3342
+ }
3343
+ verbose(`\u{1F4E8} Formatted message: ${formattedMessage.substring(0, 100)}...`);
3344
+ const preview = formattedMessage.slice(0, 50).replace(/\n/g, " ");
3345
+ const who = senderUsername ? `@${senderUsername}` : userName;
3346
+ const msgType = isGroup ? `Group ${chatId} ${who}` : `DM ${who}`;
3347
+ console.log(`
3348
+ \u{1F4E8} ${msgType}: "${preview}${formattedMessage.length > 50 ? "..." : ""}"`);
3333
3349
  let relevantContext = "";
3334
3350
  if (this.contextBuilder) {
3335
3351
  try {
@@ -3358,7 +3374,7 @@ ${dbContext.relevantFeed.join("\n")}`
3358
3374
  }
3359
3375
  if (contextParts.length > 0) {
3360
3376
  relevantContext = contextParts.join("\n\n");
3361
- console.log(
3377
+ verbose(
3362
3378
  `\u{1F50D} Found ${dbContext.relevantKnowledge.length} knowledge chunks, ${dbContext.relevantFeed.length} feed messages`
3363
3379
  );
3364
3380
  }
@@ -3424,7 +3440,7 @@ ${statsContext}`;
3424
3440
  const accumulatedTexts = [];
3425
3441
  while (iteration < maxIterations) {
3426
3442
  iteration++;
3427
- console.log(`
3443
+ verbose(`
3428
3444
  \u{1F504} Agentic iteration ${iteration}/${maxIterations}`);
3429
3445
  const maskedMessages = maskOldToolResults(
3430
3446
  context.messages,
@@ -3491,7 +3507,7 @@ ${statsContext}`;
3491
3507
  }
3492
3508
  const toolCalls = response2.message.content.filter((block) => block.type === "toolCall");
3493
3509
  if (toolCalls.length === 0) {
3494
- console.log(`\u2705 Agent finished (no more tool calls)`);
3510
+ console.log(` \u{1F504} ${iteration}/${maxIterations} \u2192 done`);
3495
3511
  finalResponse = response2;
3496
3512
  break;
3497
3513
  }
@@ -3499,8 +3515,9 @@ ${statsContext}`;
3499
3515
  console.error("\u26A0\uFE0F Cannot execute tools: registry or context missing");
3500
3516
  break;
3501
3517
  }
3502
- console.log(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
3518
+ verbose(`\u{1F527} Executing ${toolCalls.length} tool call(s)`);
3503
3519
  context.messages.push(response2.message);
3520
+ const iterationToolNames = [];
3504
3521
  for (const block of toolCalls) {
3505
3522
  if (block.type !== "toolCall") continue;
3506
3523
  const fullContext = {
@@ -3509,7 +3526,8 @@ ${statsContext}`;
3509
3526
  isGroup: isGroup ?? false
3510
3527
  };
3511
3528
  const result = await this.toolRegistry.execute(block, fullContext);
3512
- console.log(` ${block.name}: ${result.success ? "\u2713" : "\u2717"} ${result.error || ""}`);
3529
+ verbose(` ${block.name}: ${result.success ? "\u2713" : "\u2717"} ${result.error || ""}`);
3530
+ iterationToolNames.push(`${block.name} ${result.success ? "\u2713" : "\u2717"}`);
3513
3531
  totalToolCalls.push({
3514
3532
  name: block.name,
3515
3533
  input: block.arguments
@@ -3552,8 +3570,9 @@ ${statsContext}`;
3552
3570
  context.messages.push(toolResultMsg);
3553
3571
  appendToTranscript(session.sessionId, toolResultMsg);
3554
3572
  }
3573
+ console.log(` \u{1F504} ${iteration}/${maxIterations} \u2192 ${iterationToolNames.join(", ")}`);
3555
3574
  if (iteration === maxIterations) {
3556
- console.log(`\u26A0\uFE0F Max iterations reached (${maxIterations})`);
3575
+ console.log(` \u26A0\uFE0F Max iterations reached (${maxIterations})`);
3557
3576
  finalResponse = response2;
3558
3577
  }
3559
3578
  }
@@ -3584,9 +3603,8 @@ ${statsContext}`;
3584
3603
  }
3585
3604
  const usage = response.message.usage;
3586
3605
  if (usage) {
3587
- console.log(
3588
- `\u{1F4B0} Usage: ${usage.input} in, ${usage.output} out, ${usage.cacheRead} cache read | Cost: $${usage.cost.total.toFixed(4)}`
3589
- );
3606
+ const inK = (usage.input / 1e3).toFixed(1);
3607
+ console.log(` \u{1F4B0} ${inK}K in, ${usage.output} out | $${usage.cost.total.toFixed(3)}`);
3590
3608
  }
3591
3609
  let content = accumulatedTexts.join("\n").trim() || response.text;
3592
3610
  const telegramSendTools = [
@@ -4666,7 +4684,7 @@ var MessageHandler = class {
4666
4684
  */
4667
4685
  async handleMessage(message) {
4668
4686
  const msgType = message.isGroup ? "group" : message.isChannel ? "channel" : "dm";
4669
- console.log(
4687
+ verbose(
4670
4688
  `\u{1F4E8} [Handler] Received ${msgType} message ${message.id} from ${message.senderId} (mentions: ${message.mentionsMe})`
4671
4689
  );
4672
4690
  await this.storeTelegramMessage(message, false);
@@ -4675,15 +4693,20 @@ var MessageHandler = class {
4675
4693
  this.pendingHistory.addMessage(message.chatId, message);
4676
4694
  }
4677
4695
  if (!context.shouldRespond) {
4678
- console.log(`Skipping message ${message.id} from ${message.senderId}: ${context.reason}`);
4696
+ if (message.isGroup && context.reason === "Not mentioned") {
4697
+ const chatShort = message.chatId.length > 10 ? message.chatId.slice(0, 7) + ".." + message.chatId.slice(-2) : message.chatId;
4698
+ console.log(`\u23ED\uFE0F Group ${chatShort} msg:${message.id} (not mentioned)`);
4699
+ } else {
4700
+ verbose(`Skipping message ${message.id} from ${message.senderId}: ${context.reason}`);
4701
+ }
4679
4702
  return;
4680
4703
  }
4681
4704
  if (!this.rateLimiter.canSendMessage()) {
4682
- console.log("Rate limit reached, skipping message");
4705
+ verbose("Rate limit reached, skipping message");
4683
4706
  return;
4684
4707
  }
4685
4708
  if (message.isGroup && !this.rateLimiter.canSendToGroup(message.chatId)) {
4686
- console.log(`Group rate limit reached for ${message.chatId}`);
4709
+ verbose(`Group rate limit reached for ${message.chatId}`);
4687
4710
  return;
4688
4711
  }
4689
4712
  const releaseLock = await this.chatLock.acquire(message.chatId);
@@ -4763,7 +4786,7 @@ var MessageHandler = class {
4763
4786
  this.pendingHistory.clearPending(message.chatId);
4764
4787
  }
4765
4788
  writeOffset(message.id, message.chatId);
4766
- console.log(`Processed message ${message.id} in chat ${message.chatId}`);
4789
+ verbose(`Processed message ${message.id} in chat ${message.chatId}`);
4767
4790
  } catch (error) {
4768
4791
  console.error("Error handling message:", error);
4769
4792
  } finally {
@@ -4900,9 +4923,7 @@ async function getWalletBalance(address4) {
4900
4923
  }
4901
4924
  async function getTonPrice() {
4902
4925
  try {
4903
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/rates?tokens=ton&currencies=usd`, {
4904
- headers: tonapiHeaders()
4905
- });
4926
+ const response = await tonapiFetch(`/rates?tokens=ton&currencies=usd`);
4906
4927
  if (response.ok) {
4907
4928
  const data = await response.json();
4908
4929
  const price = data?.rates?.TON?.prices?.USD;
@@ -5044,6 +5065,8 @@ var AdminHandler = class {
5044
5065
  return this.handleStrategyCommand(command);
5045
5066
  case "stop":
5046
5067
  return await this.handleStopCommand();
5068
+ case "verbose":
5069
+ return this.handleVerboseCommand();
5047
5070
  case "help":
5048
5071
  return this.handleHelpCommand();
5049
5072
  case "ping":
@@ -5248,6 +5271,14 @@ Usage:
5248
5271
  return null;
5249
5272
  }
5250
5273
  }
5274
+ /**
5275
+ * /verbose - Toggle verbose logging at runtime
5276
+ */
5277
+ handleVerboseCommand() {
5278
+ const next = !isVerbose();
5279
+ setVerbose(next);
5280
+ return next ? "\u{1F50A} Verbose logging **ON**" : "\u{1F507} Verbose logging **OFF**";
5281
+ }
5251
5282
  /**
5252
5283
  * /help - Show available commands
5253
5284
  */
@@ -5272,6 +5303,9 @@ View or change trading thresholds
5272
5303
  **/wallet**
5273
5304
  Check TON wallet balance
5274
5305
 
5306
+ **/verbose**
5307
+ Toggle verbose debug logging
5308
+
5275
5309
  **/pause** / **/resume**
5276
5310
  Pause or resume the agent
5277
5311
 
@@ -5314,18 +5348,16 @@ var MessageDebouncer = class {
5314
5348
  async enqueue(message) {
5315
5349
  const isGroup = message.isGroup ? "group" : "dm";
5316
5350
  const shouldDebounce = this.config.debounceMs > 0 && this.shouldDebounce(message);
5317
- console.log(
5351
+ verbose(
5318
5352
  `\u{1F4E9} [Debouncer] Received ${isGroup} message from ${message.senderId} in ${message.chatId} (debounce: ${shouldDebounce})`
5319
5353
  );
5320
5354
  if (!shouldDebounce) {
5321
5355
  const key2 = message.chatId;
5322
5356
  if (this.buffers.has(key2)) {
5323
- console.log(
5324
- `\u{1F4E4} [Debouncer] Flushing pending buffer for ${key2} before immediate processing`
5325
- );
5357
+ verbose(`\u{1F4E4} [Debouncer] Flushing pending buffer for ${key2} before immediate processing`);
5326
5358
  await this.flushKey(key2);
5327
5359
  }
5328
- console.log(`\u26A1 [Debouncer] Processing immediately (no debounce)`);
5360
+ verbose(`\u26A1 [Debouncer] Processing immediately (no debounce)`);
5329
5361
  await this.processMessages([message]);
5330
5362
  return;
5331
5363
  }
@@ -5333,7 +5365,7 @@ var MessageDebouncer = class {
5333
5365
  const existing = this.buffers.get(key);
5334
5366
  if (existing) {
5335
5367
  existing.messages.push(message);
5336
- console.log(
5368
+ verbose(
5337
5369
  `\u{1F4E5} [Debouncer] Added to buffer for ${key} (${existing.messages.length} messages waiting)`
5338
5370
  );
5339
5371
  this.resetTimer(key, existing);
@@ -5367,7 +5399,7 @@ var MessageDebouncer = class {
5367
5399
  async flushKey(key) {
5368
5400
  const buffer = this.buffers.get(key);
5369
5401
  if (!buffer) {
5370
- console.log(`\u{1F4ED} [Debouncer] No buffer to flush for ${key}`);
5402
+ verbose(`\u{1F4ED} [Debouncer] No buffer to flush for ${key}`);
5371
5403
  return;
5372
5404
  }
5373
5405
  this.buffers.delete(key);
@@ -5376,10 +5408,10 @@ var MessageDebouncer = class {
5376
5408
  buffer.timer = null;
5377
5409
  }
5378
5410
  if (buffer.messages.length === 0) {
5379
- console.log(`\u{1F4ED} [Debouncer] Empty buffer for ${key}, nothing to flush`);
5411
+ verbose(`\u{1F4ED} [Debouncer] Empty buffer for ${key}, nothing to flush`);
5380
5412
  return;
5381
5413
  }
5382
- console.log(`\u{1F4E4} [Debouncer] Flushing ${buffer.messages.length} message(s) for ${key}`);
5414
+ verbose(`\u{1F4E4} [Debouncer] Flushing ${buffer.messages.length} message(s) for ${key}`);
5383
5415
  await this.processMessages(buffer.messages);
5384
5416
  }
5385
5417
  /**
@@ -5387,7 +5419,7 @@ var MessageDebouncer = class {
5387
5419
  */
5388
5420
  async processMessages(messages) {
5389
5421
  const sorted = messages.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
5390
- console.log(`\u{1F504} [Debouncer] Processing ${sorted.length} message(s)`);
5422
+ verbose(`\u{1F504} [Debouncer] Processing ${sorted.length} message(s)`);
5391
5423
  try {
5392
5424
  await this.onFlush(sorted);
5393
5425
  } catch (error) {
@@ -5447,7 +5479,7 @@ var MarketScraperService = class {
5447
5479
  this.isScrapingInProgress = true;
5448
5480
  console.log("\u{1F504} Starting full market scrape...");
5449
5481
  try {
5450
- const { runScraper } = await import("./scraper-BET6OXRF.js");
5482
+ const { runScraper } = await import("./scraper-I2TFAK4V.js");
5451
5483
  const result = await runScraper({
5452
5484
  workers: 4,
5453
5485
  limit: 0
@@ -5590,7 +5622,7 @@ var MarketPriceService = class {
5590
5622
  const updatedAt = /* @__PURE__ */ new Date(model.updated_at + "Z");
5591
5623
  const cacheAge = Date.now() - updatedAt.getTime();
5592
5624
  if (cacheAge > this.cacheTtlMs) {
5593
- console.log(
5625
+ verbose(
5594
5626
  ` \u23F0 Cache stale for ${collectionName} (${Math.round(cacheAge / 1e3 / 60)} min old)`
5595
5627
  );
5596
5628
  }
@@ -9545,15 +9577,10 @@ var telegramGetFoldersExecutor = async (_params, context) => {
9545
9577
  try {
9546
9578
  const gramJsClient = context.bridge.getClient().getClient();
9547
9579
  const result = await gramJsClient.invoke(new Api31.messages.GetDialogFilters());
9548
- if (!Array.isArray(result)) {
9549
- return {
9550
- success: false,
9551
- error: "Unexpected result type from dialog filters"
9552
- };
9553
- }
9554
- const folders = result.filter((filter) => filter.className === "DialogFilter").map((filter) => ({
9580
+ const filterList = Array.isArray(result) ? result : result.filters ?? [];
9581
+ const folders = filterList.filter((filter) => filter.className === "DialogFilter").map((filter) => ({
9555
9582
  id: filter.id,
9556
- title: filter.title,
9583
+ title: filter.title?.text ?? filter.title,
9557
9584
  emoji: filter.emoticon || null,
9558
9585
  pinnedPeersCount: filter.pinnedPeers?.length || 0,
9559
9586
  includedPeersCount: filter.includePeers?.length || 0,
@@ -9638,12 +9665,13 @@ var telegramCreateFolderExecutor = async (params, context) => {
9638
9665
  includeBots = false
9639
9666
  } = params;
9640
9667
  const gramJsClient = context.bridge.getClient().getClient();
9641
- const existingFilters = await gramJsClient.invoke(new Api32.messages.GetDialogFilters());
9642
- const maxId = Array.isArray(existingFilters) ? Math.max(0, ...existingFilters.map((f) => f.id || 0)) : 0;
9643
- const newId = maxId + 1;
9668
+ const result = await gramJsClient.invoke(new Api32.messages.GetDialogFilters());
9669
+ const filters = Array.isArray(result) ? result : result.filters ?? [];
9670
+ const usedIds = filters.filter((f) => typeof f.id === "number").map((f) => f.id);
9671
+ const newId = usedIds.length > 0 ? Math.max(...usedIds) + 1 : 2;
9644
9672
  const filterData = {
9645
9673
  id: newId,
9646
- title,
9674
+ title: new Api32.TextWithEntities({ text: title, entities: [] }),
9647
9675
  pinnedPeers: [],
9648
9676
  includePeers: [],
9649
9677
  excludePeers: [],
@@ -9700,14 +9728,9 @@ var telegramAddChatToFolderExecutor = async (params, context) => {
9700
9728
  try {
9701
9729
  const { folderId, chatId } = params;
9702
9730
  const gramJsClient = context.bridge.getClient().getClient();
9703
- const filters = await gramJsClient.invoke(new Api33.messages.GetDialogFilters());
9704
- if (!Array.isArray(filters)) {
9705
- return {
9706
- success: false,
9707
- error: "Failed to get existing folders"
9708
- };
9709
- }
9710
- const folder = filters.find((f) => f.id === folderId);
9731
+ const filtersResult = await gramJsClient.invoke(new Api33.messages.GetDialogFilters());
9732
+ const filterList = Array.isArray(filtersResult) ? filtersResult : filtersResult.filters ?? [];
9733
+ const folder = filterList.find((f) => f.id === folderId);
9711
9734
  if (!folder || folder.className !== "DialogFilter") {
9712
9735
  return {
9713
9736
  success: false,
@@ -9731,7 +9754,7 @@ var telegramAddChatToFolderExecutor = async (params, context) => {
9731
9754
  success: true,
9732
9755
  data: {
9733
9756
  folderId,
9734
- folderTitle: folder.title,
9757
+ folderTitle: folder.title?.text ?? folder.title,
9735
9758
  chatId,
9736
9759
  totalChatsInFolder: updatedIncludePeers.length
9737
9760
  }
@@ -12516,9 +12539,7 @@ var dnsCheckExecutor = async (params, context) => {
12516
12539
  };
12517
12540
  }
12518
12541
  const fullDomain = `${domain}.ton`;
12519
- const dnsInfoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
12520
- headers: tonapiHeaders()
12521
- });
12542
+ const dnsInfoResponse = await tonapiFetch(`/dns/${fullDomain}`);
12522
12543
  if (dnsInfoResponse.status === 404) {
12523
12544
  const minPrice = estimateMinPrice(domain.length);
12524
12545
  return {
@@ -12559,9 +12580,7 @@ var dnsCheckExecutor = async (params, context) => {
12559
12580
  }
12560
12581
  };
12561
12582
  }
12562
- const auctionsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
12563
- headers: tonapiHeaders()
12564
- });
12583
+ const auctionsResponse = await tonapiFetch(`/dns/auctions?tld=ton`);
12565
12584
  if (auctionsResponse.ok) {
12566
12585
  const auctions = await auctionsResponse.json();
12567
12586
  const auction = auctions.data?.find((a) => a.domain === fullDomain);
@@ -12623,9 +12642,7 @@ var dnsAuctionsTool = {
12623
12642
  var dnsAuctionsExecutor = async (params, context) => {
12624
12643
  try {
12625
12644
  const { limit = 20 } = params;
12626
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
12627
- headers: tonapiHeaders()
12628
- });
12645
+ const response = await tonapiFetch(`/dns/auctions?tld=ton`);
12629
12646
  if (!response.ok) {
12630
12647
  return {
12631
12648
  success: false,
@@ -12694,9 +12711,7 @@ var dnsResolveExecutor = async (params, context) => {
12694
12711
  let { domain } = params;
12695
12712
  domain = domain.toLowerCase().replace(/\.ton$/, "");
12696
12713
  const fullDomain = `${domain}.ton`;
12697
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
12698
- headers: tonapiHeaders()
12699
- });
12714
+ const response = await tonapiFetch(`/dns/${fullDomain}`);
12700
12715
  if (response.status === 404) {
12701
12716
  return {
12702
12717
  success: false,
@@ -12853,9 +12868,7 @@ var dnsBidExecutor = async (params, context) => {
12853
12868
  let { domain, amount } = params;
12854
12869
  domain = domain.toLowerCase().replace(/\.ton$/, "");
12855
12870
  const fullDomain = `${domain}.ton`;
12856
- const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
12857
- headers: tonapiHeaders()
12858
- });
12871
+ const dnsResponse = await tonapiFetch(`/dns/${fullDomain}`);
12859
12872
  if (dnsResponse.status === 404) {
12860
12873
  return {
12861
12874
  success: false,
@@ -12882,9 +12895,7 @@ var dnsBidExecutor = async (params, context) => {
12882
12895
  error: `Could not determine NFT address for ${fullDomain}`
12883
12896
  };
12884
12897
  }
12885
- const auctionsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
12886
- headers: tonapiHeaders()
12887
- });
12898
+ const auctionsResponse = await tonapiFetch(`/dns/auctions?tld=ton`);
12888
12899
  if (auctionsResponse.ok) {
12889
12900
  const auctions = await auctionsResponse.json();
12890
12901
  const auction = auctions.data?.find((a) => a.domain === fullDomain);
@@ -12997,9 +13008,7 @@ var dnsLinkExecutor = async (params, context) => {
12997
13008
  error: `Invalid wallet address: ${targetAddress}`
12998
13009
  };
12999
13010
  }
13000
- const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
13001
- headers: tonapiHeaders()
13002
- });
13011
+ const dnsResponse = await tonapiFetch(`/dns/${fullDomain}`);
13003
13012
  if (dnsResponse.status === 404) {
13004
13013
  return {
13005
13014
  success: false,
@@ -13112,9 +13121,7 @@ var dnsUnlinkExecutor = async (params, context) => {
13112
13121
  error: "Wallet not initialized. Contact admin to generate wallet."
13113
13122
  };
13114
13123
  }
13115
- const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
13116
- headers: tonapiHeaders()
13117
- });
13124
+ const dnsResponse = await tonapiFetch(`/dns/${fullDomain}`);
13118
13125
  if (dnsResponse.status === 404) {
13119
13126
  return {
13120
13127
  success: false,
@@ -13211,12 +13218,7 @@ var jettonBalancesExecutor = async (params, context) => {
13211
13218
  error: "Wallet not initialized. Contact admin to generate wallet."
13212
13219
  };
13213
13220
  }
13214
- const response = await fetchWithTimeout(
13215
- `${TONAPI_BASE_URL}/accounts/${walletData.address}/jettons`,
13216
- {
13217
- headers: tonapiHeaders()
13218
- }
13219
- );
13221
+ const response = await tonapiFetch(`/accounts/${walletData.address}/jettons`);
13220
13222
  if (!response.ok) {
13221
13223
  return {
13222
13224
  success: false,
@@ -16810,12 +16812,7 @@ var jettonSendExecutor = async (params, context) => {
16810
16812
  error: `Invalid recipient address: ${to}`
16811
16813
  };
16812
16814
  }
16813
- const jettonsResponse = await fetchWithTimeout(
16814
- `${TONAPI_BASE_URL}/accounts/${walletData.address}/jettons`,
16815
- {
16816
- headers: tonapiHeaders()
16817
- }
16818
- );
16815
+ const jettonsResponse = await tonapiFetch(`/accounts/${walletData.address}/jettons`);
16819
16816
  if (!jettonsResponse.ok) {
16820
16817
  return {
16821
16818
  success: false,
@@ -16908,9 +16905,7 @@ var jettonInfoTool = {
16908
16905
  var jettonInfoExecutor = async (params, context) => {
16909
16906
  try {
16910
16907
  const { jetton_address } = params;
16911
- const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
16912
- headers: tonapiHeaders()
16913
- });
16908
+ const response = await tonapiFetch(`/jettons/${jetton_address}`);
16914
16909
  if (response.status === 404) {
16915
16910
  return {
16916
16911
  success: false,
@@ -17005,11 +17000,8 @@ var jettonPriceTool = {
17005
17000
  var jettonPriceExecutor = async (params, context) => {
17006
17001
  try {
17007
17002
  const { jetton_address } = params;
17008
- const response = await fetchWithTimeout(
17009
- `${TONAPI_BASE_URL}/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`,
17010
- {
17011
- headers: tonapiHeaders()
17012
- }
17003
+ const response = await tonapiFetch(
17004
+ `/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`
17013
17005
  );
17014
17006
  if (!response.ok) {
17015
17007
  return {
@@ -17020,9 +17012,7 @@ var jettonPriceExecutor = async (params, context) => {
17020
17012
  const data = await response.json();
17021
17013
  const rateData = data.rates?.[jetton_address];
17022
17014
  if (!rateData) {
17023
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17024
- headers: tonapiHeaders()
17025
- });
17015
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17026
17016
  if (infoResponse.status === 404) {
17027
17017
  return {
17028
17018
  success: false,
@@ -17041,9 +17031,7 @@ var jettonPriceExecutor = async (params, context) => {
17041
17031
  let symbol = "TOKEN";
17042
17032
  let name = "Unknown Token";
17043
17033
  try {
17044
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17045
- headers: tonapiHeaders()
17046
- });
17034
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17047
17035
  if (infoResponse.ok) {
17048
17036
  const infoData = await infoResponse.json();
17049
17037
  symbol = infoData.metadata?.symbol || symbol;
@@ -17340,11 +17328,8 @@ var jettonHoldersTool = {
17340
17328
  var jettonHoldersExecutor = async (params, context) => {
17341
17329
  try {
17342
17330
  const { jetton_address, limit = 10 } = params;
17343
- const response = await fetchWithTimeout(
17344
- `${TONAPI_BASE_URL}/jettons/${jetton_address}/holders?limit=${Math.min(limit, 100)}`,
17345
- {
17346
- headers: tonapiHeaders()
17347
- }
17331
+ const response = await tonapiFetch(
17332
+ `/jettons/${jetton_address}/holders?limit=${Math.min(limit, 100)}`
17348
17333
  );
17349
17334
  if (response.status === 404) {
17350
17335
  return {
@@ -17363,9 +17348,7 @@ var jettonHoldersExecutor = async (params, context) => {
17363
17348
  let decimals = 9;
17364
17349
  let symbol = "TOKEN";
17365
17350
  try {
17366
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17367
- headers: tonapiHeaders()
17368
- });
17351
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17369
17352
  if (infoResponse.ok) {
17370
17353
  const infoData = await infoResponse.json();
17371
17354
  decimals = parseInt(infoData.metadata?.decimals || "9");
@@ -17432,17 +17415,14 @@ var jettonHistoryTool = {
17432
17415
  var jettonHistoryExecutor = async (params, context) => {
17433
17416
  try {
17434
17417
  const { jetton_address } = params;
17435
- const ratesResponse = await fetchWithTimeout(
17436
- `${TONAPI_BASE_URL}/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`,
17437
- { headers: tonapiHeaders() }
17418
+ const ratesResponse = await tonapiFetch(
17419
+ `/rates?tokens=${encodeURIComponent(jetton_address)}&currencies=usd,ton`
17438
17420
  );
17439
17421
  const geckoResponse = await fetchWithTimeout(
17440
17422
  `${GECKOTERMINAL_API_URL}/networks/ton/tokens/${jetton_address}`,
17441
17423
  { headers: { Accept: "application/json" } }
17442
17424
  );
17443
- const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
17444
- headers: tonapiHeaders()
17445
- });
17425
+ const infoResponse = await tonapiFetch(`/jettons/${jetton_address}`);
17446
17426
  let symbol = "TOKEN";
17447
17427
  let name = "Unknown Token";
17448
17428
  let holdersCount = 0;
@@ -21998,7 +21978,13 @@ var dealVerifyPaymentExecutor = async (params, context) => {
21998
21978
  }
21999
21979
  const now = Math.floor(Date.now() / 1e3);
22000
21980
  if (now > deal.expires_at) {
22001
- context.db.prepare(`UPDATE deals SET status = 'expired' WHERE id = ?`).run(params.dealId);
21981
+ const expireResult = context.db.prepare(`UPDATE deals SET status = 'expired' WHERE id = ? AND status = 'accepted'`).run(params.dealId);
21982
+ if (expireResult.changes !== 1) {
21983
+ return {
21984
+ success: false,
21985
+ error: `Deal #${params.dealId} already transitioned by another process`
21986
+ };
21987
+ }
22002
21988
  return {
22003
21989
  success: false,
22004
21990
  error: `Deal #${params.dealId} has expired (2 minutes elapsed)`
@@ -22034,14 +22020,20 @@ var dealVerifyPaymentExecutor = async (params, context) => {
22034
22020
  error: `Payment verification failed: ${verification.error || "Transaction not found"}`
22035
22021
  };
22036
22022
  }
22037
- context.db.prepare(
22023
+ const verifyResult = context.db.prepare(
22038
22024
  `UPDATE deals SET
22039
22025
  status = 'verified',
22040
22026
  user_payment_tx_hash = ?,
22041
22027
  user_payment_wallet = ?,
22042
22028
  user_payment_verified_at = unixepoch()
22043
- WHERE id = ?`
22029
+ WHERE id = ? AND status = 'accepted'`
22044
22030
  ).run(verification.txHash, verification.playerWallet, params.dealId);
22031
+ if (verifyResult.changes !== 1) {
22032
+ return {
22033
+ success: false,
22034
+ error: `Deal #${params.dealId} already transitioned by another process (expected 'accepted')`
22035
+ };
22036
+ }
22045
22037
  console.log(
22046
22038
  `\u2705 [Deal] Payment verified for #${params.dealId} - TX: ${verification.txHash?.slice(0, 8)}...`
22047
22039
  );
@@ -22087,13 +22079,19 @@ var dealVerifyPaymentExecutor = async (params, context) => {
22087
22079
  error: `Gift not received yet. Expected: ${deal.user_gives_gift_slug} from user ${deal.user_telegram_id}. Please ensure user has sent the gift.`
22088
22080
  };
22089
22081
  }
22090
- context.db.prepare(
22082
+ const giftVerifyResult = context.db.prepare(
22091
22083
  `UPDATE deals SET
22092
22084
  status = 'verified',
22093
22085
  user_payment_gift_msgid = ?,
22094
22086
  user_payment_verified_at = unixepoch()
22095
- WHERE id = ?`
22087
+ WHERE id = ? AND status = 'accepted'`
22096
22088
  ).run(matchingGift.msgId, params.dealId);
22089
+ if (giftVerifyResult.changes !== 1) {
22090
+ return {
22091
+ success: false,
22092
+ error: `Deal #${params.dealId} already transitioned by another process (expected 'accepted')`
22093
+ };
22094
+ }
22097
22095
  console.log(`\u2705 [Deal] Gift verified for #${params.dealId} - msgId: ${matchingGift.msgId}`);
22098
22096
  await autoExecuteAfterVerification(params.dealId, context.db, context.bridge);
22099
22097
  return {
@@ -23866,7 +23864,6 @@ var TonnetApp = class {
23866
23864
  initDealsConfig(this.config.deals);
23867
23865
  if (this.config.tonapi_key) {
23868
23866
  setTonapiKey(this.config.tonapi_key);
23869
- console.log("\u{1F511} TonAPI key configured");
23870
23867
  }
23871
23868
  const soul = loadSoul();
23872
23869
  this.toolRegistry = new ToolRegistry();
@@ -23944,7 +23941,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
23944
23941
  `\u26A0\uFE0F Tool count (${this.toolCount}) exceeds ${providerMeta.displayName} limit (${providerMeta.toolLimit})`
23945
23942
  );
23946
23943
  }
23947
- const { migrateSessionsToDb } = await import("./migrate-FGNIC4XZ.js");
23944
+ const { migrateSessionsToDb } = await import("./migrate-F256Q7LW.js");
23948
23945
  migrateSessionsToDb();
23949
23946
  const memory = initializeMemory({
23950
23947
  database: {
@@ -24009,7 +24006,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24009
24006
  const r3 = db.getDb().prepare(
24010
24007
  `UPDATE deals SET status = 'expired' WHERE status IN ('proposed', 'accepted') AND expires_at < ?`
24011
24008
  ).run(now);
24012
- if (r3.changes > 0) console.log(`\u23F0 Expired ${r3.changes} stale deal(s)`);
24009
+ if (r3.changes > 0) verbose(`\u23F0 Expired ${r3.changes} stale deal(s)`);
24013
24010
  }, DEALS_CONFIG.expiryCheckIntervalMs);
24014
24011
  }
24015
24012
  console.log(`\u2705 SOUL.md loaded`);
@@ -24026,6 +24023,9 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24026
24023
  }
24027
24024
  console.log(`\u2705 Telegram: @${username} connected`);
24028
24025
  console.log(`\u2705 TON Blockchain: connected`);
24026
+ if (this.config.tonapi_key) {
24027
+ console.log(`\u{1F511} TonAPI key configured`);
24028
+ }
24029
24029
  console.log(`\u2705 DEXs: STON.fi, DeDust connected`);
24030
24030
  console.log(`\u2705 Wallet: ${walletAddress || "not configured"}`);
24031
24031
  console.log(`\u2705 Model: ${provider}/${this.config.agent.model}`);
@@ -24125,7 +24125,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24125
24125
  const taskId = match[1];
24126
24126
  const { getTaskStore } = await import("./tasks-M3QDPTGY.js");
24127
24127
  const { executeScheduledTask } = await import("./task-executor-MNI4VIZL.js");
24128
- const { getDatabase: getDatabase2 } = await import("./memory-I4QLDRLK.js");
24128
+ const { getDatabase: getDatabase2 } = await import("./memory-Q755V5UK.js");
24129
24129
  const db = getDatabase2().getDb();
24130
24130
  const taskStore = getTaskStore(db);
24131
24131
  const task = taskStore.getTask(taskId);
@@ -24200,7 +24200,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
24200
24200
  try {
24201
24201
  const { getTaskStore } = await import("./tasks-M3QDPTGY.js");
24202
24202
  const { TaskDependencyResolver } = await import("./task-dependency-resolver-CWG6DTU4.js");
24203
- const { getDatabase: getDatabase2 } = await import("./memory-I4QLDRLK.js");
24203
+ const { getDatabase: getDatabase2 } = await import("./memory-Q755V5UK.js");
24204
24204
  const db = getDatabase2().getDb();
24205
24205
  const taskStore = getTaskStore(db);
24206
24206
  const match = message.text.match(/^\[TASK:([^\]]+)\]/);
@@ -1,6 +1,7 @@
1
1
  import {
2
- VOYAGE_API_URL
3
- } from "./chunk-ST5CO7TV.js";
2
+ VOYAGE_API_URL,
3
+ fetchWithTimeout
4
+ } from "./chunk-WMIN6AGX.js";
4
5
  import {
5
6
  KNOWLEDGE_CHUNK_OVERLAP,
6
7
  KNOWLEDGE_CHUNK_SIZE,
@@ -8,9 +9,6 @@ import {
8
9
  SQLITE_MMAP_SIZE,
9
10
  VOYAGE_BATCH_SIZE
10
11
  } from "./chunk-QMN6ZOA5.js";
11
- import {
12
- DEFAULT_FETCH_TIMEOUT_MS
13
- } from "./chunk-LJXYESJJ.js";
14
12
 
15
13
  // src/memory/database.ts
16
14
  import Database from "better-sqlite3";
@@ -884,19 +882,6 @@ var NoopEmbeddingProvider = class {
884
882
  }
885
883
  };
886
884
 
887
- // src/utils/fetch.ts
888
- var DEFAULT_TIMEOUT_MS = DEFAULT_FETCH_TIMEOUT_MS;
889
- function fetchWithTimeout(url, init) {
890
- const { timeoutMs = DEFAULT_TIMEOUT_MS, ...fetchInit } = init ?? {};
891
- if (fetchInit.signal) {
892
- return fetch(url, fetchInit);
893
- }
894
- return fetch(url, {
895
- ...fetchInit,
896
- signal: AbortSignal.timeout(timeoutMs)
897
- });
898
- }
899
-
900
885
  // src/memory/embeddings/anthropic.ts
901
886
  var AnthropicEmbeddingProvider = class {
902
887
  id = "anthropic";
@@ -2024,7 +2009,6 @@ export {
2024
2009
  getDatabase,
2025
2010
  closeDatabase,
2026
2011
  NoopEmbeddingProvider,
2027
- fetchWithTimeout,
2028
2012
  AnthropicEmbeddingProvider,
2029
2013
  LocalEmbeddingProvider,
2030
2014
  createEmbeddingProvider,
@@ -0,0 +1,74 @@
1
+ import {
2
+ DEFAULT_FETCH_TIMEOUT_MS
3
+ } from "./chunk-LJXYESJJ.js";
4
+
5
+ // src/utils/fetch.ts
6
+ var DEFAULT_TIMEOUT_MS = DEFAULT_FETCH_TIMEOUT_MS;
7
+ function fetchWithTimeout(url, init) {
8
+ const { timeoutMs = DEFAULT_TIMEOUT_MS, ...fetchInit } = init ?? {};
9
+ if (fetchInit.signal) {
10
+ return fetch(url, fetchInit);
11
+ }
12
+ return fetch(url, {
13
+ ...fetchInit,
14
+ signal: AbortSignal.timeout(timeoutMs)
15
+ });
16
+ }
17
+
18
+ // src/constants/api-endpoints.ts
19
+ var TONAPI_BASE_URL = "https://tonapi.io/v2";
20
+ var _tonapiKey;
21
+ function setTonapiKey(key) {
22
+ _tonapiKey = key;
23
+ }
24
+ function tonapiHeaders() {
25
+ const headers = { Accept: "application/json" };
26
+ if (_tonapiKey) {
27
+ headers["Authorization"] = `Bearer ${_tonapiKey}`;
28
+ }
29
+ return headers;
30
+ }
31
+ var TONAPI_MAX_RPS = 5;
32
+ var _tonapiTimestamps = [];
33
+ async function waitForTonapiSlot() {
34
+ const clean = () => {
35
+ const cutoff = Date.now() - 1e3;
36
+ while (_tonapiTimestamps.length > 0 && _tonapiTimestamps[0] <= cutoff) {
37
+ _tonapiTimestamps.shift();
38
+ }
39
+ };
40
+ clean();
41
+ if (_tonapiTimestamps.length >= TONAPI_MAX_RPS) {
42
+ const waitMs = _tonapiTimestamps[0] + 1e3 - Date.now() + 50;
43
+ if (waitMs > 0) await new Promise((r) => setTimeout(r, waitMs));
44
+ clean();
45
+ }
46
+ _tonapiTimestamps.push(Date.now());
47
+ }
48
+ async function tonapiFetch(path, init) {
49
+ await waitForTonapiSlot();
50
+ return fetchWithTimeout(`${TONAPI_BASE_URL}${path}`, {
51
+ ...init,
52
+ headers: { ...tonapiHeaders(), ...init?.headers }
53
+ });
54
+ }
55
+ var STONFI_API_BASE_URL = "https://api.ston.fi/v1";
56
+ var GECKOTERMINAL_API_URL = "https://api.geckoterminal.com/api/v2";
57
+ var COINGECKO_API_URL = "https://api.coingecko.com/api/v3";
58
+ var MARKETAPP_BASE_URL = "https://marketapp.ws";
59
+ var OPENAI_TTS_URL = "https://api.openai.com/v1/audio/speech";
60
+ var ELEVENLABS_TTS_URL = "https://api.elevenlabs.io/v1/text-to-speech";
61
+ var VOYAGE_API_URL = "https://api.voyageai.com/v1";
62
+
63
+ export {
64
+ fetchWithTimeout,
65
+ setTonapiKey,
66
+ tonapiFetch,
67
+ STONFI_API_BASE_URL,
68
+ GECKOTERMINAL_API_URL,
69
+ COINGECKO_API_URL,
70
+ MARKETAPP_BASE_URL,
71
+ OPENAI_TTS_URL,
72
+ ELEVENLABS_TTS_URL,
73
+ VOYAGE_API_URL
74
+ };
package/dist/cli/index.js CHANGED
@@ -17,15 +17,15 @@ import {
17
17
  saveWallet,
18
18
  validateApiKeyFormat,
19
19
  walletExists
20
- } from "../chunk-UQ54EXWQ.js";
21
- import {
22
- fetchWithTimeout
23
- } from "../chunk-PMX75DTX.js";
20
+ } from "../chunk-ABHUNKXQ.js";
21
+ import "../chunk-JDPS46IZ.js";
24
22
  import "../chunk-E2NXSWOS.js";
25
23
  import {
26
24
  TELETON_ROOT
27
25
  } from "../chunk-EYWNOHMJ.js";
28
- import "../chunk-ST5CO7TV.js";
26
+ import {
27
+ fetchWithTimeout
28
+ } from "../chunk-WMIN6AGX.js";
29
29
  import {
30
30
  TELEGRAM_MAX_MESSAGE_LENGTH
31
31
  } from "../chunk-QMN6ZOA5.js";
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  TonnetApp,
3
3
  main
4
- } from "./chunk-UQ54EXWQ.js";
5
- import "./chunk-PMX75DTX.js";
4
+ } from "./chunk-ABHUNKXQ.js";
5
+ import "./chunk-JDPS46IZ.js";
6
6
  import "./chunk-E2NXSWOS.js";
7
7
  import "./chunk-EYWNOHMJ.js";
8
- import "./chunk-ST5CO7TV.js";
8
+ import "./chunk-WMIN6AGX.js";
9
9
  import "./chunk-QMN6ZOA5.js";
10
10
  import "./chunk-LJXYESJJ.js";
11
11
  import "./chunk-B2PRMXOH.js";
@@ -24,12 +24,12 @@ import {
24
24
  runMigrations,
25
25
  serializeEmbedding,
26
26
  setSchemaVersion
27
- } from "./chunk-PMX75DTX.js";
27
+ } from "./chunk-JDPS46IZ.js";
28
28
  import {
29
29
  TaskStore,
30
30
  getTaskStore
31
31
  } from "./chunk-E2NXSWOS.js";
32
- import "./chunk-ST5CO7TV.js";
32
+ import "./chunk-WMIN6AGX.js";
33
33
  import "./chunk-QMN6ZOA5.js";
34
34
  import "./chunk-LJXYESJJ.js";
35
35
  import "./chunk-QGM4M3NI.js";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getDatabase
3
- } from "./chunk-PMX75DTX.js";
3
+ } from "./chunk-JDPS46IZ.js";
4
4
  import "./chunk-E2NXSWOS.js";
5
5
  import {
6
6
  TELETON_ROOT
7
7
  } from "./chunk-EYWNOHMJ.js";
8
- import "./chunk-ST5CO7TV.js";
8
+ import "./chunk-WMIN6AGX.js";
9
9
  import "./chunk-QMN6ZOA5.js";
10
10
  import "./chunk-LJXYESJJ.js";
11
11
  import "./chunk-QGM4M3NI.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-EYWNOHMJ.js";
4
4
  import {
5
5
  MARKETAPP_BASE_URL
6
- } from "./chunk-ST5CO7TV.js";
6
+ } from "./chunk-WMIN6AGX.js";
7
7
  import {
8
8
  SCRAPER_PARALLEL_WORKERS
9
9
  } from "./chunk-QMN6ZOA5.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teleton",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Personal AI Agent for Telegram",
5
5
  "author": "ZKProof (https://t.me/zkproof)",
6
6
  "license": "MIT",
@@ -1,33 +0,0 @@
1
- // src/constants/api-endpoints.ts
2
- var TONAPI_BASE_URL = "https://tonapi.io/v2";
3
- var _tonapiKey;
4
- function setTonapiKey(key) {
5
- _tonapiKey = key;
6
- }
7
- function tonapiHeaders() {
8
- const headers = { Accept: "application/json" };
9
- if (_tonapiKey) {
10
- headers["Authorization"] = `Bearer ${_tonapiKey}`;
11
- }
12
- return headers;
13
- }
14
- var STONFI_API_BASE_URL = "https://api.ston.fi/v1";
15
- var GECKOTERMINAL_API_URL = "https://api.geckoterminal.com/api/v2";
16
- var COINGECKO_API_URL = "https://api.coingecko.com/api/v3";
17
- var MARKETAPP_BASE_URL = "https://marketapp.ws";
18
- var OPENAI_TTS_URL = "https://api.openai.com/v1/audio/speech";
19
- var ELEVENLABS_TTS_URL = "https://api.elevenlabs.io/v1/text-to-speech";
20
- var VOYAGE_API_URL = "https://api.voyageai.com/v1";
21
-
22
- export {
23
- TONAPI_BASE_URL,
24
- setTonapiKey,
25
- tonapiHeaders,
26
- STONFI_API_BASE_URL,
27
- GECKOTERMINAL_API_URL,
28
- COINGECKO_API_URL,
29
- MARKETAPP_BASE_URL,
30
- OPENAI_TTS_URL,
31
- ELEVENLABS_TTS_URL,
32
- VOYAGE_API_URL
33
- };