๐Ÿ’ฐ ECONOMY & BANKING SYSTEM CHEAT SHEET

๐Ÿ’ฐ 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!