๐ฐ ECONOMY & BANKING SYSTEM CHEAT SHEET #
Ultra-Condensed Enlightenment Guide - CORRECTED VERSION
๐ฆ CORE BANK ARCHITECTURE #
- ๐ฏ Bank Module: redbot.core.bank (1088 lines, enterprise-grade banking system)
- ๐ง Storage Backend: Red’s Config API with JSON/PostgreSQL support
- ๐ Account Types: Global (cross-guild) or Per-Guild banking modes
- ๐จ Balance Management: Integer-only balances (no float precision issues)
- ๐ Cache System: Intelligent caching for default/max balances and bank names
- ๐ก๏ธ Transaction Safety: Atomic operations with rollback on exceptions
- ๐ฆ Account Model: Account class with name, balance, created_at attributes
- ๐ฏ Time Encoding: Unix timestamp encoding for account creation tracking
๐ฐ ESSENTIAL BANK API FUNCTIONS #
Core Balance Operations #
# Primary balance functions - EXACT signatures from bank.py
await bank.get_balance(member: discord.Member) -> int
await bank.set_balance(member: Union[discord.Member, discord.User], amount: int) -> int
await bank.can_spend(member: discord.Member, amount: int) -> bool
await bank.get_account(member: Union[discord.Member, discord.User]) -> Account
# Transaction functions with error handling
await bank.withdraw_credits(member: discord.Member, amount: int) -> int
await bank.deposit_credits(member: discord.Member, amount: int) -> int
await bank.transfer_credits(
from_: Union[discord.Member, discord.User],
to: Union[discord.Member, discord.User],
amount: int
) -> int # Returns new balance of recipient
Bank Configuration Functions #
# Global vs Guild modes
await bank.is_global() -> bool
await bank.set_global(global_: bool) -> bool
# Bank/Currency naming
await bank.get_bank_name(guild: discord.Guild = None) -> str
await bank.set_bank_name(name: str, guild: discord.Guild = None) -> str
await bank.get_currency_name(guild: discord.Guild = None) -> str
await bank.set_currency_name(name: str, guild: discord.Guild = None) -> str
# Balance limits and defaults
await bank.get_max_balance(guild: discord.Guild = None) -> int
await bank.set_max_balance(amount: int, guild: discord.Guild = None) -> int
await bank.get_default_balance(guild: discord.Guild = None) -> int
await bank.set_default_balance(amount: int, guild: discord.Guild = None) -> int
๐ LEADERBOARD & ANALYTICS #
Leaderboard Functions #
# Get ranked user list
await bank.get_leaderboard(
positions: int = None,
guild: discord.Guild = None
) -> List[tuple] # Returns [(user_id, raw_account), ...]
# Find user position
await bank.get_leaderboard_position(
member: Union[discord.User, discord.Member]
) -> Union[int, None]
Data Management #
# Administrative functions
await bank.wipe_bank(guild: Optional[discord.Guild] = None) -> None
await bank.bank_prune(
bot: Red,
guild: discord.Guild = None,
user_id: int = None
) -> None
โก TRANSACTION DECORATOR SYSTEM #
@cost Decorator - Command Cost Management #
from redbot.core.bank import cost, AbortPurchase
# Automatic cost deduction with refund on failure
@bank.cost(100) # Costs 100 credits
@commands.command()
async def gamble(self, ctx):
# Credits withdrawn automatically before command execution
try:
# Your command logic here
if success:
return await ctx.send("You won!")
else:
raise AbortPurchase() # Refunds the cost silently
except SomeError:
# Credits auto-refunded on any exception
raise
# Works on both commands and async functions
@bank.cost(50)
async def some_function(ctx):
# Function implementation
pass
๐จ ERROR HANDLING & EXCEPTIONS #
Bank-Specific Exception Types #
from redbot.core.errors import BalanceTooHigh, BankPruneError
from redbot.core.bank import AbortPurchase
# Handle banking errors properly
try:
await bank.deposit_credits(member, 999999999)
except BalanceTooHigh as e:
# User would exceed max balance
await ctx.send(f"Balance limit exceeded: {e}")
try:
await bank.withdraw_credits(member, amount)
except ValueError as e:
# Insufficient funds or invalid amount (amount <= 0)
await ctx.send(f"Transaction failed: {e}")
except TypeError as e:
# Amount not an integer
await ctx.send(f"Invalid amount type: {e}")
# Intentional refund in @cost decorated functions
if should_refund:
raise AbortPurchase() # Consumed by decorator, credits returned
๐ง BANK OPERATION PATTERNS #
Safe Transaction Patterns #
# Always check before spending
if await bank.can_spend(user, cost):
await bank.withdraw_credits(user, cost)
# Proceed with operation
else:
await ctx.send("Insufficient funds!")
# Transfer with validation
try:
new_balance = await bank.transfer_credits(sender, receiver, amount)
await ctx.send(f"Transfer complete! {receiver.display_name} now has {new_balance}")
except ValueError:
await ctx.send("Transfer failed - insufficient funds or invalid amount")
except BalanceTooHigh:
await ctx.send("Receiver balance would exceed maximum")
except RuntimeError:
await ctx.send("Bank operation error - check guild context")
Bank Mode Management #
# Check bank mode before operations
if await bank.is_global():
# Global bank - works across all guilds
balance = await bank.get_balance(member)
else:
# Guild-specific bank - requires guild context
if not ctx.guild:
return await ctx.send("No guild bank in DMs!")
balance = await bank.get_balance(member)
๐ฎ INTEGRATION WITH GAME SYSTEMS #
Economy Game Development #
class SlotMachine:
@bank.cost(10) # 10 credits to play
@commands.command()
async def slots(self, ctx):
# Game logic here - cost already deducted
if win:
winnings = calculate_winnings()
await bank.deposit_credits(ctx.author, winnings)
return await ctx.send(f"You won {winnings} credits!")
# Loss = credits already deducted by decorator
# Manual economy integration
async def lottery_entry(self, ctx, amount: int):
if not await bank.can_spend(ctx.author, amount):
return await ctx.send("Not enough credits!")
await bank.withdraw_credits(ctx.author, amount)
# Add to lottery pool
self.lottery_pool += amount
๐ BANK CONFIGURATION BEST PRACTICES #
Initial Bank Setup #
# Set up new guild bank
await bank.set_global(False) # Guild-specific mode
await bank.set_bank_name("Guild Treasury", guild)
await bank.set_currency_name("Gold Coins", guild)
await bank.set_default_balance(100, guild) # Starting balance
await bank.set_max_balance(1000000, guild) # Balance cap
Economy Balancing #
# Get economy statistics
leaderboard = await bank.get_leaderboard(10, guild) # Top 10
total_wealth = sum(account[1]['balance'] for account in leaderboard)
# Admin commands for economy management
@commands.admin()
async def economy_reset(self, ctx):
await bank.wipe_bank(ctx.guild)
await ctx.send("Guild economy reset!")
๐ก๏ธ SECURITY & VALIDATION #
Input Validation Patterns #
# Amount validation (bank does this automatically)
# bank functions raise TypeError for non-int amounts
# bank functions raise ValueError for amounts <= 0
# Member validation in global vs guild banks
async def validate_bank_access(member, guild=None):
if await bank.is_global():
return True # Global bank = anyone can access
else:
return guild is not None # Guild bank = need guild context
Rate Limiting Economy Commands #
@commands.cooldown(1, 30, commands.BucketType.user) # 30s cooldown
@bank.cost(50)
@commands.command()
async def daily_bonus(self, ctx):
bonus = 100
await bank.deposit_credits(ctx.author, bonus)
await ctx.send(f"Daily bonus: {bonus} credits!")
๐ DEBUGGING & MONITORING #
Bank State Inspection #
# Debug bank configuration
bank_mode = "Global" if await bank.is_global() else "Guild-specific"
currency = await bank.get_currency_name(guild)
max_bal = await bank.get_max_balance(guild)
default_bal = await bank.get_default_balance(guild)
await ctx.send(f"Bank: {bank_mode} | Currency: {currency} | Max: {max_bal}")
# Account debugging
account = await bank.get_account(member)
await ctx.send(f"Account: {account.name} | Balance: {account.balance} | Created: {account.created_at}")
๐ CRITICAL IMPLEMENTATION DETAILS #
Constants & Limits #
# From bank.py implementation
_MAX_BALANCE = 2 ** 63 - 1 # Maximum possible balance
# Default balance: 0
# Default max balance: 1000000
# Account.name = member.display_name
# Account.created_at = datetime object from encoded timestamp
Function Return Behaviors #
# withdraw_credits() returns new balance after withdrawal
# deposit_credits() returns new balance after deposit
# transfer_credits() returns recipient's new balance
# set_balance() returns the newly set balance
# All balance functions return int, never float
๐ฐ Master Red-DiscordBot’s banking system with 100% accurate API implementation patterns!