dao-governance-framework/forum-network/src/classes/actors/expert.js

102 lines
3.6 KiB
JavaScript

import { Action } from '../display/action.js';
import { PostMessage } from '../forum-network/message.js';
import { CryptoUtil } from '../util/crypto.js';
import { ReputationHolder } from './reputation-holder.js';
export class Expert extends ReputationHolder {
constructor(dao, name, scene) {
super(name, scene);
this.dao = dao;
this.actions = {
submitPostViaNetwork: new Action('submit post via network', scene),
submitPost: new Action('submit post', scene),
initiateValidationPool: new Action('initiate validation pool', scene),
stake: new Action('stake on post', scene),
registerAvailability: new Action('register availability', scene),
getAssignedWork: new Action('get assigned work', scene),
submitWork: new Action('submit work evidence', scene),
};
this.validationPools = new Map();
this.tokens = [];
}
async initialize() {
this.reputationKey = await CryptoUtil.generateAsymmetricKey();
// this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey);
this.reputationPublicKey = this.name;
this.status.set('Initialized');
return this;
}
async submitPostViaNetwork(forumNode, post, stake) {
// TODO: Include fee
const postMessage = new PostMessage({ post, stake });
await postMessage.sign(this.reputationKey);
await this.actions.submitPostViaNetwork.log(this, forumNode);
// For now, directly call forumNode.receiveMessage();
await forumNode.receiveMessage(JSON.stringify(postMessage.toJSON()));
}
async submitPostWithFee(postContent, poolOptions) {
const post = await this.dao.forum.addPost(this.reputationPublicKey, postContent);
await this.actions.submitPost.log(this, post);
const postId = post.id;
const pool = await this.initiateValidationPool({ ...poolOptions, postId });
this.tokens.push(pool.tokenId);
return { postId, pool };
}
async initiateValidationPool(poolOptions) {
// For now, directly call bench.initiateValidationPool();
poolOptions.reputationPublicKey = this.reputationPublicKey;
const pool = await this.dao.initiateValidationPool(poolOptions);
this.tokens.push(pool.tokenId);
this.validationPools.set(pool.id, poolOptions);
await this.actions.initiateValidationPool.log(
this,
pool,
`(fee: ${poolOptions.fee}, stake: ${poolOptions.authorStakeAmount ?? 0})`,
);
return pool;
}
async stake(validationPool, {
position, amount, lockingTime,
}) {
// TODO: encrypt stake
// TODO: sign message
await this.actions.stake.log(
this,
validationPool,
`(${position ? 'for' : 'against'}, stake: ${amount})`,
);
return validationPool.stake(this.reputationPublicKey, {
position, amount, lockingTime, tokenId: this.tokens[0],
});
}
async registerAvailability(stakeAmount, duration) {
await this.actions.registerAvailability.log(
this,
this.dao.availability,
`(stake: ${stakeAmount}, duration: ${duration})`,
);
this.workerId = await this.dao.availability.register(this.reputationPublicKey, {
stakeAmount,
tokenId: this.tokens[0],
duration,
});
}
async getAssignedWork() {
const requestId = await this.dao.availability.getAssignedWork(this.workerId);
const request = await this.dao.business.getRequest(requestId);
return request;
}
async submitWork(requestId, evidence, { tokenLossRatio, duration }) {
await this.actions.submitWork.log(this, this.dao.business);
return this.dao.business.submitWork(this.reputationPublicKey, requestId, evidence, { tokenLossRatio, duration });
}
}