2022-12-31 16:08:42 -06:00
|
|
|
import { Action } from './action.js';
|
|
|
|
import { PostMessage } from './message.js';
|
|
|
|
import { CryptoUtil } from './crypto.js';
|
2023-01-18 01:07:10 -06:00
|
|
|
import { ReputationHolder } from './reputation-holder.js';
|
2022-11-07 17:44:57 -06:00
|
|
|
|
2023-01-18 01:07:10 -06:00
|
|
|
export class Expert extends ReputationHolder {
|
2022-11-07 17:44:57 -06:00
|
|
|
constructor(name, scene) {
|
2023-01-18 01:07:10 -06:00
|
|
|
super(undefined, name, scene);
|
2022-11-07 17:44:57 -06:00
|
|
|
this.actions = {
|
2023-01-03 01:26:55 -06:00
|
|
|
submitPostViaNetwork: new Action('submit post via network', scene),
|
2022-12-31 16:08:42 -06:00
|
|
|
submitPost: new Action('submit post', scene),
|
|
|
|
initiateValidationPool: new Action('initiate validation pool', scene),
|
2023-01-12 16:41:55 -06:00
|
|
|
stake: new Action('stake on post', scene),
|
2023-01-02 13:14:32 -06:00
|
|
|
registerAvailability: new Action('register availability', scene),
|
|
|
|
getAssignedWork: new Action('get assigned work', scene),
|
|
|
|
submitWork: new Action('submit work evidence', scene),
|
2022-11-07 17:44:57 -06:00
|
|
|
};
|
2022-11-13 12:23:30 -06:00
|
|
|
this.validationPools = new Map();
|
2023-01-18 01:07:10 -06:00
|
|
|
this.tokens = [];
|
2022-11-07 17:44:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
async initialize() {
|
2022-11-12 16:20:42 -06:00
|
|
|
this.reputationKey = await CryptoUtil.generateAsymmetricKey();
|
2022-11-17 08:30:06 -06:00
|
|
|
// this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey);
|
|
|
|
this.reputationPublicKey = this.name;
|
2022-12-31 16:08:42 -06:00
|
|
|
this.status.set('Initialized');
|
2022-11-07 17:44:57 -06:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2023-01-03 01:26:55 -06:00
|
|
|
async submitPostViaNetwork(forumNode, post, stake) {
|
2022-11-12 16:20:42 -06:00
|
|
|
// TODO: Include fee
|
2022-11-07 17:44:57 -06:00
|
|
|
const postMessage = new PostMessage({ post, stake });
|
2022-11-12 16:20:42 -06:00
|
|
|
await postMessage.sign(this.reputationKey);
|
2023-01-05 14:21:45 -06:00
|
|
|
await this.actions.submitPostViaNetwork.log(this, forumNode, null, { id: post.id });
|
2022-11-07 17:44:57 -06:00
|
|
|
// For now, directly call forumNode.receiveMessage();
|
|
|
|
await forumNode.receiveMessage(JSON.stringify(postMessage.toJSON()));
|
|
|
|
}
|
2022-11-11 16:52:57 -06:00
|
|
|
|
2023-01-03 01:26:55 -06:00
|
|
|
async submitPost(forum, postContent) {
|
|
|
|
// TODO: Include fee
|
2023-01-05 14:21:45 -06:00
|
|
|
await this.actions.submitPost.log(this, forum);
|
2023-01-03 01:26:55 -06:00
|
|
|
return forum.addPost(this.reputationPublicKey, postContent);
|
|
|
|
}
|
|
|
|
|
2023-01-04 15:18:29 -06:00
|
|
|
async submitPostWithFee(bench, forum, postContent, poolOptions) {
|
2023-01-05 14:21:45 -06:00
|
|
|
await this.actions.submitPost.log(this, forum);
|
2023-01-04 15:18:29 -06:00
|
|
|
const postId = await forum.addPost(this.reputationPublicKey, postContent);
|
|
|
|
const pool = await this.initiateValidationPool(bench, { ...poolOptions, postId, anonymous: false });
|
2023-01-18 01:07:10 -06:00
|
|
|
this.tokens.push(pool.tokenId);
|
2023-01-04 15:18:29 -06:00
|
|
|
return { postId, pool };
|
|
|
|
}
|
|
|
|
|
|
|
|
async initiateValidationPool(bench, poolOptions) {
|
2022-11-13 10:54:07 -06:00
|
|
|
// For now, directly call bench.initiateValidationPool();
|
2023-01-18 01:07:10 -06:00
|
|
|
poolOptions.reputationPublicKey = this.reputationPublicKey;
|
2023-01-05 14:21:45 -06:00
|
|
|
await this.actions.initiateValidationPool.log(
|
2022-11-30 09:13:52 -06:00
|
|
|
this,
|
|
|
|
bench,
|
2023-01-18 01:07:10 -06:00
|
|
|
`(fee: ${poolOptions.fee}, stake: ${poolOptions.authorStakeAmount ?? 0})`,
|
2022-11-30 09:13:52 -06:00
|
|
|
);
|
2023-01-05 14:21:45 -06:00
|
|
|
const pool = await bench.initiateValidationPool(poolOptions);
|
2023-01-18 01:07:10 -06:00
|
|
|
this.tokens.push(pool.tokenId);
|
2023-01-04 15:18:29 -06:00
|
|
|
this.validationPools.set(pool.id, poolOptions);
|
2022-11-17 08:30:06 -06:00
|
|
|
return pool;
|
2022-11-12 16:20:42 -06:00
|
|
|
}
|
|
|
|
|
2023-01-12 16:41:55 -06:00
|
|
|
async stake(validationPool, {
|
2023-01-18 01:07:10 -06:00
|
|
|
position, amount, lockingTime,
|
2023-01-02 13:14:32 -06:00
|
|
|
}) {
|
2023-01-12 16:41:55 -06:00
|
|
|
// TODO: encrypt stake
|
2022-11-12 16:20:42 -06:00
|
|
|
// TODO: sign message
|
2023-01-12 16:41:55 -06:00
|
|
|
await this.actions.stake.log(
|
2022-11-30 09:13:52 -06:00
|
|
|
this,
|
|
|
|
validationPool,
|
2023-01-18 01:07:10 -06:00
|
|
|
`(${position ? 'for' : 'against'}, stake: ${amount})`,
|
2022-11-30 09:13:52 -06:00
|
|
|
);
|
2023-01-18 01:07:10 -06:00
|
|
|
return validationPool.stake(this, {
|
|
|
|
position, amount, lockingTime, tokenId: this.tokens[0],
|
2023-01-02 13:14:32 -06:00
|
|
|
});
|
2022-11-11 16:52:57 -06:00
|
|
|
}
|
|
|
|
|
2023-01-18 01:07:10 -06:00
|
|
|
async registerAvailability(availability, stakeAmount) {
|
|
|
|
await this.actions.registerAvailability.log(this, availability, `(stake: ${stakeAmount})`);
|
|
|
|
await availability.register({ stakeAmount, tokenId: this.tokens[0].id });
|
2023-01-02 13:14:32 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
async getAssignedWork(availability, business) {
|
|
|
|
const requestId = await availability.getAssignedWork(this.reputationPublicKey);
|
|
|
|
const request = await business.getRequest(requestId);
|
|
|
|
return request;
|
|
|
|
}
|
|
|
|
|
|
|
|
async submitWork(business, requestId, evidence, { tokenLossRatio, duration }) {
|
2023-01-05 14:21:45 -06:00
|
|
|
await this.actions.submitWork.log(this, business);
|
2023-01-02 13:14:32 -06:00
|
|
|
return business.submitWork(this.reputationPublicKey, requestId, evidence, { tokenLossRatio, duration });
|
2023-01-01 21:09:02 -06:00
|
|
|
}
|
2022-11-07 17:44:57 -06:00
|
|
|
}
|