Skip to content

Tondi-Foundation/x-taskchecker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

105 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

X-TaskChecker

X-TaskChecker is an airdrop management system for the Tondi blockchain that integrates with Twitter (X) and Telegram to verify user tasks and distribute token rewards.

Features

  • Twitter (X) Integration: OAuth authentication and task verification
  • Telegram Integration: User verification and bot integration
  • Airdrop Management: Automated token distribution with configurable rewards
  • Invitation System: Referral tracking with milestone-based rewards
  • Task Verification: Automated checking of likes, retweets, quote tweets, and replies
  • Scheduled Processing: Periodic claim approval and airdrop distribution

Architecture

The system consists of:

  • External API (public-facing endpoints)
  • Internal API (administrative endpoints)
  • Background workers for task fetching and verification
  • SQLite database for state management
  • Tondi blockchain integration for token transfers

API Endpoints

Error Response Format

All API endpoints return errors in a standardized JSON format with appropriate HTTP status codes:

{
  "error": "Human-readable error message",
  "code": "MACHINE_READABLE_ERROR_CODE"
}

Common HTTP Status Codes:

  • 400 BAD_REQUEST - Invalid request parameters
  • 401 UNAUTHORIZED - Missing or invalid authentication
  • 403 FORBIDDEN - Insufficient permissions
  • 404 NOT_FOUND - Resource not found
  • 409 CONFLICT - Resource conflict (e.g., pool exhausted)
  • 429 TOO_MANY_REQUESTS - Rate limit exceeded
  • 500 INTERNAL_SERVER_ERROR - Server error

Common Error Codes:

  • AUTH_FAILED - Authentication failed
  • RATE_LIMITED - Too many requests
  • VALIDATION_FAILED - Request validation failed
  • RECORD_NOT_FOUND - Requested record not found

External API (Public)

Authentication & OAuth

GET /xlogin

Initiates Twitter OAuth flow.

  • Response: Redirects to Twitter OAuth URL
  • Sets cookie: pkce_verifier for OAuth verification
GET /oauth?code={authorization_code}

OAuth callback endpoint.

  • Query Parameters:
    • code: Authorization code from Twitter
  • Returns: Redirects to https://tondi.org/airdrop?token={jwt_token}&x_user_id={user_id}
  • Response: JWT token for authenticated user
  • Error Codes:
    • OAUTH_SESSION_EXPIRED - OAuth session invalid
    • INVALID_OAUTH_CODE - Invalid OAuth code
    • TOKEN_FAILED - Failed to obtain access token
    • OAUTH_FAILED - General OAuth failure

Task Verification

GET /checkxtasksstatus/{x_user_id}

Check X (Twitter) task completion status for a user.

  • Path Parameters:
    • x_user_id: Twitter user ID
  • Response:
{
  "user_id": "string",
  "liking_posts": ["post_id1", "post_id2"],
  "retweeted_posts": ["post_id1"],
  "quote_tweet_posts": ["post_id1"],
  "reply_posts": ["post_id1"]
}
  • Error Codes:
    • TASKS_NOT_FOUND - No task results found for user
    • TASKS_CHECK_FAILED - Failed to check task status
POST /checktguseringroup

Verify if a Telegram user is in the specified channel.

  • Headers:
    • Authorization: Bearer {tg_jwt_token}
  • Response: "true" or "false"
  • Error Codes:
    • RATE_LIMITED - Too many requests (max 1 per 2 seconds per user)
    • AUTH_FAILED - Invalid authorization token
    • CHECK_FAILED - Failed to verify membership

Claim Management

POST /applyclaim

Submit an airdrop claim request.

  • Headers:
    • Authorization: Bearer {x_jwt_token}
    • X-Real-IP: User's IP address (set by proxy)
  • Request Body:
{
  "tg_auth": "telegram_jwt_token",
  "recv_address": "tondi_testnet_address"
}
  • Response: 200 OK or error response
  • Error Codes:
    • AUTH_FAILED - Invalid authorization token
    • INVALID_ADDRESS - Invalid TON wallet address format
    • INVALID_NETWORK - Only testnet addresses accepted
    • POOL_EXHAUSTED - Airdrop pool exhausted
    • VALIDATION_FAILED - Request validation failed
    • CLAIM_FAILED - Failed to submit claim
POST /claimstatus

