Initial commit - purely ai generated code
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
// .gitignore
|
||||
// config.php
|
||||
config.php
|
||||
*.log
|
||||
.DS_Store
|
||||
*.swp
|
||||
.vscode/
|
||||
.idea/
|
||||
@@ -0,0 +1,15 @@
|
||||
// LICENSE
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 [Your Name]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
|
||||
*/
|
||||
@@ -0,0 +1,28 @@
|
||||
// README.md
|
||||
/*
|
||||
# Salvium Tip Bot
|
||||
|
||||
A PHP-based Telegram tip bot for the Salvium (Monero fork) cryptocurrency.
|
||||
|
||||
## Features
|
||||
- Telegram tipping via subaddresses
|
||||
- Wallet interaction via JSON-RPC
|
||||
- Secure MySQL backend using PDO
|
||||
- Deposit, withdraw, balance, and tipping commands
|
||||
- Cron-compatible monitoring of deposits and withdrawals
|
||||
|
||||
## Installation
|
||||
1. Clone the repo
|
||||
2. Update `config.php` with your RPC, DB, and Telegram Bot credentials
|
||||
3. Run `salvium_tipbot.php` as a Telegram webhook listener
|
||||
4. Schedule `salvium_tipbot_monitor.php` using `cron` for periodic checks
|
||||
|
||||
## Requirements
|
||||
- PHP 8.1+
|
||||
- MySQL 5.7+/MariaDB
|
||||
- Telegram Bot Token
|
||||
- Salvium RPC Wallet node
|
||||
|
||||
## License
|
||||
MIT
|
||||
*/
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
// salvium_tipbot.php
|
||||
use Salvium\SalviumTipBotDB;
|
||||
use Salvium\SalviumWallet;
|
||||
|
||||
$config = require __DIR__ . '/config.php';
|
||||
require_once __DIR__ . '/src/salvium_tipbot_db.php';
|
||||
require_once __DIR__ . '/src/salvium_tipbot_wallet.php';
|
||||
|
||||
$db = new SalviumTipBotDB($config);
|
||||
$wallet = new SalviumWallet(
|
||||
$config['SALVIUM_RPC_HOST'],
|
||||
$config['SALVIUM_RPC_PORT'],
|
||||
$config['SALVIUM_RPC_USERNAME'],
|
||||
$config['SALVIUM_RPC_PASSWORD']
|
||||
);
|
||||
|
||||
function sendMessage(int $chatId, string $text, array $options = []): void {
|
||||
global $config;
|
||||
$payload = array_merge(['chat_id' => $chatId, 'text' => $text], $options);
|
||||
file_get_contents("https://api.telegram.org/bot{$config['TELEGRAM_BOT_TOKEN']}/sendMessage?" . http_build_query($payload));
|
||||
}
|
||||
|
||||
$update = json_decode(file_get_contents("php://input"), true);
|
||||
if (!$update || !isset($update['message'])) exit;
|
||||
|
||||
$message = $update['message'];
|
||||
$chatId = $message['chat']['id'];
|
||||
$userId = $message['from']['id'];
|
||||
$username = $message['from']['username'] ?? '';
|
||||
$text = trim($message['text'] ?? '');
|
||||
$args = explode(' ', $text);
|
||||
$command = strtolower($args[0] ?? '');
|
||||
|
||||
switch ($command) {
|
||||
case '/start':
|
||||
sendMessage($chatId, "Welcome to the Salvium Tip Bot! Use /deposit to get started.");
|
||||
break;
|
||||
|
||||
case '/deposit':
|
||||
$user = $db->getUserByTelegramId($userId);
|
||||
if (!$user) {
|
||||
$subaddress = $wallet->getNewSubaddress();
|
||||
if (!$subaddress) {
|
||||
sendMessage($chatId, "Error generating subaddress. Try again later.");
|
||||
exit;
|
||||
}
|
||||
$db->createUser($userId, $subaddress);
|
||||
$user = ['salvium_subaddress' => $subaddress];
|
||||
}
|
||||
sendMessage($chatId, "Your Salvium deposit address is: {$user['salvium_subaddress']}");
|
||||
break;
|
||||
|
||||
case '/balance':
|
||||
$user = $db->getUserByTelegramId($userId);
|
||||
if (!$user) {
|
||||
sendMessage($chatId, "You don't have an account yet. Use /deposit to create one.");
|
||||
break;
|
||||
}
|
||||
sendMessage($chatId, "Your balance: {$user['tip_balance']} XSL.");
|
||||
break;
|
||||
|
||||
case '/withdraw':
|
||||
if (count($args) < 3) {
|
||||
sendMessage($chatId, "Usage: /withdraw <address> <amount>");
|
||||
break;
|
||||
}
|
||||
list(, $address, $amount) = $args;
|
||||
$amount = (float)$amount;
|
||||
$user = $db->getUserByTelegramId($userId);
|
||||
if (!$user || $user['tip_balance'] < $amount) {
|
||||
sendMessage($chatId, "Insufficient balance or invalid account.");
|
||||
break;
|
||||
}
|
||||
if (!preg_match('/^4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}$/', $address)) {
|
||||
sendMessage($chatId, "Invalid address format.");
|
||||
break;
|
||||
}
|
||||
$db->updateUserTipBalance($user['id'], $amount, 'subtract');
|
||||
$db->logWithdrawal($user['id'], $address, $amount);
|
||||
sendMessage($chatId, "Withdrawal request submitted. Processing soon.");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (str_starts_with($command, '/tip')) {
|
||||
if (count($args) < 3) {
|
||||
sendMessage($chatId, "Usage: /tip <username> <amount>");
|
||||
break;
|
||||
}
|
||||
list(, $targetUsername, $amount) = $args;
|
||||
$amount = (float)$amount;
|
||||
$sender = $db->getUserByTelegramId($userId);
|
||||
$recipient = $db->getUserByTelegramId(ltrim($targetUsername, '@'));
|
||||
if (!$sender || $sender['tip_balance'] < $amount) {
|
||||
sendMessage($chatId, "Insufficient funds or invalid sender.");
|
||||
break;
|
||||
}
|
||||
if (!$recipient) {
|
||||
sendMessage($chatId, "Recipient not found. Ask them to run /start first.");
|
||||
break;
|
||||
}
|
||||
$db->updateUserTipBalance($sender['id'], $amount, 'subtract');
|
||||
$db->addTip($sender['id'], $recipient['id'], $amount, $chatId);
|
||||
sendMessage($chatId, "Tipped {$targetUsername} {$amount} XSL successfully!");
|
||||
sendMessage($recipient['telegram_user_id'], "You received a tip of {$amount} XSL! Use /balance to check.");
|
||||
} else {
|
||||
sendMessage($chatId, "Unknown command.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
// salvium_tipbot.php
|
||||
use Salvium\SalviumTipBotDB;
|
||||
use Salvium\SalviumWallet;
|
||||
|
||||
$config = require __DIR__ . '/config.php';
|
||||
require_once __DIR__ . '/src/salvium_tipbot_db.php';
|
||||
require_once __DIR__ . '/src/salvium_tipbot_wallet.php';
|
||||
|
||||
$db = new SalviumTipBotDB($config);
|
||||
$wallet = new SalviumWallet(
|
||||
$config['SALVIUM_RPC_HOST'],
|
||||
$config['SALVIUM_RPC_PORT'],
|
||||
$config['SALVIUM_RPC_USERNAME'],
|
||||
$config['SALVIUM_RPC_PASSWORD']
|
||||
);
|
||||
|
||||
function sendMessage(int $chatId, string $text, array $options = []): void {
|
||||
global $config;
|
||||
$payload = array_merge(['chat_id' => $chatId, 'text' => $text], $options);
|
||||
file_get_contents("https://api.telegram.org/bot{$config['TELEGRAM_BOT_TOKEN']}/sendMessage?" . http_build_query($payload));
|
||||
}
|
||||
|
||||
$update = json_decode(file_get_contents("php://input"), true);
|
||||
if (!$update || !isset($update['message'])) exit;
|
||||
|
||||
$message = $update['message'];
|
||||
$chatId = $message['chat']['id'];
|
||||
$userId = $message['from']['id'];
|
||||
$username = $message['from']['username'] ?? '';
|
||||
$text = trim($message['text'] ?? '');
|
||||
$args = explode(' ', $text);
|
||||
$command = strtolower($args[0] ?? '');
|
||||
|
||||
switch ($command) {
|
||||
case '/start':
|
||||
sendMessage($chatId, "Welcome to the Salvium Tip Bot! Use /deposit to get started.");
|
||||
break;
|
||||
|
||||
case '/deposit':
|
||||
$user = $db->getUserByTelegramId($userId);
|
||||
if (!$user) {
|
||||
$subaddress = $wallet->getNewSubaddress();
|
||||
if (!$subaddress) {
|
||||
sendMessage($chatId, "Error generating subaddress. Try again later.");
|
||||
exit;
|
||||
}
|
||||
$db->createUser($userId, $subaddress);
|
||||
$user = ['salvium_subaddress' => $subaddress];
|
||||
}
|
||||
sendMessage($chatId, "Your Salvium deposit address is: {$user['salvium_subaddress']}");
|
||||
break;
|
||||
|
||||
case '/balance':
|
||||
$user = $db->getUserByTelegramId($userId);
|
||||
if (!$user) {
|
||||
sendMessage($chatId, "You don't have an account yet. Use /deposit to create one.");
|
||||
break;
|
||||
}
|
||||
sendMessage($chatId, "Your balance: {$user['tip_balance']} XSL.");
|
||||
break;
|
||||
|
||||
case '/withdraw':
|
||||
if (count($args) < 3) {
|
||||
sendMessage($chatId, "Usage: /withdraw <address> <amount>");
|
||||
break;
|
||||
}
|
||||
list(, $address, $amount) = $args;
|
||||
$amount = (float)$amount;
|
||||
$user = $db->getUserByTelegramId($userId);
|
||||
if (!$user || $user['tip_balance'] < $amount) {
|
||||
sendMessage($chatId, "Insufficient balance or invalid account.");
|
||||
break;
|
||||
}
|
||||
if (!preg_match('/^4[0-9AB][1-9A-HJ-NP-Za-km-z]{93}$/', $address)) {
|
||||
sendMessage($chatId, "Invalid address format.");
|
||||
break;
|
||||
}
|
||||
$db->updateUserTipBalance($user['id'], $amount, 'subtract');
|
||||
$db->logWithdrawal($user['id'], $address, $amount);
|
||||
sendMessage($chatId, "Withdrawal request submitted. Processing soon.");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (str_starts_with($command, '/tip')) {
|
||||
if (count($args) < 3) {
|
||||
sendMessage($chatId, "Usage: /tip <username> <amount>");
|
||||
break;
|
||||
}
|
||||
list(, $targetUsername, $amount) = $args;
|
||||
$amount = (float)$amount;
|
||||
$sender = $db->getUserByTelegramId($userId);
|
||||
$recipient = $db->getUserByTelegramId(ltrim($targetUsername, '@'));
|
||||
if (!$sender || $sender['tip_balance'] < $amount) {
|
||||
sendMessage($chatId, "Insufficient funds or invalid sender.");
|
||||
break;
|
||||
}
|
||||
if (!$recipient) {
|
||||
sendMessage($chatId, "Recipient not found. Ask them to run /start first.");
|
||||
break;
|
||||
}
|
||||
$db->updateUserTipBalance($sender['id'], $amount, 'subtract');
|
||||
$db->addTip($sender['id'], $recipient['id'], $amount, $chatId);
|
||||
sendMessage($chatId, "Tipped {$targetUsername} {$amount} XSL successfully!");
|
||||
sendMessage($recipient['telegram_user_id'], "You received a tip of {$amount} XSL! Use /balance to check.");
|
||||
} else {
|
||||
sendMessage($chatId, "Unknown command.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
// src/salvium_tipbot_db.php
|
||||
namespace Salvium;
|
||||
|
||||
use PDO;
|
||||
use PDOException;
|
||||
|
||||
class SalviumTipBotDB {
|
||||
private PDO $pdo;
|
||||
|
||||
public function __construct(array $config) {
|
||||
try {
|
||||
$dsn = "mysql:host={$config['DB_HOST']};dbname={$config['DB_NAME']};charset={$config['DB_CHARSET']}";
|
||||
$this->pdo = new PDO($dsn, $config['DB_USER'], $config['DB_PASS']);
|
||||
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
} catch (PDOException $e) {
|
||||
error_log("Database connection failed: " . $e->getMessage());
|
||||
die("Database connection error.");
|
||||
}
|
||||
}
|
||||
|
||||
// --- Table Creation SQL (Commented for reference) ---
|
||||
/*
|
||||
CREATE TABLE users (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
telegram_user_id BIGINT UNIQUE NOT NULL,
|
||||
salvium_subaddress VARCHAR(128) UNIQUE NOT NULL,
|
||||
tip_balance DECIMAL(20, 12) DEFAULT 0.000000000000,
|
||||
withdrawal_address VARCHAR(128),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE deposits (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
txid VARCHAR(64) UNIQUE NOT NULL,
|
||||
amount DECIMAL(20, 12) NOT NULL,
|
||||
block_height INT NOT NULL,
|
||||
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE withdrawals (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id INT NOT NULL,
|
||||
txid VARCHAR(64),
|
||||
address VARCHAR(128) NOT NULL,
|
||||
amount DECIMAL(20, 12) NOT NULL,
|
||||
status ENUM('pending', 'sent', 'failed') DEFAULT 'pending',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE TABLE tips (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
sender_user_id INT NOT NULL,
|
||||
recipient_user_id INT NOT NULL,
|
||||
amount DECIMAL(20, 12) NOT NULL,
|
||||
channel_id BIGINT,
|
||||
status ENUM('pending', 'credited') DEFAULT 'pending',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (sender_user_id) REFERENCES users(id),
|
||||
FOREIGN KEY (recipient_user_id) REFERENCES users(id)
|
||||
);
|
||||
*/
|
||||
|
||||
public function getUserByTelegramId(int $telegramUserId): array|false {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE telegram_user_id = ?");
|
||||
$stmt->execute([$telegramUserId]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function getUserBySubaddress(string $subaddress): array|false {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE salvium_subaddress = ?");
|
||||
$stmt->execute([$subaddress]);
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function createUser(int $telegramUserId, string $subaddress): bool {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO users (telegram_user_id, salvium_subaddress) VALUES (?, ?)");
|
||||
return $stmt->execute([$telegramUserId, $subaddress]);
|
||||
}
|
||||
|
||||
public function updateUserTipBalance(int $userId, float $amount, string $operation = 'add'): bool {
|
||||
$sql = $operation === 'add' ? "UPDATE users SET tip_balance = tip_balance + ? WHERE id = ?" : "UPDATE users SET tip_balance = tip_balance - ? WHERE id = ?";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
return $stmt->execute([$amount, $userId]);
|
||||
}
|
||||
|
||||
public function setWithdrawalAddress(int $userId, string $address): bool {
|
||||
$stmt = $this->pdo->prepare("UPDATE users SET withdrawal_address = ? WHERE id = ?");
|
||||
return $stmt->execute([$address, $userId]);
|
||||
}
|
||||
|
||||
public function logDeposit(int $userId, string $txid, float $amount, int $blockHeight): bool {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO deposits (user_id, txid, amount, block_height) VALUES (?, ?, ?, ?)");
|
||||
return $stmt->execute([$userId, $txid, $amount, $blockHeight]);
|
||||
}
|
||||
|
||||
public function isTxidLogged(string $txid): bool {
|
||||
$stmt = $this->pdo->prepare("SELECT COUNT(*) FROM deposits WHERE txid = ?");
|
||||
$stmt->execute([$txid]);
|
||||
return $stmt->fetchColumn() > 0;
|
||||
}
|
||||
|
||||
public function logWithdrawal(int $userId, string $address, float $amount): int|false {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO withdrawals (user_id, address, amount) VALUES (?, ?, ?)");
|
||||
if ($stmt->execute([$userId, $address, $amount])) {
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateWithdrawalTxid(int $withdrawalId, string $txid): bool {
|
||||
$stmt = $this->pdo->prepare("UPDATE withdrawals SET txid = ? WHERE id = ?");
|
||||
return $stmt->execute([$txid, $withdrawalId]);
|
||||
}
|
||||
|
||||
public function updateWithdrawalStatus(int $withdrawalId, string $status): bool {
|
||||
$stmt = $this->pdo->prepare("UPDATE withdrawals SET status = ? WHERE id = ?");
|
||||
return $stmt->execute([$status, $withdrawalId]);
|
||||
}
|
||||
|
||||
public function addTip(int $senderUserId, int $recipientUserId, float $amount, ?int $channelId = null): bool {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO tips (sender_user_id, recipient_user_id, amount, channel_id) VALUES (?, ?, ?, ?)");
|
||||
return $stmt->execute([$senderUserId, $recipientUserId, $amount, $channelId]);
|
||||
}
|
||||
|
||||
public function getPendingTipsForUser(int $recipientUserId): array {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM tips WHERE recipient_user_id = ? AND status = 'pending'");
|
||||
$stmt->execute([$recipientUserId]);
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
public function markTipsAsCredited(array $tipIds): bool {
|
||||
$placeholders = implode(',', array_fill(0, count($tipIds), '?'));
|
||||
$stmt = $this->pdo->prepare("UPDATE tips SET status = 'credited' WHERE id IN ($placeholders)");
|
||||
return $stmt->execute($tipIds);
|
||||
}
|
||||
|
||||
public function getPendingWithdrawals(): array {
|
||||
$stmt = $this->pdo->query("SELECT * FROM withdrawals WHERE status = 'pending'");
|
||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
// src/salvium_tipbot_wallet.php
|
||||
namespace Salvium;
|
||||
|
||||
class SalviumWallet {
|
||||
private string $host;
|
||||
private int $port;
|
||||
private ?string $username;
|
||||
private ?string $password;
|
||||
|
||||
public function __construct(string $host, int $port, ?string $username = null, ?string $password = null) {
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->username = $username;
|
||||
$this->password = $password;
|
||||
}
|
||||
|
||||
private function _callRpc(string $method, array $params = []): array|false {
|
||||
$url = "http://{$this->host}:{$this->port}/json_rpc";
|
||||
$request = json_encode([
|
||||
'jsonrpc' => '2.0',
|
||||
'id' => '0',
|
||||
'method' => $method,
|
||||
'params' => $params
|
||||
]);
|
||||
|
||||
$headers = ['Content-Type: application/json'];
|
||||
$options = [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => $request,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
];
|
||||
|
||||
if ($this->username && $this->password) {
|
||||
$options[CURLOPT_USERPWD] = "{$this->username}:{$this->password}";
|
||||
}
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, $options);
|
||||
$response = curl_exec($ch);
|
||||
|
||||
if (curl_errno($ch)) {
|
||||
error_log('RPC Curl Error: ' . curl_error($ch));
|
||||
curl_close($ch);
|
||||
return false;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
$decoded = json_decode($response, true);
|
||||
return $decoded['result'] ?? false;
|
||||
}
|
||||
|
||||
public function getWalletBalance(): array|false {
|
||||
return $this->_callRpc('get_balance');
|
||||
}
|
||||
|
||||
public function getNewSubaddress(int $accountIndex = 0, ?string $label = null): string|false {
|
||||
$params = ['account_index' => $accountIndex];
|
||||
if ($label) $params['label'] = $label;
|
||||
$result = $this->_callRpc('create_address', $params);
|
||||
return $result['address'] ?? false;
|
||||
}
|
||||
|
||||
public function getAddresses(): array|false {
|
||||
$result = $this->_callRpc('get_address');
|
||||
return $result['addresses'] ?? false;
|
||||
}
|
||||
|
||||
public function transfer(array $destinations, int $mixin = 11, int $unlockTime = 0, bool $getTxKey = false, bool $doNotRelay = false): array|false {
|
||||
$params = [
|
||||
'destinations' => $destinations,
|
||||
'mixin' => $mixin,
|
||||
'unlock_time' => $unlockTime,
|
||||
'get_tx_key' => $getTxKey,
|
||||
'do_not_relay' => $doNotRelay
|
||||
];
|
||||
return $this->_callRpc('transfer', $params);
|
||||
}
|
||||
|
||||
public function getTransfers(string $inOrOut = 'in', bool $pending = false, bool $failed = false): array|false {
|
||||
$params = [
|
||||
$inOrOut => true,
|
||||
'pending' => $pending,
|
||||
'failed' => $failed
|
||||
];
|
||||
$result = $this->_callRpc('get_transfers', $params);
|
||||
return $result[$inOrOut] ?? false;
|
||||
}
|
||||
|
||||
public function getPayments(string $paymentId): array|false {
|
||||
$result = $this->_callRpc('get_payments', ['payment_id' => $paymentId]);
|
||||
return $result['payments'] ?? false;
|
||||
}
|
||||
|
||||
public function getHeight(): int|false {
|
||||
$result = $this->_callRpc('get_height');
|
||||
return $result['height'] ?? false;
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user