dao-governance-framework/forum-network/public/classes/reputation.js

89 lines
2.2 KiB
JavaScript
Raw Normal View History

2022-11-12 16:20:42 -06:00
class Lock {
constructor(tokens, duration) {
this.dateCreated = new Date();
this.tokens = tokens;
this.duration = duration;
}
}
class Reputation {
2022-11-12 16:20:42 -06:00
constructor() {
this.tokens = 0;
this.locks = new Set();
}
addTokens(tokens) {
if (this.tokens + tokens < 0) {
2022-12-31 16:08:42 -06:00
throw new Error('Token balance can not become negative');
2022-11-12 16:20:42 -06:00
}
this.tokens += tokens;
}
lockTokens(tokens, duration) {
if (tokens > this.getAvailableTokens()) {
2022-12-31 16:08:42 -06:00
throw new Error('Can not lock more tokens than are available');
2022-11-12 16:20:42 -06:00
}
const lock = new Lock(tokens, duration);
this.locks.add(lock);
// TODO: Prune locks once expired
}
getTokens() {
return this.tokens;
}
getAvailableTokens() {
const now = new Date();
const tokensLocked = Array.from(this.locks.values())
2022-12-31 16:08:42 -06:00
.filter(({ dateCreated, duration }) => now - dateCreated < duration)
2022-11-13 12:23:30 -06:00
.reduce((acc, cur) => acc += cur.tokens, 0);
if (tokensLocked > this.tokens) {
2022-12-31 16:08:42 -06:00
throw new Error('Assertion failure. tokensLocked > tokens');
}
return this.tokens - tokensLocked;
2022-11-12 16:20:42 -06:00
}
}
export class Reputations extends Map {
getTokens(reputationPublicKey) {
const reputation = this.get(reputationPublicKey);
if (!reputation) {
return 0;
}
return reputation.getTokens();
}
getAvailableTokens(reputationPublicKey) {
const reputation = this.get(reputationPublicKey);
if (!reputation) {
return 0;
}
return reputation.getAvailableTokens();
}
addTokens(reputationPublicKey, tokens) {
const reputation = this.get(reputationPublicKey) ?? new Reputation();
reputation.addTokens(tokens);
this.set(reputationPublicKey, reputation);
}
lockTokens(reputationPublicKey, tokens, duration) {
if (!tokens || !duration) {
return;
}
const reputation = this.get(reputationPublicKey);
if (!reputation) {
throw new Error(`${reputationPublicKey} has no tokens to lock`);
}
reputation.lockTokens(tokens, duration);
}
getTotal() {
return Array.from(this.values()).reduce((acc, cur) => acc += cur.getTokens(), 0);
}
getTotalAvailable() {
return Array.from(this.values()).reduce((acc, cur) => acc += cur.getAvailableTokens(), 0);
}
}