109 lines
3.8 KiB
JavaScript
109 lines
3.8 KiB
JavaScript
import { Action } from '../display/action.js';
|
|
import { PostMessage } from '../forum-network/message.js';
|
|
import { CryptoUtil } from '../supporting/crypto.js';
|
|
import { ReputationHolder } from '../reputation/reputation-holder.js';
|
|
import { EdgeTypes } from '../../util/constants.js';
|
|
import { displayNumber } from '../../util/helpers.js';
|
|
|
|
export class Expert extends ReputationHolder {
|
|
constructor(dao, name, scene, options) {
|
|
super(name, scene, options);
|
|
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 = [];
|
|
}
|
|
|
|
getReputation() {
|
|
const authorVertex = this.dao.forum.graph.getVertex(this.reputationPublicKey);
|
|
if (!authorVertex) {
|
|
return 0;
|
|
}
|
|
const authorEdges = authorVertex.getEdges(EdgeTypes.AUTHOR, false);
|
|
const tokenValues = authorEdges.map(({ data: { tokenId } }) => this.dao.reputation.valueOf(tokenId));
|
|
return tokenValues.reduce((value, total) => total += value, 0);
|
|
}
|
|
|
|
getLabel() {
|
|
return `${this.name}
|
|
<table><tr>
|
|
<td>reputation</td>
|
|
<td>${displayNumber(this.getReputation())}</td>
|
|
</tr></table>`
|
|
.replaceAll(/\n\s*/g, '');
|
|
}
|
|
|
|
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 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, make direct call rather than network
|
|
poolOptions.reputationPublicKey = this.reputationPublicKey;
|
|
const pool = await this.dao.initiateValidationPool(this, poolOptions);
|
|
this.tokens.push(pool.tokenId);
|
|
this.validationPools.set(pool.id, poolOptions);
|
|
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 });
|
|
}
|
|
}
|