UNPKG

almtools

Version:

Tools Downloader For WhatsApp Bot

164 lines (124 loc) 3.96 kB
const fs = require('fs'); const crypto = require('crypto'); const path = require('path'); class Asset { constructor(filePath, secret) { if (!secret) throw new Error('Secret key required'); this.filePath = filePath; this.key = crypto.createHash('sha256').update(secret).digest(); this.state = { balances: {}, locked: {}, ledger: [], lastId: 0, meta: { supply: 0 } }; this._ensureDir(); this._load(); } /* ===== STORAGE ===== */ _ensureDir() { const dir = path.dirname(this.filePath); if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); } _hash(data) { return crypto.createHash('sha256').update(data).digest('hex'); } _encrypt(data) { const iv = crypto.randomBytes(12); const cipher = crypto.createCipheriv('aes-256-gcm', this.key, iv); const enc = Buffer.concat([ cipher.update(JSON.stringify(data)), cipher.final() ]); const tag = cipher.getAuthTag(); return Buffer.concat([iv, tag, enc]).toString('base64'); } _decrypt(payload) { const raw = Buffer.from(payload, 'base64'); const iv = raw.subarray(0, 12); const tag = raw.subarray(12, 28); const enc = raw.subarray(28); const decipher = crypto.createDecipheriv('aes-256-gcm', this.key, iv); decipher.setAuthTag(tag); return JSON.parse( Buffer.concat([decipher.update(enc), decipher.final()]).toString() ); } _load() { if (!fs.existsSync(this.filePath)) return; this.state = this._decrypt(fs.readFileSync(this.filePath, 'utf8')); } _save() { fs.writeFileSync(this.filePath, this._encrypt(this.state), 'utf8'); } /* ===== LEDGER ===== */ _commit(from, to, amount, type) { const prev = this.state.ledger.at(-1); const prevHash = prev ? prev.hash : 'GENESIS'; const id = ++this.state.lastId; const time = Date.now(); const payload = `${id}|${from}|${to}|${amount}|${type}|${time}|${prevHash}`; const hash = this._hash(payload); this.state.ledger.push({ id, from, to, amount, type, time, prevHash, hash }); this._save(); } getLedgerHash() { return this.state.ledger.at(-1)?.hash || null; } /* ===== CORE ===== */ register(user, initial = 0) { if (this.state.balances[user] !== undefined) return false; this.state.balances[user] = 0; this.state.locked[user] = 0; if (initial > 0) { this.mint(user, initial); } else { this._save(); } return true; } balance(user) { return (this.state.balances[user] || 0) - (this.state.locked[user] || 0); } mint(to, amount) { if (amount <= 0) return false; this.state.balances[to] = (this.state.balances[to] || 0) + amount; this.state.meta.supply += amount; this._commit('system', to, amount, 'mint'); return true; } burn(from, amount) { if (this.balance(from) < amount) return false; this.state.balances[from] -= amount; this.state.meta.supply -= amount; this._commit(from, 'system', amount, 'burn'); return true; } transfer(from, to, amount) { if (this.balance(from) < amount) return false; this.state.balances[from] -= amount; this.state.balances[to] = (this.state.balances[to] || 0) + amount; this._commit(from, to, amount, 'transfer'); return true; } lock(user, amount) { if (this.balance(user) < amount) return false; this.state.locked[user] = (this.state.locked[user] || 0) + amount; this._commit(user, user, amount, 'lock'); return true; } unlock(user, amount) { this.state.locked[user] = Math.max( (this.state.locked[user] || 0) - amount, 0 ); this._commit(user, user, amount, 'unlock'); return true; } } module.exports = Asset;