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

85 lines
2.7 KiB
JavaScript

import { Action } from './action.js';
import { Actor } from './actor.js';
import { CryptoUtil } from './crypto.js';
import { PostContent } from './post.js';
class Request {
constructor(fee, content) {
this.id = CryptoUtil.randomUUID();
this.fee = fee;
this.content = content;
}
}
/**
* Purpose: Enable fee-driven work requests, to be completed by workers from the availability pool
*/
export class Business extends Actor {
requests = new Map();
constructor(bench, forum, availability, name, scene) {
super(name, scene);
this.bench = bench;
this.forum = forum;
this.availability = availability;
this.actions = {
assignWork: new Action('assign work', scene),
addPost: new Action('add post', scene),
initiateValidationPool: new Action('initiate validation pool', scene),
};
}
/**
* Fee should be held in escrow.
* That means there should be specific conditions under which the fee will be refunded.
* That means the submission should include some time value to indicate when it expires.
* There could be separate thresholds to indicate the earliest that the job may be cancelled,
* and the time at which the job will be automatically cancelled.
*/
async submitRequest(fee, content) {
const request = new Request(fee, content);
this.requests.set(request.id, request);
this.actions.assignWork.log(this, this.availability);
await this.availability.assignWork(request.id);
return request.id;
}
async getRequest(requestId) {
const request = this.requests.get(requestId);
return request;
}
async submitWork(reputationPublicKey, requestId, workEvidence, { tokenLossRatio, duration }) {
const request = this.requests.get(requestId);
if (!request) {
throw new Error(`Request not found! id: ${requestId}`);
}
// Create a post representing this submission.
const post = new PostContent({
requestId,
workEvidence,
});
this.actions.addPost.log(this, this.forum);
await this.forum.addPost(reputationPublicKey, post);
// Initiate a validation pool for this work evidence.
// Validation pool supports secret ballots but we aren't using that here, since we want
// the post to be attributable to the reputation holder.
this.actions.initiateValidationPool.log(this, this.bench);
const pool = await this.bench.initiateValidationPool(reputationPublicKey, {
postId: post.id,
fee: request.fee,
duration,
tokenLossRatio,
signingPublicKey: reputationPublicKey,
anonymous: false,
});
// When the validation pool concludes,
// reputation should be awarded and fees should be distributed.
return pool;
}
}