lilend's Simple Economy (LSE)
Version: 1.0
Language: Kotlin (JVM 21)
Platform: Paper / Purpur 1.21+
Author: lilenddd
API: LSEAPI, Vault, PlaceholderAPI
A lightweight, secure, modern economy plugin for Minecraft Paper 1.21+ servers. Written entirely in Kotlin with thread-safe concurrent data structures, atomic transactions, and a modular architecture.
Features
- Player balances with YAML persistence
- Physical check items (right-click to redeem via GUI)
- Player-to-player payments with confirmation GUI
- Balance leaderboard (/baltop)
- Admin commands (add, remove, set balances)
- Transaction tax system (configurable rate & per-feature)
- Auto-save mechanism (configurable interval)
- Vault API hook (QuickShop, ChestShop, GriefPrevention, etc.)
- PlaceholderAPI expansion (%lse_balance%, %lse_balancetop_1%, etc.)
- Public developer API (LSEAPI object)
- Fully customizable messages with & color codes and placeholders
- Per-command permissions (default true or op)
- Toggleable features (checks, transfers, tax)
- Transaction logging with daily rotation
- Security validation (overflow protection, NaN checks, balance caps)
Commands
`/balance` or `/bal` | Show your balance | `lse.balance`
`/balance <player>` | Show another player's balance |
`lse.balance.others`
`/pay <player> <amount>` | Send money to a player | `lse.pay`
`/check <amount>` | Create a physical check | `lse.check`
`/baltop` or `/top` | Balance leaderboard | `lse.baltop`
`/lse add <player> <amount>` | Add money to a player | `lse.lse.add`
`/lse remove <player> <amount>` | Remove money from a player | `lse.lse.remove`
`/lse set <player> <amount>` | Set a player's balance | `lse.lse.set`
`/lse balance [player]` | View any player's balance | `lse.lse.balance`
Permissions
`lse.balance` | true | Check your balance
`lse.balance.others` | true | Check others' balances
`lse.pay` | true | Send money to players
`lse.check` | true | Create physical checks
`lse.baltop` | true | View balance leaderboard
`lse.lse` | op | Admin commands base
`lse.lse.add` | op | Add money to a player
`lse.lse.remove` | op | Remove money from a player
`lse.lse.set` | op | Set a player's balance
`lse.lse.balance` | op | View any balance via /lse
`lse.tax.exempt` | op | Exempt from transaction taxes
`lse.admin` | op | All admin permissions (inherits all lse.lse.*)
Check System
1. Run `/check <amount>` to create a Paper item with PersistentDataContainer metadata.
2. The check item name shows the value in bold gold with configurable lore.
3. Right-click the check (main hand) to open the confirmation GUI.
4. Click green glass to approve, red glass to cancel.
5. Anti-double-redeem: each check has a unique UUID tracked in a ConcurrentHashMap.
6. On redeem, the check is consumed (1 removed from stack) and the amount is added to the player's balance.
Transfer System
1. Run `/pay <player> <amount>`.
2. A 9-slot confirmation GUI opens with cancel (slot 0), info (slot 4), approve (slot 8).
3. On approval, money moves atomically from sender to receiver.
4. Both parties receive a notification.
5. If tax is enabled and applies to transfers, tax is deducted from the sent amount.
Tax System
Fully configurable transaction tax system:
```yaml
tax:
enabled: false
rate: 5.0 # percentage (0.0 - 100.0)
applies-to:
transfers: true # /pay transactions
checks: false # check creation fee
```
How it works:
- Transfers: Sender specifies amount X. Receiver gets X - tax%. Tax disappears from the economy (deflationary).
- Checks: Player pays amount + tax to create a check worth amount. Tax charged on top.
- Players with `lse.tax.exempt` permission are not taxed.
- Total collected tax is tracked and available via PlaceholderAPI (`%lse_tax_collected%`).
PlaceholderAPI Expansion
When PlaceholderAPI is installed, the following placeholders are available:
`%lse_balance%` | Formatted balance of the player (e.g., $1,234.50)
`%lse_balance_raw%` | Raw balance value (e.g., 1234.50)
`%lse_balance_<player>%` | Formatted balance of another player
`%lse_balancetop_<rank>%` | Top balance at rank (e.g., "lilenddd: $5,000.00")
`%lse_currency_symbol%` | Currency symbol ($)
`%lse_currency_name%` | Currency name (Dollar)
`%lse_version%` | Plugin version |
`%lse_tax_collected%` | Formatted total tax collected
`%lse_tax_collected_raw%` | Raw total tax collected
Developer API (LSEAPI)
Add `LilendsSimpleEconomy.jar` as a dependency and use the singleton API object:
```kotlin
import com.lilend.lse.api.LSEAPI
LSEAPI.getBalance(player) // → Double
LSEAPI.getBalance(playerId) // → Double
LSEAPI.getFormattedBalance(player) // → "$1,234.50"
LSEAPI.getFormattedBalance(playerId) // → "$1,234.50"
LSEAPI.getFormattedAmount(500.0) // → "$500.00"
LSEAPI.getRawFormattedAmount(500.0) // → "500.00"
LSEAPI.setBalance(player, 1000.0) // → Unit
LSEAPI.setBalance(playerId, 1000.0) // → Unit
LSEAPI.addBalance(player, 100.0) // → Unit
LSEAPI.addBalance(playerId, 100.0) // → Unit
LSEAPI.removeBalance(player, 50.0) // → Boolean
LSEAPI.removeBalance(playerId, 50.0) // → Boolean
LSEAPI.hasBalance(player, 25.0) // → Boolean
LSEAPI.hasBalance(playerId, 25.0) // → Boolean
LSEAPI.getCurrencySymbol() // → "$"
LSEAPI.getCurrencyName() // → "Dollar"
```
All API methods are null-safe and return default values if the plugin is not loaded.
Vault API Integration
Place Vault.jar in your plugins/ folder and LSE hooks automatically via ServiceManager.
Compatible with:
- QuickShop / QuickShop-Hikari
- ChestShop
- GriefPrevention
- Any plugin using Vault Economy interface
Banks are not supported (returns NOT_IMPLEMENTED).
Configuration
All files are in `plugins/LilendsSimpleEconomy/`.
config.yml
```yaml
currency:
symbol: "$"
name: "Dollar"
settings:
default-balance: 0.0
max-check-amount: 1000000.0
auto-save-interval: 300 # seconds between auto-saves (min 30)
baltop:
max: 10
format:
commas: true # $1,000,000.50 vs $1000000.50
features:
transfers:
enabled: true
checks:
enabled: true
tax:
enabled: false
rate: 5.0 # percentage (0-100)
applies-to:
transfers: true # /pay taxed
checks: false # check creation taxed
```
messages.yml
All messages use & color codes. Placeholders vary per message:
```yaml
prefix: "&8[&6LSE&8] &r"
balance:
self: "&aBalance: &6%balance%"
other: "&e%player%&a's balance: &6%balance%"
others-no-perm: "&cYou don't have permission to view others' balances."
pay:
sent: "&aYou sent &6%amount% &ato &e%target%"
received: "&aYou received &6%amount% &afrom &e%sender%"
insufficient: "&cInsufficient funds! Your balance: &6%balance%"
self: "&cYou cannot pay yourself!"
disabled: "&cTransfers are disabled on this server."
confirm-title: "&8&lSend &6%amount% &8<o &e%target%&8&l?"
confirm-accept: "&a&lApprove"
confirm-cancel: "&c&lCancel"
tax-applied: "&7Transaction tax: &c-%tax%"
check:
created: "&aYou created a check worth &6%amount%"
created-tax: "&aYou created a check worth &6%amount% &7(-%tax% tax)"
redeemed: "&aYou redeemed a check worth &6%amount%"
disabled: "&cChecks are disabled on this server."
invalid-amount: "&cInvalid amount! Max check: &6%max%"
no-balance: "&cYou don't have enough money to create a check worth &6%amount%"
no-balance-tax: "&cInsufficient funds! Check: &6%amount% &c+ Tax: &6%tax% &c= &6%total%"
confirm-title: "&8&lRedeem this check?"
confirm-accept: "&a&lApprove"
confirm-cancel: "&c&lCancel"
item-name: "&6&l%amount% &e&lCheck"
item-lore:
- "&7Created by: &f%creator%"
- "&7Value: &6%amount%"
lse:
added: "&aAdded &6%amount% &ato &e%player%"
removed: "&aRemoved &6%amount% &afrom &e%player%"
set: "&aSet &e%player%'s &abalance to &6%amount%"
balance: "&e%player%'s &abalance: &6%balance%"
insufficient: "&cThat player doesn't have enough money!"
baltop:
header: "&8&m----------&8[ &6&lTop Balances &8]&m----------"
entry: "&6%rank%. &e%player% &8- &6%balance%"
footer: "&8&m------------------------------------"
empty: "&cNo balances to display."
errors:
player-only: "&cOnly players can use this command."
invalid-player: "&cPlayer not found!"
invalid-amount: "&cInvalid amount!"
no-permission: "&cYou don't have permission to use this command."
not-enough-money: "&cYou don't have enough money!"
invalid-syntax: "&cInvalid syntax! Usage: &e%usage%"
```
Installation
1. Download `LilendsSimpleEconomy-1.0.jar`
2. Place it in your server's `plugins/` folder
3. (Optional) Install Vault.jar for cross-plugin economy support
4. (Optional) Install PlaceholderAPI for placeholder expansion
5. Restart or reload your server
6. Edit `config.yml` and `messages.yml` to your liking
7. Run `/balance` to verify