A Discord bot that enables seamless Solana (SOL) tipping and airdrops with automatic wallet creation for users.
- On-Demand Wallet Creation - Automatically creates Solana wallets when users receive their first tip or airdrop
- Secure Encryption - Private keys encrypted with AES-256-GCM
- Discord Integration - Slash commands for tipping, airdrops, and wallet management
- User-Friendly - No complex setup required for recipients
- Transaction Tracking - Full transaction history and verification
- π€ Intelligent FAQ Bot - Natural language question answering with 20+ FAQs
- π¬ Natural Language Processing - Process transactions using natural conversation
- π Automated Reports - Generate transaction reports with analytics
- π― Contextual Help - Smart assistance based on user intent
Ask questions naturally and get instant answers:
- "How do I create a wallet?"
- "Is JustTheTip safe?"
- "What are the fees?"
Use /faq to browse categories or search for specific topics.
Talk to the bot naturally:
- "send 0.5 SOL to @friend"
- "what's my balance?"
- "show my transaction history"
The bot understands your intent and helps you complete actions.
Generate detailed transaction reports:
/report period:this_week- Weekly activity summary/report period:this_month- Monthly statistics- Analytics including top tippers, volume, and trends
See Intelligent Features Documentation for details.
βββ db/
β βββ db.js # SQLite database connection
β βββ walletManager.js # On-demand wallet creation & management
βββ utils/
β βββ walletHelper.js # Helper functions for tip/airdrop commands
βββ examples/
β βββ tipCommandIntegration.js # Example command implementation
βββ scripts/
βββ migrateToOnDemand.js # Migration from pre-gen system
-- User wallets with encrypted private keys
CREATE TABLE user_wallets (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT UNIQUE NOT NULL, -- Discord user ID
wallet_address TEXT NOT NULL, -- Solana public key
wallet_id TEXT UNIQUE NOT NULL, -- Internal wallet UUID
private_key_encrypted TEXT NOT NULL, -- AES-256-GCM encrypted private key
network TEXT DEFAULT 'solana',
auth_method TEXT DEFAULT 'auto-generated',
created_at INTEGER NOT NULL,
created_trigger TEXT DEFAULT 'manual', -- 'tip', 'airdrop', 'manual'
discord_username TEXT,
user_email TEXT,
last_used_at INTEGER
);- Node.js 16+
- Discord Bot Token
- Solana RPC endpoint
- SQLite3
# Clone repository
git clone https://github.com/jmenichole/Justthetip.git
cd Justthetip
# Install dependencies
npm install
# Set environment variables
cp .env.example .env
# Edit .env with your configuration# Discord
DISCORD_TOKEN=your_discord_bot_token
CLIENT_ID=your_discord_client_id
# Solana
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
SOLANA_NETWORK=mainnet-beta
# Security
WALLET_ENCRYPTION_KEY=your_32_byte_encryption_key_here
# Database
DATABASE_PATH=./data/bot.dbnode scripts/migrateToOnDemand.jsconst walletHelper = require('./utils/walletHelper');
// In your tip command
async function handleTip(interaction, recipient, amount) {
// Ensure recipient has wallet (creates if needed)
const walletResult = await walletHelper.ensureWalletForTip(recipient.id, {
username: recipient.username
});
if (!walletResult.success) {
return interaction.reply(walletResult.message);
}
// Process transaction to walletResult.wallet.wallet_address
const txResult = await processTransaction(amount, walletResult.wallet.wallet_address);
// Notify user if wallet was auto-created
if (walletResult.created) {
await notifyNewWallet(recipient, walletResult.wallet);
}
}// For airdrop commands
const walletResult = await walletHelper.ensureWalletForAirdrop(userId, userData);const walletManager = require('./db/walletManager');
// Check if user has wallet
const wallet = walletManager.getUserWallet(userId);
// Get private key for transactions (be careful!)
const privateKey = walletManager.getUserPrivateKey(userId);
// Get wallet statistics
const stats = walletManager.getWalletStats();// FAQ Service
const { searchFAQ, analyzeIntent } = require('./src/services/faqService');
// Search FAQs
const results = searchFAQ('how to create wallet');
// Analyze user intent
const intent = analyzeIntent('what is my balance?');
// Natural Language Service
const { processNaturalLanguage } = require('./src/services/naturalLanguageService');
// Process natural language message
const intent = processNaturalLanguage('send 0.5 SOL to @user');
// Report Service
const { generateUserReport } = require('./src/services/reportService');
// Generate transaction report
const report = await generateUserReport(userId, transactions, 'this_week');Core Commands:
/tip @user 0.1 # Tip user 0.1 SOL (creates wallet if needed)
/airdrop 0.05 50 # Airdrop 0.05 SOL to 50 claimers
/register-magic # Create wallet with Discord OAuth
/status # Check your connection and balance
/logs # View transaction history
/disconnect-wallet # Unlink your wallet
/support <issue> # Report issues
New Intelligent Commands:
/faq # Browse FAQ categories
/faq query:<question> # Search FAQs (e.g., "how to tip")
/faq category:tipping # View FAQs by category
/report # Generate weekly transaction report
/report period:this_month # Generate monthly report
Natural Language (DM or @mention):
"How do I create a wallet?" # Get FAQ answer
"what's my balance?" # Check balance
"send 0.5 SOL to @friend" # Initiate tip
"show my transactions" # View history
"generate my weekly report" # Create report
- AES-256-GCM encryption for private keys
- Unique IV for each encryption operation
- Authentication tags prevent tampering
- Environment-based keys for production security
- Private keys never stored in plaintext
- Automatic wallet creation reduces user error
- Transaction verification and logging
- Rate limiting on wallet operations
class WalletManager {
// Create wallet when user receives tip/airdrop
async createWalletForUser(userId, userData, trigger)
// Check if user has existing wallet
getUserWallet(userId)
// Get decrypted private key for transactions
getUserPrivateKey(userId)
// Generate new Solana keypair
generateSolanaWallet()
}class WalletHelper {
// Ensure wallet exists for tip recipient
async ensureWalletForTip(userId, userData)
// Ensure wallet exists for airdrop recipient
async ensureWalletForAirdrop(userId, userData)
// Get formatted wallet info
getUserWalletInfo(userId)
}# Run tests
npm test
# Test wallet creation
node -e "
const wm = require('./db/walletManager');
wm.initializeWalletTables();
console.log('Tables initialized');
"
# Test encryption/decryption
node -e "
const wm = require('./db/walletManager');
const key = 'test_private_key_here';
const encrypted = wm.encryptPrivateKey(key);
const decrypted = wm.decryptPrivateKey(encrypted);
console.log('Encryption test:', key === decrypted ? 'PASS' : 'FAIL');
"const stats = walletManager.getWalletStats();
// Returns: { total, tipCreated, airdropCreated, createdToday }-- Check wallet creation triggers
SELECT created_trigger, COUNT(*) FROM user_wallets GROUP BY created_trigger;
-- Recent wallet activity
SELECT * FROM user_wallets WHERE created_at > datetime('now', '-7 days');If upgrading from the old pre-generation wallet system:
- Run
node scripts/migrateToOnDemand.js - Update all tip/airdrop commands to use
walletHelper - Remove old
pregenWalletDb.jsreferences
- Set strong
WALLET_ENCRYPTION_KEY(32 bytes) - Use secure Solana RPC endpoint
- Enable database backups
- Monitor wallet creation rates
- Implement transaction fee management
- User receives tip/airdrop without wallet
- Bot automatically creates encrypted wallet
- User gets notification with wallet address
- Bot sends transaction to new wallet
- User can manage wallet with Discord commands
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open Pull Request
This software is proprietary and confidential. Unauthorized copying, distribution, or use is strictly prohibited.
- GitHub Repository: github.com/jmenichole/Justthetip
- Landing Page: GitHub Pages
- API Server: Vercel Deployment
Built with β€οΈ for the Solana community