-
Notifications
You must be signed in to change notification settings - Fork 6
features physical notes
Converts digital balance into redeemable physical paper items. Each note carries an HMAC-SHA256 signature that makes duplication via NBT / external plugins infeasible.
/vault withdraw <amount>
Required permission: vault.withdraw (default true).
Flow:
- Validates positive amount and withdraws from wallet with
TxType.NOTE_WITHDRAW - Generates a random 16-char hex
noteId(truncated UUID) - Builds an
ItemStackofMaterial.PAPERwith display name + i18n lore - Stores signed metadata and delivers the item to the player
If the NamespacedKey + PersistentDataContainer API is available at runtime, 6 keys are saved via reflection (PhysicalNoteService.java:89–132):
| NamespacedKey | Type | Content |
|---|---|---|
vault:note_id |
STRING | Unique note ID |
vault:note_amount |
DOUBLE | Face value |
vault:note_currency |
STRING | Currency ID (e.g. default) |
vault:note_issuer |
STRING | Issuer UUID |
vault:note_issued_at |
LONG | Issue timestamp (epoch ms) |
vault:note_sig |
STRING | HMAC(payload) in Base64 URL-safe |
Signed payload: noteId|cid|amount|issuerId|issuedAt
If PDC does not exist, the signature written as the last lore line is validated:
§8SIG: <HMAC(noteId|currency|amount)>
Lore tags are extracted via dynamic parsers.
For compatibility with 11 languages and pre-v2.1 legacy notes, extractFallback() detects prefixes such as "Nº serie", "Importe", "Moneda" using labelStarts() + hardcoded fallback lists (PhysicalNoteService.java:408–482):
Serial — Detects: Nº serie / Serial / S/N / Número de série / Seriennummer / Numer seryjny / Серийный номер / 序列号 / 序號 / क्रम संख्या
Amount — Detects: Importe / Amount / Valor / Montant / Betrag / Bedrag / Kwota / Сумма / 金额 / 金額 / राशि
Currency — Detects: Moneda / Currency / Moeda / Devise / Währung / Valuta / Waluta / Валюта / 货币 / 貨幣 / मुद्रा
Additionally parseAmountLoose() interprets decimal/thousand separators . and , based on position (last occurrence = decimal).
Right-click while holding the note (air or block) triggers PlayerInteractEvent. Flow:
-
extractNoteData()validates PDC first, then lore fallback - Checks
redeemed_notes.ymltable for already-redeemed IDs - If new: deposits the amount →
TxType.NOTE_REDEEM→ marks as redeemed - Removes 1 unit from the stack (or
setItemInHand(null)if quantity = 1)
- redeemed_notes.yml stores the global list of redeemed IDs (persisted on disk)
-
ConcurrentHashMapin memory as a fast cache - If HMAC does not match or the ID was already used, returns
note.redeem.invalidornote.redeem.already_redeemed
Generated via SecureRandom → 32 bytes and saved in .note-secret.dat (hidden with attrib +H on Windows). Without this file, no existing note can be validated.
Vault Economy v2.1.0 · Compatible with Spigot 1.8.8 – 1.21.x
📦 Modrinth ·
💬 Discord ·
Java 17 (legacy) · Java 21 (modern)
Documentation generated on 2026-09-03 · Vault Project Team
- 🏠 Home
- 🚀 First Install
- 🧑🏫 Getting Started
- ❓ Basic FAQ
- 📋 Complete Command List
- 🛡️ Complete Permission List
- ⚙️ config.yml Reference
- 🌐 Supported Languages
- 🆕 Modrinth Updates
- 💰 Player-to-Player Payments
- 🏦 Bank System
- 💵 Physical Notes
- 💸 Loans
- 📜 Transaction History
- 📊 Top Players
- ⏸️ Offline Payments
- 💳 Charges / Payment Requests
- 🔔 Discord Webhook
- 🛠️ Installation Errors
- 🚫 Players Can't Pay
- 🧨 Balances Wiped on Restart
- 📉 Bank Doesn't Pay Interest
- 🧾 Invalid / Expired Notes
- 🩺 Complete Step-by-Step Troubleshooting
- Java API
- 📜 Skript
- 🧰 Contribute · Dual Maven Build