teleton 0.1.0 → 0.1.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.
- package/README.md +7 -7
- package/dist/chunk-5BEHAIBQ.js +38 -0
- package/dist/chunk-EBFMA7CL.js +40 -0
- package/dist/chunk-I6ZVPVLK.js +20 -0
- package/dist/{chunk-WDUHRPGA.js → chunk-MPU2XS5H.js} +121 -6
- package/dist/{chunk-WXVHT6CI.js → chunk-UQUYPDZJ.js} +944 -652
- package/dist/cli/index.js +334 -86
- package/dist/index.js +5 -2
- package/dist/{memory-O5NYYWF3.js → memory-WSP5MEER.js} +4 -1
- package/dist/{migrate-25RH22HJ.js → migrate-JPXMIIPI.js} +4 -1
- package/dist/{scraper-DW5Z2AP5.js → scraper-PGYSNQRD.js} +36 -17
- package/dist/{task-dependency-resolver-5I62EU67.js → task-dependency-resolver-KRQRZKAD.js} +7 -2
- package/dist/{task-executor-ZMXWLMI7.js → task-executor-L6DTJANH.js} +14 -6
- package/package.json +17 -7
- package/src/templates/SECURITY.md +31 -0
|
@@ -7,9 +7,10 @@ import {
|
|
|
7
7
|
ContextBuilder,
|
|
8
8
|
MessageStore,
|
|
9
9
|
UserStore,
|
|
10
|
+
fetchWithTimeout,
|
|
10
11
|
getDatabase,
|
|
11
12
|
initializeMemory
|
|
12
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MPU2XS5H.js";
|
|
13
14
|
import {
|
|
14
15
|
ALLOWED_EXTENSIONS,
|
|
15
16
|
MAX_FILE_SIZES,
|
|
@@ -17,6 +18,30 @@ import {
|
|
|
17
18
|
WORKSPACE_PATHS,
|
|
18
19
|
WORKSPACE_ROOT
|
|
19
20
|
} from "./chunk-7NJ46ZIX.js";
|
|
21
|
+
import {
|
|
22
|
+
COINGECKO_API_URL,
|
|
23
|
+
ELEVENLABS_TTS_URL,
|
|
24
|
+
GECKOTERMINAL_API_URL,
|
|
25
|
+
OPENAI_TTS_URL,
|
|
26
|
+
STONFI_API_BASE_URL,
|
|
27
|
+
TONAPI_BASE_URL
|
|
28
|
+
} from "./chunk-I6ZVPVLK.js";
|
|
29
|
+
import {
|
|
30
|
+
COMPACTION_KEEP_RECENT,
|
|
31
|
+
COMPACTION_MAX_MESSAGES,
|
|
32
|
+
COMPACTION_MAX_TOKENS_RATIO,
|
|
33
|
+
COMPACTION_SOFT_THRESHOLD_RATIO,
|
|
34
|
+
DEAL_VERIFICATION_WINDOW_SECONDS,
|
|
35
|
+
DEFAULT_GIFTS_QUERY_LIMIT,
|
|
36
|
+
MAX_POLL_QUESTION_LENGTH,
|
|
37
|
+
MAX_TOOL_RESULT_SIZE,
|
|
38
|
+
SECONDS_PER_DAY,
|
|
39
|
+
TELEGRAM_MAX_MESSAGE_LENGTH
|
|
40
|
+
} from "./chunk-5BEHAIBQ.js";
|
|
41
|
+
import {
|
|
42
|
+
MESSAGE_HANDLER_LOCK_TIMEOUT_MS,
|
|
43
|
+
TTS_TIMEOUT_MS
|
|
44
|
+
} from "./chunk-EBFMA7CL.js";
|
|
20
45
|
|
|
21
46
|
// src/config/schema.ts
|
|
22
47
|
import { z } from "zod";
|
|
@@ -50,7 +75,7 @@ var TelegramConfigSchema = z.object({
|
|
|
50
75
|
group_policy: GroupPolicy.default("open"),
|
|
51
76
|
group_allow_from: z.array(z.number()).default([]),
|
|
52
77
|
require_mention: z.boolean().default(true),
|
|
53
|
-
max_message_length: z.number().default(
|
|
78
|
+
max_message_length: z.number().default(TELEGRAM_MAX_MESSAGE_LENGTH),
|
|
54
79
|
typing_simulation: z.boolean().default(true),
|
|
55
80
|
rate_limit_messages_per_second: z.number().default(1),
|
|
56
81
|
rate_limit_groups_per_minute: z.number().default(20),
|
|
@@ -102,6 +127,7 @@ var DealsConfigSchema = z.object({
|
|
|
102
127
|
expiry_check_interval_ms: z.number().default(6e4)
|
|
103
128
|
}).default({});
|
|
104
129
|
var MarketConfigSchema = z.object({
|
|
130
|
+
enabled: z.boolean().default(true),
|
|
105
131
|
cache_ttl_minutes: z.number().default(15),
|
|
106
132
|
refresh_interval_minutes: z.number().default(120)
|
|
107
133
|
}).default({});
|
|
@@ -437,6 +463,7 @@ async function ensureWorkspace(config) {
|
|
|
437
463
|
userPath: WORKSPACE_PATHS.USER,
|
|
438
464
|
bootstrapPath: WORKSPACE_PATHS.BOOTSTRAP,
|
|
439
465
|
strategyPath: WORKSPACE_PATHS.STRATEGY,
|
|
466
|
+
securityPath: WORKSPACE_PATHS.SECURITY,
|
|
440
467
|
// Workspace directories
|
|
441
468
|
memoryDir: WORKSPACE_PATHS.MEMORY_DIR,
|
|
442
469
|
downloadsDir: WORKSPACE_PATHS.DOWNLOADS_DIR,
|
|
@@ -459,7 +486,8 @@ async function bootstrapTemplates(workspace) {
|
|
|
459
486
|
{ name: "MEMORY.md", path: workspace.memoryPath },
|
|
460
487
|
{ name: "IDENTITY.md", path: workspace.identityPath },
|
|
461
488
|
{ name: "USER.md", path: workspace.userPath },
|
|
462
|
-
{ name: "BOOTSTRAP.md", path: workspace.bootstrapPath }
|
|
489
|
+
{ name: "BOOTSTRAP.md", path: workspace.bootstrapPath },
|
|
490
|
+
{ name: "SECURITY.md", path: workspace.securityPath }
|
|
463
491
|
];
|
|
464
492
|
for (const template of templates) {
|
|
465
493
|
if (!existsSync3(template.path)) {
|
|
@@ -1563,10 +1591,10 @@ This session was compacted and migrated to a new session ID. The summary above p
|
|
|
1563
1591
|
import { encodingForModel } from "js-tiktoken";
|
|
1564
1592
|
var DEFAULT_COMPACTION_CONFIG = {
|
|
1565
1593
|
enabled: true,
|
|
1566
|
-
maxMessages:
|
|
1594
|
+
maxMessages: COMPACTION_MAX_MESSAGES,
|
|
1567
1595
|
maxTokens: 96e3,
|
|
1568
1596
|
// Conservative: fits 128K context with buffer
|
|
1569
|
-
keepRecentMessages:
|
|
1597
|
+
keepRecentMessages: COMPACTION_KEEP_RECENT,
|
|
1570
1598
|
memoryFlushEnabled: true,
|
|
1571
1599
|
softThresholdTokens: 64e3
|
|
1572
1600
|
// ~50% of 128K (smallest supported context)
|
|
@@ -1891,11 +1919,11 @@ var AgentRuntime = class {
|
|
|
1891
1919
|
const ctx = model.contextWindow;
|
|
1892
1920
|
this.compactionManager = new CompactionManager({
|
|
1893
1921
|
enabled: true,
|
|
1894
|
-
maxMessages:
|
|
1895
|
-
maxTokens: Math.floor(ctx *
|
|
1896
|
-
keepRecentMessages:
|
|
1922
|
+
maxMessages: COMPACTION_MAX_MESSAGES,
|
|
1923
|
+
maxTokens: Math.floor(ctx * COMPACTION_MAX_TOKENS_RATIO),
|
|
1924
|
+
keepRecentMessages: COMPACTION_KEEP_RECENT,
|
|
1897
1925
|
memoryFlushEnabled: true,
|
|
1898
|
-
softThresholdTokens: Math.floor(ctx *
|
|
1926
|
+
softThresholdTokens: Math.floor(ctx * COMPACTION_SOFT_THRESHOLD_RATIO)
|
|
1899
1927
|
});
|
|
1900
1928
|
} catch {
|
|
1901
1929
|
this.compactionManager = new CompactionManager(DEFAULT_COMPACTION_CONFIG);
|
|
@@ -2133,7 +2161,6 @@ ${statsContext}`;
|
|
|
2133
2161
|
input: block.arguments
|
|
2134
2162
|
});
|
|
2135
2163
|
let resultText = JSON.stringify(result, null, 2);
|
|
2136
|
-
const MAX_TOOL_RESULT_SIZE = 5e4;
|
|
2137
2164
|
if (resultText.length > MAX_TOOL_RESULT_SIZE) {
|
|
2138
2165
|
console.warn(`\u26A0\uFE0F Tool result too large (${resultText.length} chars), truncating...`);
|
|
2139
2166
|
const data = result.data;
|
|
@@ -2218,7 +2245,8 @@ ${statsContext}`;
|
|
|
2218
2245
|
"telegram_send_video",
|
|
2219
2246
|
"telegram_send_poll",
|
|
2220
2247
|
"telegram_forward_message",
|
|
2221
|
-
"telegram_reply_message"
|
|
2248
|
+
"telegram_reply_message",
|
|
2249
|
+
"deal_propose"
|
|
2222
2250
|
];
|
|
2223
2251
|
const usedTelegramSendTool = totalToolCalls.some((tc) => telegramSendTools.includes(tc.name));
|
|
2224
2252
|
if (!content && totalToolCalls.length > 0 && !usedTelegramSendTool) {
|
|
@@ -2319,9 +2347,9 @@ import { TelegramClient, Api } from "telegram";
|
|
|
2319
2347
|
import { Logger, LogLevel } from "telegram/extensions/Logger.js";
|
|
2320
2348
|
import { StringSession } from "telegram/sessions/index.js";
|
|
2321
2349
|
import { NewMessage } from "telegram/events/index.js";
|
|
2322
|
-
import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync5 } from "fs";
|
|
2350
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync5, chmodSync } from "fs";
|
|
2323
2351
|
import { dirname as dirname4 } from "path";
|
|
2324
|
-
import
|
|
2352
|
+
import { createInterface } from "readline";
|
|
2325
2353
|
|
|
2326
2354
|
// src/telegram/formatting.ts
|
|
2327
2355
|
function escapeHtml(text) {
|
|
@@ -2386,6 +2414,15 @@ function markdownToTelegramHtml(markdown) {
|
|
|
2386
2414
|
}
|
|
2387
2415
|
|
|
2388
2416
|
// src/telegram/client.ts
|
|
2417
|
+
function promptInput(question) {
|
|
2418
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
2419
|
+
return new Promise((resolve2) => {
|
|
2420
|
+
rl.question(question, (answer) => {
|
|
2421
|
+
rl.close();
|
|
2422
|
+
resolve2(answer);
|
|
2423
|
+
});
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2389
2426
|
var TelegramUserClient = class {
|
|
2390
2427
|
client;
|
|
2391
2428
|
config;
|
|
@@ -2432,6 +2469,7 @@ var TelegramUserClient = class {
|
|
|
2432
2469
|
mkdirSync5(dir, { recursive: true });
|
|
2433
2470
|
}
|
|
2434
2471
|
writeFileSync3(this.config.sessionPath, sessionString, { encoding: "utf-8" });
|
|
2472
|
+
chmodSync(this.config.sessionPath, 384);
|
|
2435
2473
|
console.log("\u2705 Session saved");
|
|
2436
2474
|
} catch (error) {
|
|
2437
2475
|
console.error("Failed to save session:", error);
|
|
@@ -2452,9 +2490,9 @@ var TelegramUserClient = class {
|
|
|
2452
2490
|
} else {
|
|
2453
2491
|
console.log("Starting authentication flow...");
|
|
2454
2492
|
await this.client.start({
|
|
2455
|
-
phoneNumber: async () => this.config.phone || await
|
|
2456
|
-
phoneCode: async () => await
|
|
2457
|
-
password: async () => await
|
|
2493
|
+
phoneNumber: async () => this.config.phone || await promptInput("Phone number: "),
|
|
2494
|
+
phoneCode: async () => await promptInput("Verification code: "),
|
|
2495
|
+
password: async () => await promptInput("2FA password (if enabled): "),
|
|
2458
2496
|
onError: (err) => console.error("Auth error:", err)
|
|
2459
2497
|
});
|
|
2460
2498
|
console.log("\u2705 Authenticated");
|
|
@@ -3089,8 +3127,7 @@ var RateLimiter = class {
|
|
|
3089
3127
|
};
|
|
3090
3128
|
var ChatLock = class {
|
|
3091
3129
|
locks = /* @__PURE__ */ new Map();
|
|
3092
|
-
LOCK_TIMEOUT_MS =
|
|
3093
|
-
// 2 minutes
|
|
3130
|
+
LOCK_TIMEOUT_MS = MESSAGE_HANDLER_LOCK_TIMEOUT_MS;
|
|
3094
3131
|
async acquire(chatId) {
|
|
3095
3132
|
const existing = this.locks.get(chatId);
|
|
3096
3133
|
if (existing) {
|
|
@@ -3320,7 +3357,8 @@ var MessageHandler = class {
|
|
|
3320
3357
|
"telegram_send_video",
|
|
3321
3358
|
"telegram_send_poll",
|
|
3322
3359
|
"telegram_forward_message",
|
|
3323
|
-
"telegram_reply_message"
|
|
3360
|
+
"telegram_reply_message",
|
|
3361
|
+
"deal_propose"
|
|
3324
3362
|
];
|
|
3325
3363
|
const telegramSendCalled = hasToolCalls && response.toolCalls?.some((tc) => telegramSendTools.includes(tc.name));
|
|
3326
3364
|
if (!telegramSendCalled && response.content && response.content.trim().length > 0) {
|
|
@@ -3690,7 +3728,7 @@ var MarketScraperService = class {
|
|
|
3690
3728
|
this.isScrapingInProgress = true;
|
|
3691
3729
|
console.log("\u{1F504} Starting full market scrape...");
|
|
3692
3730
|
try {
|
|
3693
|
-
const { runScraper } = await import("./scraper-
|
|
3731
|
+
const { runScraper } = await import("./scraper-PGYSNQRD.js");
|
|
3694
3732
|
const result = await runScraper({
|
|
3695
3733
|
workers: 4,
|
|
3696
3734
|
limit: 0
|
|
@@ -3976,9 +4014,9 @@ var MarketPriceService = class {
|
|
|
3976
4014
|
};
|
|
3977
4015
|
|
|
3978
4016
|
// src/ton/wallet-service.ts
|
|
3979
|
-
import { mnemonicNew, mnemonicToPrivateKey } from "@ton/crypto";
|
|
4017
|
+
import { mnemonicNew, mnemonicToPrivateKey, mnemonicValidate } from "@ton/crypto";
|
|
3980
4018
|
import { WalletContractV5R1, TonClient, fromNano } from "@ton/ton";
|
|
3981
|
-
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, existsSync as existsSync9, mkdirSync as mkdirSync7, chmodSync } from "fs";
|
|
4019
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5, existsSync as existsSync9, mkdirSync as mkdirSync7, chmodSync as chmodSync2 } from "fs";
|
|
3982
4020
|
import { join as join9, dirname as dirname6 } from "path";
|
|
3983
4021
|
import { getHttpEndpoint } from "@orbs-network/ton-access";
|
|
3984
4022
|
var WALLET_FILE = join9(TELETON_ROOT, "wallet.json");
|
|
@@ -4004,7 +4042,7 @@ function saveWallet(wallet) {
|
|
|
4004
4042
|
mkdirSync7(dir, { recursive: true });
|
|
4005
4043
|
}
|
|
4006
4044
|
writeFileSync5(WALLET_FILE, JSON.stringify(wallet, null, 2), "utf-8");
|
|
4007
|
-
|
|
4045
|
+
chmodSync2(WALLET_FILE, 384);
|
|
4008
4046
|
}
|
|
4009
4047
|
function loadWallet() {
|
|
4010
4048
|
if (!existsSync9(WALLET_FILE)) {
|
|
@@ -4018,6 +4056,28 @@ function loadWallet() {
|
|
|
4018
4056
|
return null;
|
|
4019
4057
|
}
|
|
4020
4058
|
}
|
|
4059
|
+
function walletExists() {
|
|
4060
|
+
return existsSync9(WALLET_FILE);
|
|
4061
|
+
}
|
|
4062
|
+
async function importWallet(mnemonic) {
|
|
4063
|
+
const valid = await mnemonicValidate(mnemonic);
|
|
4064
|
+
if (!valid) {
|
|
4065
|
+
throw new Error("Invalid mnemonic: words do not form a valid TON seed phrase");
|
|
4066
|
+
}
|
|
4067
|
+
const keyPair = await mnemonicToPrivateKey(mnemonic);
|
|
4068
|
+
const wallet = WalletContractV5R1.create({
|
|
4069
|
+
workchain: 0,
|
|
4070
|
+
publicKey: keyPair.publicKey
|
|
4071
|
+
});
|
|
4072
|
+
const address = wallet.address.toString({ bounceable: true, testOnly: false });
|
|
4073
|
+
return {
|
|
4074
|
+
version: "w5r1",
|
|
4075
|
+
address,
|
|
4076
|
+
publicKey: keyPair.publicKey.toString("hex"),
|
|
4077
|
+
mnemonic,
|
|
4078
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4079
|
+
};
|
|
4080
|
+
}
|
|
4021
4081
|
function getWalletAddress() {
|
|
4022
4082
|
const wallet = loadWallet();
|
|
4023
4083
|
return wallet?.address || null;
|
|
@@ -4041,8 +4101,8 @@ async function getWalletBalance(address) {
|
|
|
4041
4101
|
}
|
|
4042
4102
|
async function getTonPrice() {
|
|
4043
4103
|
try {
|
|
4044
|
-
const response = await
|
|
4045
|
-
|
|
4104
|
+
const response = await fetchWithTimeout(
|
|
4105
|
+
`${COINGECKO_API_URL}/simple/price?ids=the-open-network&vs_currencies=usd`
|
|
4046
4106
|
);
|
|
4047
4107
|
if (!response.ok) {
|
|
4048
4108
|
throw new Error(`CoinGecko API error: ${response.status}`);
|
|
@@ -4145,7 +4205,7 @@ var telegramSendMessageTool = {
|
|
|
4145
4205
|
}),
|
|
4146
4206
|
text: Type.String({
|
|
4147
4207
|
description: "The message text to send (max 4096 characters)",
|
|
4148
|
-
maxLength:
|
|
4208
|
+
maxLength: TELEGRAM_MAX_MESSAGE_LENGTH
|
|
4149
4209
|
}),
|
|
4150
4210
|
replyToId: Type.Optional(
|
|
4151
4211
|
Type.Number({
|
|
@@ -4192,7 +4252,7 @@ var telegramEditMessageTool = {
|
|
|
4192
4252
|
}),
|
|
4193
4253
|
text: Type2.String({
|
|
4194
4254
|
description: "The new text content for the message (max 4096 characters)",
|
|
4195
|
-
maxLength:
|
|
4255
|
+
maxLength: TELEGRAM_MAX_MESSAGE_LENGTH
|
|
4196
4256
|
})
|
|
4197
4257
|
})
|
|
4198
4258
|
};
|
|
@@ -4359,7 +4419,7 @@ var telegramScheduleMessageTool = {
|
|
|
4359
4419
|
}),
|
|
4360
4420
|
text: Type5.String({
|
|
4361
4421
|
description: "The message text to send (max 4096 characters)",
|
|
4362
|
-
maxLength:
|
|
4422
|
+
maxLength: TELEGRAM_MAX_MESSAGE_LENGTH
|
|
4363
4423
|
}),
|
|
4364
4424
|
scheduleDate: Type5.String({
|
|
4365
4425
|
description: "When to send the message (ISO 8601 format, e.g., '2024-12-25T10:00:00Z' or Unix timestamp as string)"
|
|
@@ -4615,7 +4675,7 @@ var telegramQuoteReplyTool = {
|
|
|
4615
4675
|
}),
|
|
4616
4676
|
text: Type8.String({
|
|
4617
4677
|
description: "Your reply message text",
|
|
4618
|
-
maxLength:
|
|
4678
|
+
maxLength: TELEGRAM_MAX_MESSAGE_LENGTH
|
|
4619
4679
|
}),
|
|
4620
4680
|
quoteOffset: Type8.Optional(
|
|
4621
4681
|
Type8.Number({
|
|
@@ -5086,7 +5146,7 @@ async function generateOpenAITTS(text, voice) {
|
|
|
5086
5146
|
mkdirSync8(tempDir, { recursive: true });
|
|
5087
5147
|
}
|
|
5088
5148
|
const outputPath = join10(tempDir, `${randomUUID3()}.mp3`);
|
|
5089
|
-
const response = await
|
|
5149
|
+
const response = await fetchWithTimeout(OPENAI_TTS_URL, {
|
|
5090
5150
|
method: "POST",
|
|
5091
5151
|
headers: {
|
|
5092
5152
|
Authorization: `Bearer ${apiKey}`,
|
|
@@ -5098,7 +5158,8 @@ async function generateOpenAITTS(text, voice) {
|
|
|
5098
5158
|
voice,
|
|
5099
5159
|
// alloy, echo, fable, onyx, nova, shimmer
|
|
5100
5160
|
response_format: "mp3"
|
|
5101
|
-
})
|
|
5161
|
+
}),
|
|
5162
|
+
timeoutMs: TTS_TIMEOUT_MS
|
|
5102
5163
|
});
|
|
5103
5164
|
if (!response.ok) {
|
|
5104
5165
|
const error = await response.text();
|
|
@@ -5122,7 +5183,7 @@ async function generateElevenLabsTTS(text, voiceId) {
|
|
|
5122
5183
|
mkdirSync8(tempDir, { recursive: true });
|
|
5123
5184
|
}
|
|
5124
5185
|
const outputPath = join10(tempDir, `${randomUUID3()}.mp3`);
|
|
5125
|
-
const response = await
|
|
5186
|
+
const response = await fetchWithTimeout(`${ELEVENLABS_TTS_URL}/${voiceId}`, {
|
|
5126
5187
|
method: "POST",
|
|
5127
5188
|
headers: {
|
|
5128
5189
|
"xi-api-key": apiKey,
|
|
@@ -5135,7 +5196,8 @@ async function generateElevenLabsTTS(text, voiceId) {
|
|
|
5135
5196
|
stability: 0.5,
|
|
5136
5197
|
similarity_boost: 0.75
|
|
5137
5198
|
}
|
|
5138
|
-
})
|
|
5199
|
+
}),
|
|
5200
|
+
timeoutMs: TTS_TIMEOUT_MS
|
|
5139
5201
|
});
|
|
5140
5202
|
if (!response.ok) {
|
|
5141
5203
|
const error = await response.text();
|
|
@@ -6415,7 +6477,7 @@ FIELDS:
|
|
|
6415
6477
|
|
|
6416
6478
|
NOTE: To change the photo, use a separate photo upload tool.
|
|
6417
6479
|
|
|
6418
|
-
Example: Update your channel @
|
|
6480
|
+
Example: Update your channel @my_channel with a new description.`,
|
|
6419
6481
|
parameters: Type23.Object({
|
|
6420
6482
|
channelId: Type23.String({
|
|
6421
6483
|
description: "Channel or group ID to edit"
|
|
@@ -7178,8 +7240,8 @@ var telegramCreatePollTool = {
|
|
|
7178
7240
|
description: "The chat ID where the poll will be created"
|
|
7179
7241
|
}),
|
|
7180
7242
|
question: Type30.String({
|
|
7181
|
-
description:
|
|
7182
|
-
maxLength:
|
|
7243
|
+
description: `The poll question/prompt (max ${MAX_POLL_QUESTION_LENGTH} characters)`,
|
|
7244
|
+
maxLength: MAX_POLL_QUESTION_LENGTH
|
|
7183
7245
|
}),
|
|
7184
7246
|
options: Type30.Array(
|
|
7185
7247
|
Type30.String({
|
|
@@ -8453,7 +8515,7 @@ var telegramSendGiftExecutor = async (params, context) => {
|
|
|
8453
8515
|
AND agent_gives_type = 'gift'
|
|
8454
8516
|
AND agent_gives_gift_id = ?
|
|
8455
8517
|
AND user_telegram_id = ?
|
|
8456
|
-
AND user_payment_verified_at >= unixepoch() -
|
|
8518
|
+
AND user_payment_verified_at >= unixepoch() - ${DEAL_VERIFICATION_WINDOW_SECONDS}
|
|
8457
8519
|
AND agent_sent_at IS NULL
|
|
8458
8520
|
LIMIT 1`
|
|
8459
8521
|
).get(giftId, userId);
|
|
@@ -8543,7 +8605,7 @@ var telegramTransferCollectibleExecutor = async (params, context) => {
|
|
|
8543
8605
|
AND agent_gives_type = 'gift'
|
|
8544
8606
|
AND agent_gives_gift_id = ?
|
|
8545
8607
|
AND user_telegram_id = ?
|
|
8546
|
-
AND user_payment_verified_at >= unixepoch() -
|
|
8608
|
+
AND user_payment_verified_at >= unixepoch() - ${DEAL_VERIFICATION_WINDOW_SECONDS}
|
|
8547
8609
|
AND agent_sent_at IS NULL
|
|
8548
8610
|
LIMIT 1`
|
|
8549
8611
|
).get(msgId.toString(), toUserId);
|
|
@@ -9714,7 +9776,7 @@ var marketGetFloorExecutor = async (params, context) => {
|
|
|
9714
9776
|
updatedAt: result.updatedAt,
|
|
9715
9777
|
cacheAgeMinutes: cacheAgeMin,
|
|
9716
9778
|
cacheStatus,
|
|
9717
|
-
message: `${result.model} in ${result.collection}: ${result.floorTon
|
|
9779
|
+
message: `${result.model} in ${result.collection}: ${result.floorTon?.toLocaleString() ?? "N/A"} TON (${result.rarityPercent}% rarity, ${cacheAgeMin} min old)`
|
|
9718
9780
|
}
|
|
9719
9781
|
};
|
|
9720
9782
|
} else {
|
|
@@ -9738,7 +9800,7 @@ var marketGetFloorExecutor = async (params, context) => {
|
|
|
9738
9800
|
updatedAt: result.updatedAt,
|
|
9739
9801
|
cacheAgeMinutes: cacheAgeMin,
|
|
9740
9802
|
cacheStatus,
|
|
9741
|
-
message: `${result.name} floor: ${result.floorTon
|
|
9803
|
+
message: `${result.name} floor: ${result.floorTon?.toLocaleString() ?? "N/A"} TON (~$${result.floorUsd?.toLocaleString() || "N/A"}, ${cacheAgeMin} min old)`
|
|
9742
9804
|
}
|
|
9743
9805
|
};
|
|
9744
9806
|
}
|
|
@@ -10792,7 +10854,6 @@ var tonMyTransactionsExecutor = async (params, context) => {
|
|
|
10792
10854
|
|
|
10793
10855
|
// src/agent/tools/dns/check.ts
|
|
10794
10856
|
import { Type as Type73 } from "@sinclair/typebox";
|
|
10795
|
-
var TONAPI_BASE = "https://tonapi.io/v2";
|
|
10796
10857
|
var dnsCheckTool = {
|
|
10797
10858
|
name: "dns_check",
|
|
10798
10859
|
description: "Check if a .ton domain is available, in auction, or already owned. Returns status with relevant details (price estimates, current bids, owner info).",
|
|
@@ -10825,7 +10886,7 @@ var dnsCheckExecutor = async (params, context) => {
|
|
|
10825
10886
|
};
|
|
10826
10887
|
}
|
|
10827
10888
|
const fullDomain = `${domain}.ton`;
|
|
10828
|
-
const dnsInfoResponse = await
|
|
10889
|
+
const dnsInfoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
|
|
10829
10890
|
headers: { Accept: "application/json" }
|
|
10830
10891
|
});
|
|
10831
10892
|
if (dnsInfoResponse.status === 404) {
|
|
@@ -10868,7 +10929,7 @@ var dnsCheckExecutor = async (params, context) => {
|
|
|
10868
10929
|
}
|
|
10869
10930
|
};
|
|
10870
10931
|
}
|
|
10871
|
-
const auctionsResponse = await
|
|
10932
|
+
const auctionsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
|
|
10872
10933
|
headers: { Accept: "application/json" }
|
|
10873
10934
|
});
|
|
10874
10935
|
if (auctionsResponse.ok) {
|
|
@@ -10916,7 +10977,6 @@ var dnsCheckExecutor = async (params, context) => {
|
|
|
10916
10977
|
|
|
10917
10978
|
// src/agent/tools/dns/auctions.ts
|
|
10918
10979
|
import { Type as Type74 } from "@sinclair/typebox";
|
|
10919
|
-
var TONAPI_BASE2 = "https://tonapi.io/v2";
|
|
10920
10980
|
var dnsAuctionsTool = {
|
|
10921
10981
|
name: "dns_auctions",
|
|
10922
10982
|
description: "List all active .ton domain auctions. Returns domains currently in auction with current bid prices, number of bids, and end times.",
|
|
@@ -10933,7 +10993,7 @@ var dnsAuctionsTool = {
|
|
|
10933
10993
|
var dnsAuctionsExecutor = async (params, context) => {
|
|
10934
10994
|
try {
|
|
10935
10995
|
const { limit = 20 } = params;
|
|
10936
|
-
const response = await
|
|
10996
|
+
const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
|
|
10937
10997
|
headers: { Accept: "application/json" }
|
|
10938
10998
|
});
|
|
10939
10999
|
if (!response.ok) {
|
|
@@ -10990,7 +11050,6 @@ ${summary}`
|
|
|
10990
11050
|
|
|
10991
11051
|
// src/agent/tools/dns/resolve.ts
|
|
10992
11052
|
import { Type as Type75 } from "@sinclair/typebox";
|
|
10993
|
-
var TONAPI_BASE3 = "https://tonapi.io/v2";
|
|
10994
11053
|
var dnsResolveTool = {
|
|
10995
11054
|
name: "dns_resolve",
|
|
10996
11055
|
description: "Resolve a .ton domain to its associated wallet address. Only works for domains that are already owned (not available or in auction).",
|
|
@@ -11005,7 +11064,7 @@ var dnsResolveExecutor = async (params, context) => {
|
|
|
11005
11064
|
let { domain } = params;
|
|
11006
11065
|
domain = domain.toLowerCase().replace(/\.ton$/, "");
|
|
11007
11066
|
const fullDomain = `${domain}.ton`;
|
|
11008
|
-
const response = await
|
|
11067
|
+
const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
|
|
11009
11068
|
headers: { Accept: "application/json" }
|
|
11010
11069
|
});
|
|
11011
11070
|
if (response.status === 404) {
|
|
@@ -11146,7 +11205,6 @@ import { mnemonicToPrivateKey as mnemonicToPrivateKey4 } from "@ton/crypto";
|
|
|
11146
11205
|
import { WalletContractV5R1 as WalletContractV5R14, TonClient as TonClient6, toNano as toNano3, internal as internal3 } from "@ton/ton";
|
|
11147
11206
|
import { Address as Address5, SendMode as SendMode3 } from "@ton/core";
|
|
11148
11207
|
import { getHttpEndpoint as getHttpEndpoint6 } from "@orbs-network/ton-access";
|
|
11149
|
-
var TONAPI_BASE4 = "https://tonapi.io/v2";
|
|
11150
11208
|
var dnsBidTool = {
|
|
11151
11209
|
name: "dns_bid",
|
|
11152
11210
|
description: "Place a bid on an existing .ton domain auction. Bid must be at least 5% higher than current bid. The domain must already be in auction (use dns_check first to verify status and get current bid).",
|
|
@@ -11165,7 +11223,7 @@ var dnsBidExecutor = async (params, context) => {
|
|
|
11165
11223
|
let { domain, amount } = params;
|
|
11166
11224
|
domain = domain.toLowerCase().replace(/\.ton$/, "");
|
|
11167
11225
|
const fullDomain = `${domain}.ton`;
|
|
11168
|
-
const dnsResponse = await
|
|
11226
|
+
const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
|
|
11169
11227
|
headers: { Accept: "application/json" }
|
|
11170
11228
|
});
|
|
11171
11229
|
if (dnsResponse.status === 404) {
|
|
@@ -11194,7 +11252,7 @@ var dnsBidExecutor = async (params, context) => {
|
|
|
11194
11252
|
error: `Could not determine NFT address for ${fullDomain}`
|
|
11195
11253
|
};
|
|
11196
11254
|
}
|
|
11197
|
-
const auctionsResponse = await
|
|
11255
|
+
const auctionsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/auctions?tld=ton`, {
|
|
11198
11256
|
headers: { Accept: "application/json" }
|
|
11199
11257
|
});
|
|
11200
11258
|
if (auctionsResponse.ok) {
|
|
@@ -11269,10 +11327,11 @@ import { mnemonicToPrivateKey as mnemonicToPrivateKey5 } from "@ton/crypto";
|
|
|
11269
11327
|
import { WalletContractV5R1 as WalletContractV5R15, TonClient as TonClient7, toNano as toNano4, internal as internal4, beginCell as beginCell2 } from "@ton/ton";
|
|
11270
11328
|
import { Address as Address6, SendMode as SendMode4 } from "@ton/core";
|
|
11271
11329
|
import { getHttpEndpoint as getHttpEndpoint7 } from "@orbs-network/ton-access";
|
|
11272
|
-
var TONAPI_BASE5 = "https://tonapi.io/v2";
|
|
11273
11330
|
var DNS_CHANGE_RECORD_OP = 1320284409;
|
|
11274
11331
|
var DNS_SMC_ADDRESS_PREFIX = 40915;
|
|
11275
|
-
var WALLET_RECORD_KEY = BigInt(
|
|
11332
|
+
var WALLET_RECORD_KEY = BigInt(
|
|
11333
|
+
"0xe8d44050873dba865aa7c170ab4cce64d90839a34dcfd6cf71d14e0205443b1b"
|
|
11334
|
+
);
|
|
11276
11335
|
var dnsLinkTool = {
|
|
11277
11336
|
name: "dns_link",
|
|
11278
11337
|
description: "Link a wallet address to a .ton domain you own. This sets the wallet record so the domain resolves to the specified address. If no wallet_address is provided, links to your own wallet.",
|
|
@@ -11308,7 +11367,7 @@ var dnsLinkExecutor = async (params, context) => {
|
|
|
11308
11367
|
error: `Invalid wallet address: ${targetAddress}`
|
|
11309
11368
|
};
|
|
11310
11369
|
}
|
|
11311
|
-
const dnsResponse = await
|
|
11370
|
+
const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
|
|
11312
11371
|
headers: { Accept: "application/json" }
|
|
11313
11372
|
});
|
|
11314
11373
|
if (dnsResponse.status === 404) {
|
|
@@ -11398,9 +11457,10 @@ import { mnemonicToPrivateKey as mnemonicToPrivateKey6 } from "@ton/crypto";
|
|
|
11398
11457
|
import { WalletContractV5R1 as WalletContractV5R16, TonClient as TonClient8, toNano as toNano5, internal as internal5, beginCell as beginCell3 } from "@ton/ton";
|
|
11399
11458
|
import { Address as Address7, SendMode as SendMode5 } from "@ton/core";
|
|
11400
11459
|
import { getHttpEndpoint as getHttpEndpoint8 } from "@orbs-network/ton-access";
|
|
11401
|
-
var TONAPI_BASE6 = "https://tonapi.io/v2";
|
|
11402
11460
|
var DNS_CHANGE_RECORD_OP2 = 1320284409;
|
|
11403
|
-
var WALLET_RECORD_KEY2 = BigInt(
|
|
11461
|
+
var WALLET_RECORD_KEY2 = BigInt(
|
|
11462
|
+
"0xe8d44050873dba865aa7c170ab4cce64d90839a34dcfd6cf71d14e0205443b1b"
|
|
11463
|
+
);
|
|
11404
11464
|
var dnsUnlinkTool = {
|
|
11405
11465
|
name: "dns_unlink",
|
|
11406
11466
|
description: "Remove the wallet link from a .ton domain you own. This deletes the wallet record so the domain no longer resolves to any address.",
|
|
@@ -11422,7 +11482,7 @@ var dnsUnlinkExecutor = async (params, context) => {
|
|
|
11422
11482
|
error: "Wallet not initialized. Contact admin to generate wallet."
|
|
11423
11483
|
};
|
|
11424
11484
|
}
|
|
11425
|
-
const dnsResponse = await
|
|
11485
|
+
const dnsResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/dns/${fullDomain}`, {
|
|
11426
11486
|
headers: { Accept: "application/json" }
|
|
11427
11487
|
});
|
|
11428
11488
|
if (dnsResponse.status === 404) {
|
|
@@ -11506,7 +11566,6 @@ var dnsUnlinkExecutor = async (params, context) => {
|
|
|
11506
11566
|
|
|
11507
11567
|
// src/agent/tools/jetton/balances.ts
|
|
11508
11568
|
import { Type as Type80 } from "@sinclair/typebox";
|
|
11509
|
-
var TONAPI_BASE7 = "https://tonapi.io/v2";
|
|
11510
11569
|
var jettonBalancesTool = {
|
|
11511
11570
|
name: "jetton_balances",
|
|
11512
11571
|
description: "Get all Jetton (token) balances owned by the agent. Returns a list of all tokens with their balances, names, symbols, and verification status. Useful to check what tokens you currently hold.",
|
|
@@ -11521,9 +11580,12 @@ var jettonBalancesExecutor = async (params, context) => {
|
|
|
11521
11580
|
error: "Wallet not initialized. Contact admin to generate wallet."
|
|
11522
11581
|
};
|
|
11523
11582
|
}
|
|
11524
|
-
const response = await
|
|
11525
|
-
|
|
11526
|
-
|
|
11583
|
+
const response = await fetchWithTimeout(
|
|
11584
|
+
`${TONAPI_BASE_URL}/accounts/${walletData.address}/jettons`,
|
|
11585
|
+
{
|
|
11586
|
+
headers: { Accept: "application/json" }
|
|
11587
|
+
}
|
|
11588
|
+
);
|
|
11527
11589
|
if (!response.ok) {
|
|
11528
11590
|
return {
|
|
11529
11591
|
success: false,
|
|
@@ -11748,7 +11810,6 @@ import { mnemonicToPrivateKey as mnemonicToPrivateKey8 } from "@ton/crypto";
|
|
|
11748
11810
|
import { WalletContractV5R1 as WalletContractV5R18, TonClient as TonClient10, toNano as toNano7, internal as internal7 } from "@ton/ton";
|
|
11749
11811
|
import { Address as Address8, SendMode as SendMode7, beginCell as beginCell4 } from "@ton/core";
|
|
11750
11812
|
import { getHttpEndpoint as getHttpEndpoint10 } from "@orbs-network/ton-access";
|
|
11751
|
-
var TONAPI_BASE8 = "https://tonapi.io/v2";
|
|
11752
11813
|
var JETTON_TRANSFER_OP = 260734629;
|
|
11753
11814
|
var jettonSendTool = {
|
|
11754
11815
|
name: "jetton_send",
|
|
@@ -11789,9 +11850,12 @@ var jettonSendExecutor = async (params, context) => {
|
|
|
11789
11850
|
error: `Invalid recipient address: ${to}`
|
|
11790
11851
|
};
|
|
11791
11852
|
}
|
|
11792
|
-
const jettonsResponse = await
|
|
11793
|
-
|
|
11794
|
-
|
|
11853
|
+
const jettonsResponse = await fetchWithTimeout(
|
|
11854
|
+
`${TONAPI_BASE_URL}/accounts/${walletData.address}/jettons`,
|
|
11855
|
+
{
|
|
11856
|
+
headers: { Accept: "application/json" }
|
|
11857
|
+
}
|
|
11858
|
+
);
|
|
11795
11859
|
if (!jettonsResponse.ok) {
|
|
11796
11860
|
return {
|
|
11797
11861
|
success: false,
|
|
@@ -11872,7 +11936,6 @@ var jettonSendExecutor = async (params, context) => {
|
|
|
11872
11936
|
|
|
11873
11937
|
// src/agent/tools/jetton/info.ts
|
|
11874
11938
|
import { Type as Type83 } from "@sinclair/typebox";
|
|
11875
|
-
var TONAPI_BASE9 = "https://tonapi.io/v2";
|
|
11876
11939
|
var jettonInfoTool = {
|
|
11877
11940
|
name: "jetton_info",
|
|
11878
11941
|
description: "Get detailed information about a Jetton (token) by its master contract address. Returns name, symbol, decimals, total supply, holders count, and verification status. Useful to research a token before buying or sending.",
|
|
@@ -11885,7 +11948,7 @@ var jettonInfoTool = {
|
|
|
11885
11948
|
var jettonInfoExecutor = async (params, context) => {
|
|
11886
11949
|
try {
|
|
11887
11950
|
const { jetton_address } = params;
|
|
11888
|
-
const response = await
|
|
11951
|
+
const response = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
|
|
11889
11952
|
headers: { Accept: "application/json" }
|
|
11890
11953
|
});
|
|
11891
11954
|
if (response.status === 404) {
|
|
@@ -11970,7 +12033,6 @@ function formatLargeNumber(num) {
|
|
|
11970
12033
|
|
|
11971
12034
|
// src/agent/tools/jetton/price.ts
|
|
11972
12035
|
import { Type as Type84 } from "@sinclair/typebox";
|
|
11973
|
-
var TONAPI_BASE10 = "https://tonapi.io/v2";
|
|
11974
12036
|
var jettonPriceTool = {
|
|
11975
12037
|
name: "jetton_price",
|
|
11976
12038
|
description: "Get the current price of a Jetton (token) in USD and TON, along with 24h, 7d, and 30d price changes. Useful to check token value before swapping or to monitor investments.",
|
|
@@ -11983,8 +12045,8 @@ var jettonPriceTool = {
|
|
|
11983
12045
|
var jettonPriceExecutor = async (params, context) => {
|
|
11984
12046
|
try {
|
|
11985
12047
|
const { jetton_address } = params;
|
|
11986
|
-
const response = await
|
|
11987
|
-
`${
|
|
12048
|
+
const response = await fetchWithTimeout(
|
|
12049
|
+
`${TONAPI_BASE_URL}/rates?tokens=${encodeURIComponent(jetton_address)}¤cies=usd,ton`,
|
|
11988
12050
|
{
|
|
11989
12051
|
headers: { Accept: "application/json" }
|
|
11990
12052
|
}
|
|
@@ -11998,7 +12060,7 @@ var jettonPriceExecutor = async (params, context) => {
|
|
|
11998
12060
|
const data = await response.json();
|
|
11999
12061
|
const rateData = data.rates?.[jetton_address];
|
|
12000
12062
|
if (!rateData) {
|
|
12001
|
-
const infoResponse = await
|
|
12063
|
+
const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
|
|
12002
12064
|
headers: { Accept: "application/json" }
|
|
12003
12065
|
});
|
|
12004
12066
|
if (infoResponse.status === 404) {
|
|
@@ -12019,7 +12081,7 @@ var jettonPriceExecutor = async (params, context) => {
|
|
|
12019
12081
|
let symbol = "TOKEN";
|
|
12020
12082
|
let name = "Unknown Token";
|
|
12021
12083
|
try {
|
|
12022
|
-
const infoResponse = await
|
|
12084
|
+
const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
|
|
12023
12085
|
headers: { Accept: "application/json" }
|
|
12024
12086
|
});
|
|
12025
12087
|
if (infoResponse.ok) {
|
|
@@ -12076,7 +12138,6 @@ var jettonPriceExecutor = async (params, context) => {
|
|
|
12076
12138
|
|
|
12077
12139
|
// src/agent/tools/jetton/search.ts
|
|
12078
12140
|
import { Type as Type85 } from "@sinclair/typebox";
|
|
12079
|
-
var STONFI_API = "https://api.ston.fi/v1";
|
|
12080
12141
|
var jettonSearchTool = {
|
|
12081
12142
|
name: "jetton_search",
|
|
12082
12143
|
description: "Search for Jettons (tokens) by name or symbol. Returns a list of matching tokens with their addresses, useful for finding a token's address before swapping or checking prices. Search is case-insensitive.",
|
|
@@ -12098,7 +12159,7 @@ var jettonSearchExecutor = async (params, context) => {
|
|
|
12098
12159
|
try {
|
|
12099
12160
|
const { query, limit = 10 } = params;
|
|
12100
12161
|
const searchQuery = query.toLowerCase().trim();
|
|
12101
|
-
const response = await
|
|
12162
|
+
const response = await fetchWithTimeout(`${STONFI_API_BASE_URL}/assets`, {
|
|
12102
12163
|
headers: { Accept: "application/json" }
|
|
12103
12164
|
});
|
|
12104
12165
|
if (!response.ok) {
|
|
@@ -12301,7 +12362,6 @@ var jettonQuoteExecutor = async (params, context) => {
|
|
|
12301
12362
|
|
|
12302
12363
|
// src/agent/tools/jetton/holders.ts
|
|
12303
12364
|
import { Type as Type87 } from "@sinclair/typebox";
|
|
12304
|
-
var TONAPI_BASE11 = "https://tonapi.io/v2";
|
|
12305
12365
|
var jettonHoldersTool = {
|
|
12306
12366
|
name: "jetton_holders",
|
|
12307
12367
|
description: "Get the top holders of a Jetton (token). Shows wallet addresses and their balances. Useful to analyze token distribution and identify whale wallets.",
|
|
@@ -12321,8 +12381,8 @@ var jettonHoldersTool = {
|
|
|
12321
12381
|
var jettonHoldersExecutor = async (params, context) => {
|
|
12322
12382
|
try {
|
|
12323
12383
|
const { jetton_address, limit = 10 } = params;
|
|
12324
|
-
const response = await
|
|
12325
|
-
`${
|
|
12384
|
+
const response = await fetchWithTimeout(
|
|
12385
|
+
`${TONAPI_BASE_URL}/jettons/${jetton_address}/holders?limit=${Math.min(limit, 100)}`,
|
|
12326
12386
|
{
|
|
12327
12387
|
headers: { Accept: "application/json" }
|
|
12328
12388
|
}
|
|
@@ -12344,7 +12404,7 @@ var jettonHoldersExecutor = async (params, context) => {
|
|
|
12344
12404
|
let decimals = 9;
|
|
12345
12405
|
let symbol = "TOKEN";
|
|
12346
12406
|
try {
|
|
12347
|
-
const infoResponse = await
|
|
12407
|
+
const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
|
|
12348
12408
|
headers: { Accept: "application/json" }
|
|
12349
12409
|
});
|
|
12350
12410
|
if (infoResponse.ok) {
|
|
@@ -12366,7 +12426,10 @@ var jettonHoldersExecutor = async (params, context) => {
|
|
|
12366
12426
|
isWallet: h.owner?.is_wallet || false
|
|
12367
12427
|
};
|
|
12368
12428
|
});
|
|
12369
|
-
const totalTop = holders.reduce(
|
|
12429
|
+
const totalTop = holders.reduce(
|
|
12430
|
+
(sum, h) => sum + parseFloat(h.balance.replace(/,/g, "")),
|
|
12431
|
+
0
|
|
12432
|
+
);
|
|
12370
12433
|
let message = `Top ${holders.length} holders of ${symbol}:
|
|
12371
12434
|
|
|
12372
12435
|
`;
|
|
@@ -12398,8 +12461,6 @@ var jettonHoldersExecutor = async (params, context) => {
|
|
|
12398
12461
|
|
|
12399
12462
|
// src/agent/tools/jetton/history.ts
|
|
12400
12463
|
import { Type as Type88 } from "@sinclair/typebox";
|
|
12401
|
-
var TONAPI_BASE12 = "https://tonapi.io/v2";
|
|
12402
|
-
var GECKOTERMINAL_API = "https://api.geckoterminal.com/api/v2";
|
|
12403
12464
|
var jettonHistoryTool = {
|
|
12404
12465
|
name: "jetton_history",
|
|
12405
12466
|
description: "Get price history and performance data for a Jetton. Shows price changes over 24h, 7d, 30d periods, along with volume and market data. Useful for analyzing token trends.",
|
|
@@ -12412,15 +12473,15 @@ var jettonHistoryTool = {
|
|
|
12412
12473
|
var jettonHistoryExecutor = async (params, context) => {
|
|
12413
12474
|
try {
|
|
12414
12475
|
const { jetton_address } = params;
|
|
12415
|
-
const ratesResponse = await
|
|
12416
|
-
`${
|
|
12476
|
+
const ratesResponse = await fetchWithTimeout(
|
|
12477
|
+
`${TONAPI_BASE_URL}/rates?tokens=${encodeURIComponent(jetton_address)}¤cies=usd,ton`,
|
|
12417
12478
|
{ headers: { Accept: "application/json" } }
|
|
12418
12479
|
);
|
|
12419
|
-
const geckoResponse = await
|
|
12420
|
-
`${
|
|
12480
|
+
const geckoResponse = await fetchWithTimeout(
|
|
12481
|
+
`${GECKOTERMINAL_API_URL}/networks/ton/tokens/${jetton_address}`,
|
|
12421
12482
|
{ headers: { Accept: "application/json" } }
|
|
12422
12483
|
);
|
|
12423
|
-
const infoResponse = await
|
|
12484
|
+
const infoResponse = await fetchWithTimeout(`${TONAPI_BASE_URL}/jettons/${jetton_address}`, {
|
|
12424
12485
|
headers: { Accept: "application/json" }
|
|
12425
12486
|
});
|
|
12426
12487
|
let symbol = "TOKEN";
|
|
@@ -12456,13 +12517,17 @@ var jettonHistoryExecutor = async (params, context) => {
|
|
|
12456
12517
|
const attrs = geckoData.data?.attributes;
|
|
12457
12518
|
if (attrs) {
|
|
12458
12519
|
if (attrs.volume_usd?.h24) {
|
|
12459
|
-
volume24h = parseFloat(attrs.volume_usd.h24).toLocaleString(void 0, {
|
|
12520
|
+
volume24h = parseFloat(attrs.volume_usd.h24).toLocaleString(void 0, {
|
|
12521
|
+
maximumFractionDigits: 0
|
|
12522
|
+
});
|
|
12460
12523
|
}
|
|
12461
12524
|
if (attrs.fdv_usd) {
|
|
12462
12525
|
fdv = parseFloat(attrs.fdv_usd).toLocaleString(void 0, { maximumFractionDigits: 0 });
|
|
12463
12526
|
}
|
|
12464
12527
|
if (attrs.market_cap_usd) {
|
|
12465
|
-
marketCap = parseFloat(attrs.market_cap_usd).toLocaleString(void 0, {
|
|
12528
|
+
marketCap = parseFloat(attrs.market_cap_usd).toLocaleString(void 0, {
|
|
12529
|
+
maximumFractionDigits: 0
|
|
12530
|
+
});
|
|
12466
12531
|
}
|
|
12467
12532
|
}
|
|
12468
12533
|
}
|
|
@@ -12524,7 +12589,6 @@ var jettonHistoryExecutor = async (params, context) => {
|
|
|
12524
12589
|
|
|
12525
12590
|
// src/agent/tools/jetton/trending.ts
|
|
12526
12591
|
import { Type as Type89 } from "@sinclair/typebox";
|
|
12527
|
-
var STONFI_API2 = "https://api.ston.fi/v1";
|
|
12528
12592
|
var jettonTrendingTool = {
|
|
12529
12593
|
name: "jetton_trending",
|
|
12530
12594
|
description: "Get trending/popular Jettons on the TON blockchain. Shows tokens ranked by trading volume and liquidity. Useful for discovering popular tokens.",
|
|
@@ -12541,7 +12605,7 @@ var jettonTrendingTool = {
|
|
|
12541
12605
|
var jettonTrendingExecutor = async (params, context) => {
|
|
12542
12606
|
try {
|
|
12543
12607
|
const { limit = 10 } = params;
|
|
12544
|
-
const response = await
|
|
12608
|
+
const response = await fetchWithTimeout(`${STONFI_API_BASE_URL}/assets`, {
|
|
12545
12609
|
headers: { Accept: "application/json" }
|
|
12546
12610
|
});
|
|
12547
12611
|
if (!response.ok) {
|
|
@@ -12598,7 +12662,6 @@ var jettonTrendingExecutor = async (params, context) => {
|
|
|
12598
12662
|
|
|
12599
12663
|
// src/agent/tools/jetton/pools.ts
|
|
12600
12664
|
import { Type as Type90 } from "@sinclair/typebox";
|
|
12601
|
-
var STONFI_API3 = "https://api.ston.fi/v1";
|
|
12602
12665
|
var jettonPoolsTool = {
|
|
12603
12666
|
name: "jetton_pools",
|
|
12604
12667
|
description: "Get liquidity pools for a Jetton or list top pools by volume. Shows pool addresses, liquidity, volume, APY, and trading pairs. Useful for finding where to trade a token or analyzing DeFi opportunities.",
|
|
@@ -12620,7 +12683,7 @@ var jettonPoolsTool = {
|
|
|
12620
12683
|
var jettonPoolsExecutor = async (params, context) => {
|
|
12621
12684
|
try {
|
|
12622
12685
|
const { jetton_address, limit = 10 } = params;
|
|
12623
|
-
const response = await
|
|
12686
|
+
const response = await fetchWithTimeout(`${STONFI_API_BASE_URL}/pools`, {
|
|
12624
12687
|
headers: { Accept: "application/json" }
|
|
12625
12688
|
});
|
|
12626
12689
|
if (!response.ok) {
|
|
@@ -12639,10 +12702,12 @@ var jettonPoolsExecutor = async (params, context) => {
|
|
|
12639
12702
|
return token0.includes(targetAddress) || token1.includes(targetAddress) || targetAddress.includes(token0) || targetAddress.includes(token1);
|
|
12640
12703
|
});
|
|
12641
12704
|
}
|
|
12642
|
-
pools = pools.filter((p) => !p.deprecated).sort(
|
|
12643
|
-
|
|
12705
|
+
pools = pools.filter((p) => !p.deprecated).sort(
|
|
12706
|
+
(a, b) => parseFloat(b.volume_24h_usd || "0") - parseFloat(a.volume_24h_usd || "0")
|
|
12707
|
+
).slice(0, limit);
|
|
12708
|
+
const assetMap = {};
|
|
12644
12709
|
try {
|
|
12645
|
-
const assetsResponse = await
|
|
12710
|
+
const assetsResponse = await fetchWithTimeout(`${STONFI_API_BASE_URL}/assets`);
|
|
12646
12711
|
if (assetsResponse.ok) {
|
|
12647
12712
|
const assetsData = await assetsResponse.json();
|
|
12648
12713
|
for (const asset of assetsData.asset_list || []) {
|
|
@@ -13071,7 +13136,7 @@ var dedustPoolsTool = {
|
|
|
13071
13136
|
var dedustPoolsExecutor = async (params, context) => {
|
|
13072
13137
|
try {
|
|
13073
13138
|
const { jetton_address, pool_type, limit = 20 } = params;
|
|
13074
|
-
const response = await
|
|
13139
|
+
const response = await fetchWithTimeout(`${DEDUST_API_URL}/pools`);
|
|
13075
13140
|
if (!response.ok) {
|
|
13076
13141
|
throw new Error(`DeDust API error: ${response.status} ${response.statusText}`);
|
|
13077
13142
|
}
|
|
@@ -13080,9 +13145,7 @@ var dedustPoolsExecutor = async (params, context) => {
|
|
|
13080
13145
|
if (jetton_address) {
|
|
13081
13146
|
const normalizedAddress = jetton_address.toLowerCase();
|
|
13082
13147
|
filteredPools = filteredPools.filter(
|
|
13083
|
-
(pool) => pool.assets.some(
|
|
13084
|
-
(asset) => asset.address?.toLowerCase() === normalizedAddress
|
|
13085
|
-
)
|
|
13148
|
+
(pool) => pool.assets.some((asset) => asset.address?.toLowerCase() === normalizedAddress)
|
|
13086
13149
|
);
|
|
13087
13150
|
}
|
|
13088
13151
|
if (pool_type) {
|
|
@@ -13924,7 +13987,7 @@ var JournalStore = class {
|
|
|
13924
13987
|
values.outcome = params.outcome;
|
|
13925
13988
|
}
|
|
13926
13989
|
if (params.days) {
|
|
13927
|
-
const cutoff = Math.floor(Date.now() / 1e3) - params.days *
|
|
13990
|
+
const cutoff = Math.floor(Date.now() / 1e3) - params.days * SECONDS_PER_DAY;
|
|
13928
13991
|
conditions.push("timestamp >= @cutoff");
|
|
13929
13992
|
values.cutoff = cutoff;
|
|
13930
13993
|
}
|
|
@@ -13961,7 +14024,7 @@ var JournalStore = class {
|
|
|
13961
14024
|
values.type = params.type;
|
|
13962
14025
|
}
|
|
13963
14026
|
if (params.days) {
|
|
13964
|
-
const cutoff = Math.floor(Date.now() / 1e3) - params.days *
|
|
14027
|
+
const cutoff = Math.floor(Date.now() / 1e3) - params.days * SECONDS_PER_DAY;
|
|
13965
14028
|
conditions.push("timestamp >= @cutoff");
|
|
13966
14029
|
values.cutoff = cutoff;
|
|
13967
14030
|
}
|
|
@@ -15017,7 +15080,7 @@ Returns:
|
|
|
15017
15080
|
Teleton Casino needs sufficient balance to cover potential payouts (up to 5x the bet).
|
|
15018
15081
|
|
|
15019
15082
|
IMPORTANT: When a player wants to bet, tell them to send TON to Teleton Casino address with their username as memo.
|
|
15020
|
-
Example: "Send 2 TON to EQxxx with memo:
|
|
15083
|
+
Example: "Send 2 TON to EQxxx with memo: john_doe"`,
|
|
15021
15084
|
parameters: Type105.Object({})
|
|
15022
15085
|
};
|
|
15023
15086
|
var casinoBalanceExecutor = async (params, context) => {
|
|
@@ -15085,6 +15148,8 @@ var casinoBalanceExecutor = async (params, context) => {
|
|
|
15085
15148
|
|
|
15086
15149
|
// src/agent/tools/casino/spin.ts
|
|
15087
15150
|
import { Type as Type106 } from "@sinclair/typebox";
|
|
15151
|
+
|
|
15152
|
+
// src/casino/game-engine.ts
|
|
15088
15153
|
import { Api as Api53 } from "telegram";
|
|
15089
15154
|
|
|
15090
15155
|
// src/casino/payment-verifier.ts
|
|
@@ -15244,6 +15309,16 @@ function checkCooldown(db, userId) {
|
|
|
15244
15309
|
}
|
|
15245
15310
|
return { allowed: true };
|
|
15246
15311
|
}
|
|
15312
|
+
function checkAndUpdateCooldown(db, userId) {
|
|
15313
|
+
const txn = db.transaction(() => {
|
|
15314
|
+
const check = checkCooldown(db, userId);
|
|
15315
|
+
if (check.allowed) {
|
|
15316
|
+
updateCooldown(db, userId);
|
|
15317
|
+
}
|
|
15318
|
+
return check;
|
|
15319
|
+
});
|
|
15320
|
+
return txn();
|
|
15321
|
+
}
|
|
15247
15322
|
function updateCooldown(db, userId) {
|
|
15248
15323
|
const now = Math.floor(Date.now() / 1e3);
|
|
15249
15324
|
db.prepare(
|
|
@@ -15433,59 +15508,19 @@ function checkRateLimit(userId, action) {
|
|
|
15433
15508
|
return { allowed: true };
|
|
15434
15509
|
}
|
|
15435
15510
|
|
|
15436
|
-
// src/
|
|
15437
|
-
|
|
15438
|
-
name: "casino_spin",
|
|
15439
|
-
description: `Execute a Teleton Casino slot machine spin with full security checks.
|
|
15440
|
-
|
|
15441
|
-
Slot payout table (40% house edge):
|
|
15442
|
-
- \u{1F3B0} 64 (777) = JACKPOT (5x bet)
|
|
15443
|
-
- \u{1F3B0} 60-63 = Big win (2.5x bet)
|
|
15444
|
-
- \u{1F3B0} 55-59 = Medium win (1.8x bet)
|
|
15445
|
-
- \u{1F3B0} 43-54 = Small win (1.2x bet)
|
|
15446
|
-
- \u{1F3B0} 1-42 = No win
|
|
15447
|
-
|
|
15448
|
-
Process:
|
|
15449
|
-
1. Validates bet amount (min 0.1 TON, max 5% of bankroll)
|
|
15450
|
-
2. Checks user cooldown (30 seconds between spins)
|
|
15451
|
-
3. Verifies TON payment with username as memo
|
|
15452
|
-
4. Auto-discovers player wallet from transaction
|
|
15453
|
-
5. Sends \u{1F3B0} slot machine animation
|
|
15454
|
-
6. Processes house edge (5%) to daily jackpot
|
|
15455
|
-
7. AUTO-PAYOUT if player wins
|
|
15456
|
-
|
|
15457
|
-
Tell the user: "Send X TON to [casino_address] with memo: your_username"`,
|
|
15458
|
-
parameters: Type106.Object({
|
|
15459
|
-
chat_id: Type106.String({
|
|
15460
|
-
description: "Telegram chat ID where to send the spin"
|
|
15461
|
-
}),
|
|
15462
|
-
bet_amount: Type106.Number({
|
|
15463
|
-
description: "Bet amount in TON",
|
|
15464
|
-
minimum: 0.1
|
|
15465
|
-
}),
|
|
15466
|
-
player_username: Type106.String({
|
|
15467
|
-
description: "Player's Telegram username (without @)"
|
|
15468
|
-
}),
|
|
15469
|
-
reply_to: Type106.Optional(
|
|
15470
|
-
Type106.Number({
|
|
15471
|
-
description: "Message ID to reply to"
|
|
15472
|
-
})
|
|
15473
|
-
)
|
|
15474
|
-
})
|
|
15475
|
-
};
|
|
15476
|
-
var casinoSpinExecutor = async (params, context) => {
|
|
15511
|
+
// src/casino/game-engine.ts
|
|
15512
|
+
async function executeGame(config, params, context) {
|
|
15477
15513
|
try {
|
|
15478
15514
|
const { chat_id, bet_amount, player_username, reply_to } = params;
|
|
15479
|
-
const
|
|
15515
|
+
const userId = context.senderId.toString();
|
|
15480
15516
|
const username = player_username?.replace(/^@/, "").toLowerCase().trim();
|
|
15481
|
-
const userId = oddsId;
|
|
15482
15517
|
if (!username || username.length === 0) {
|
|
15483
15518
|
return {
|
|
15484
15519
|
success: false,
|
|
15485
15520
|
error: "\u274C You need a Telegram @username to play at Teleton Casino. Set up your username in Telegram settings and try again!"
|
|
15486
15521
|
};
|
|
15487
15522
|
}
|
|
15488
|
-
const rateCheck = checkRateLimit(
|
|
15523
|
+
const rateCheck = checkRateLimit(userId, config.toolName);
|
|
15489
15524
|
if (!rateCheck.allowed) {
|
|
15490
15525
|
return {
|
|
15491
15526
|
success: false,
|
|
@@ -15494,20 +15529,13 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15494
15529
|
}
|
|
15495
15530
|
const casinoWallet = getWalletAddress();
|
|
15496
15531
|
if (!casinoWallet) {
|
|
15497
|
-
return {
|
|
15498
|
-
success: false,
|
|
15499
|
-
error: "Casino wallet not initialized."
|
|
15500
|
-
};
|
|
15532
|
+
return { success: false, error: "Casino wallet not initialized." };
|
|
15501
15533
|
}
|
|
15502
15534
|
const balanceInfo = await getWalletBalance(casinoWallet);
|
|
15503
15535
|
if (!balanceInfo) {
|
|
15504
|
-
return {
|
|
15505
|
-
success: false,
|
|
15506
|
-
error: "Failed to check casino balance."
|
|
15507
|
-
};
|
|
15536
|
+
return { success: false, error: "Failed to check casino balance." };
|
|
15508
15537
|
}
|
|
15509
15538
|
const balance = parseFloat(balanceInfo.balance);
|
|
15510
|
-
const jackpotMultiplier = CASINO_CONFIG.slot.jackpot.multiplier;
|
|
15511
15539
|
if (balance < CASINO_CONFIG.minBankroll) {
|
|
15512
15540
|
return {
|
|
15513
15541
|
success: false,
|
|
@@ -15515,7 +15543,7 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15515
15543
|
};
|
|
15516
15544
|
}
|
|
15517
15545
|
const maxBetByPercent = balance * (CASINO_CONFIG.maxBetPercent / 100);
|
|
15518
|
-
const maxBetByCoverage = balance /
|
|
15546
|
+
const maxBetByCoverage = balance / config.maxMultiplier;
|
|
15519
15547
|
const maxBet = Math.min(maxBetByPercent, maxBetByCoverage);
|
|
15520
15548
|
if (bet_amount > maxBet) {
|
|
15521
15549
|
return {
|
|
@@ -15529,11 +15557,11 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15529
15557
|
error: `\u274C Minimum bet is ${CASINO_CONFIG.minBet} TON`
|
|
15530
15558
|
};
|
|
15531
15559
|
}
|
|
15532
|
-
const cooldownCheck =
|
|
15560
|
+
const cooldownCheck = checkAndUpdateCooldown(context.db, userId);
|
|
15533
15561
|
if (!cooldownCheck.allowed) {
|
|
15534
15562
|
return {
|
|
15535
15563
|
success: false,
|
|
15536
|
-
error: cooldownCheck.message || "Please wait before
|
|
15564
|
+
error: cooldownCheck.message || "Please wait before playing again."
|
|
15537
15565
|
};
|
|
15538
15566
|
}
|
|
15539
15567
|
const requestTime = Date.now();
|
|
@@ -15541,9 +15569,8 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15541
15569
|
botWalletAddress: casinoWallet,
|
|
15542
15570
|
betAmount: bet_amount,
|
|
15543
15571
|
requestTime: requestTime - CASINO_CONFIG.paymentWindowMinutes * 60 * 1e3,
|
|
15544
|
-
gameType:
|
|
15572
|
+
gameType: config.gameType,
|
|
15545
15573
|
userId: username
|
|
15546
|
-
// Use username for memo matching
|
|
15547
15574
|
});
|
|
15548
15575
|
if (!paymentVerification.verified || !paymentVerification.playerWallet) {
|
|
15549
15576
|
return {
|
|
@@ -15552,76 +15579,74 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15552
15579
|
};
|
|
15553
15580
|
}
|
|
15554
15581
|
const playerWallet = paymentVerification.playerWallet;
|
|
15555
|
-
updateCooldown(context.db, userId);
|
|
15556
15582
|
const gramJsClient = context.bridge.getClient().getClient();
|
|
15557
|
-
const
|
|
15583
|
+
const result = await gramJsClient.invoke(
|
|
15558
15584
|
new Api53.messages.SendMedia({
|
|
15559
15585
|
peer: chat_id,
|
|
15560
|
-
media: new Api53.InputMediaDice({ emoticon:
|
|
15586
|
+
media: new Api53.InputMediaDice({ emoticon: config.emoticon }),
|
|
15561
15587
|
message: "",
|
|
15562
15588
|
randomId: BigInt(Math.floor(Math.random() * 1e16)),
|
|
15563
15589
|
replyTo: reply_to ? new Api53.InputReplyToMessage({ replyToMsgId: reply_to }) : void 0
|
|
15564
15590
|
})
|
|
15565
15591
|
);
|
|
15566
|
-
let
|
|
15592
|
+
let gameValue;
|
|
15567
15593
|
let messageId;
|
|
15568
|
-
if (
|
|
15569
|
-
for (const update of
|
|
15594
|
+
if (result instanceof Api53.Updates || result instanceof Api53.UpdatesCombined) {
|
|
15595
|
+
for (const update of result.updates) {
|
|
15570
15596
|
if (update instanceof Api53.UpdateNewMessage || update instanceof Api53.UpdateNewChannelMessage) {
|
|
15571
15597
|
const msg = update.message;
|
|
15572
15598
|
if (msg instanceof Api53.Message && msg.media instanceof Api53.MessageMediaDice) {
|
|
15573
|
-
|
|
15599
|
+
gameValue = msg.media.value;
|
|
15574
15600
|
messageId = msg.id;
|
|
15575
15601
|
break;
|
|
15576
15602
|
}
|
|
15577
15603
|
}
|
|
15578
15604
|
}
|
|
15579
15605
|
}
|
|
15580
|
-
if (
|
|
15606
|
+
if (gameValue === void 0) {
|
|
15581
15607
|
return {
|
|
15582
15608
|
success: false,
|
|
15583
|
-
error:
|
|
15609
|
+
error: `Failed to get ${config.gameType} result from Telegram.`
|
|
15584
15610
|
};
|
|
15585
15611
|
}
|
|
15586
15612
|
const houseEdge = processBetForJackpot(context.db, bet_amount);
|
|
15587
|
-
|
|
15588
|
-
`
|
|
15589
|
-
INSERT INTO casino_users (telegram_id, wallet_address, total_bets, total_wagered, last_bet_at)
|
|
15590
|
-
VALUES (?, ?, 1, ?, unixepoch())
|
|
15591
|
-
ON CONFLICT(telegram_id) DO UPDATE SET
|
|
15592
|
-
wallet_address = excluded.wallet_address,
|
|
15593
|
-
total_bets = total_bets + 1,
|
|
15594
|
-
total_wagered = total_wagered + ?,
|
|
15595
|
-
last_bet_at = unixepoch()
|
|
15596
|
-
`
|
|
15597
|
-
).run(userId, playerWallet, bet_amount, bet_amount);
|
|
15598
|
-
const journalEntry = context.db.prepare(
|
|
15599
|
-
`
|
|
15600
|
-
INSERT INTO journal (
|
|
15601
|
-
type, action, asset_from, asset_to, amount_from,
|
|
15602
|
-
platform, reasoning, outcome, tx_hash, tool_used,
|
|
15603
|
-
chat_id, user_id, timestamp
|
|
15604
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, unixepoch())
|
|
15605
|
-
`
|
|
15606
|
-
).run(
|
|
15607
|
-
"trade",
|
|
15608
|
-
"casino_spin",
|
|
15609
|
-
"TON",
|
|
15610
|
-
"SPIN",
|
|
15611
|
-
bet_amount,
|
|
15612
|
-
"telegram_casino",
|
|
15613
|
-
`Slot spin result: ${slotValue}/64`,
|
|
15614
|
-
"pending",
|
|
15615
|
-
paymentVerification.txHash,
|
|
15616
|
-
"casino_spin",
|
|
15617
|
-
chat_id,
|
|
15618
|
-
userId
|
|
15619
|
-
);
|
|
15620
|
-
const journalId = journalEntry.lastInsertRowid;
|
|
15621
|
-
const multiplier = getSlotMultiplier(slotValue);
|
|
15613
|
+
const multiplier = config.getMultiplier(gameValue);
|
|
15622
15614
|
const won = multiplier > 0;
|
|
15623
15615
|
const payoutAmount = won ? bet_amount * multiplier : 0;
|
|
15624
15616
|
const jackpot = getJackpot(context.db);
|
|
15617
|
+
const recordBet = context.db.transaction(() => {
|
|
15618
|
+
context.db.prepare(
|
|
15619
|
+
`INSERT INTO casino_users (telegram_id, wallet_address, total_bets, total_wagered, last_bet_at)
|
|
15620
|
+
VALUES (?, ?, 1, ?, unixepoch())
|
|
15621
|
+
ON CONFLICT(telegram_id) DO UPDATE SET
|
|
15622
|
+
wallet_address = excluded.wallet_address,
|
|
15623
|
+
total_bets = total_bets + 1,
|
|
15624
|
+
total_wagered = total_wagered + ?,
|
|
15625
|
+
last_bet_at = unixepoch()`
|
|
15626
|
+
).run(userId, playerWallet, bet_amount, bet_amount);
|
|
15627
|
+
const journalEntry = context.db.prepare(
|
|
15628
|
+
`INSERT INTO journal (
|
|
15629
|
+
type, action, asset_from, asset_to, amount_from,
|
|
15630
|
+
platform, reasoning, outcome, tx_hash, tool_used,
|
|
15631
|
+
chat_id, user_id, timestamp
|
|
15632
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, unixepoch())`
|
|
15633
|
+
).run(
|
|
15634
|
+
"trade",
|
|
15635
|
+
config.toolName,
|
|
15636
|
+
"TON",
|
|
15637
|
+
config.assetLabel,
|
|
15638
|
+
bet_amount,
|
|
15639
|
+
"telegram_casino",
|
|
15640
|
+
`${config.gameType} result: ${gameValue}/${config.maxValue}`,
|
|
15641
|
+
"pending",
|
|
15642
|
+
paymentVerification.txHash,
|
|
15643
|
+
config.toolName,
|
|
15644
|
+
chat_id,
|
|
15645
|
+
userId
|
|
15646
|
+
);
|
|
15647
|
+
return journalEntry.lastInsertRowid;
|
|
15648
|
+
});
|
|
15649
|
+
const journalId = recordBet();
|
|
15625
15650
|
let payoutSent = false;
|
|
15626
15651
|
let payoutTxHash;
|
|
15627
15652
|
if (won && payoutAmount > 0) {
|
|
@@ -15630,41 +15655,30 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15630
15655
|
if (payoutResult.success) {
|
|
15631
15656
|
payoutSent = true;
|
|
15632
15657
|
payoutTxHash = payoutResult.txHash;
|
|
15633
|
-
context.db.
|
|
15634
|
-
|
|
15635
|
-
|
|
15636
|
-
|
|
15637
|
-
|
|
15638
|
-
|
|
15639
|
-
|
|
15640
|
-
)
|
|
15641
|
-
|
|
15642
|
-
`UPDATE casino_users
|
|
15643
|
-
SET total_wins = total_wins + 1,
|
|
15644
|
-
total_won = total_won + ?
|
|
15645
|
-
WHERE telegram_id = ?`
|
|
15646
|
-
).run(payoutAmount, oddsId);
|
|
15658
|
+
const recordWin = context.db.transaction(() => {
|
|
15659
|
+
context.db.prepare(
|
|
15660
|
+
`UPDATE journal SET outcome = 'loss', amount_to = ?, pnl_ton = ?, closed_at = unixepoch() WHERE id = ?`
|
|
15661
|
+
).run(payoutAmount, -(payoutAmount - bet_amount), journalId);
|
|
15662
|
+
context.db.prepare(
|
|
15663
|
+
`UPDATE casino_users SET total_wins = total_wins + 1, total_won = total_won + ? WHERE telegram_id = ?`
|
|
15664
|
+
).run(payoutAmount, userId);
|
|
15665
|
+
});
|
|
15666
|
+
recordWin();
|
|
15647
15667
|
}
|
|
15648
15668
|
} else {
|
|
15649
|
-
context.db.
|
|
15650
|
-
|
|
15651
|
-
|
|
15652
|
-
|
|
15653
|
-
|
|
15654
|
-
|
|
15655
|
-
|
|
15656
|
-
).run(bet_amount, journalId);
|
|
15657
|
-
context.db.prepare(
|
|
15658
|
-
`UPDATE casino_users
|
|
15659
|
-
SET total_losses = total_losses + 1
|
|
15660
|
-
WHERE telegram_id = ?`
|
|
15661
|
-
).run(oddsId);
|
|
15669
|
+
const recordLoss = context.db.transaction(() => {
|
|
15670
|
+
context.db.prepare(
|
|
15671
|
+
`UPDATE journal SET outcome = 'profit', amount_to = 0, pnl_ton = ?, closed_at = unixepoch() WHERE id = ?`
|
|
15672
|
+
).run(bet_amount, journalId);
|
|
15673
|
+
context.db.prepare(`UPDATE casino_users SET total_losses = total_losses + 1 WHERE telegram_id = ?`).run(userId);
|
|
15674
|
+
});
|
|
15675
|
+
recordLoss();
|
|
15662
15676
|
}
|
|
15663
|
-
const interpretation =
|
|
15677
|
+
const interpretation = config.getInterpretation(gameValue);
|
|
15664
15678
|
return {
|
|
15665
15679
|
success: true,
|
|
15666
15680
|
data: {
|
|
15667
|
-
|
|
15681
|
+
game_value: gameValue,
|
|
15668
15682
|
won,
|
|
15669
15683
|
multiplier,
|
|
15670
15684
|
payout_amount: payoutAmount > 0 ? payoutAmount.toFixed(2) : "0",
|
|
@@ -15682,17 +15696,73 @@ var casinoSpinExecutor = async (params, context) => {
|
|
|
15682
15696
|
}
|
|
15683
15697
|
};
|
|
15684
15698
|
} catch (error) {
|
|
15685
|
-
console.error(
|
|
15699
|
+
console.error(`Error in ${config.toolName}:`, error);
|
|
15686
15700
|
return {
|
|
15687
15701
|
success: false,
|
|
15688
15702
|
error: error instanceof Error ? error.message : String(error)
|
|
15689
15703
|
};
|
|
15690
15704
|
}
|
|
15705
|
+
}
|
|
15706
|
+
|
|
15707
|
+
// src/agent/tools/casino/spin.ts
|
|
15708
|
+
var casinoSpinTool = {
|
|
15709
|
+
name: "casino_spin",
|
|
15710
|
+
description: `Execute a Teleton Casino slot machine spin with full security checks.
|
|
15711
|
+
|
|
15712
|
+
Slot payout table (40% house edge):
|
|
15713
|
+
- \u{1F3B0} 64 (777) = JACKPOT (5x bet)
|
|
15714
|
+
- \u{1F3B0} 60-63 = Big win (2.5x bet)
|
|
15715
|
+
- \u{1F3B0} 55-59 = Medium win (1.8x bet)
|
|
15716
|
+
- \u{1F3B0} 43-54 = Small win (1.2x bet)
|
|
15717
|
+
- \u{1F3B0} 1-42 = No win
|
|
15718
|
+
|
|
15719
|
+
Process:
|
|
15720
|
+
1. Validates bet amount (min 0.1 TON, max 5% of bankroll)
|
|
15721
|
+
2. Checks user cooldown (30 seconds between spins)
|
|
15722
|
+
3. Verifies TON payment with username as memo
|
|
15723
|
+
4. Auto-discovers player wallet from transaction
|
|
15724
|
+
5. Sends \u{1F3B0} slot machine animation
|
|
15725
|
+
6. Processes house edge (5%) to daily jackpot
|
|
15726
|
+
7. AUTO-PAYOUT if player wins
|
|
15727
|
+
|
|
15728
|
+
Tell the user: "Send X TON to [casino_address] with memo: your_username"`,
|
|
15729
|
+
parameters: Type106.Object({
|
|
15730
|
+
chat_id: Type106.String({
|
|
15731
|
+
description: "Telegram chat ID where to send the spin"
|
|
15732
|
+
}),
|
|
15733
|
+
bet_amount: Type106.Number({
|
|
15734
|
+
description: "Bet amount in TON",
|
|
15735
|
+
minimum: 0.1
|
|
15736
|
+
}),
|
|
15737
|
+
player_username: Type106.String({
|
|
15738
|
+
description: "Player's Telegram username (without @)"
|
|
15739
|
+
}),
|
|
15740
|
+
reply_to: Type106.Optional(
|
|
15741
|
+
Type106.Number({
|
|
15742
|
+
description: "Message ID to reply to"
|
|
15743
|
+
})
|
|
15744
|
+
)
|
|
15745
|
+
})
|
|
15746
|
+
};
|
|
15747
|
+
var casinoSpinExecutor = async (params, context) => {
|
|
15748
|
+
return executeGame(
|
|
15749
|
+
{
|
|
15750
|
+
emoticon: "\u{1F3B0}",
|
|
15751
|
+
gameType: "slot",
|
|
15752
|
+
toolName: "casino_spin",
|
|
15753
|
+
assetLabel: "SPIN",
|
|
15754
|
+
maxMultiplier: CASINO_CONFIG.slot.jackpot.multiplier,
|
|
15755
|
+
getMultiplier: getSlotMultiplier,
|
|
15756
|
+
getInterpretation: getSlotInterpretation,
|
|
15757
|
+
maxValue: 64
|
|
15758
|
+
},
|
|
15759
|
+
params,
|
|
15760
|
+
context
|
|
15761
|
+
);
|
|
15691
15762
|
};
|
|
15692
15763
|
|
|
15693
15764
|
// src/agent/tools/casino/dice.ts
|
|
15694
15765
|
import { Type as Type107 } from "@sinclair/typebox";
|
|
15695
|
-
import { Api as Api54 } from "telegram";
|
|
15696
15766
|
var casinoDiceTool = {
|
|
15697
15767
|
name: "casino_dice",
|
|
15698
15768
|
description: `Execute a Teleton Casino dice roll with full security checks.
|
|
@@ -15711,7 +15781,7 @@ Same security as slot:
|
|
|
15711
15781
|
5. Sends \u{1F3B2} dice animation
|
|
15712
15782
|
6. AUTO-PAYOUT if player wins
|
|
15713
15783
|
|
|
15714
|
-
Tell the user: "Send X TON to
|
|
15784
|
+
Tell the user: "Send X TON to [casino_address] with memo: your_username"`,
|
|
15715
15785
|
parameters: Type107.Object({
|
|
15716
15786
|
chat_id: Type107.String({
|
|
15717
15787
|
description: "Telegram chat ID where to send the dice"
|
|
@@ -15731,197 +15801,20 @@ Tell the user: "Send X TON to EQxxx with memo: your_username"`,
|
|
|
15731
15801
|
})
|
|
15732
15802
|
};
|
|
15733
15803
|
var casinoDiceExecutor = async (params, context) => {
|
|
15734
|
-
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
const username = player_username?.replace(/^@/, "").toLowerCase().trim();
|
|
15738
|
-
if (!username || username.length === 0) {
|
|
15739
|
-
return {
|
|
15740
|
-
success: false,
|
|
15741
|
-
error: "\u274C You need a Telegram @username to play at Teleton Casino. Set up your username in Telegram settings and try again!"
|
|
15742
|
-
};
|
|
15743
|
-
}
|
|
15744
|
-
const rateCheck = checkRateLimit(oddsId, "casino_dice");
|
|
15745
|
-
if (!rateCheck.allowed) {
|
|
15746
|
-
return {
|
|
15747
|
-
success: false,
|
|
15748
|
-
error: rateCheck.message || "Too many attempts. Please wait."
|
|
15749
|
-
};
|
|
15750
|
-
}
|
|
15751
|
-
const casinoWallet = getWalletAddress();
|
|
15752
|
-
if (!casinoWallet) {
|
|
15753
|
-
return {
|
|
15754
|
-
success: false,
|
|
15755
|
-
error: "Casino wallet not initialized."
|
|
15756
|
-
};
|
|
15757
|
-
}
|
|
15758
|
-
const balanceInfo = await getWalletBalance(casinoWallet);
|
|
15759
|
-
if (!balanceInfo) {
|
|
15760
|
-
return {
|
|
15761
|
-
success: false,
|
|
15762
|
-
error: "Failed to check casino balance."
|
|
15763
|
-
};
|
|
15764
|
-
}
|
|
15765
|
-
const balance = parseFloat(balanceInfo.balance);
|
|
15766
|
-
if (balance < CASINO_CONFIG.minBankroll) {
|
|
15767
|
-
return {
|
|
15768
|
-
success: false,
|
|
15769
|
-
error: "\u{1F6A8} Teleton Casino is temporarily closed (insufficient bankroll)."
|
|
15770
|
-
};
|
|
15771
|
-
}
|
|
15772
|
-
const diceMaxMultiplier = CASINO_CONFIG.dice.jackpot.multiplier;
|
|
15773
|
-
const maxBetByPercent = balance * (CASINO_CONFIG.maxBetPercent / 100);
|
|
15774
|
-
const maxBetByCoverage = balance / diceMaxMultiplier;
|
|
15775
|
-
const maxBet = Math.min(maxBetByPercent, maxBetByCoverage);
|
|
15776
|
-
if (bet_amount > maxBet) {
|
|
15777
|
-
return {
|
|
15778
|
-
success: false,
|
|
15779
|
-
error: `\u274C Bet too high. Maximum bet: ${maxBet.toFixed(2)} TON`
|
|
15780
|
-
};
|
|
15781
|
-
}
|
|
15782
|
-
if (bet_amount < CASINO_CONFIG.minBet) {
|
|
15783
|
-
return {
|
|
15784
|
-
success: false,
|
|
15785
|
-
error: `\u274C Minimum bet is ${CASINO_CONFIG.minBet} TON`
|
|
15786
|
-
};
|
|
15787
|
-
}
|
|
15788
|
-
const cooldownCheck = checkCooldown(context.db, oddsId);
|
|
15789
|
-
if (!cooldownCheck.allowed) {
|
|
15790
|
-
return {
|
|
15791
|
-
success: false,
|
|
15792
|
-
error: cooldownCheck.message || "Please wait before rolling again."
|
|
15793
|
-
};
|
|
15794
|
-
}
|
|
15795
|
-
const requestTime = Date.now();
|
|
15796
|
-
const paymentVerification = await verifyPayment(context.db, {
|
|
15797
|
-
botWalletAddress: casinoWallet,
|
|
15798
|
-
betAmount: bet_amount,
|
|
15799
|
-
requestTime: requestTime - CASINO_CONFIG.paymentWindowMinutes * 60 * 1e3,
|
|
15804
|
+
return executeGame(
|
|
15805
|
+
{
|
|
15806
|
+
emoticon: "\u{1F3B2}",
|
|
15800
15807
|
gameType: "dice",
|
|
15801
|
-
|
|
15802
|
-
|
|
15803
|
-
|
|
15804
|
-
|
|
15805
|
-
|
|
15806
|
-
|
|
15807
|
-
|
|
15808
|
-
|
|
15809
|
-
|
|
15810
|
-
|
|
15811
|
-
const gramJsClient = context.bridge.getClient().getClient();
|
|
15812
|
-
const diceResult = await gramJsClient.invoke(
|
|
15813
|
-
new Api54.messages.SendMedia({
|
|
15814
|
-
peer: chat_id,
|
|
15815
|
-
media: new Api54.InputMediaDice({ emoticon: "\u{1F3B2}" }),
|
|
15816
|
-
message: "",
|
|
15817
|
-
randomId: BigInt(Math.floor(Math.random() * 1e16)),
|
|
15818
|
-
replyTo: reply_to ? new Api54.InputReplyToMessage({ replyToMsgId: reply_to }) : void 0
|
|
15819
|
-
})
|
|
15820
|
-
);
|
|
15821
|
-
let diceValue;
|
|
15822
|
-
let messageId;
|
|
15823
|
-
if (diceResult instanceof Api54.Updates || diceResult instanceof Api54.UpdatesCombined) {
|
|
15824
|
-
for (const update of diceResult.updates) {
|
|
15825
|
-
if (update instanceof Api54.UpdateNewMessage || update instanceof Api54.UpdateNewChannelMessage) {
|
|
15826
|
-
const msg = update.message;
|
|
15827
|
-
if (msg instanceof Api54.Message && msg.media instanceof Api54.MessageMediaDice) {
|
|
15828
|
-
diceValue = msg.media.value;
|
|
15829
|
-
messageId = msg.id;
|
|
15830
|
-
break;
|
|
15831
|
-
}
|
|
15832
|
-
}
|
|
15833
|
-
}
|
|
15834
|
-
}
|
|
15835
|
-
if (diceValue === void 0) {
|
|
15836
|
-
return {
|
|
15837
|
-
success: false,
|
|
15838
|
-
error: "Failed to get dice result from Telegram."
|
|
15839
|
-
};
|
|
15840
|
-
}
|
|
15841
|
-
const houseEdge = processBetForJackpot(context.db, bet_amount);
|
|
15842
|
-
context.db.prepare(
|
|
15843
|
-
`INSERT INTO casino_users (telegram_id, wallet_address, total_bets, total_wagered, last_bet_at)
|
|
15844
|
-
VALUES (?, ?, 1, ?, unixepoch())
|
|
15845
|
-
ON CONFLICT(telegram_id) DO UPDATE SET
|
|
15846
|
-
wallet_address = excluded.wallet_address,
|
|
15847
|
-
total_bets = total_bets + 1,
|
|
15848
|
-
total_wagered = total_wagered + ?,
|
|
15849
|
-
last_bet_at = unixepoch()`
|
|
15850
|
-
).run(oddsId, playerWallet, bet_amount, bet_amount);
|
|
15851
|
-
const journalEntry = context.db.prepare(
|
|
15852
|
-
`INSERT INTO journal (
|
|
15853
|
-
type, action, asset_from, asset_to, amount_from,
|
|
15854
|
-
platform, reasoning, outcome, tx_hash, tool_used,
|
|
15855
|
-
chat_id, user_id, timestamp
|
|
15856
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, unixepoch())`
|
|
15857
|
-
).run(
|
|
15858
|
-
"trade",
|
|
15859
|
-
"casino_dice",
|
|
15860
|
-
"TON",
|
|
15861
|
-
"DICE",
|
|
15862
|
-
bet_amount,
|
|
15863
|
-
"telegram_casino",
|
|
15864
|
-
`Dice roll result: ${diceValue}/6`,
|
|
15865
|
-
"pending",
|
|
15866
|
-
paymentVerification.txHash,
|
|
15867
|
-
"casino_dice",
|
|
15868
|
-
chat_id,
|
|
15869
|
-
oddsId
|
|
15870
|
-
);
|
|
15871
|
-
const journalId = journalEntry.lastInsertRowid;
|
|
15872
|
-
const multiplier = getDiceMultiplier(diceValue);
|
|
15873
|
-
const won = multiplier > 0;
|
|
15874
|
-
const payoutAmount = won ? bet_amount * multiplier : 0;
|
|
15875
|
-
const jackpot = getJackpot(context.db);
|
|
15876
|
-
let payoutSent = false;
|
|
15877
|
-
let payoutTxHash;
|
|
15878
|
-
if (won && payoutAmount > 0) {
|
|
15879
|
-
const winMessage = getWinMessage(multiplier, payoutAmount);
|
|
15880
|
-
const payoutResult = await sendPayout(playerWallet, payoutAmount, winMessage);
|
|
15881
|
-
if (payoutResult.success) {
|
|
15882
|
-
payoutSent = true;
|
|
15883
|
-
payoutTxHash = payoutResult.txHash;
|
|
15884
|
-
context.db.prepare(
|
|
15885
|
-
`UPDATE journal SET outcome = 'loss', amount_to = ?, pnl_ton = ?, closed_at = unixepoch() WHERE id = ?`
|
|
15886
|
-
).run(payoutAmount, -(payoutAmount - bet_amount), journalId);
|
|
15887
|
-
context.db.prepare(
|
|
15888
|
-
`UPDATE casino_users SET total_wins = total_wins + 1, total_won = total_won + ? WHERE telegram_id = ?`
|
|
15889
|
-
).run(payoutAmount, oddsId);
|
|
15890
|
-
}
|
|
15891
|
-
} else {
|
|
15892
|
-
context.db.prepare(
|
|
15893
|
-
`UPDATE journal SET outcome = 'profit', amount_to = 0, pnl_ton = ?, closed_at = unixepoch() WHERE id = ?`
|
|
15894
|
-
).run(bet_amount, journalId);
|
|
15895
|
-
context.db.prepare(`UPDATE casino_users SET total_losses = total_losses + 1 WHERE telegram_id = ?`).run(oddsId);
|
|
15896
|
-
}
|
|
15897
|
-
const interpretation = getDiceInterpretation(diceValue);
|
|
15898
|
-
return {
|
|
15899
|
-
success: true,
|
|
15900
|
-
data: {
|
|
15901
|
-
dice_value: diceValue,
|
|
15902
|
-
won,
|
|
15903
|
-
multiplier,
|
|
15904
|
-
payout_amount: payoutAmount > 0 ? payoutAmount.toFixed(2) : "0",
|
|
15905
|
-
payout_sent: payoutSent,
|
|
15906
|
-
payout_tx_hash: payoutTxHash,
|
|
15907
|
-
bet_amount: bet_amount.toFixed(2),
|
|
15908
|
-
player_username: username,
|
|
15909
|
-
player_wallet: playerWallet,
|
|
15910
|
-
house_edge: houseEdge.toFixed(2),
|
|
15911
|
-
current_jackpot: jackpot.amount.toFixed(2),
|
|
15912
|
-
payment_tx_hash: paymentVerification.txHash,
|
|
15913
|
-
journal_id: journalId,
|
|
15914
|
-
message_id: messageId,
|
|
15915
|
-
interpretation
|
|
15916
|
-
}
|
|
15917
|
-
};
|
|
15918
|
-
} catch (error) {
|
|
15919
|
-
console.error("Error in casino_dice:", error);
|
|
15920
|
-
return {
|
|
15921
|
-
success: false,
|
|
15922
|
-
error: error instanceof Error ? error.message : String(error)
|
|
15923
|
-
};
|
|
15924
|
-
}
|
|
15808
|
+
toolName: "casino_dice",
|
|
15809
|
+
assetLabel: "DICE",
|
|
15810
|
+
maxMultiplier: CASINO_CONFIG.dice.jackpot.multiplier,
|
|
15811
|
+
getMultiplier: getDiceMultiplier,
|
|
15812
|
+
getInterpretation: getDiceInterpretation,
|
|
15813
|
+
maxValue: 6
|
|
15814
|
+
},
|
|
15815
|
+
params,
|
|
15816
|
+
context
|
|
15817
|
+
);
|
|
15925
15818
|
};
|
|
15926
15819
|
|
|
15927
15820
|
// src/agent/tools/casino/payout.ts
|
|
@@ -16143,6 +16036,12 @@ Shows:
|
|
|
16143
16036
|
var casinoLeaderboardExecutor = async (params, context) => {
|
|
16144
16037
|
try {
|
|
16145
16038
|
const { limit = 10, type = "winners" } = params;
|
|
16039
|
+
const ORDER_BY = {
|
|
16040
|
+
winners: "total_pnl DESC",
|
|
16041
|
+
losers: "total_pnl ASC",
|
|
16042
|
+
wagered: "cu.total_wagered DESC"
|
|
16043
|
+
};
|
|
16044
|
+
const orderBy = ORDER_BY[type] ?? ORDER_BY.winners;
|
|
16146
16045
|
const query = `
|
|
16147
16046
|
SELECT
|
|
16148
16047
|
cu.telegram_id,
|
|
@@ -16157,7 +16056,7 @@ var casinoLeaderboardExecutor = async (params, context) => {
|
|
|
16157
16056
|
LEFT JOIN journal j ON j.user_id = cu.telegram_id AND j.type = 'trade' AND j.action = 'casino_spin'
|
|
16158
16057
|
WHERE cu.total_bets > 0
|
|
16159
16058
|
GROUP BY cu.telegram_id
|
|
16160
|
-
ORDER BY ${
|
|
16059
|
+
ORDER BY ${orderBy}
|
|
16161
16060
|
LIMIT ?
|
|
16162
16061
|
`;
|
|
16163
16062
|
const leaderboard = context.db.prepare(query).all(limit);
|
|
@@ -16795,11 +16694,11 @@ To confirm, type: @${botUsername} ${dealId}` : proposalText;
|
|
|
16795
16694
|
};
|
|
16796
16695
|
async function sendInlineBotResult(bridge, chatId, botUsername, dealId) {
|
|
16797
16696
|
const gramJsClient = bridge.getClient().getClient();
|
|
16798
|
-
const
|
|
16697
|
+
const Api58 = (await import("telegram")).Api;
|
|
16799
16698
|
const bot = await gramJsClient.getInputEntity(botUsername);
|
|
16800
16699
|
const peer = await gramJsClient.getInputEntity(chatId.startsWith("-") ? Number(chatId) : chatId);
|
|
16801
16700
|
const results = await gramJsClient.invoke(
|
|
16802
|
-
new
|
|
16701
|
+
new Api58.messages.GetInlineBotResults({
|
|
16803
16702
|
bot,
|
|
16804
16703
|
peer,
|
|
16805
16704
|
query: dealId,
|
|
@@ -16813,7 +16712,7 @@ async function sendInlineBotResult(bridge, chatId, botUsername, dealId) {
|
|
|
16813
16712
|
const dealResult = results.results.find((r) => r.id === dealId);
|
|
16814
16713
|
const resultToSend = dealResult || results.results[0];
|
|
16815
16714
|
await gramJsClient.invoke(
|
|
16816
|
-
new
|
|
16715
|
+
new Api58.messages.SendInlineBotResult({
|
|
16817
16716
|
peer,
|
|
16818
16717
|
queryId: results.queryId,
|
|
16819
16718
|
id: resultToSend.id,
|
|
@@ -16840,7 +16739,7 @@ var GiftDetector = class {
|
|
|
16840
16739
|
const result = await telegramGetMyGiftsExecutor(
|
|
16841
16740
|
{
|
|
16842
16741
|
userId: userId.toString(),
|
|
16843
|
-
limit:
|
|
16742
|
+
limit: DEFAULT_GIFTS_QUERY_LIMIT
|
|
16844
16743
|
},
|
|
16845
16744
|
context
|
|
16846
16745
|
);
|
|
@@ -17024,15 +16923,15 @@ Thank you for trading! \u{1F389}`
|
|
|
17024
16923
|
`\u{1F381} [Deal] Sending gift ${deal.agent_gives_gift_slug} (msgId: ${deal.agent_gives_gift_id}) to user ${deal.user_telegram_id}...`
|
|
17025
16924
|
);
|
|
17026
16925
|
const gramJsClient = bridge.getClient().getClient();
|
|
17027
|
-
const
|
|
16926
|
+
const Api58 = (await import("telegram")).Api;
|
|
17028
16927
|
try {
|
|
17029
16928
|
const toUser = await gramJsClient.getInputEntity(deal.user_telegram_id);
|
|
17030
|
-
const stargiftInput = new
|
|
16929
|
+
const stargiftInput = new Api58.InputSavedStarGiftUser({
|
|
17031
16930
|
msgId: parseInt(deal.agent_gives_gift_id, 10)
|
|
17032
16931
|
});
|
|
17033
16932
|
try {
|
|
17034
16933
|
await gramJsClient.invoke(
|
|
17035
|
-
new
|
|
16934
|
+
new Api58.payments.TransferStarGift({
|
|
17036
16935
|
stargift: stargiftInput,
|
|
17037
16936
|
toId: toUser
|
|
17038
16937
|
})
|
|
@@ -17040,17 +16939,17 @@ Thank you for trading! \u{1F389}`
|
|
|
17040
16939
|
} catch (freeTransferError) {
|
|
17041
16940
|
if (freeTransferError?.errorMessage === "PAYMENT_REQUIRED") {
|
|
17042
16941
|
console.log("Transfer requires payment, using payment flow...");
|
|
17043
|
-
const invoice = new
|
|
16942
|
+
const invoice = new Api58.InputInvoiceStarGiftTransfer({
|
|
17044
16943
|
stargift: stargiftInput,
|
|
17045
16944
|
toId: toUser
|
|
17046
16945
|
});
|
|
17047
16946
|
const form = await gramJsClient.invoke(
|
|
17048
|
-
new
|
|
16947
|
+
new Api58.payments.GetPaymentForm({
|
|
17049
16948
|
invoice
|
|
17050
16949
|
})
|
|
17051
16950
|
);
|
|
17052
16951
|
await gramJsClient.invoke(
|
|
17053
|
-
new
|
|
16952
|
+
new Api58.payments.SendStarsForm({
|
|
17054
16953
|
formId: form.formId,
|
|
17055
16954
|
invoice
|
|
17056
16955
|
})
|
|
@@ -17607,8 +17506,138 @@ No payment has been processed. You can propose a new deal if you'd like.`
|
|
|
17607
17506
|
}
|
|
17608
17507
|
};
|
|
17609
17508
|
|
|
17509
|
+
// src/agent/tools/register-all.ts
|
|
17510
|
+
function registerAllTools(registry, config) {
|
|
17511
|
+
registry.register(telegramSendMessageTool, telegramSendMessageExecutor);
|
|
17512
|
+
registry.register(telegramQuoteReplyTool, telegramQuoteReplyExecutor);
|
|
17513
|
+
registry.register(telegramGetRepliesTool, telegramGetRepliesExecutor);
|
|
17514
|
+
registry.register(telegramEditMessageTool, telegramEditMessageExecutor);
|
|
17515
|
+
registry.register(telegramScheduleMessageTool, telegramScheduleMessageExecutor);
|
|
17516
|
+
registry.register(telegramCreateScheduledTaskTool, telegramCreateScheduledTaskExecutor);
|
|
17517
|
+
registry.register(telegramSearchMessagesTool, telegramSearchMessagesExecutor);
|
|
17518
|
+
registry.register(telegramPinMessageTool, telegramPinMessageExecutor);
|
|
17519
|
+
registry.register(telegramUnpinMessageTool, telegramUnpinMessageExecutor);
|
|
17520
|
+
registry.register(telegramReactTool, telegramReactExecutor);
|
|
17521
|
+
registry.register(telegramSendDiceTool, telegramSendDiceExecutor);
|
|
17522
|
+
registry.register(telegramForwardMessageTool, telegramForwardMessageExecutor);
|
|
17523
|
+
registry.register(telegramSendPhotoTool, telegramSendPhotoExecutor);
|
|
17524
|
+
registry.register(telegramSendVoiceTool, telegramSendVoiceExecutor);
|
|
17525
|
+
registry.register(telegramSendStickerTool, telegramSendStickerExecutor);
|
|
17526
|
+
registry.register(telegramSendGifTool, telegramSendGifExecutor);
|
|
17527
|
+
registry.register(telegramCreatePollTool, telegramCreatePollExecutor);
|
|
17528
|
+
registry.register(telegramCreateQuizTool, telegramCreateQuizExecutor);
|
|
17529
|
+
registry.register(telegramReplyKeyboardTool, telegramReplyKeyboardExecutor);
|
|
17530
|
+
registry.register(telegramSearchStickersTool, telegramSearchStickersExecutor);
|
|
17531
|
+
registry.register(telegramGetMyStickersTool, telegramGetMyStickersExecutor);
|
|
17532
|
+
registry.register(telegramSearchGifsTool, telegramSearchGifsExecutor);
|
|
17533
|
+
registry.register(telegramAddStickerSetTool, telegramAddStickerSetExecutor);
|
|
17534
|
+
registry.register(telegramGetHistoryTool, telegramGetHistoryExecutor);
|
|
17535
|
+
registry.register(telegramGetDialogsTool, telegramGetDialogsExecutor);
|
|
17536
|
+
registry.register(telegramMarkAsReadTool, telegramMarkAsReadExecutor);
|
|
17537
|
+
registry.register(telegramGetChatInfoTool, telegramGetChatInfoExecutor);
|
|
17538
|
+
registry.register(telegramJoinChannelTool, telegramJoinChannelExecutor);
|
|
17539
|
+
registry.register(telegramLeaveChannelTool, telegramLeaveChannelExecutor);
|
|
17540
|
+
registry.register(telegramGetMeTool, telegramGetMeExecutor);
|
|
17541
|
+
registry.register(telegramGetParticipantsTool, telegramGetParticipantsExecutor);
|
|
17542
|
+
registry.register(telegramKickUserTool, telegramKickUserExecutor);
|
|
17543
|
+
registry.register(telegramBanUserTool, telegramBanUserExecutor);
|
|
17544
|
+
registry.register(telegramUnbanUserTool, telegramUnbanUserExecutor);
|
|
17545
|
+
registry.register(telegramCreateGroupTool, telegramCreateGroupExecutor);
|
|
17546
|
+
registry.register(telegramSetChatPhotoTool, telegramSetChatPhotoExecutor);
|
|
17547
|
+
registry.register(telegramBlockUserTool, telegramBlockUserExecutor);
|
|
17548
|
+
registry.register(telegramGetBlockedTool, telegramGetBlockedExecutor);
|
|
17549
|
+
registry.register(telegramGetCommonChatsTool, telegramGetCommonChatsExecutor);
|
|
17550
|
+
registry.register(telegramSendStoryTool, telegramSendStoryExecutor);
|
|
17551
|
+
registry.register(telegramGetFoldersTool, telegramGetFoldersExecutor);
|
|
17552
|
+
registry.register(telegramCreateFolderTool, telegramCreateFolderExecutor);
|
|
17553
|
+
registry.register(telegramAddChatToFolderTool, telegramAddChatToFolderExecutor);
|
|
17554
|
+
registry.register(telegramCreateChannelTool, telegramCreateChannelExecutor);
|
|
17555
|
+
registry.register(telegramUpdateProfileTool, telegramUpdateProfileExecutor);
|
|
17556
|
+
registry.register(telegramSetBioTool, telegramSetBioExecutor);
|
|
17557
|
+
registry.register(telegramSetUsernameTool, telegramSetUsernameExecutor);
|
|
17558
|
+
registry.register(telegramDeleteMessageTool, telegramDeleteMessageExecutor);
|
|
17559
|
+
registry.register(telegramDownloadMediaTool, telegramDownloadMediaExecutor);
|
|
17560
|
+
registry.register(visionAnalyzeTool, visionAnalyzeExecutor);
|
|
17561
|
+
registry.register(telegramGetStarsBalanceTool, telegramGetStarsBalanceExecutor);
|
|
17562
|
+
registry.register(telegramGetStarsTransactionsTool, telegramGetStarsTransactionsExecutor);
|
|
17563
|
+
registry.register(telegramGetAvailableGiftsTool, telegramGetAvailableGiftsExecutor);
|
|
17564
|
+
registry.register(telegramSendGiftTool, telegramSendGiftExecutor);
|
|
17565
|
+
registry.register(telegramGetMyGiftsTool, telegramGetMyGiftsExecutor);
|
|
17566
|
+
registry.register(telegramTransferCollectibleTool, telegramTransferCollectibleExecutor);
|
|
17567
|
+
registry.register(telegramSetCollectiblePriceTool, telegramSetCollectiblePriceExecutor);
|
|
17568
|
+
registry.register(telegramGetResaleGiftsTool, telegramGetResaleGiftsExecutor);
|
|
17569
|
+
registry.register(telegramBuyResaleGiftTool, telegramBuyResaleGiftExecutor);
|
|
17570
|
+
registry.register(telegramSetGiftStatusTool, telegramSetGiftStatusExecutor);
|
|
17571
|
+
registry.register(memoryWriteTool, memoryWriteExecutor);
|
|
17572
|
+
registry.register(memoryReadTool, memoryReadExecutor);
|
|
17573
|
+
registry.register(telegramGetUserInfoTool, telegramGetUserInfoExecutor);
|
|
17574
|
+
registry.register(telegramCheckUsernameTool, telegramCheckUsernameExecutor);
|
|
17575
|
+
registry.register(telegramEditChannelInfoTool, telegramEditChannelInfoExecutor);
|
|
17576
|
+
registry.register(telegramInviteToChannelTool, telegramInviteToChannelExecutor);
|
|
17577
|
+
registry.register(marketGetFloorTool, marketGetFloorExecutor);
|
|
17578
|
+
registry.register(marketSearchTool, marketSearchExecutor);
|
|
17579
|
+
registry.register(marketCheapestTool, marketCheapestExecutor);
|
|
17580
|
+
registry.register(marketPriceHistoryTool, marketPriceHistoryExecutor);
|
|
17581
|
+
registry.register(tonGetAddressTool, tonGetAddressExecutor);
|
|
17582
|
+
registry.register(tonGetBalanceTool, tonGetBalanceExecutor);
|
|
17583
|
+
registry.register(tonPriceTool, tonPriceExecutor);
|
|
17584
|
+
registry.register(tonSendTool, tonSendExecutor);
|
|
17585
|
+
registry.register(tonGetTransactionsTool, tonGetTransactionsExecutor);
|
|
17586
|
+
registry.register(tonMyTransactionsTool, tonMyTransactionsExecutor);
|
|
17587
|
+
registry.register(jettonBalancesTool, jettonBalancesExecutor);
|
|
17588
|
+
registry.register(jettonSwapTool, jettonSwapExecutor);
|
|
17589
|
+
registry.register(jettonSendTool, jettonSendExecutor);
|
|
17590
|
+
registry.register(jettonInfoTool, jettonInfoExecutor);
|
|
17591
|
+
registry.register(jettonPriceTool, jettonPriceExecutor);
|
|
17592
|
+
registry.register(jettonSearchTool, jettonSearchExecutor);
|
|
17593
|
+
registry.register(jettonQuoteTool, jettonQuoteExecutor);
|
|
17594
|
+
registry.register(jettonHoldersTool, jettonHoldersExecutor);
|
|
17595
|
+
registry.register(jettonHistoryTool, jettonHistoryExecutor);
|
|
17596
|
+
registry.register(jettonTrendingTool, jettonTrendingExecutor);
|
|
17597
|
+
registry.register(jettonPoolsTool, jettonPoolsExecutor);
|
|
17598
|
+
registry.register(dnsCheckTool, dnsCheckExecutor);
|
|
17599
|
+
registry.register(dnsAuctionsTool, dnsAuctionsExecutor);
|
|
17600
|
+
registry.register(dnsResolveTool, dnsResolveExecutor);
|
|
17601
|
+
registry.register(dnsStartAuctionTool, dnsStartAuctionExecutor);
|
|
17602
|
+
registry.register(dnsBidTool, dnsBidExecutor);
|
|
17603
|
+
registry.register(dnsLinkTool, dnsLinkExecutor);
|
|
17604
|
+
registry.register(dnsUnlinkTool, dnsUnlinkExecutor);
|
|
17605
|
+
registry.register(dedustQuoteTool, dedustQuoteExecutor);
|
|
17606
|
+
registry.register(dedustSwapTool, dedustSwapExecutor);
|
|
17607
|
+
registry.register(dedustPoolsTool, dedustPoolsExecutor);
|
|
17608
|
+
registry.register(dexQuoteTool, dexQuoteExecutor);
|
|
17609
|
+
registry.register(dexSwapTool, dexSwapExecutor);
|
|
17610
|
+
registry.register(journalLogTool, journalLogExecutor);
|
|
17611
|
+
registry.register(journalQueryTool, journalQueryExecutor);
|
|
17612
|
+
registry.register(journalUpdateTool, journalUpdateExecutor);
|
|
17613
|
+
registry.register(workspaceListTool, workspaceListExecutor);
|
|
17614
|
+
registry.register(workspaceReadTool, workspaceReadExecutor);
|
|
17615
|
+
registry.register(workspaceWriteTool, workspaceWriteExecutor);
|
|
17616
|
+
registry.register(workspaceDeleteTool, workspaceDeleteExecutor);
|
|
17617
|
+
registry.register(workspaceInfoTool, workspaceInfoExecutor);
|
|
17618
|
+
registry.register(workspaceRenameTool, workspaceRenameExecutor);
|
|
17619
|
+
if (config.casino.enabled) {
|
|
17620
|
+
registry.register(casinoBalanceTool, casinoBalanceExecutor);
|
|
17621
|
+
registry.register(casinoSpinTool, casinoSpinExecutor);
|
|
17622
|
+
registry.register(casinoDiceTool, casinoDiceExecutor);
|
|
17623
|
+
registry.register(casinoPayoutTool, casinoPayoutExecutor);
|
|
17624
|
+
registry.register(casinoLeaderboardTool, casinoLeaderboardExecutor);
|
|
17625
|
+
registry.register(casinoMyStatsTool, casinoMyStatsExecutor);
|
|
17626
|
+
registry.register(casinoJackpotInfoTool, casinoJackpotInfoExecutor);
|
|
17627
|
+
registry.register(casinoAwardJackpotTool, casinoAwardJackpotExecutor);
|
|
17628
|
+
}
|
|
17629
|
+
if (config.deals.enabled) {
|
|
17630
|
+
registry.register(dealProposeTool, dealProposeExecutor);
|
|
17631
|
+
registry.register(dealVerifyPaymentTool, dealVerifyPaymentExecutor);
|
|
17632
|
+
registry.register(dealStatusTool, dealStatusExecutor);
|
|
17633
|
+
registry.register(dealListTool, dealListExecutor);
|
|
17634
|
+
registry.register(dealCancelTool, dealCancelExecutor);
|
|
17635
|
+
}
|
|
17636
|
+
}
|
|
17637
|
+
|
|
17610
17638
|
// src/bot/index.ts
|
|
17611
17639
|
import { Bot } from "grammy";
|
|
17640
|
+
import { Api as Api57 } from "telegram";
|
|
17612
17641
|
|
|
17613
17642
|
// src/bot/types.ts
|
|
17614
17643
|
function decodeCallback(raw) {
|
|
@@ -17658,7 +17687,7 @@ function getDeal(db, dealId) {
|
|
|
17658
17687
|
};
|
|
17659
17688
|
}
|
|
17660
17689
|
function acceptDeal(db, dealId) {
|
|
17661
|
-
const newExpiry = Math.floor(Date.now() / 1e3) +
|
|
17690
|
+
const newExpiry = Math.floor(Date.now() / 1e3) + DEAL_VERIFICATION_WINDOW_SECONDS;
|
|
17662
17691
|
db.prepare(`UPDATE deals SET status = 'accepted', expires_at = ? WHERE id = ?`).run(
|
|
17663
17692
|
newExpiry,
|
|
17664
17693
|
dealId
|
|
@@ -17745,10 +17774,10 @@ function updateUserStats(db, userId, username, deal, completed) {
|
|
|
17745
17774
|
}
|
|
17746
17775
|
|
|
17747
17776
|
// src/bot/services/message-builder.ts
|
|
17748
|
-
import { InlineKeyboard } from "grammy";
|
|
17749
17777
|
function esc(text) {
|
|
17750
17778
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
17751
17779
|
}
|
|
17780
|
+
var TIMER_EMOJI = `<tg-emoji emoji-id="5451646226975955576">\u23F3</tg-emoji>`;
|
|
17752
17781
|
function formatAsset2(type, tonAmount, giftSlug) {
|
|
17753
17782
|
if (type === "ton" && tonAmount) {
|
|
17754
17783
|
return `<b>${tonAmount} TON</b>`;
|
|
@@ -17779,14 +17808,19 @@ function buildProposalMessage(deal) {
|
|
|
17779
17808
|
);
|
|
17780
17809
|
const remaining = getRemainingTime(deal.expiresAt);
|
|
17781
17810
|
const user = deal.username ? `@${esc(deal.username)}` : `${deal.userId}`;
|
|
17782
|
-
const text = `\u{
|
|
17811
|
+
const text = `\u{1F45B} <b>Deal</b> #${esc(deal.dealId)}
|
|
17783
17812
|
|
|
17784
17813
|
\u{1F464} ${user}
|
|
17785
17814
|
\u{1F4E4} Sends: ${userGives}
|
|
17786
17815
|
\u{1F4E5} Receives: ${agentGives}
|
|
17787
|
-
|
|
17788
|
-
const
|
|
17789
|
-
|
|
17816
|
+
${TIMER_EMOJI} Expires in ${remaining}`;
|
|
17817
|
+
const buttons = [
|
|
17818
|
+
[
|
|
17819
|
+
{ text: "\u2705 Accept", callbackData: `accept:${deal.dealId}`, style: "success" },
|
|
17820
|
+
{ text: "\u274C Decline", callbackData: `decline:${deal.dealId}`, style: "danger" }
|
|
17821
|
+
]
|
|
17822
|
+
];
|
|
17823
|
+
return { text, buttons };
|
|
17790
17824
|
}
|
|
17791
17825
|
function buildAcceptedMessage(deal, agentWallet) {
|
|
17792
17826
|
const userGives = formatAsset2(
|
|
@@ -17800,38 +17834,48 @@ function buildAcceptedMessage(deal, agentWallet) {
|
|
|
17800
17834
|
deal.agentGivesGiftSlug
|
|
17801
17835
|
);
|
|
17802
17836
|
let instructions;
|
|
17803
|
-
let
|
|
17837
|
+
let buttons;
|
|
17804
17838
|
if (deal.userGivesType === "ton") {
|
|
17805
17839
|
instructions = `
|
|
17806
17840
|
\u{1F4B0} <b>Send ${deal.userGivesTonAmount} TON</b>
|
|
17807
17841
|
\u{1F4CD} <code>${esc(agentWallet)}</code>
|
|
17808
17842
|
\u{1F4DD} Memo: <code>${esc(deal.dealId)}</code>
|
|
17809
17843
|
|
|
17810
|
-
\
|
|
17811
|
-
|
|
17844
|
+
\u203C\uFE0F <b>Memo is required!</b>`;
|
|
17845
|
+
buttons = [
|
|
17846
|
+
[
|
|
17847
|
+
{ text: "Copy Address", callbackData: `copy_addr:${deal.dealId}`, copyText: agentWallet },
|
|
17848
|
+
{ text: "Copy Memo", callbackData: `copy_memo:${deal.dealId}`, copyText: deal.dealId }
|
|
17849
|
+
],
|
|
17850
|
+
[{ text: "\u2705 I've sent the payment", callbackData: `sent:${deal.dealId}`, style: "primary" }]
|
|
17851
|
+
];
|
|
17812
17852
|
} else {
|
|
17813
17853
|
instructions = `
|
|
17814
17854
|
\u{1F381} Send your ${formatAsset2("gift", void 0, deal.userGivesGiftSlug)} to the agent`;
|
|
17815
|
-
|
|
17855
|
+
buttons = [
|
|
17856
|
+
[{ text: "\u2705 I've sent the gift", callbackData: `sent:${deal.dealId}`, style: "success" }]
|
|
17857
|
+
];
|
|
17816
17858
|
}
|
|
17817
17859
|
const remaining = getRemainingTime(deal.expiresAt);
|
|
17818
17860
|
const text = `\u2705 <b>Deal Accepted</b> #${esc(deal.dealId)}
|
|
17819
17861
|
|
|
17820
17862
|
\u{1F4E4} You send: ${userGives}
|
|
17821
17863
|
\u{1F4E5} You receive: ${agentGives}
|
|
17822
|
-
|
|
17864
|
+
${TIMER_EMOJI} ${remaining} to complete
|
|
17823
17865
|
${instructions}`;
|
|
17824
|
-
return { text,
|
|
17866
|
+
return { text, buttons };
|
|
17825
17867
|
}
|
|
17826
17868
|
function buildVerifyingMessage(deal) {
|
|
17827
17869
|
const itemType = deal.userGivesType === "ton" ? "payment" : "gift";
|
|
17828
|
-
const text =
|
|
17870
|
+
const text = `${TIMER_EMOJI} <b>Verifying ${itemType}...</b>
|
|
17829
17871
|
|
|
17830
17872
|
Deal #${esc(deal.dealId)}
|
|
17831
17873
|
|
|
17832
17874
|
This usually takes 10-30 seconds.`;
|
|
17833
|
-
const
|
|
17834
|
-
|
|
17875
|
+
const buttons = [
|
|
17876
|
+
[{ text: "\u{1F504} Refresh", callbackData: `refresh:${deal.dealId}`, style: "primary" }]
|
|
17877
|
+
];
|
|
17878
|
+
return { text, buttons };
|
|
17835
17879
|
}
|
|
17836
17880
|
function buildSendingMessage(deal) {
|
|
17837
17881
|
const agentGives = formatAsset2(
|
|
@@ -17843,8 +17887,7 @@ function buildSendingMessage(deal) {
|
|
|
17843
17887
|
|
|
17844
17888
|
Deal #${esc(deal.dealId)}
|
|
17845
17889
|
Sending ${agentGives}...`;
|
|
17846
|
-
|
|
17847
|
-
return { text, keyboard };
|
|
17890
|
+
return { text, buttons: [] };
|
|
17848
17891
|
}
|
|
17849
17892
|
function buildCompletedMessage(deal) {
|
|
17850
17893
|
const userGives = formatAsset2(
|
|
@@ -17859,31 +17902,27 @@ function buildCompletedMessage(deal) {
|
|
|
17859
17902
|
);
|
|
17860
17903
|
const user = deal.username ? `@${esc(deal.username)}` : `${deal.userId}`;
|
|
17861
17904
|
const duration = deal.completedAt ? Math.floor(deal.completedAt - deal.createdAt) : Math.floor(Date.now() / 1e3 - deal.createdAt);
|
|
17862
|
-
const text = `\u{
|
|
17905
|
+
const text = `\u{1F91D} <b>Deal Complete</b> #${esc(deal.dealId)}
|
|
17863
17906
|
|
|
17864
17907
|
\u{1F464} ${user}
|
|
17865
17908
|
\u{1F4E4} Sent: ${userGives} \u2713
|
|
17866
17909
|
\u{1F4E5} Received: ${agentGives} \u2713
|
|
17867
|
-
|
|
17868
|
-
|
|
17869
|
-
return { text, keyboard };
|
|
17910
|
+
${TIMER_EMOJI} ${duration}s`;
|
|
17911
|
+
return { text, buttons: [] };
|
|
17870
17912
|
}
|
|
17871
17913
|
function buildDeclinedMessage(deal) {
|
|
17872
17914
|
const text = `\u274C <b>Deal Declined</b> #${esc(deal.dealId)}`;
|
|
17873
|
-
|
|
17874
|
-
return { text, keyboard };
|
|
17915
|
+
return { text, buttons: [] };
|
|
17875
17916
|
}
|
|
17876
17917
|
function buildExpiredMessage(deal) {
|
|
17877
|
-
const text =
|
|
17878
|
-
|
|
17879
|
-
return { text, keyboard };
|
|
17918
|
+
const text = `${TIMER_EMOJI} <b>Deal Expired</b> #${esc(deal.dealId)}`;
|
|
17919
|
+
return { text, buttons: [] };
|
|
17880
17920
|
}
|
|
17881
17921
|
function buildFailedMessage(deal, error) {
|
|
17882
17922
|
const text = `\u274C <b>Deal Failed</b> #${esc(deal.dealId)}
|
|
17883
17923
|
|
|
17884
17924
|
${esc(error || "Unknown error")}`;
|
|
17885
|
-
|
|
17886
|
-
return { text, keyboard };
|
|
17925
|
+
return { text, buttons: [] };
|
|
17887
17926
|
}
|
|
17888
17927
|
function buildNotFoundMessage(dealId) {
|
|
17889
17928
|
return `\u274C Deal #${esc(dealId)} not found.`;
|
|
@@ -17911,6 +17950,255 @@ function buildMessageForState(deal, agentWallet) {
|
|
|
17911
17950
|
}
|
|
17912
17951
|
}
|
|
17913
17952
|
|
|
17953
|
+
// src/bot/services/styled-keyboard.ts
|
|
17954
|
+
import { Api as Api54 } from "telegram";
|
|
17955
|
+
import { InlineKeyboard } from "grammy";
|
|
17956
|
+
function toTLMarkup(buttons) {
|
|
17957
|
+
const ApiAny = Api54;
|
|
17958
|
+
return new Api54.ReplyInlineMarkup({
|
|
17959
|
+
rows: buttons.filter((row) => row.length > 0).map(
|
|
17960
|
+
(row) => new Api54.KeyboardButtonRow({
|
|
17961
|
+
buttons: row.map((btn) => {
|
|
17962
|
+
if (btn.copyText) {
|
|
17963
|
+
return new ApiAny.KeyboardButtonCopy({
|
|
17964
|
+
text: btn.text,
|
|
17965
|
+
copyText: btn.copyText
|
|
17966
|
+
});
|
|
17967
|
+
}
|
|
17968
|
+
const style = btn.style ? new ApiAny.KeyboardButtonStyle({
|
|
17969
|
+
bgSuccess: btn.style === "success",
|
|
17970
|
+
bgDanger: btn.style === "danger",
|
|
17971
|
+
bgPrimary: btn.style === "primary"
|
|
17972
|
+
}) : void 0;
|
|
17973
|
+
return new ApiAny.KeyboardButtonCallback({
|
|
17974
|
+
text: btn.text,
|
|
17975
|
+
data: Buffer.from(btn.callbackData),
|
|
17976
|
+
style
|
|
17977
|
+
});
|
|
17978
|
+
})
|
|
17979
|
+
})
|
|
17980
|
+
)
|
|
17981
|
+
});
|
|
17982
|
+
}
|
|
17983
|
+
function toGrammyKeyboard(buttons) {
|
|
17984
|
+
const kb = new InlineKeyboard();
|
|
17985
|
+
for (let i = 0; i < buttons.length; i++) {
|
|
17986
|
+
if (i > 0) kb.row();
|
|
17987
|
+
for (const btn of buttons[i]) {
|
|
17988
|
+
if (btn.copyText) {
|
|
17989
|
+
kb.copyText(btn.text, btn.copyText);
|
|
17990
|
+
} else {
|
|
17991
|
+
kb.text(btn.text, btn.callbackData);
|
|
17992
|
+
}
|
|
17993
|
+
}
|
|
17994
|
+
}
|
|
17995
|
+
return kb;
|
|
17996
|
+
}
|
|
17997
|
+
function hasStyledButtons(buttons) {
|
|
17998
|
+
return buttons.some((row) => row.length > 0);
|
|
17999
|
+
}
|
|
18000
|
+
|
|
18001
|
+
// src/bot/services/html-parser.ts
|
|
18002
|
+
import { Api as Api55 } from "telegram";
|
|
18003
|
+
import bigInt5 from "big-integer";
|
|
18004
|
+
function parseHtml(html) {
|
|
18005
|
+
const entities = [];
|
|
18006
|
+
let text = "";
|
|
18007
|
+
let pos = 0;
|
|
18008
|
+
const stack = [];
|
|
18009
|
+
while (pos < html.length) {
|
|
18010
|
+
if (html[pos] === "<") {
|
|
18011
|
+
const endBracket = html.indexOf(">", pos);
|
|
18012
|
+
if (endBracket === -1) {
|
|
18013
|
+
text += "<";
|
|
18014
|
+
pos++;
|
|
18015
|
+
continue;
|
|
18016
|
+
}
|
|
18017
|
+
const tagStr = html.substring(pos + 1, endBracket);
|
|
18018
|
+
if (tagStr.startsWith("/")) {
|
|
18019
|
+
const tagName = tagStr.substring(1).toLowerCase().trim();
|
|
18020
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
18021
|
+
if (stack[i].tag === tagName) {
|
|
18022
|
+
const open = stack[i];
|
|
18023
|
+
const length = text.length - open.offset;
|
|
18024
|
+
if (length > 0) {
|
|
18025
|
+
switch (tagName) {
|
|
18026
|
+
case "b":
|
|
18027
|
+
case "strong":
|
|
18028
|
+
entities.push(new Api55.MessageEntityBold({ offset: open.offset, length }));
|
|
18029
|
+
break;
|
|
18030
|
+
case "i":
|
|
18031
|
+
case "em":
|
|
18032
|
+
entities.push(new Api55.MessageEntityItalic({ offset: open.offset, length }));
|
|
18033
|
+
break;
|
|
18034
|
+
case "code":
|
|
18035
|
+
entities.push(new Api55.MessageEntityCode({ offset: open.offset, length }));
|
|
18036
|
+
break;
|
|
18037
|
+
case "a":
|
|
18038
|
+
if (open.url) {
|
|
18039
|
+
entities.push(
|
|
18040
|
+
new Api55.MessageEntityTextUrl({
|
|
18041
|
+
offset: open.offset,
|
|
18042
|
+
length,
|
|
18043
|
+
url: open.url
|
|
18044
|
+
})
|
|
18045
|
+
);
|
|
18046
|
+
}
|
|
18047
|
+
break;
|
|
18048
|
+
case "tg-emoji":
|
|
18049
|
+
if (open.emojiId) {
|
|
18050
|
+
entities.push(
|
|
18051
|
+
new Api55.MessageEntityCustomEmoji({
|
|
18052
|
+
offset: open.offset,
|
|
18053
|
+
length,
|
|
18054
|
+
documentId: bigInt5(open.emojiId)
|
|
18055
|
+
})
|
|
18056
|
+
);
|
|
18057
|
+
}
|
|
18058
|
+
break;
|
|
18059
|
+
}
|
|
18060
|
+
}
|
|
18061
|
+
stack.splice(i, 1);
|
|
18062
|
+
break;
|
|
18063
|
+
}
|
|
18064
|
+
}
|
|
18065
|
+
} else {
|
|
18066
|
+
const spaceIdx = tagStr.indexOf(" ");
|
|
18067
|
+
const tagName = (spaceIdx >= 0 ? tagStr.substring(0, spaceIdx) : tagStr).toLowerCase();
|
|
18068
|
+
const attrs = spaceIdx >= 0 ? tagStr.substring(spaceIdx) : "";
|
|
18069
|
+
let url;
|
|
18070
|
+
let emojiId;
|
|
18071
|
+
if (tagName === "a") {
|
|
18072
|
+
const hrefMatch = attrs.match(/href="([^"]+)"/);
|
|
18073
|
+
if (hrefMatch) url = unescapeHtml(hrefMatch[1]);
|
|
18074
|
+
} else if (tagName === "tg-emoji") {
|
|
18075
|
+
const eidMatch = attrs.match(/emoji-id="([^"]+)"/);
|
|
18076
|
+
if (eidMatch) emojiId = eidMatch[1];
|
|
18077
|
+
}
|
|
18078
|
+
stack.push({ tag: tagName, offset: text.length, url, emojiId });
|
|
18079
|
+
}
|
|
18080
|
+
pos = endBracket + 1;
|
|
18081
|
+
} else if (html.substring(pos, pos + 5) === "&") {
|
|
18082
|
+
text += "&";
|
|
18083
|
+
pos += 5;
|
|
18084
|
+
} else if (html.substring(pos, pos + 4) === "<") {
|
|
18085
|
+
text += "<";
|
|
18086
|
+
pos += 4;
|
|
18087
|
+
} else if (html.substring(pos, pos + 4) === ">") {
|
|
18088
|
+
text += ">";
|
|
18089
|
+
pos += 4;
|
|
18090
|
+
} else if (html.substring(pos, pos + 6) === """) {
|
|
18091
|
+
text += '"';
|
|
18092
|
+
pos += 6;
|
|
18093
|
+
} else {
|
|
18094
|
+
text += html[pos];
|
|
18095
|
+
pos++;
|
|
18096
|
+
}
|
|
18097
|
+
}
|
|
18098
|
+
return { text, entities };
|
|
18099
|
+
}
|
|
18100
|
+
function stripCustomEmoji(html) {
|
|
18101
|
+
return html.replace(/<tg-emoji[^>]*>([^<]*)<\/tg-emoji>/g, "$1");
|
|
18102
|
+
}
|
|
18103
|
+
function unescapeHtml(text) {
|
|
18104
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"');
|
|
18105
|
+
}
|
|
18106
|
+
|
|
18107
|
+
// src/bot/gramjs-bot.ts
|
|
18108
|
+
import { TelegramClient as TelegramClient2, Api as Api56 } from "telegram";
|
|
18109
|
+
import { StringSession as StringSession2 } from "telegram/sessions/index.js";
|
|
18110
|
+
import { Logger as Logger2, LogLevel as LogLevel2 } from "telegram/extensions/Logger.js";
|
|
18111
|
+
import bigInt6 from "big-integer";
|
|
18112
|
+
function decodeInlineMessageId(encoded) {
|
|
18113
|
+
const buf = Buffer.from(encoded, "base64url");
|
|
18114
|
+
if (buf.length === 20) {
|
|
18115
|
+
return new Api56.InputBotInlineMessageID({
|
|
18116
|
+
dcId: buf.readInt32LE(0),
|
|
18117
|
+
id: bigInt6(buf.readBigInt64LE(4).toString()),
|
|
18118
|
+
accessHash: bigInt6(buf.readBigInt64LE(12).toString())
|
|
18119
|
+
});
|
|
18120
|
+
} else if (buf.length === 24) {
|
|
18121
|
+
return new Api56.InputBotInlineMessageID64({
|
|
18122
|
+
dcId: buf.readInt32LE(0),
|
|
18123
|
+
ownerId: bigInt6(buf.readBigInt64LE(4).toString()),
|
|
18124
|
+
id: buf.readInt32LE(12),
|
|
18125
|
+
accessHash: bigInt6(buf.readBigInt64LE(16).toString())
|
|
18126
|
+
});
|
|
18127
|
+
}
|
|
18128
|
+
throw new Error(`Unknown inline_message_id format (${buf.length} bytes)`);
|
|
18129
|
+
}
|
|
18130
|
+
var GramJSBotClient = class {
|
|
18131
|
+
client;
|
|
18132
|
+
connected = false;
|
|
18133
|
+
constructor(apiId, apiHash) {
|
|
18134
|
+
const logger = new Logger2(LogLevel2.NONE);
|
|
18135
|
+
this.client = new TelegramClient2(new StringSession2(""), apiId, apiHash, {
|
|
18136
|
+
connectionRetries: 3,
|
|
18137
|
+
retryDelay: 1e3,
|
|
18138
|
+
autoReconnect: true,
|
|
18139
|
+
baseLogger: logger
|
|
18140
|
+
});
|
|
18141
|
+
}
|
|
18142
|
+
/**
|
|
18143
|
+
* Connect and authenticate as bot via MTProto
|
|
18144
|
+
*/
|
|
18145
|
+
async connect(botToken) {
|
|
18146
|
+
try {
|
|
18147
|
+
await this.client.start({ botAuthToken: botToken });
|
|
18148
|
+
this.connected = true;
|
|
18149
|
+
console.log("\u{1F3A8} [Bot] Styled buttons enabled (MTProto)");
|
|
18150
|
+
} catch (error) {
|
|
18151
|
+
console.error("\u274C [GramJS Bot] Connection failed:", error);
|
|
18152
|
+
throw error;
|
|
18153
|
+
}
|
|
18154
|
+
}
|
|
18155
|
+
isConnected() {
|
|
18156
|
+
return this.connected;
|
|
18157
|
+
}
|
|
18158
|
+
/**
|
|
18159
|
+
* Answer an inline query with styled buttons via MTProto
|
|
18160
|
+
*/
|
|
18161
|
+
async answerInlineQuery(params) {
|
|
18162
|
+
if (!this.connected) throw new Error("GramJS bot not connected");
|
|
18163
|
+
await this.client.invoke(
|
|
18164
|
+
new Api56.messages.SetInlineBotResults({
|
|
18165
|
+
queryId: bigInt6(params.queryId),
|
|
18166
|
+
results: params.results,
|
|
18167
|
+
cacheTime: params.cacheTime ?? 0
|
|
18168
|
+
})
|
|
18169
|
+
);
|
|
18170
|
+
}
|
|
18171
|
+
/**
|
|
18172
|
+
* Edit an inline message with styled/copy buttons via MTProto.
|
|
18173
|
+
* Accepts the Bot API inline_message_id string directly (decodes internally).
|
|
18174
|
+
*/
|
|
18175
|
+
async editInlineMessageByStringId(params) {
|
|
18176
|
+
if (!this.connected) throw new Error("GramJS bot not connected");
|
|
18177
|
+
const id = decodeInlineMessageId(params.inlineMessageId);
|
|
18178
|
+
const dcId = id.dcId;
|
|
18179
|
+
await this.client.invoke(
|
|
18180
|
+
new Api56.messages.EditInlineBotMessage({
|
|
18181
|
+
id,
|
|
18182
|
+
message: params.text,
|
|
18183
|
+
entities: params.entities,
|
|
18184
|
+
replyMarkup: params.replyMarkup,
|
|
18185
|
+
noWebpage: true
|
|
18186
|
+
}),
|
|
18187
|
+
dcId
|
|
18188
|
+
);
|
|
18189
|
+
}
|
|
18190
|
+
async disconnect() {
|
|
18191
|
+
if (!this.connected) return;
|
|
18192
|
+
try {
|
|
18193
|
+
await this.client.disconnect();
|
|
18194
|
+
this.connected = false;
|
|
18195
|
+
console.log("\u{1F6D1} [GramJS Bot] Disconnected");
|
|
18196
|
+
} catch (error) {
|
|
18197
|
+
console.error("\u274C [GramJS Bot] Disconnect error:", error);
|
|
18198
|
+
}
|
|
18199
|
+
}
|
|
18200
|
+
};
|
|
18201
|
+
|
|
17914
18202
|
// src/bot/services/verification-poller.ts
|
|
17915
18203
|
var VerificationPoller = class {
|
|
17916
18204
|
db;
|
|
@@ -17935,10 +18223,10 @@ var VerificationPoller = class {
|
|
|
17935
18223
|
return;
|
|
17936
18224
|
}
|
|
17937
18225
|
console.log(`\u{1F504} [Poller] Started (interval: ${this.config.pollIntervalMs}ms)`);
|
|
17938
|
-
this.intervalId = setInterval(
|
|
17939
|
-
|
|
18226
|
+
this.intervalId = setInterval(() => {
|
|
18227
|
+
this.poll().catch((err) => console.error("\u274C [Poller] Unhandled poll error:", err));
|
|
17940
18228
|
}, this.config.pollIntervalMs);
|
|
17941
|
-
this.poll();
|
|
18229
|
+
this.poll().catch((err) => console.error("\u274C [Poller] Initial poll error:", err));
|
|
17942
18230
|
}
|
|
17943
18231
|
/**
|
|
17944
18232
|
* Stop polling
|
|
@@ -18091,22 +18379,22 @@ var VerificationPoller = class {
|
|
|
18091
18379
|
).run(giftMsgId, deal.dealId);
|
|
18092
18380
|
}
|
|
18093
18381
|
if (deal.inlineMessageId) {
|
|
18094
|
-
const { text,
|
|
18095
|
-
await this.bot.editMessageByInlineId(deal.inlineMessageId, text,
|
|
18382
|
+
const { text, buttons } = buildSendingMessage(deal);
|
|
18383
|
+
await this.bot.editMessageByInlineId(deal.inlineMessageId, text, buttons);
|
|
18096
18384
|
}
|
|
18097
18385
|
const result = await executeDeal(deal.dealId, this.db, this.bridge);
|
|
18098
18386
|
if (result.success) {
|
|
18099
18387
|
updateUserStats(this.db, deal.userId, deal.username, deal, true);
|
|
18100
18388
|
const completedDeal = { ...deal, status: "completed" };
|
|
18101
18389
|
if (deal.inlineMessageId) {
|
|
18102
|
-
const { text,
|
|
18103
|
-
await this.bot.editMessageByInlineId(deal.inlineMessageId, text,
|
|
18390
|
+
const { text, buttons } = buildCompletedMessage(completedDeal);
|
|
18391
|
+
await this.bot.editMessageByInlineId(deal.inlineMessageId, text, buttons);
|
|
18104
18392
|
}
|
|
18105
18393
|
console.log(`\u{1F389} [Poller] Deal ${deal.dealId} completed successfully!`);
|
|
18106
18394
|
} else {
|
|
18107
18395
|
if (deal.inlineMessageId) {
|
|
18108
|
-
const { text,
|
|
18109
|
-
await this.bot.editMessageByInlineId(deal.inlineMessageId, text,
|
|
18396
|
+
const { text, buttons } = buildFailedMessage(deal, result.error);
|
|
18397
|
+
await this.bot.editMessageByInlineId(deal.inlineMessageId, text, buttons);
|
|
18110
18398
|
}
|
|
18111
18399
|
console.error(`\u274C [Poller] Deal ${deal.dealId} execution failed:`, result.error);
|
|
18112
18400
|
}
|
|
@@ -18122,11 +18410,11 @@ var VerificationPoller = class {
|
|
|
18122
18410
|
WHERE id = ?`
|
|
18123
18411
|
).run(deal.dealId);
|
|
18124
18412
|
if (deal.inlineMessageId) {
|
|
18125
|
-
const { text,
|
|
18413
|
+
const { text, buttons } = buildFailedMessage(
|
|
18126
18414
|
deal,
|
|
18127
18415
|
"Payment not detected after 60 seconds. Contact support if you have sent it."
|
|
18128
18416
|
);
|
|
18129
|
-
await this.bot.editMessageByInlineId(deal.inlineMessageId, text,
|
|
18417
|
+
await this.bot.editMessageByInlineId(deal.inlineMessageId, text, buttons);
|
|
18130
18418
|
}
|
|
18131
18419
|
await this.bridge.sendMessage({
|
|
18132
18420
|
chatId: deal.chatId,
|
|
@@ -18145,21 +18433,20 @@ var DealBot = class {
|
|
|
18145
18433
|
bot;
|
|
18146
18434
|
db;
|
|
18147
18435
|
config;
|
|
18436
|
+
gramjsBot = null;
|
|
18148
18437
|
constructor(config, db) {
|
|
18149
18438
|
this.config = config;
|
|
18150
18439
|
this.db = db;
|
|
18151
18440
|
this.bot = new Bot(config.token);
|
|
18441
|
+
if (config.apiId && config.apiHash) {
|
|
18442
|
+
this.gramjsBot = new GramJSBotClient(config.apiId, config.apiHash);
|
|
18443
|
+
}
|
|
18152
18444
|
this.setupHandlers();
|
|
18153
18445
|
}
|
|
18154
|
-
/**
|
|
18155
|
-
* Check if keyboard has buttons
|
|
18156
|
-
*/
|
|
18157
|
-
hasButtons(keyboard) {
|
|
18158
|
-
return keyboard.inline_keyboard?.length > 0;
|
|
18159
|
-
}
|
|
18160
18446
|
setupHandlers() {
|
|
18161
18447
|
this.bot.on("inline_query", async (ctx) => {
|
|
18162
18448
|
const query = ctx.inlineQuery.query.trim();
|
|
18449
|
+
const queryId = ctx.inlineQuery.id;
|
|
18163
18450
|
const userId = ctx.from.id;
|
|
18164
18451
|
console.log(`\u{1F50D} [Bot] Inline query from ${userId}: "${query}"`);
|
|
18165
18452
|
const dealId = query;
|
|
@@ -18204,7 +18491,16 @@ var DealBot = class {
|
|
|
18204
18491
|
deal.status = "expired";
|
|
18205
18492
|
}
|
|
18206
18493
|
const agentWallet = getWalletAddress() || "";
|
|
18207
|
-
const { text,
|
|
18494
|
+
const { text, buttons } = buildMessageForState(deal, agentWallet);
|
|
18495
|
+
if (this.gramjsBot?.isConnected() && hasStyledButtons(buttons)) {
|
|
18496
|
+
try {
|
|
18497
|
+
await this.answerInlineQueryStyled(queryId, dealId, deal, text, buttons);
|
|
18498
|
+
return;
|
|
18499
|
+
} catch (error) {
|
|
18500
|
+
console.warn("\u26A0\uFE0F [Bot] GramJS styled answer failed, falling back to Grammy:", error);
|
|
18501
|
+
}
|
|
18502
|
+
}
|
|
18503
|
+
const keyboard = toGrammyKeyboard(buttons);
|
|
18208
18504
|
await ctx.answerInlineQuery(
|
|
18209
18505
|
[
|
|
18210
18506
|
{
|
|
@@ -18213,11 +18509,11 @@ var DealBot = class {
|
|
|
18213
18509
|
title: `\u{1F4CB} Deal #${dealId}`,
|
|
18214
18510
|
description: this.formatShortDescription(deal),
|
|
18215
18511
|
input_message_content: {
|
|
18216
|
-
message_text: text,
|
|
18512
|
+
message_text: stripCustomEmoji(text),
|
|
18217
18513
|
parse_mode: "HTML",
|
|
18218
18514
|
link_preview_options: { is_disabled: true }
|
|
18219
18515
|
},
|
|
18220
|
-
reply_markup:
|
|
18516
|
+
reply_markup: hasStyledButtons(buttons) ? keyboard : void 0
|
|
18221
18517
|
}
|
|
18222
18518
|
],
|
|
18223
18519
|
{ cache_time: 0 }
|
|
@@ -18227,8 +18523,39 @@ var DealBot = class {
|
|
|
18227
18523
|
const resultId = ctx.chosenInlineResult.result_id;
|
|
18228
18524
|
const inlineMessageId = ctx.chosenInlineResult.inline_message_id;
|
|
18229
18525
|
if (inlineMessageId && resultId !== "help" && resultId !== "not_found" && resultId !== "wrong_user") {
|
|
18230
|
-
console.log(`\u{1F4DD} [Bot] Storing inline message ID for deal ${resultId}: ${inlineMessageId}`);
|
|
18231
18526
|
setInlineMessageId(this.db, resultId, inlineMessageId);
|
|
18527
|
+
const deal = getDeal(this.db, resultId);
|
|
18528
|
+
if (deal) {
|
|
18529
|
+
const agentWallet = getWalletAddress() || "";
|
|
18530
|
+
const { text, buttons } = buildMessageForState(deal, agentWallet);
|
|
18531
|
+
let edited = false;
|
|
18532
|
+
if (this.gramjsBot?.isConnected()) {
|
|
18533
|
+
try {
|
|
18534
|
+
await this.editViaGramJS(inlineMessageId, text, buttons);
|
|
18535
|
+
edited = true;
|
|
18536
|
+
} catch (error) {
|
|
18537
|
+
console.warn(
|
|
18538
|
+
"\u26A0\uFE0F [Bot] chosen_inline_result GramJS edit failed:",
|
|
18539
|
+
error?.errorMessage || error
|
|
18540
|
+
);
|
|
18541
|
+
}
|
|
18542
|
+
}
|
|
18543
|
+
if (!edited) {
|
|
18544
|
+
try {
|
|
18545
|
+
const keyboard = hasStyledButtons(buttons) ? toGrammyKeyboard(buttons) : void 0;
|
|
18546
|
+
await this.bot.api.editMessageTextInline(inlineMessageId, stripCustomEmoji(text), {
|
|
18547
|
+
parse_mode: "HTML",
|
|
18548
|
+
link_preview_options: { is_disabled: true },
|
|
18549
|
+
reply_markup: keyboard
|
|
18550
|
+
});
|
|
18551
|
+
} catch (error) {
|
|
18552
|
+
console.error(
|
|
18553
|
+
"\u274C [Bot] chosen_inline_result Grammy fallback failed:",
|
|
18554
|
+
error?.description || error
|
|
18555
|
+
);
|
|
18556
|
+
}
|
|
18557
|
+
}
|
|
18558
|
+
}
|
|
18232
18559
|
}
|
|
18233
18560
|
});
|
|
18234
18561
|
this.bot.on("callback_query:data", async (ctx) => {
|
|
@@ -18258,8 +18585,8 @@ var DealBot = class {
|
|
|
18258
18585
|
}
|
|
18259
18586
|
if (isDealExpired(deal) && ["proposed", "accepted"].includes(deal.status)) {
|
|
18260
18587
|
expireDeal(this.db, dealId);
|
|
18261
|
-
const { text,
|
|
18262
|
-
await this.editInlineMessage(ctx, text,
|
|
18588
|
+
const { text, buttons } = buildExpiredMessage(deal);
|
|
18589
|
+
await this.editInlineMessage(ctx, text, buttons);
|
|
18263
18590
|
await ctx.answerCallbackQuery({ text: "Deal expired!" });
|
|
18264
18591
|
return;
|
|
18265
18592
|
}
|
|
@@ -18288,6 +18615,35 @@ var DealBot = class {
|
|
|
18288
18615
|
console.error("\u274C [Bot] Error:", err);
|
|
18289
18616
|
});
|
|
18290
18617
|
}
|
|
18618
|
+
/**
|
|
18619
|
+
* Answer inline query via GramJS MTProto with styled buttons.
|
|
18620
|
+
* Sends full deal content (custom emojis stripped since SetInlineBotResults drops them).
|
|
18621
|
+
* chosen_inline_result then edits to upgrade to custom emojis.
|
|
18622
|
+
*/
|
|
18623
|
+
async answerInlineQueryStyled(queryId, dealId, deal, htmlText, buttons) {
|
|
18624
|
+
if (!this.gramjsBot) throw new Error("GramJS bot not available");
|
|
18625
|
+
const strippedHtml = stripCustomEmoji(htmlText);
|
|
18626
|
+
const { text: plainText, entities } = parseHtml(strippedHtml);
|
|
18627
|
+
const markup = hasStyledButtons(buttons) ? toTLMarkup(buttons) : void 0;
|
|
18628
|
+
await this.gramjsBot.answerInlineQuery({
|
|
18629
|
+
queryId,
|
|
18630
|
+
results: [
|
|
18631
|
+
new Api57.InputBotInlineResult({
|
|
18632
|
+
id: dealId,
|
|
18633
|
+
type: "article",
|
|
18634
|
+
title: `\u{1F4CB} Deal #${dealId}`,
|
|
18635
|
+
description: this.formatShortDescription(deal),
|
|
18636
|
+
sendMessage: new Api57.InputBotInlineMessageText({
|
|
18637
|
+
message: plainText,
|
|
18638
|
+
entities: entities.length > 0 ? entities : void 0,
|
|
18639
|
+
noWebpage: true,
|
|
18640
|
+
replyMarkup: markup
|
|
18641
|
+
})
|
|
18642
|
+
})
|
|
18643
|
+
],
|
|
18644
|
+
cacheTime: 0
|
|
18645
|
+
});
|
|
18646
|
+
}
|
|
18291
18647
|
async handleAccept(ctx, deal) {
|
|
18292
18648
|
if (deal.status !== "proposed") {
|
|
18293
18649
|
await ctx.answerCallbackQuery({ text: "Already processed" });
|
|
@@ -18295,10 +18651,10 @@ var DealBot = class {
|
|
|
18295
18651
|
}
|
|
18296
18652
|
acceptDeal(this.db, deal.dealId);
|
|
18297
18653
|
deal.status = "accepted";
|
|
18298
|
-
deal.expiresAt = Math.floor(Date.now() / 1e3) +
|
|
18654
|
+
deal.expiresAt = Math.floor(Date.now() / 1e3) + DEAL_VERIFICATION_WINDOW_SECONDS;
|
|
18299
18655
|
const agentWallet = getWalletAddress() || "";
|
|
18300
|
-
const { text,
|
|
18301
|
-
await this.editInlineMessage(ctx, text,
|
|
18656
|
+
const { text, buttons } = buildAcceptedMessage(deal, agentWallet);
|
|
18657
|
+
await this.editInlineMessage(ctx, text, buttons);
|
|
18302
18658
|
await ctx.answerCallbackQuery({ text: "\u2705 Deal accepted!" });
|
|
18303
18659
|
console.log(`\u2705 [Bot] Deal ${deal.dealId} accepted by ${deal.userId}`);
|
|
18304
18660
|
}
|
|
@@ -18309,8 +18665,8 @@ var DealBot = class {
|
|
|
18309
18665
|
}
|
|
18310
18666
|
declineDeal(this.db, deal.dealId);
|
|
18311
18667
|
deal.status = "declined";
|
|
18312
|
-
const { text,
|
|
18313
|
-
await this.editInlineMessage(ctx, text,
|
|
18668
|
+
const { text, buttons } = buildDeclinedMessage(deal);
|
|
18669
|
+
await this.editInlineMessage(ctx, text, buttons);
|
|
18314
18670
|
await ctx.answerCallbackQuery({ text: "\u274C Deal declined" });
|
|
18315
18671
|
console.log(`\u274C [Bot] Deal ${deal.dealId} declined by ${deal.userId}`);
|
|
18316
18672
|
}
|
|
@@ -18321,8 +18677,8 @@ var DealBot = class {
|
|
|
18321
18677
|
}
|
|
18322
18678
|
claimPayment(this.db, deal.dealId);
|
|
18323
18679
|
deal.status = "payment_claimed";
|
|
18324
|
-
const { text,
|
|
18325
|
-
await this.editInlineMessage(ctx, text,
|
|
18680
|
+
const { text, buttons } = buildVerifyingMessage(deal);
|
|
18681
|
+
await this.editInlineMessage(ctx, text, buttons);
|
|
18326
18682
|
await ctx.answerCallbackQuery({ text: "\u23F3 Verifying..." });
|
|
18327
18683
|
console.log(`\u{1F4E4} [Bot] Deal ${deal.dealId} payment claimed by ${deal.userId}`);
|
|
18328
18684
|
}
|
|
@@ -18346,38 +18702,81 @@ var DealBot = class {
|
|
|
18346
18702
|
return;
|
|
18347
18703
|
}
|
|
18348
18704
|
const agentWallet = getWalletAddress() || "";
|
|
18349
|
-
const { text,
|
|
18350
|
-
await this.editInlineMessage(ctx, text,
|
|
18705
|
+
const { text, buttons } = buildMessageForState(freshDeal, agentWallet);
|
|
18706
|
+
await this.editInlineMessage(ctx, text, buttons);
|
|
18351
18707
|
await ctx.answerCallbackQuery({ text: "\u{1F504} Refreshed" });
|
|
18352
18708
|
}
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
|
|
18356
|
-
|
|
18357
|
-
|
|
18358
|
-
|
|
18359
|
-
|
|
18360
|
-
|
|
18709
|
+
/**
|
|
18710
|
+
* Edit inline message: try GramJS MTProto first (styled + copy buttons), fallback to Grammy
|
|
18711
|
+
*/
|
|
18712
|
+
async editInlineMessage(ctx, text, buttons) {
|
|
18713
|
+
const inlineMsgId = ctx.callbackQuery?.inline_message_id;
|
|
18714
|
+
if (!inlineMsgId) return;
|
|
18715
|
+
if (this.gramjsBot?.isConnected()) {
|
|
18716
|
+
try {
|
|
18717
|
+
await this.editViaGramJS(inlineMsgId, text, buttons);
|
|
18718
|
+
return;
|
|
18719
|
+
} catch (error) {
|
|
18720
|
+
if (error?.errorMessage === "MESSAGE_NOT_MODIFIED") return;
|
|
18721
|
+
console.warn(
|
|
18722
|
+
"\u26A0\uFE0F [Bot] GramJS edit failed, falling back to Grammy:",
|
|
18723
|
+
error?.errorMessage || error
|
|
18724
|
+
);
|
|
18361
18725
|
}
|
|
18726
|
+
}
|
|
18727
|
+
try {
|
|
18728
|
+
const keyboard = hasStyledButtons(buttons) ? toGrammyKeyboard(buttons) : void 0;
|
|
18729
|
+
await ctx.editMessageText(stripCustomEmoji(text), {
|
|
18730
|
+
parse_mode: "HTML",
|
|
18731
|
+
link_preview_options: { is_disabled: true },
|
|
18732
|
+
reply_markup: keyboard
|
|
18733
|
+
});
|
|
18362
18734
|
} catch (error) {
|
|
18363
18735
|
if (error?.description?.includes("message is not modified")) return;
|
|
18364
18736
|
console.error("\u274C [Bot] Failed to edit inline message:", error);
|
|
18365
18737
|
}
|
|
18366
18738
|
}
|
|
18367
18739
|
/**
|
|
18368
|
-
* Edit a message by inline_message_id (for external updates)
|
|
18740
|
+
* Edit a message by inline_message_id (for external updates like VerificationPoller)
|
|
18369
18741
|
*/
|
|
18370
|
-
async editMessageByInlineId(inlineMessageId, text,
|
|
18742
|
+
async editMessageByInlineId(inlineMessageId, text, buttons) {
|
|
18743
|
+
if (this.gramjsBot?.isConnected() && buttons) {
|
|
18744
|
+
try {
|
|
18745
|
+
await this.editViaGramJS(inlineMessageId, text, buttons);
|
|
18746
|
+
return;
|
|
18747
|
+
} catch (error) {
|
|
18748
|
+
if (error?.errorMessage === "MESSAGE_NOT_MODIFIED") return;
|
|
18749
|
+
console.warn(
|
|
18750
|
+
"\u26A0\uFE0F [Bot] GramJS edit failed, falling back to Grammy:",
|
|
18751
|
+
error?.errorMessage || error
|
|
18752
|
+
);
|
|
18753
|
+
}
|
|
18754
|
+
}
|
|
18371
18755
|
try {
|
|
18372
|
-
|
|
18756
|
+
const keyboard = buttons && hasStyledButtons(buttons) ? toGrammyKeyboard(buttons) : void 0;
|
|
18757
|
+
await this.bot.api.editMessageTextInline(inlineMessageId, stripCustomEmoji(text), {
|
|
18373
18758
|
parse_mode: "HTML",
|
|
18374
18759
|
link_preview_options: { is_disabled: true },
|
|
18375
|
-
reply_markup: keyboard
|
|
18760
|
+
reply_markup: keyboard
|
|
18376
18761
|
});
|
|
18377
18762
|
} catch (error) {
|
|
18378
18763
|
console.error("\u274C [Bot] Failed to edit message by inline ID:", error);
|
|
18379
18764
|
}
|
|
18380
18765
|
}
|
|
18766
|
+
/**
|
|
18767
|
+
* Edit inline message via GramJS MTProto (styled + copy buttons)
|
|
18768
|
+
*/
|
|
18769
|
+
async editViaGramJS(inlineMessageId, htmlText, buttons) {
|
|
18770
|
+
if (!this.gramjsBot) throw new Error("GramJS bot not available");
|
|
18771
|
+
const { text: plainText, entities } = parseHtml(htmlText);
|
|
18772
|
+
const markup = hasStyledButtons(buttons) ? toTLMarkup(buttons) : void 0;
|
|
18773
|
+
await this.gramjsBot.editInlineMessageByStringId({
|
|
18774
|
+
inlineMessageId,
|
|
18775
|
+
text: plainText,
|
|
18776
|
+
entities: entities.length > 0 ? entities : void 0,
|
|
18777
|
+
replyMarkup: markup
|
|
18778
|
+
});
|
|
18779
|
+
}
|
|
18381
18780
|
formatShortDescription(deal) {
|
|
18382
18781
|
const userGives = deal.userGivesType === "ton" ? `${deal.userGivesTonAmount} TON` : deal.userGivesGiftSlug || "Gift";
|
|
18383
18782
|
const agentGives = deal.agentGivesType === "ton" ? `${deal.agentGivesTonAmount} TON` : deal.agentGivesGiftSlug || "Gift";
|
|
@@ -18388,9 +18787,19 @@ var DealBot = class {
|
|
|
18388
18787
|
*/
|
|
18389
18788
|
async start() {
|
|
18390
18789
|
console.log(`\u{1F916} [Bot] Starting @${this.config.username}...`);
|
|
18790
|
+
if (this.gramjsBot) {
|
|
18791
|
+
try {
|
|
18792
|
+
await this.gramjsBot.connect(this.config.token);
|
|
18793
|
+
} catch {
|
|
18794
|
+
console.warn("\u26A0\uFE0F [Bot] GramJS MTProto connection failed, buttons will be unstyled");
|
|
18795
|
+
this.gramjsBot = null;
|
|
18796
|
+
}
|
|
18797
|
+
}
|
|
18391
18798
|
await this.bot.init();
|
|
18392
18799
|
this.bot.start({
|
|
18393
18800
|
onStart: () => console.log(`\u{1F916} [Bot] @${this.config.username} polling started`)
|
|
18801
|
+
}).catch((err) => {
|
|
18802
|
+
console.error(`\u274C [Bot] Polling error:`, err);
|
|
18394
18803
|
});
|
|
18395
18804
|
}
|
|
18396
18805
|
/**
|
|
@@ -18399,6 +18808,9 @@ var DealBot = class {
|
|
|
18399
18808
|
async stop() {
|
|
18400
18809
|
console.log(`\u{1F6D1} [Bot] Stopping @${this.config.username}...`);
|
|
18401
18810
|
await this.bot.stop();
|
|
18811
|
+
if (this.gramjsBot) {
|
|
18812
|
+
await this.gramjsBot.disconnect();
|
|
18813
|
+
}
|
|
18402
18814
|
}
|
|
18403
18815
|
/**
|
|
18404
18816
|
* Get bot instance for external access
|
|
@@ -18430,143 +18842,7 @@ var TonnetApp = class {
|
|
|
18430
18842
|
initDealsConfig(this.config.deals);
|
|
18431
18843
|
const soul = loadSoul();
|
|
18432
18844
|
this.toolRegistry = new ToolRegistry();
|
|
18433
|
-
this.toolRegistry
|
|
18434
|
-
this.toolRegistry.register(telegramQuoteReplyTool, telegramQuoteReplyExecutor);
|
|
18435
|
-
this.toolRegistry.register(telegramGetRepliesTool, telegramGetRepliesExecutor);
|
|
18436
|
-
this.toolRegistry.register(telegramEditMessageTool, telegramEditMessageExecutor);
|
|
18437
|
-
this.toolRegistry.register(telegramScheduleMessageTool, telegramScheduleMessageExecutor);
|
|
18438
|
-
this.toolRegistry.register(
|
|
18439
|
-
telegramCreateScheduledTaskTool,
|
|
18440
|
-
telegramCreateScheduledTaskExecutor
|
|
18441
|
-
);
|
|
18442
|
-
this.toolRegistry.register(telegramSearchMessagesTool, telegramSearchMessagesExecutor);
|
|
18443
|
-
this.toolRegistry.register(telegramPinMessageTool, telegramPinMessageExecutor);
|
|
18444
|
-
this.toolRegistry.register(telegramUnpinMessageTool, telegramUnpinMessageExecutor);
|
|
18445
|
-
this.toolRegistry.register(telegramReactTool, telegramReactExecutor);
|
|
18446
|
-
this.toolRegistry.register(telegramSendDiceTool, telegramSendDiceExecutor);
|
|
18447
|
-
this.toolRegistry.register(telegramForwardMessageTool, telegramForwardMessageExecutor);
|
|
18448
|
-
this.toolRegistry.register(telegramSendPhotoTool, telegramSendPhotoExecutor);
|
|
18449
|
-
this.toolRegistry.register(telegramSendVoiceTool, telegramSendVoiceExecutor);
|
|
18450
|
-
this.toolRegistry.register(telegramSendStickerTool, telegramSendStickerExecutor);
|
|
18451
|
-
this.toolRegistry.register(telegramSendGifTool, telegramSendGifExecutor);
|
|
18452
|
-
this.toolRegistry.register(telegramCreatePollTool, telegramCreatePollExecutor);
|
|
18453
|
-
this.toolRegistry.register(telegramCreateQuizTool, telegramCreateQuizExecutor);
|
|
18454
|
-
this.toolRegistry.register(telegramReplyKeyboardTool, telegramReplyKeyboardExecutor);
|
|
18455
|
-
this.toolRegistry.register(telegramSearchStickersTool, telegramSearchStickersExecutor);
|
|
18456
|
-
this.toolRegistry.register(telegramGetMyStickersTool, telegramGetMyStickersExecutor);
|
|
18457
|
-
this.toolRegistry.register(telegramSearchGifsTool, telegramSearchGifsExecutor);
|
|
18458
|
-
this.toolRegistry.register(telegramAddStickerSetTool, telegramAddStickerSetExecutor);
|
|
18459
|
-
this.toolRegistry.register(telegramGetHistoryTool, telegramGetHistoryExecutor);
|
|
18460
|
-
this.toolRegistry.register(telegramGetDialogsTool, telegramGetDialogsExecutor);
|
|
18461
|
-
this.toolRegistry.register(telegramMarkAsReadTool, telegramMarkAsReadExecutor);
|
|
18462
|
-
this.toolRegistry.register(telegramGetChatInfoTool, telegramGetChatInfoExecutor);
|
|
18463
|
-
this.toolRegistry.register(telegramJoinChannelTool, telegramJoinChannelExecutor);
|
|
18464
|
-
this.toolRegistry.register(telegramLeaveChannelTool, telegramLeaveChannelExecutor);
|
|
18465
|
-
this.toolRegistry.register(telegramGetMeTool, telegramGetMeExecutor);
|
|
18466
|
-
this.toolRegistry.register(telegramGetParticipantsTool, telegramGetParticipantsExecutor);
|
|
18467
|
-
this.toolRegistry.register(telegramKickUserTool, telegramKickUserExecutor);
|
|
18468
|
-
this.toolRegistry.register(telegramBanUserTool, telegramBanUserExecutor);
|
|
18469
|
-
this.toolRegistry.register(telegramUnbanUserTool, telegramUnbanUserExecutor);
|
|
18470
|
-
this.toolRegistry.register(telegramCreateGroupTool, telegramCreateGroupExecutor);
|
|
18471
|
-
this.toolRegistry.register(telegramSetChatPhotoTool, telegramSetChatPhotoExecutor);
|
|
18472
|
-
this.toolRegistry.register(telegramBlockUserTool, telegramBlockUserExecutor);
|
|
18473
|
-
this.toolRegistry.register(telegramGetBlockedTool, telegramGetBlockedExecutor);
|
|
18474
|
-
this.toolRegistry.register(telegramGetCommonChatsTool, telegramGetCommonChatsExecutor);
|
|
18475
|
-
this.toolRegistry.register(telegramSendStoryTool, telegramSendStoryExecutor);
|
|
18476
|
-
this.toolRegistry.register(telegramGetFoldersTool, telegramGetFoldersExecutor);
|
|
18477
|
-
this.toolRegistry.register(telegramCreateFolderTool, telegramCreateFolderExecutor);
|
|
18478
|
-
this.toolRegistry.register(telegramAddChatToFolderTool, telegramAddChatToFolderExecutor);
|
|
18479
|
-
this.toolRegistry.register(telegramCreateChannelTool, telegramCreateChannelExecutor);
|
|
18480
|
-
this.toolRegistry.register(telegramUpdateProfileTool, telegramUpdateProfileExecutor);
|
|
18481
|
-
this.toolRegistry.register(telegramSetBioTool, telegramSetBioExecutor);
|
|
18482
|
-
this.toolRegistry.register(telegramSetUsernameTool, telegramSetUsernameExecutor);
|
|
18483
|
-
this.toolRegistry.register(telegramDeleteMessageTool, telegramDeleteMessageExecutor);
|
|
18484
|
-
this.toolRegistry.register(telegramDownloadMediaTool, telegramDownloadMediaExecutor);
|
|
18485
|
-
this.toolRegistry.register(visionAnalyzeTool, visionAnalyzeExecutor);
|
|
18486
|
-
this.toolRegistry.register(telegramGetStarsBalanceTool, telegramGetStarsBalanceExecutor);
|
|
18487
|
-
this.toolRegistry.register(
|
|
18488
|
-
telegramGetStarsTransactionsTool,
|
|
18489
|
-
telegramGetStarsTransactionsExecutor
|
|
18490
|
-
);
|
|
18491
|
-
this.toolRegistry.register(telegramGetAvailableGiftsTool, telegramGetAvailableGiftsExecutor);
|
|
18492
|
-
this.toolRegistry.register(telegramSendGiftTool, telegramSendGiftExecutor);
|
|
18493
|
-
this.toolRegistry.register(telegramGetMyGiftsTool, telegramGetMyGiftsExecutor);
|
|
18494
|
-
this.toolRegistry.register(
|
|
18495
|
-
telegramTransferCollectibleTool,
|
|
18496
|
-
telegramTransferCollectibleExecutor
|
|
18497
|
-
);
|
|
18498
|
-
this.toolRegistry.register(
|
|
18499
|
-
telegramSetCollectiblePriceTool,
|
|
18500
|
-
telegramSetCollectiblePriceExecutor
|
|
18501
|
-
);
|
|
18502
|
-
this.toolRegistry.register(telegramGetResaleGiftsTool, telegramGetResaleGiftsExecutor);
|
|
18503
|
-
this.toolRegistry.register(telegramBuyResaleGiftTool, telegramBuyResaleGiftExecutor);
|
|
18504
|
-
this.toolRegistry.register(telegramSetGiftStatusTool, telegramSetGiftStatusExecutor);
|
|
18505
|
-
this.toolRegistry.register(memoryWriteTool, memoryWriteExecutor);
|
|
18506
|
-
this.toolRegistry.register(memoryReadTool, memoryReadExecutor);
|
|
18507
|
-
this.toolRegistry.register(telegramGetUserInfoTool, telegramGetUserInfoExecutor);
|
|
18508
|
-
this.toolRegistry.register(telegramCheckUsernameTool, telegramCheckUsernameExecutor);
|
|
18509
|
-
this.toolRegistry.register(telegramEditChannelInfoTool, telegramEditChannelInfoExecutor);
|
|
18510
|
-
this.toolRegistry.register(telegramInviteToChannelTool, telegramInviteToChannelExecutor);
|
|
18511
|
-
this.toolRegistry.register(marketGetFloorTool, marketGetFloorExecutor);
|
|
18512
|
-
this.toolRegistry.register(marketSearchTool, marketSearchExecutor);
|
|
18513
|
-
this.toolRegistry.register(marketCheapestTool, marketCheapestExecutor);
|
|
18514
|
-
this.toolRegistry.register(marketPriceHistoryTool, marketPriceHistoryExecutor);
|
|
18515
|
-
this.toolRegistry.register(tonGetAddressTool, tonGetAddressExecutor);
|
|
18516
|
-
this.toolRegistry.register(tonGetBalanceTool, tonGetBalanceExecutor);
|
|
18517
|
-
this.toolRegistry.register(tonPriceTool, tonPriceExecutor);
|
|
18518
|
-
this.toolRegistry.register(tonSendTool, tonSendExecutor);
|
|
18519
|
-
this.toolRegistry.register(tonGetTransactionsTool, tonGetTransactionsExecutor);
|
|
18520
|
-
this.toolRegistry.register(tonMyTransactionsTool, tonMyTransactionsExecutor);
|
|
18521
|
-
this.toolRegistry.register(jettonBalancesTool, jettonBalancesExecutor);
|
|
18522
|
-
this.toolRegistry.register(jettonSwapTool, jettonSwapExecutor);
|
|
18523
|
-
this.toolRegistry.register(jettonSendTool, jettonSendExecutor);
|
|
18524
|
-
this.toolRegistry.register(jettonInfoTool, jettonInfoExecutor);
|
|
18525
|
-
this.toolRegistry.register(jettonPriceTool, jettonPriceExecutor);
|
|
18526
|
-
this.toolRegistry.register(jettonSearchTool, jettonSearchExecutor);
|
|
18527
|
-
this.toolRegistry.register(jettonQuoteTool, jettonQuoteExecutor);
|
|
18528
|
-
this.toolRegistry.register(jettonHoldersTool, jettonHoldersExecutor);
|
|
18529
|
-
this.toolRegistry.register(jettonHistoryTool, jettonHistoryExecutor);
|
|
18530
|
-
this.toolRegistry.register(jettonTrendingTool, jettonTrendingExecutor);
|
|
18531
|
-
this.toolRegistry.register(jettonPoolsTool, jettonPoolsExecutor);
|
|
18532
|
-
this.toolRegistry.register(dnsCheckTool, dnsCheckExecutor);
|
|
18533
|
-
this.toolRegistry.register(dnsAuctionsTool, dnsAuctionsExecutor);
|
|
18534
|
-
this.toolRegistry.register(dnsResolveTool, dnsResolveExecutor);
|
|
18535
|
-
this.toolRegistry.register(dnsStartAuctionTool, dnsStartAuctionExecutor);
|
|
18536
|
-
this.toolRegistry.register(dnsBidTool, dnsBidExecutor);
|
|
18537
|
-
this.toolRegistry.register(dnsLinkTool, dnsLinkExecutor);
|
|
18538
|
-
this.toolRegistry.register(dnsUnlinkTool, dnsUnlinkExecutor);
|
|
18539
|
-
this.toolRegistry.register(dedustQuoteTool, dedustQuoteExecutor);
|
|
18540
|
-
this.toolRegistry.register(dedustSwapTool, dedustSwapExecutor);
|
|
18541
|
-
this.toolRegistry.register(dedustPoolsTool, dedustPoolsExecutor);
|
|
18542
|
-
this.toolRegistry.register(dexQuoteTool, dexQuoteExecutor);
|
|
18543
|
-
this.toolRegistry.register(dexSwapTool, dexSwapExecutor);
|
|
18544
|
-
this.toolRegistry.register(journalLogTool, journalLogExecutor);
|
|
18545
|
-
this.toolRegistry.register(journalQueryTool, journalQueryExecutor);
|
|
18546
|
-
this.toolRegistry.register(journalUpdateTool, journalUpdateExecutor);
|
|
18547
|
-
this.toolRegistry.register(workspaceListTool, workspaceListExecutor);
|
|
18548
|
-
this.toolRegistry.register(workspaceReadTool, workspaceReadExecutor);
|
|
18549
|
-
this.toolRegistry.register(workspaceWriteTool, workspaceWriteExecutor);
|
|
18550
|
-
this.toolRegistry.register(workspaceDeleteTool, workspaceDeleteExecutor);
|
|
18551
|
-
this.toolRegistry.register(workspaceInfoTool, workspaceInfoExecutor);
|
|
18552
|
-
this.toolRegistry.register(workspaceRenameTool, workspaceRenameExecutor);
|
|
18553
|
-
if (this.config.casino.enabled) {
|
|
18554
|
-
this.toolRegistry.register(casinoBalanceTool, casinoBalanceExecutor);
|
|
18555
|
-
this.toolRegistry.register(casinoSpinTool, casinoSpinExecutor);
|
|
18556
|
-
this.toolRegistry.register(casinoDiceTool, casinoDiceExecutor);
|
|
18557
|
-
this.toolRegistry.register(casinoPayoutTool, casinoPayoutExecutor);
|
|
18558
|
-
this.toolRegistry.register(casinoLeaderboardTool, casinoLeaderboardExecutor);
|
|
18559
|
-
this.toolRegistry.register(casinoMyStatsTool, casinoMyStatsExecutor);
|
|
18560
|
-
this.toolRegistry.register(casinoJackpotInfoTool, casinoJackpotInfoExecutor);
|
|
18561
|
-
this.toolRegistry.register(casinoAwardJackpotTool, casinoAwardJackpotExecutor);
|
|
18562
|
-
}
|
|
18563
|
-
if (this.config.deals.enabled) {
|
|
18564
|
-
this.toolRegistry.register(dealProposeTool, dealProposeExecutor);
|
|
18565
|
-
this.toolRegistry.register(dealVerifyPaymentTool, dealVerifyPaymentExecutor);
|
|
18566
|
-
this.toolRegistry.register(dealStatusTool, dealStatusExecutor);
|
|
18567
|
-
this.toolRegistry.register(dealListTool, dealListExecutor);
|
|
18568
|
-
this.toolRegistry.register(dealCancelTool, dealCancelExecutor);
|
|
18569
|
-
}
|
|
18845
|
+
registerAllTools(this.toolRegistry, this.config);
|
|
18570
18846
|
this.toolCount = this.toolRegistry.count;
|
|
18571
18847
|
this.agent = new AgentRuntime(this.config, soul, this.toolRegistry);
|
|
18572
18848
|
const TELEGRAM_CONNECTION_RETRIES = 5;
|
|
@@ -18634,7 +18910,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
18634
18910
|
`\u26A0\uFE0F Tool count (${this.toolCount}) exceeds ${providerMeta.displayName} limit (${providerMeta.toolLimit})`
|
|
18635
18911
|
);
|
|
18636
18912
|
}
|
|
18637
|
-
const { migrateSessionsToDb } = await import("./migrate-
|
|
18913
|
+
const { migrateSessionsToDb } = await import("./migrate-JPXMIIPI.js");
|
|
18638
18914
|
migrateSessionsToDb();
|
|
18639
18915
|
const memory = initializeMemory({
|
|
18640
18916
|
database: {
|
|
@@ -18673,7 +18949,12 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
18673
18949
|
if (botToken && botToken !== "YOUR_BOT_TOKEN_FROM_BOTFATHER") {
|
|
18674
18950
|
try {
|
|
18675
18951
|
this.dealBot = new DealBot(
|
|
18676
|
-
{
|
|
18952
|
+
{
|
|
18953
|
+
token: botToken,
|
|
18954
|
+
username: botUsername || "deals_bot",
|
|
18955
|
+
apiId: this.config.telegram.api_id,
|
|
18956
|
+
apiHash: this.config.telegram.api_hash
|
|
18957
|
+
},
|
|
18677
18958
|
db.getDb()
|
|
18678
18959
|
);
|
|
18679
18960
|
await this.dealBot.start();
|
|
@@ -18788,8 +19069,8 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
18788
19069
|
}
|
|
18789
19070
|
const taskId = match[1];
|
|
18790
19071
|
const { getTaskStore } = await import("./tasks-NUFMZNV5.js");
|
|
18791
|
-
const { executeScheduledTask } = await import("./task-executor-
|
|
18792
|
-
const { getDatabase: getDatabase2 } = await import("./memory-
|
|
19072
|
+
const { executeScheduledTask } = await import("./task-executor-L6DTJANH.js");
|
|
19073
|
+
const { getDatabase: getDatabase2 } = await import("./memory-WSP5MEER.js");
|
|
18793
19074
|
const db = getDatabase2().getDb();
|
|
18794
19075
|
const taskStore = getTaskStore(db);
|
|
18795
19076
|
const task = taskStore.getTask(taskId);
|
|
@@ -18855,7 +19136,7 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
18855
19136
|
taskStore.completeTask(taskId, response.content);
|
|
18856
19137
|
console.log(`\u2705 Executed scheduled task ${taskId}: ${task.description}`);
|
|
18857
19138
|
if (!this.dependencyResolver) {
|
|
18858
|
-
const { TaskDependencyResolver } = await import("./task-dependency-resolver-
|
|
19139
|
+
const { TaskDependencyResolver } = await import("./task-dependency-resolver-KRQRZKAD.js");
|
|
18859
19140
|
this.dependencyResolver = new TaskDependencyResolver(taskStore, this.bridge);
|
|
18860
19141
|
}
|
|
18861
19142
|
await this.dependencyResolver.onTaskComplete(taskId);
|
|
@@ -18863,8 +19144,8 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
18863
19144
|
console.error("Error handling scheduled task:", error);
|
|
18864
19145
|
try {
|
|
18865
19146
|
const { getTaskStore } = await import("./tasks-NUFMZNV5.js");
|
|
18866
|
-
const { TaskDependencyResolver } = await import("./task-dependency-resolver-
|
|
18867
|
-
const { getDatabase: getDatabase2 } = await import("./memory-
|
|
19147
|
+
const { TaskDependencyResolver } = await import("./task-dependency-resolver-KRQRZKAD.js");
|
|
19148
|
+
const { getDatabase: getDatabase2 } = await import("./memory-WSP5MEER.js");
|
|
18868
19149
|
const db = getDatabase2().getDb();
|
|
18869
19150
|
const taskStore = getTaskStore(db);
|
|
18870
19151
|
const match = message.text.match(/^\[TASK:([^\]]+)\]/);
|
|
@@ -18902,6 +19183,13 @@ ${blue} \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
18902
19183
|
};
|
|
18903
19184
|
async function main(configPath) {
|
|
18904
19185
|
const app = new TonnetApp(configPath);
|
|
19186
|
+
process.on("unhandledRejection", (reason) => {
|
|
19187
|
+
console.error("\u26A0\uFE0F Unhandled promise rejection:", reason);
|
|
19188
|
+
});
|
|
19189
|
+
process.on("uncaughtException", (error) => {
|
|
19190
|
+
console.error("\u{1F4A5} Uncaught exception:", error);
|
|
19191
|
+
process.exit(1);
|
|
19192
|
+
});
|
|
18905
19193
|
process.on("SIGINT", async () => {
|
|
18906
19194
|
await app.stop();
|
|
18907
19195
|
process.exit(0);
|
|
@@ -18931,8 +19219,12 @@ export {
|
|
|
18931
19219
|
getDefaultConfigPath,
|
|
18932
19220
|
ensureWorkspace,
|
|
18933
19221
|
isNewWorkspace,
|
|
19222
|
+
TelegramUserClient,
|
|
18934
19223
|
generateWallet,
|
|
18935
19224
|
saveWallet,
|
|
19225
|
+
loadWallet,
|
|
19226
|
+
walletExists,
|
|
19227
|
+
importWallet,
|
|
18936
19228
|
TonnetApp,
|
|
18937
19229
|
main
|
|
18938
19230
|
};
|