almtools
Version:
Tools Downloader For WhatsApp Bot
164 lines (124 loc) • 3.96 kB
JavaScript
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;