Check the status of a claim.

  • Headers:
    • Authorization: Bearer {x_jwt_token}
  • Request Body: tg_token (string)
  • Response:
{
  "x_user_id": "string",
  "x_username": "string",
  "tg_user_id": "string",
  "tg_username": "string",
  "create_timestamp": 1234567890,
  "status": "pending_review|waiting_manual_verification|claim_submitted|claim_denied",
  "amount": 15000000,
  "lock_amount": 85000000,
  "recv_address": "tondi_testnet_address",
  "airdrop_tx": [...],
  "user_ip": "127.0.0.1"
}
  • Error Codes:
    • AUTH_FAILED - Invalid authorization token
    • RECORD_NOT_FOUND - No claim record found
    • STATUS_FAILED - Failed to retrieve status
GET /airdroppoolstatus

Get the current status of the airdrop pool.

  • Response:
{
  "claimed_amount": 1000,
  "total_amount": 10000,
  "pre_claimed_amount": 0
}
  • Error Codes:
    • POOL_STATUS_FAILED - Failed to retrieve pool status

Invitation System

POST /geninvitationcode

Generate an invitation code for the authenticated user.

  • Headers:
    • Authorization: Bearer {x_jwt_token}
  • Request Body:
{
  "tg_token": "telegram_jwt_token"
}
  • Response:
{
  "invitation_code": "abc123de"
}
  • Error Codes:
    • AUTH_FAILED - Invalid authorization token
    • CLAIM_NOT_FOUND - Claim record not found
    • CLAIM_DENIED - Claim has been denied
    • GENERATION_FAILED - Failed to generate code
    • GEN_CODE_FAILED - General generation failure
POST /bindinviterinvitee

Bind an invitee to an inviter using invitation code.

  • Headers:
    • Authorization: Bearer {x_jwt_token}
  • Request Body:
{
  "invitation_code": "abc123de",
  "tg_token": "telegram_jwt_token"
}
  • Response: 200 OK or error response
  • Error Codes:
    • AUTH_FAILED - Invalid authorization token
    • CLAIM_NOT_FOUND - Claim record not found
    • CLAIM_DENIED - Claim has been denied
    • INVALID_INVITATION_CODE - Invalid invitation code
    • SELF_INVITATION - Cannot use own invitation code
    • BIND_FAILED - Failed to bind relationship
GET /getinviter/{invitee}

Get the inviter address for a specific invitee.

  • Path Parameters:
    • invitee: Invitee's Tondi address
  • Response:
{
  "inviter": "tondi_testnet_address"
}
  • Note: Returns {"inviter": null} if no inviter is found
  • Error Codes:
    • INVITER_FAILED - Failed to retrieve inviter
GET /countinvitees/{inviter}

Count total and available invitees for an inviter.

  • Path Parameters:
    • inviter: Inviter's Tondi address
  • Response:
{
  "total_invitees": 10,
  "available_invitees": 8
}
  • Error Codes:
    • COUNT_FAILED - Failed to count invitees
GET /milestones

Get the configured invitation milestones.

  • Response:
[
  {"invitees_count": 1, "reward_amount": 10},
  {"invitees_count": 5, "reward_amount": 20},
  {"invitees_count": 10, "reward_amount": 30}
]
GET /milestonesairdroprecords/{inviter}

Get milestone reward records for an inviter.

  • Path Parameters:
    • inviter: Inviter's Tondi address
  • Response:
[
  {
    "inviter": "tondi_testnet_address",
    "amount": 20,
    "invitees_count": 5,
    "create_timestamp": 1234567890,
    "airdrop_tx": [...]
  }
]
  • Error Codes:
    • RECORDS_FAILED - Failed to retrieve records

Internal API (Administrative)

POST /taskupdate

Update the task configuration (admin only).

  • Headers:
    • Authorization: Bearer {admin_jwt_token}
  • Request Body:
{
  "watch_tweets": ["tweet_id1", "tweet_id2", "tweet_id3"]
}
  • Response: 200 OK or 500 with error message

Configuration

Environment Variables

Required environment variables:

# Twitter OAuth credentials
API_KEY_CODE="your_twitter_api_key"
API_SECRET_CODE="your_twitter_api_secret"
CALLBACK_URL="https://your-domain.com/oauth"

# Database
DATABASE_URL="sqlite://sqlite-db/taskchecker.db"

