diff --git a/forum-network/.eslintrc.js b/forum-network/.eslintrc.js index 3a4f0e3..6f3bea1 100644 --- a/forum-network/.eslintrc.js +++ b/forum-network/.eslintrc.js @@ -37,6 +37,7 @@ module.exports = { 'no-multi-assign': ['off'], 'no-constant-condition': ['off'], 'no-await-in-loop': ['off'], + 'no-underscore-dangle': ['off'], }, globals: { _: 'readonly', @@ -44,5 +45,6 @@ module.exports = { sinon: 'readonly', sinonChai: 'readonly', should: 'readonly', + mocha: 'readonly', }, }; diff --git a/forum-network/notes/business.md b/forum-network/notes/business.md new file mode 100644 index 0000000..ff50bde --- /dev/null +++ b/forum-network/notes/business.md @@ -0,0 +1,101 @@ +# Revenue-generating work + +## Expert stakes REP to register availability + +```mermaid +graph + +subgraph EOA + expert(Expert) + +end + +subgraph Contracts + availability(Availability) +end + +expert -- 1. Stake ℝ --> availability + +``` + +## Public submits work request with fee + +```mermaid +graph + +subgraph EOA + expert(Expert) + public(Public) +end + +subgraph Contracts + business(Business) + availability(Availability) +end + +public -- 1. Request
with fee $ --> business +business -- 2. Assign
work --> availability +availability -- 3. Transfer
staked ℝ --> business +availability -- 4. TODO Notify --> expert +``` + +## Expert submits work evidence + +```mermaid +graph + +subgraph EOA + expert(Expert) +end + +subgraph Contracts + business(Business) + forum(Forum) + pool(Pool) +end + +expert -- 1. Work
evidence --> business +business -- 2. Post --> forum +business -- 3. Stake ℝ --> pool +``` + +## Peers validate the work evidence + +```mermaid +graph + +subgraph EOA + peers(Peers) +end + +subgraph Contracts + forum(Forum) + pool(Pool) +end + +peers -- 8. Stake ℝ --> pool +pool -- 9. Validate post,
Transfer ℝ --> forum +``` + +## Rewards are distributed + +```mermaid +graph + +subgraph EOA + expert(Expert) + peers(Peers) +end + +subgraph Contracts + pool(Pool) + business(Business) + forum(Forum) +end + +pool -- Reward ℝ --> peers +forum -- Award ℝ --> expert +forum -- Award ℝ
via citation
WDAG --> peers +business -- Award % fee $
weighted by ℝ--> expert +business -- Award % fee $
weighted by ℝ--> peers +``` diff --git a/forum-network/notes/classes.md b/forum-network/notes/classes.md deleted file mode 100644 index 36cb19d..0000000 --- a/forum-network/notes/classes.md +++ /dev/null @@ -1,43 +0,0 @@ -# Primary - -## Forum - -## ValidationPool - -## ReputationToken - -## WDAG - -# Secondary - -## Availability - -## Business - -## ERC721 - -## Expert - -## Bench - -# Tertiary - -## Actor - -## Action - -## Scene - -# To Explore - -## Exchange - -## Storage - -## Network - -## Wallet - -## Agent/UI - -## BlockConsensus diff --git a/forum-network/notes/client-or-ui.md b/forum-network/notes/client-or-ui.md new file mode 100644 index 0000000..ad24afd --- /dev/null +++ b/forum-network/notes/client-or-ui.md @@ -0,0 +1,9 @@ +## Client/UI + +Voting consists of staking operations performed by software operated by owners of EOA. + +This software may be referred to as "The UI". It may also be considered "a client". + +It will need to be a network-connected application. It will need a certain minimum of RAM, +and for some features disk storage, +and for some features uptime . diff --git a/forum-network/notes/client.md b/forum-network/notes/client.md new file mode 100644 index 0000000..55df288 --- /dev/null +++ b/forum-network/notes/client.md @@ -0,0 +1,5 @@ +# Client Operations + +Client must communicate with one or more servers. + +Client must build a local view diff --git a/forum-network/notes/dao.md b/forum-network/notes/dao.md index 58f017a..048efbf 100644 --- a/forum-network/notes/dao.md +++ b/forum-network/notes/dao.md @@ -33,3 +33,114 @@ WHAT is our protocol for evaluating the perspectives offered by peers? - If there is the HOPE of exact agreement, mistakes and attacks can be costly - If there is an EXPECTATION of exact agreement, there must be externalities supporting that agreement, i.e. a common protocol and governance of that protocol. + +--- + +# Internal operations + +## Expert starts new DAO + +```mermaid +graph + +subgraph EOA + expert(Expert) +end + +subgraph Contracts + forum(Forum) + pool(Pool) +end + +expert -- Post --> forum +expert -- Fee $ --> pool + +``` + +## Expert joins existing DAO + +```mermaid +graph + +subgraph EOA + expert(Expert) + peers(Peers) +end + +subgraph Contracts + forum(Forum) + pool(Pool) +end + +expert -- 1. Post --> forum +expert -- 2. Fee $ --> pool +peers -- 3. Stake ℝ
to approve --> pool +``` + +## Expert submits governance post + +A governance post can be considered one that is respected in some way by the operations of the [Client/UI](./client-or-ui.md). + +This is a broad class of posts. + +Each type of governance post can be individually (or by category?) handled by the business contract for a given DAO. + +```mermaid +graph + +subgraph EOA + expert(Expert) + peers(Peers) +end + +subgraph Contracts + forum(Forum) + pool(Pool) + business(Business) +end + +expert -- 1. Stake ℝ on
governance post --> business +business -- 2. Post --> forum +business -- 2. Fee $ from
internal fund? --> pool +peers -- 3. Stake ℝ
to approve --> pool +pool -- 4. Validate --> forum +``` + +Forum usage is open-ended. +DAO protocol consists of core contracts + client behaviors. +Core contracts provide resilience to attacks, since reputation minting is financially backed by future income + +Question: What does the DAO do with funds it receives? +Awswer: Distributes the funds to members immediately upon resolution of the reputation effects of a funded validation pool. + +--- + +Before we delve into example use cases, we need to talk about the [Client/UI](./client-or-ui.md), and make sure we have +a sound understanding of how client/ui behaviors interact with the core of the system. + +--- + +The forum, pool, business, and availability contracts all work together to express a single DAO. + +Each post in the forum can be its own new DAO + +What it would take for that to happen: + +The seed of the new DAO becomes the tokens minted by that post DAO when it receives fees. + +When will it receive fees? When submitted to its business contract interface. + +What happens then? Work is assigned via availability stakes. + +Meaning that someone has staked reputation. + +Meaning that they had previously been awarded reputation. + +The business contract, or the DAO, or the seed post, must be able to accept an initial fee +to mint the reputation of the first expert. + +Then, that expert can stake their reputation on availability to perform the work expressed by the post and its associated business contract. + +These operations can be consolidated. + +When submitting a post to the forum, you may include an optional fee diff --git a/forum-network/notes/governance.md b/forum-network/notes/governance.md new file mode 100644 index 0000000..74dd787 --- /dev/null +++ b/forum-network/notes/governance.md @@ -0,0 +1 @@ +Each DAO needs to allocate some of its incoming fees to incentivize development. diff --git a/forum-network/notes/rooms.md b/forum-network/notes/rooms.md new file mode 100644 index 0000000..4674fa2 --- /dev/null +++ b/forum-network/notes/rooms.md @@ -0,0 +1,30 @@ +Matrix uses rooms to establish contexts. + +We can have a forum context, +wherein a few things happen. + +One is that the forum will have a root post; equivalently, any post can be the root of a forum. + +The context of that post can be preserved. + +The forum is thus a collection of posts. Each post MAY have its own internal structure. +A post MAY "replace" a prior post. This consists of on-chain and off-chain elements. +On-chain, a new post replaces a prior post. + +--- + +Reading Matrix spec, https://spec.matrix.org/latest/ + +> Events are signed by the originating server (the signature includes the parent relations, type, depth and payload hash) and are pushed over federation to the participating servers in a room, currently using full mesh topology. Servers may also request backfill of events over federation from the other servers participating in a room. + +> In order to ensure that the mapping from 3PID to user ID is genuine, a globally federated cluster of trusted “identity servers” (IS) are used to verify the 3PID and persist and replicate the mappings. +> +> Usage of an IS is not required in order for a client application to be part of the Matrix ecosystem. However, without one clients will not be able to look up user IDs using 3PIDs. + +> Users may publish arbitrary key/value data associated with their account +> +> - such as a human-readable display name, a profile photo URL, contact information (email address, phone numbers, website URLs etc). + +> Users may also store arbitrary private key/value data in their account - such as client preferences, or server configuration settings which lack any other dedicated API. The API is symmetrical to managing Profile data. + +> The client-server API allows clients to send messages, control rooms and synchronise conversation history. It is designed to support both lightweight clients which store no state and lazy-load data from the server as required - as well as heavyweight clients which maintain a full local persistent copy of server state. diff --git a/forum-network/notes/system.gv b/forum-network/notes/system.gv new file mode 100644 index 0000000..e3a4a59 --- /dev/null +++ b/forum-network/notes/system.gv @@ -0,0 +1,4 @@ +digraph { + layout=neato + +} diff --git a/forum-network/notes/system.md b/forum-network/notes/system.md new file mode 100644 index 0000000..d19418c --- /dev/null +++ b/forum-network/notes/system.md @@ -0,0 +1,56 @@ +```mermaid +graph + classDef blue fill:#08f, color:#d8d8d8, stroke-width: 0 + classDef yellow fill:#dd0, color:#a0c, stroke-width: 0 + classDef green fill:#8c8, color:#333, stroke-width: 0 + classDef purple stroke:#c38, stroke-width:2px, fill:#bbf, color:#c38 + classDef orange fill:#d60, color:#dff, stroke-width: 0 + classDef fuscia fill:#f6c, color:#00c + + nodeSpec(Node spec
Matrix homeservers):::blue + storageSpec(Storage spec
Matrix homeservers):::orange + archiveSpec(Archive spec
Weavechain):::green + blockchainSpec(Blockchain spec):::purple + peerProtocolSpec(Peer protocol spec
Matrix messaging):::yellow + uiSpec(UI spec
Matrix client):::fuscia + + + nodeSpec --- uiSpec + linkStyle 0 stroke:#08f + nodeSpec --- storageSpec + linkStyle 1 stroke:#08f + nodeSpec --- peerProtocolSpec + linkStyle 2 stroke:#08f + nodeSpec --- archiveSpec + linkStyle 3 stroke:#08f + nodeSpec --- blockchainSpec + linkStyle 4 stroke:#08f + + peerProtocolSpec --- storageSpec + linkStyle 5 stroke:#d60 + + storageSpec --- blockchainSpec + linkStyle 6 stroke:#c38 + storageSpec --- archiveSpec + linkStyle 7 stroke:#8c8 + + archiveSpec --- blockchainSpec + linkStyle 8 stroke:#c38 + + uiSpec --- blockchainSpec + linkStyle 9 stroke:#c38 + uiSpec --- archiveSpec + linkStyle 10 stroke:#8c8 + uiSpec --- storageSpec + linkStyle 11 stroke:#d60 +``` + +```mermaid +graph + +forum --- pool +availability --- business +business --- forum +business --- pool + +``` diff --git a/forum-network/src/classes/actors/expert.js b/forum-network/src/classes/actors/expert.js index b8ecda0..69a1d7c 100644 --- a/forum-network/src/classes/actors/expert.js +++ b/forum-network/src/classes/actors/expert.js @@ -1,7 +1,7 @@ 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'; +import { ReputationHolder } from '../reputation/reputation-holder.js'; export class Expert extends ReputationHolder { constructor(dao, name, scene) { @@ -47,7 +47,7 @@ export class Expert extends ReputationHolder { } async initiateValidationPool(poolOptions) { - // For now, directly call bench.initiateValidationPool(); + // For now, make direct call rather than network poolOptions.reputationPublicKey = this.reputationPublicKey; const pool = await this.dao.initiateValidationPool(poolOptions); this.tokens.push(pool.tokenId); diff --git a/forum-network/src/classes/actors/post.js b/forum-network/src/classes/actors/post.js deleted file mode 100644 index a214c6d..0000000 --- a/forum-network/src/classes/actors/post.js +++ /dev/null @@ -1,46 +0,0 @@ -import { Actor } from '../display/actor.js'; -import { displayNumber } from '../../util.js'; -import params from '../../params.js'; - -export class Post extends Actor { - constructor(forum, authorPublicKey, postContent) { - const index = forum.posts.countVertices(); - const name = `Post${index + 1}`; - super(name, forum.scene); - this.id = postContent.id ?? name; - this.authorPublicKey = authorPublicKey; - this.value = 0; - this.initialValue = 0; - this.citations = postContent.citations; - this.title = postContent.title; - const leachingTotal = this.citations - .filter(({ weight }) => weight < 0) - .reduce((total, { weight }) => total += -weight, 0); - const donationTotal = this.citations - .filter(({ weight }) => weight > 0) - .reduce((total, { weight }) => total += weight, 0); - if (leachingTotal > params.revaluationLimit) { - throw new Error('Post leaching total exceeds revaluation limit ' - + `(${leachingTotal} > ${params.revaluationLimit})`); - } - if (donationTotal > params.revaluationLimit) { - throw new Error('Post donation total exceeds revaluation limit ' - + `(${donationTotal} > ${params.revaluationLimit})`); - } - if (this.citations.some(({ weight }) => Math.abs(weight) > params.revaluationLimit)) { - throw new Error(`Each citation magnitude must not exceed revaluation limit ${params.revaluationLimit}`); - } - } - - getLabel() { - return `${this.name} - - - - - - -
initial${displayNumber(this.initialValue)}
value${displayNumber(this.value)}
` - .replaceAll(/\n\s*/g, ''); - } -} diff --git a/forum-network/src/classes/actors/availability.js b/forum-network/src/classes/dao/availability.js similarity index 100% rename from forum-network/src/classes/actors/availability.js rename to forum-network/src/classes/dao/availability.js diff --git a/forum-network/src/classes/actors/business.js b/forum-network/src/classes/dao/business.js similarity index 100% rename from forum-network/src/classes/actors/business.js rename to forum-network/src/classes/dao/business.js diff --git a/forum-network/src/classes/actors/dao.js b/forum-network/src/classes/dao/dao.js similarity index 90% rename from forum-network/src/classes/actors/dao.js rename to forum-network/src/classes/dao/dao.js index ee6f6a3..938d019 100644 --- a/forum-network/src/classes/actors/dao.js +++ b/forum-network/src/classes/dao/dao.js @@ -1,6 +1,6 @@ import params from '../../params.js'; import { Forum } from './forum.js'; -import { ReputationTokenContract } from '../contracts/reputation-token.js'; +import { ReputationTokenContract } from '../reputation/reputation-token.js'; import { ValidationPool } from './validation-pool.js'; import { Availability } from './availability.js'; import { Business } from './business.js'; @@ -72,9 +72,4 @@ export class DAO extends Actor { return pool; } - - async submitPost(reputationPublicKey, postContent) { - const post = await this.forum.addPost(reputationPublicKey, postContent); - return post.id; - } } diff --git a/forum-network/src/classes/actors/forum.js b/forum-network/src/classes/dao/forum.js similarity index 79% rename from forum-network/src/classes/actors/forum.js rename to forum-network/src/classes/dao/forum.js index 41ae511..6a6db0f 100644 --- a/forum-network/src/classes/actors/forum.js +++ b/forum-network/src/classes/dao/forum.js @@ -1,13 +1,56 @@ import { WDAG } from '../supporting/wdag.js'; import { Action } from '../display/action.js'; +import { Actor } from '../display/actor.js'; import params from '../../params.js'; -import { ReputationHolder } from './reputation-holder.js'; +import { ReputationHolder } from '../reputation/reputation-holder.js'; import { displayNumber, EPSILON } from '../../util.js'; -import { Post } from './post.js'; const CITATION = 'citation'; const BALANCE = 'balance'; +class Post extends Actor { + constructor(forum, authorPublicKey, postContent) { + const index = forum.posts.countVertices(); + const name = `Post${index + 1}`; + super(name, forum.scene); + this.id = postContent.id ?? name; + this.authorPublicKey = authorPublicKey; + this.value = 0; + this.initialValue = 0; + this.citations = postContent.citations; + this.title = postContent.title; + const leachingTotal = this.citations + .filter(({ weight }) => weight < 0) + .reduce((total, { weight }) => total += -weight, 0); + const donationTotal = this.citations + .filter(({ weight }) => weight > 0) + .reduce((total, { weight }) => total += weight, 0); + if (leachingTotal > params.revaluationLimit) { + throw new Error('Post leaching total exceeds revaluation limit ' + + `(${leachingTotal} > ${params.revaluationLimit})`); + } + if (donationTotal > params.revaluationLimit) { + throw new Error('Post donation total exceeds revaluation limit ' + + `(${donationTotal} > ${params.revaluationLimit})`); + } + if (this.citations.some(({ weight }) => Math.abs(weight) > params.revaluationLimit)) { + throw new Error(`Each citation magnitude must not exceed revaluation limit ${params.revaluationLimit}`); + } + } + + getLabel() { + return `${this.name} + + + + + + +
initial${displayNumber(this.initialValue)}
value${displayNumber(this.value)}
` + .replaceAll(/\n\s*/g, ''); + } +} + /** * Purpose: * - Forum: Maintain a directed, acyclic, graph of positively and negatively weighted citations. diff --git a/forum-network/src/classes/actors/validation-pool.js b/forum-network/src/classes/dao/validation-pool.js similarity index 99% rename from forum-network/src/classes/actors/validation-pool.js rename to forum-network/src/classes/dao/validation-pool.js index 5accbf6..4781608 100644 --- a/forum-network/src/classes/actors/validation-pool.js +++ b/forum-network/src/classes/dao/validation-pool.js @@ -1,4 +1,4 @@ -import { ReputationHolder } from './reputation-holder.js'; +import { ReputationHolder } from '../reputation/reputation-holder.js'; import { Stake } from '../supporting/stake.js'; import { Voter } from '../supporting/voter.js'; import params from '../../params.js'; diff --git a/forum-network/src/classes/display/action.js b/forum-network/src/classes/display/action.js index 9c1329e..3a2e24c 100644 --- a/forum-network/src/classes/display/action.js +++ b/forum-network/src/classes/display/action.js @@ -4,6 +4,15 @@ export class Action { this.scene = scene; } + /** + * + * @param src + * @param dest + * @param msg + * @param obj + * @param symbol + * @returns {Promise} + */ async log(src, dest, msg, obj, symbol = '->>') { await this.scene?.sequence?.log( `${src.name} ${symbol} ${dest.name} : ${this.name} ${msg ?? ''} ${ diff --git a/forum-network/src/classes/display/box.js b/forum-network/src/classes/display/box.js index faacf17..46f49f6 100644 --- a/forum-network/src/classes/display/box.js +++ b/forum-network/src/classes/display/box.js @@ -2,16 +2,20 @@ import { DisplayValue } from './display-value.js'; import { randomID } from '../../util.js'; export class Box { - constructor(name, parentEl, elementType = 'div') { + constructor(name, parentEl, options = {}) { this.name = name; - this.el = document.createElement(elementType); + this.el = document.createElement('div'); this.el.id = `box_${randomID()}`; this.el.classList.add('box'); if (name) { this.el.setAttribute('box-name', name); } if (parentEl) { - parentEl.appendChild(this.el); + if (options.prepend) { + parentEl.prepend(this.el); + } else { + parentEl.appendChild(this.el); + } } } @@ -35,8 +39,8 @@ export class Box { return this; } - addBox(name, elementType) { - const box = new Box(name, this.el, elementType); + addBox(name) { + const box = new Box(name, this.el); return box; } diff --git a/forum-network/src/classes/display/controls.js b/forum-network/src/classes/display/controls.js new file mode 100644 index 0000000..4911456 --- /dev/null +++ b/forum-network/src/classes/display/controls.js @@ -0,0 +1,52 @@ +class Button { + constructor(innerHTML, onclick) { + this.el = document.createElement('button'); + this.el.innerHTML = innerHTML; + this.el.onclick = onclick; + } +} + +export class Controls { + constructor(parentBox) { + this.disableAutoplayButton = new Button('Disable Auto-play', () => { + const url = new URL(window.location.href); + url.searchParams.set('auto', 'false'); + window.location.href = url.href; + }); + this.enableAutoplayButton = new Button('Enable Auto-play', () => { + const url = new URL(window.location.href); + url.searchParams.delete('auto'); + window.location.href = url.href; + }); + this.stepButton = new Button('Next Action', () => { + console.log('Next Action button clicked'); + document.dispatchEvent(new Event('next-action')); + }); + + if (window.autoPlay) { + parentBox.el.appendChild(this.disableAutoplayButton.el); + } else { + parentBox.el.appendChild(this.enableAutoplayButton.el); + parentBox.el.appendChild(this.stepButton.el); + // Disable `stepButton` when test is complete + setInterval(() => { + this.stepButton.el.disabled = mocha._state !== 'running'; + }, 200); + } + } +} + +export async function delayOrWait(delayMs) { + if (window.autoPlay) { + await new Promise((resolve) => { + setTimeout(resolve, delayMs); + }); + } else { + await new Promise((resolve) => { + document.addEventListener('next-action', () => { + console.log('next-action event received'); + resolve(); + }, { once: true }); + }); + } +} diff --git a/forum-network/src/classes/display/scene.js b/forum-network/src/classes/display/scene.js index e455421..f0e76b3 100644 --- a/forum-network/src/classes/display/scene.js +++ b/forum-network/src/classes/display/scene.js @@ -4,6 +4,8 @@ import { MermaidDiagram } from './mermaid.js'; import { SequenceDiagram } from './sequence.js'; import { Table } from './table.js'; import { Flowchart } from './flowchart.js'; +import { Controls } from './controls.js'; +import { Box } from './box.js'; export class Scene { constructor(name, rootBox) { @@ -24,6 +26,14 @@ export class Scene { this.options = { edgeNodeColor: '#4d585c', }; + + window.autoPlay = new URL(window.location.href).searchParams.get('auto') !== 'false'; + + if (!window.disableSceneControls) { + this.topRail = new Box('Top rail', document.body, { prepend: true }).addClass('top-rail'); + this.controlsBox = this.topRail.addBox('Controls').addClass('controls'); + this.controls = new Controls(this.controlsBox); + } } withSequenceDiagram() { diff --git a/forum-network/src/classes/display/table.js b/forum-network/src/classes/display/table.js index 10dbd0b..ee579d4 100644 --- a/forum-network/src/classes/display/table.js +++ b/forum-network/src/classes/display/table.js @@ -42,4 +42,8 @@ export class Table { cell.innerHTML = typeof value === 'number' ? displayNumber(value) : value ?? ''; } } + + listUniqueValueKeys() { + return this.columns; // TODO + } } diff --git a/forum-network/src/classes/forum-network/forum-node.js b/forum-network/src/classes/forum-network/forum-node.js index f36032e..49ae7c5 100644 --- a/forum-network/src/classes/forum-network/forum-node.js +++ b/forum-network/src/classes/forum-network/forum-node.js @@ -4,7 +4,7 @@ import { } from './message.js'; import { ForumView } from './forum-view.js'; import { NetworkNode } from './network-node.js'; -import { randomID } from '../../util.js'; +import { randomID } from '../util/util.js'; export class ForumNode extends NetworkNode { constructor(name, scene) { diff --git a/forum-network/src/classes/ideas/exchange.js b/forum-network/src/classes/ideas/exchange.js index e69de29..2c1021f 100644 --- a/forum-network/src/classes/ideas/exchange.js +++ b/forum-network/src/classes/ideas/exchange.js @@ -0,0 +1,45 @@ +import { DAO } from '../actors/dao.js'; +/** + * An Exchange provides conversion between currencies / facilitates such. + * That means they carry some of the risk of managing these transactions. + * + */ + +class Offer { + constructor({ + _fromType, _toType, _amount, price, + }) { + this.price = price; + // const from = + } +} + +export class Exchange extends DAO { + constructor(name, scene) { + super(name, scene); + this.offersByType = new Map(); // > + } + + getOffers(offerType) { + return this.buyOffersByType.get(offerType) ?? new Map(); // < + } + + addOffer(offerOptions) { + const offer = new Offer(offerOptions); + const { fromType, toType } = offer; + [fromType, toType].forEach((type) => { + this.offersByType.s(); + }); + } + + requestTransaction({ + fromType, toType, amount, price, + }) { + // this. + } + + buy(fromType, toType, _priceParameters) { + const buyOffer = { + }; + } +} diff --git a/forum-network/src/classes/ideas/finance.js b/forum-network/src/classes/ideas/finance.js index 0ca5f53..07e7531 100644 --- a/forum-network/src/classes/ideas/finance.js +++ b/forum-network/src/classes/ideas/finance.js @@ -1,10 +1,6 @@ -export class Token { - constructor(ownerPublicKey) { - this.ownerPublicKey = ownerPublicKey; - } +/** + * Finance does the work of analysis of the dynamics of reputation and currency exchange + */ - transfer(newOwnerPublicKey) { - // TODO: Current owner must sign this request - this.ownerPublicKey = newOwnerPublicKey; - } +export class Finance { } diff --git a/forum-network/src/classes/ideas/storage.js b/forum-network/src/classes/ideas/storage.js index e69de29..e317264 100644 --- a/forum-network/src/classes/ideas/storage.js +++ b/forum-network/src/classes/ideas/storage.js @@ -0,0 +1,24 @@ +import { randomID } from '../util/util.js'; + +class Pledge { + constructor({ stake, duration }) { + this.stake = stake; + this.duration = duration; + } +} + +/** + * Storage work is providing data availability and integrity. + * It probably makes sense to manage it in pledges of finite duration. + */ +export class Storage { + constructor() { + this.pledges = new Map(); + } + + pledge(pledgeOptions) { + const id = randomID(); + this.pledge.set(id, new Pledge(pledgeOptions)); + return id; + } +} diff --git a/forum-network/src/classes/actors/reputation-holder.js b/forum-network/src/classes/reputation/reputation-holder.js similarity index 100% rename from forum-network/src/classes/actors/reputation-holder.js rename to forum-network/src/classes/reputation/reputation-holder.js diff --git a/forum-network/src/classes/contracts/reputation-token.js b/forum-network/src/classes/reputation/reputation-token.js similarity index 94% rename from forum-network/src/classes/contracts/reputation-token.js rename to forum-network/src/classes/reputation/reputation-token.js index c39af4d..6a479e1 100644 --- a/forum-network/src/classes/contracts/reputation-token.js +++ b/forum-network/src/classes/reputation/reputation-token.js @@ -1,4 +1,4 @@ -import { ERC721 } from './erc721.js'; +import { ERC721 } from '../supporting/erc721.js'; import { EPSILON, randomID } from '../../util.js'; @@ -19,7 +19,14 @@ export class ReputationTokenContract extends ERC721 { this.locks = new Set(); // {tokenId, amount, start, duration} } - mint(to, value, context) { + /** + * + * @param to + * @param value + * @param context + * @returns {string} + */ + mint(to, value, context = {}) { const tokenId = `token_${randomID()}`; super.mint(to, tokenId); this.values.set(tokenId, value); diff --git a/forum-network/src/classes/contracts/erc20.js b/forum-network/src/classes/supporting/erc20.js similarity index 100% rename from forum-network/src/classes/contracts/erc20.js rename to forum-network/src/classes/supporting/erc20.js diff --git a/forum-network/src/classes/contracts/erc721.js b/forum-network/src/classes/supporting/erc721.js similarity index 100% rename from forum-network/src/classes/contracts/erc721.js rename to forum-network/src/classes/supporting/erc721.js diff --git a/forum-network/src/index.css b/forum-network/src/index.css index 1c71ee9..1ff9007 100644 --- a/forum-network/src/index.css +++ b/forum-network/src/index.css @@ -36,6 +36,17 @@ a:visited { .padded { padding: 20px; } +.top-rail { + position: sticky; + top: 0; + left: 0; + width: 100%; + height: 0; +} +.controls { + position: relative; + left: 150px; +} svg { width: 800px; } @@ -49,3 +60,14 @@ td { .edge > rect { fill: #216262 !important; } +button { + margin: 5px; + margin-top: 1em; + background-color: #c6f4ff; + border-color: #b6b6b6; + border-radius: 5px; +} +button:disabled { + background-color: #2a535e; + color: #919191; +} diff --git a/forum-network/src/tests/all.test.html b/forum-network/src/tests/all.test.html index 82baba7..7f89e7c 100644 --- a/forum-network/src/tests/all.test.html +++ b/forum-network/src/tests/all.test.html @@ -12,6 +12,9 @@
+ @@ -32,12 +35,6 @@ - diff --git a/forum-network/src/tests/availability.test.html b/forum-network/src/tests/availability.test.html index a6bdbaf..3efa0df 100644 --- a/forum-network/src/tests/availability.test.html +++ b/forum-network/src/tests/availability.test.html @@ -26,12 +26,6 @@ - diff --git a/forum-network/src/tests/business.test.html b/forum-network/src/tests/business.test.html index 03644c7..fe8bb01 100644 --- a/forum-network/src/tests/business.test.html +++ b/forum-network/src/tests/business.test.html @@ -15,18 +15,16 @@ - - + + - diff --git a/forum-network/src/tests/debounce.test.html b/forum-network/src/tests/debounce.test.html index 219c100..b45f7eb 100644 --- a/forum-network/src/tests/debounce.test.html +++ b/forum-network/src/tests/debounce.test.html @@ -25,12 +25,6 @@ - diff --git a/forum-network/src/tests/flowchart.test.html b/forum-network/src/tests/flowchart.test.html index 893644e..a252871 100644 --- a/forum-network/src/tests/flowchart.test.html +++ b/forum-network/src/tests/flowchart.test.html @@ -10,10 +10,10 @@
- - + + - diff --git a/forum-network/src/tests/forum1.test.html b/forum-network/src/tests/forum1.test.html index 7af331d..4e338af 100644 --- a/forum-network/src/tests/forum1.test.html +++ b/forum-network/src/tests/forum1.test.html @@ -21,12 +21,6 @@ - diff --git a/forum-network/src/tests/forum2.test.html b/forum-network/src/tests/forum2.test.html index ff4d512..29af18a 100644 --- a/forum-network/src/tests/forum2.test.html +++ b/forum-network/src/tests/forum2.test.html @@ -21,12 +21,6 @@ - diff --git a/forum-network/src/tests/forum3.test.html b/forum-network/src/tests/forum3.test.html index 97a8df0..d9e41ed 100644 --- a/forum-network/src/tests/forum3.test.html +++ b/forum-network/src/tests/forum3.test.html @@ -21,12 +21,6 @@ - diff --git a/forum-network/src/tests/forum4.test.html b/forum-network/src/tests/forum4.test.html index 2b451d1..262977e 100644 --- a/forum-network/src/tests/forum4.test.html +++ b/forum-network/src/tests/forum4.test.html @@ -21,12 +21,6 @@ - diff --git a/forum-network/src/tests/forum5.test.html b/forum-network/src/tests/forum5.test.html index 142e468..f99f35e 100644 --- a/forum-network/src/tests/forum5.test.html +++ b/forum-network/src/tests/forum5.test.html @@ -21,12 +21,6 @@ - diff --git a/forum-network/src/tests/mocha.test.html b/forum-network/src/tests/mocha.test.html index 54287d7..174b492 100644 --- a/forum-network/src/tests/mocha.test.html +++ b/forum-network/src/tests/mocha.test.html @@ -20,7 +20,6 @@ mocha.setup({ ui: 'bdd', }); - mocha.checkLeaks(); chai.should(); diff --git a/forum-network/src/tests/reputation.test.html b/forum-network/src/tests/reputation.test.html index a836f6a..6c2bad7 100644 --- a/forum-network/src/tests/reputation.test.html +++ b/forum-network/src/tests/reputation.test.html @@ -10,8 +10,8 @@
- diff --git a/forum-network/src/tests/vm.test.html b/forum-network/src/tests/vm.test.html index 8aeff12..f78597e 100644 --- a/forum-network/src/tests/vm.test.html +++ b/forum-network/src/tests/vm.test.html @@ -21,12 +21,6 @@ - diff --git a/forum-network/src/tests/wdag.test.html b/forum-network/src/tests/wdag.test.html index 44190be..49eece4 100644 --- a/forum-network/src/tests/wdag.test.html +++ b/forum-network/src/tests/wdag.test.html @@ -21,13 +21,7 @@ - diff --git a/forum-network/src/util.js b/forum-network/src/util.js index b8a4ac8..2505b93 100644 --- a/forum-network/src/util.js +++ b/forum-network/src/util.js @@ -38,3 +38,9 @@ export const displayNumber = (value, decimals = 2) => (value.toString().length > : value); export const randomID = () => CryptoUtil.randomUUID().replaceAll('-', '').slice(0, 8); + +export const mochaRun = () => { + if (mocha._state !== 'running') { + mocha.run(); + } +};