UPLOAD INSTRUCTIONS (cPanel)

1) Upload this ZIP contents into:
   /home/abir/public_html/

2) Your URLs:
   https://testtonapp.shajahanabir.top/app/
   https://testtonapp.shajahanabir.top/admin/

3) Create DB + import schema.sql (phpMyAdmin):
   - Create DB: ton_app
   - Create user and assign ALL PRIVILEGES
   - Import api/schema.sql

4) Edit api/config.php:
   - DB user/pass
   - telegram_bot_token (ROTATED)
   - api_key (same in app/admin HTML)

5) Cron Jobs (every 1 minute):
   /usr/local/bin/php -q /home/abir/public_html/api/cron_package_settle.php >/dev/null 2>&1
   /usr/local/bin/php -q /home/abir/public_html/api/cron_verify_deposits.php >/dev/null 2>&1

TASK VERIFICATION NOTE
- getChatMember is only guaranteed if the bot is an admin in the channel/group. (Telegram Bot API docs)

WITHDRAW AUTO-SEND (OPTIONAL)
- cPanel often blocks node/exec. If you want auto-send:
  a) Ensure Node.js is available and exec() enabled.
  b) In /home/abir/public_html/sender:
     npm install @ton/ton @ton/crypto
  c) Set env vars for cron or server:
     TON_ENDPOINT=https://toncenter.com/api/v2/jsonRPC
     TON_API_KEY=...
     TON_MNEMONIC="24 words..."
  d) Enable autosend in DB:
     UPDATE settings SET sval='1' WHERE skey='auto_system_enabled';
     UPDATE settings SET sval='1' WHERE skey='withdraw_autosend';

NO NODE.JS MODE
- Withdraw auto-send is disabled if Node.js/exec isn't available.
- Admin approves withdraw (deducts user balance), then manually sends TON and uses 'Mark Sent' button to save tx hash.

API KEY (already set)
- This package has API_KEY prefilled in app/admin and api/config.php.
- If you change it, update all three places.

ADMIN LOGIN (Browser username/password)
- Admin panel now uses username/password stored in DB table admin_users.
- If you already imported old schema.sql, run the SQL PATCH below in phpMyAdmin.

SQL PATCH (run once):
CREATE TABLE IF NOT EXISTS admin_users (
  admin_id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(64) NOT NULL UNIQUE,
  password_hash VARCHAR(255) NOT NULL,
  is_active TINYINT(1) NOT NULL DEFAULT 1,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

-- If admin_sessions already exists with FK to admins, drop and recreate:
DROP TABLE IF EXISTS admin_sessions;

CREATE TABLE IF NOT EXISTS admin_sessions (
  token CHAR(64) PRIMARY KEY,
  admin_id INT NOT NULL,
  expires_at DATETIME NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  INDEX(admin_id),
  FOREIGN KEY (admin_id) REFERENCES admin_users(admin_id) ON DELETE CASCADE
) ENGINE=InnoDB;

Then insert your admin user (example):
INSERT INTO admin_users(username, password_hash, is_active)
VALUES ('admin@gmail.com', '<bcrypt_hash_here>', 1)
ON DUPLICATE KEY UPDATE password_hash=VALUES(password_hash), is_active=1;

TASKS TABLE PATCH (only if Admin->Tasks can't save / db_error):
CREATE TABLE IF NOT EXISTS tasks (
  task_id INT PRIMARY KEY,
  title VARCHAR(64) NOT NULL,
  chat_id VARCHAR(128) NOT NULL,
  reward DECIMAL(18,6) NOT NULL,
  is_active TINYINT(1) NOT NULL DEFAULT 1
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS user_tasks (
  ut_id BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id BIGINT NOT NULL,
  task_id INT NOT NULL,
  claimed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uq_task (user_id, task_id),
  FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
  FOREIGN KEY (task_id) REFERENCES tasks(task_id) ON DELETE CASCADE
) ENGINE=InnoDB;


[Admin Routing]
- Admin entry: /admin (uses /admin/index.php)
- If your ROOT .htaccess rewrites everything to /index.php and /admin gives 404, add this ABOVE your other RewriteRules:
  RewriteRule ^admin(/.*)?$ - [L]