# Telegram Bot
TG_BOT_TOKEN="your_telegram_bot_token"
TG_CHANNEL="@YOUR_CHANNEL"

# Airdrop configuration
AIRDROP_SENDER_SK="sender_private_key_hex"

# Admin user (for task updates)
ADMIN_X_USERNAME="admin_twitter_username"

Command Line Arguments

cargo run --release -- \
  --network "testnet" \
  --airdrop-total-amount 100000000000 \
  --pre-claimed-amount 0 \
  --amount-per-claim 100 \
  --tondi-node-url "grpc://localhost:16210" \
  --lock-time 1764839943070 \
  --external-bind-addr "0.0.0.0:80" \
  --internal-api-addr "0.0.0.0:8080" \
  --task-call-interval-secs 900 \
  --approve-claim-interval-mins 10 \
  --invite-milestone "[[1, 10], [5, 20], [10, 30]]" \
  --set-invite-code-reward-amount 10

Arguments Description

  • --network: Network type (mainnet, testnet, devnet)
  • --airdrop-total-amount: Total tokens available for airdrop (in smallest unit)
  • --pre-claimed-amount: Amount already claimed before system start
  • --amount-per-claim: Tokens awarded per successful claim
  • --tondi-node-url: Tondi GRPC node URL
  • --lock-time: Lock time in Unix timestamp or block height for locked tokens
  • --external-bind-addr: Public API bind address (default: 0.0.0.0:80)
  • --internal-api-addr: Internal API bind address (default: 0.0.0.0:8080)
  • --task-call-interval-secs: Interval between task fetching calls (default: 900 seconds / 15 minutes)
  • --approve-claim-interval-mins: Interval between claim approval runs (default: 10 minutes)
  • --invite-milestone: JSON array of [invitee_count, reward_amount] pairs
  • --set-invite-code-reward-amount: Reward amount for setting invitation code

Token Distribution

Claim Distribution

Each claim distributes tokens with a lock mechanism:

  • 15% non-locked: Immediately available
  • 85% locked: Locked until the configured lock_time

Invitation Rewards

  • Invitee Reward: Fixed amount when an invitee successfully claims (configured via set-invite-code-reward-amount)
  • Milestone Rewards: Inviter receives additional rewards upon reaching invitation milestones

Claim Status Flow

  1. pending_review: Initial state after claim submission
  2. waiting_manual_verification: Tasks verified, awaiting final approval
  3. claim_submitted: Approved and tokens distributed
  4. claim_denied: Claim rejected

Task Verification Requirements

For a claim to be approved, users must complete:

  1. Like at least one tracked tweet
  2. Perform at least one of:
    • Retweet a tracked tweet
    • Quote tweet a tracked tweet
    • Reply to a tracked tweet
  3. Join the Telegram channel

Database

Uses SQLite database with tables for:

  • User tokens (OAuth credentials)
  • Claim records
  • Invitation mappings
  • Invitation codes
  • Invitee rewards
  • Milestone claim records

Database file location: sqlite-db/taskchecker.db

Building

# Build release version
cargo build --release

# Run tests
cargo test

# Run with configuration
./xtaskcheck-start.sh  # Linux/Mac
./xtaskcheck-start.ps1  # Windows

Background Workers

Task Fetchers

Four concurrent workers fetch Twitter data:

  1. Liking users fetcher
  2. Retweeted by fetcher
  3. Quote tweets fetcher
  4. Search recent (replies) fetcher

Data is stored in out/ directory as JSON files.

Claims Checker

Periodically checks claims in pending_review status and moves them to waiting_manual_verification when requirements are met.

Approve Claim Schedule

Automatically approves and processes claims in waiting_manual_verification status based on the configured interval.

Invitation Airdrop Schedule

  • Distributes rewards to invitees who successfully claim
  • Processes milestone rewards for inviters
  • Runs every 10 minutes

Security Notes

  • JWT tokens expire after 7 days for Twitter auth
  • Rate limiting on Telegram verification endpoint (2 seconds between requests per user)
  • Admin-only access to task update endpoint
  • IP address tracking for claim submissions
  • PKCE flow for Twitter OAuth
  • HTTPS and secure cookies for production use

License

See repository for license information.

About

TaskChecker can get the list of users who liked and retweeted a given tweet.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages