diff --git a/salvium_tipbot.php b/salvium_tipbot.php
index 73e6ad0..2407c3d 100755
--- a/salvium_tipbot.php
+++ b/salvium_tipbot.php
@@ -1,5 +1,4 @@
['private'],
'deposit' => ['private'],
+ 'claim' => ['private'],
'withdraw' => ['private'],
'balance' => ['private'],
'tip' => ['private', 'group', 'supergroup'],
@@ -44,26 +45,62 @@ class SalviumTipBotCommands {
}
private function cmd_start(array $args, array $ctx): string {
- if (!empty($ctx['username'])) {
- $this->db->updateUsername($ctx['user_id'], $ctx['username']);
+ $user = $this->db->getUserByTelegramId($ctx['user_id']);
+
+ if (!$user) {
+ $sub = $this->wallet->getNewSubaddress();
+ if ($sub) {
+ $this->db->createUser($ctx['user_id'], $sub);
+
+ if (!empty($ctx['username'])) {
+ $this->db->updateUsername($ctx['user_id'], $ctx['username']);
+ }
+ }
}
- return "Welcome to the Salvium Tip Bot! Use /deposit to get started.";
+
+ return "๐ Welcome to the Salvium Tip Bot!\n\n"
+ . "You can use the following commands:\n"
+ . "/deposit โ View your deposit address\n"
+ . "/balance โ Check your current balance\n"
+ . "/withdraw
โ Withdraw your SAL\n"
+ . "/tip โ Tip another user\n"
+ . "/claim โ Claim tips sent to your username (if you havenโt used the bot before)\n\n"
+ . "โน๏ธ All commands except /tip must be used in a private chat with the bot.";
}
private function cmd_deposit(array $args, array $ctx): string {
$user = $this->db->getUserByTelegramId($ctx['user_id']);
+
+ // If no exact match, attempt upgrade by matching username with placeholder
+ if (!$user && !empty($ctx['username'])) {
+ $user = $this->db->getUserByUsername($ctx['username']);
+
+ // Check if it's a placeholder user (telegram_user_id is synthetic)
+ if ($user && $user['telegram_user_id'] < 1000000) {
+ // Upgrade the telegram_user_id to the real one
+ $this->db->upgradeTelegramUserId($user['telegram_user_id'], $ctx['user_id']);
+ // Refresh user
+ $user = $this->db->getUserByTelegramId($ctx['user_id']);
+ }
+ }
+
+ // If still not found, create new user
if (!$user) {
$sub = $this->wallet->getNewSubaddress();
if (!$sub) return "Error generating subaddress.";
$this->db->createUser($ctx['user_id'], $sub);
+
if (!empty($ctx['username'])) {
$this->db->updateUsername($ctx['user_id'], $ctx['username']);
}
+
return "Your deposit address: $sub";
}
+
return "Your deposit address: {$user['salvium_subaddress']}";
}
+
private function cmd_balance(array $args, array $ctx): string {
$user = $this->db->getUserByTelegramId($ctx['user_id']);
return $user ? "Your balance: {$user['tip_balance']} SAL" : "No account found. Use /deposit first.";
@@ -97,20 +134,63 @@ class SalviumTipBotCommands {
$amount = (float)$amount;
if ($amount < $this->config['MIN_TIP_AMOUNT']) {
- return "Tip too small. Minimum tip is {$this->config['MIN_TIP_AMOUNT']} SAL.";
+ return "Tip {$amount} for {$targetUsername} too small. Minimum tip is {$this->config['MIN_TIP_AMOUNT']} SAL.";
}
$sender = $this->db->getUserByTelegramId($ctx['user_id']);
- $recipient = $this->db->getUserByUsername(ltrim($targetUsername, '@'));
+ if (!$sender || $sender['tip_balance'] < $amount) {
+ return "Insufficient funds or invalid sender.";
+ }
- if (!$sender || $sender['tip_balance'] < $amount) return "Insufficient funds or invalid sender.";
- if (!$recipient) return "Recipient not found. Ask them to run /start first.";
+ $cleanUsername = ltrim($targetUsername, '@');
+ $recipient = $this->db->getUserByUsername($cleanUsername);
+
+ // If recipient not known, create placeholder
+ if (!$recipient) {
+ $syntheticId = 100000 + (crc32($cleanUsername) % 900000);// Use a consistent pseudo-ID
+ $subaddress = $this->wallet->getNewSubaddress();
+ if (!$subaddress) {
+ return "Failed to create deposit address for {$cleanUsername}.";
+ }
+
+ $existing = $this->db->getUserByTelegramId($syntheticId);
+ if (!$existing) {
+ if (!$this->db->createUser($syntheticId, $subaddress)) {
+ return "Failed to create recipient account for {$cleanUsername}.";
+ }
+ $this->db->updateUsername($syntheticId, $cleanUsername);
+ }
+ $recipient = $this->db->getUserByUsername($cleanUsername);
+
+ // Send a message to the group telling recipient to DM bot
+ sendMessage($ctx['chat_id'], "Hey @$cleanUsername, you just got a tip from @$ctx[username]!");
+ sendGif($ctx['chat_id'], 'CgACAgQAAxkBAAOQaDjcu6ftEKHp3ZCCKX8p6hTkqxEAAtYaAAL4YMlR4yZwk_GMuWg2BA', "DM me and run /claim to receive it.");
+
+ }
$this->db->updateUserTipBalance($sender['id'], $amount, 'subtract');
$this->db->addTip($sender['id'], $recipient['id'], $amount, $ctx['chat_id']);
- sendMessage($recipient['telegram_user_id'], "You received a tip of {$amount} SAL! Use /balance to check.");
+
+ if (!empty($recipient['telegram_user_id']) && $recipient['telegram_user_id'] > 0 && $recipient['telegram_user_id'] != crc32($cleanUsername)) {
+ sendMessage($recipient['telegram_user_id'], "You received a tip of {$amount} SAL! Use /balance to check.");
+ }
return "Tipped {$targetUsername} {$amount} SAL successfully!";
}
+
+ private function cmd_claim(array $args, array $ctx): string {
+ $user = $this->db->getUserByUsername($ctx['username']);
+
+ if (!$user || $user['telegram_user_id'] > 1000000) {
+ return "Nothing to claim or already claimed.";
+ }
+
+ // Upgrade placeholder to real user ID
+ $this->db->upgradeTelegramUserId($user['telegram_user_id'], $ctx['user_id']);
+
+ return "Welcome @{$ctx['username']}, your account has been activated. You can now check your balance and receive tips!";
+ }
+
+
}
?>
diff --git a/src/salvium_tipbot_common.php b/src/salvium_tipbot_common.php
index bfaf0c7..99ee811 100644
--- a/src/salvium_tipbot_common.php
+++ b/src/salvium_tipbot_common.php
@@ -16,6 +16,32 @@ function sendMessage(int $chatId, string $text, array $options = []): void {
curl_close($ch);
}
+
+function sendGif(int $chatId, string $fileIdOrUrl, ?string $caption = null): void {
+ global $config;
+ $url = "https://api.telegram.org/bot{$config['TELEGRAM_BOT_TOKEN']}/sendAnimation";
+
+ $payload = [
+ 'chat_id' => $chatId,
+ 'animation' => $fileIdOrUrl,
+ ];
+
+ if ($caption) {
+ $payload['caption'] = $caption;
+ }
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
+ if (!empty($config['IPV4_ONLY'])) {
+ curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ }
+ curl_exec($ch);
+ curl_close($ch);
+}
+
function isValidSalviumAddress(string $address): bool {
// Accepts standard and subaddress prefixes for Salvium (e.g. SaLvd, SaLvs)
return preg_match('/^SaLv[a-zA-Z0-9]{95}$/', $address) === 1;
diff --git a/src/salvium_tipbot_db.php b/src/salvium_tipbot_db.php
index 5e6f05b..fbbaff9 100755
--- a/src/salvium_tipbot_db.php
+++ b/src/salvium_tipbot_db.php
@@ -93,6 +93,11 @@ class SalviumTipBotDB {
$stmt->execute([$username, $telegramUserId]);
}
+ public function upgradeTelegramUserId(int $oldId, int $newId): bool {
+ $stmt = $this->pdo->prepare("UPDATE users SET telegram_user_id = ? WHERE telegram_user_id = ?");
+ return $stmt->execute([$newId, $oldId]);
+ }
+
public function getUserBySubaddress(string $subaddress): array|false {
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE salvium_subaddress = ?");
$stmt->execute([$subaddress]);