@leofcoin/standards 0.2.15 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitattributes +2 -2
- package/.github/workflows/test.yml +33 -0
- package/.prettierrc +8 -8
- package/CHANGELOG.md +16 -3
- package/LICENSE +21 -21
- package/README.md +25 -23
- package/exports/helpers.js +1 -1
- package/exports/i-public-voting.js +1 -0
- package/exports/index.d.ts +2 -1
- package/exports/index.js +2 -3
- package/exports/meta-D7uruGOw.js +28 -0
- package/exports/meta.d.ts +11 -0
- package/exports/private-voting.js +104 -11
- package/exports/public-voting.js +103 -4
- package/exports/roles.d.ts +5 -10
- package/exports/roles.js +7 -8
- package/exports/token-receiver.d.ts +5 -7
- package/exports/token-receiver.js +25 -14
- package/exports/token.d.ts +14 -27
- package/exports/token.js +14 -48
- package/exports/types.d.ts +21 -0
- package/exports/voting/private-voting.d.ts +108 -11
- package/exports/voting/public-voting.d.ts +45 -8
- package/exports/voting/types.d.ts +11 -7
- package/package.json +9 -14
- package/rollup.config.js +28 -28
- package/src/helpers.ts +19 -19
- package/src/index.ts +8 -7
- package/src/meta.ts +31 -0
- package/src/roles.ts +88 -89
- package/src/token-receiver.ts +196 -175
- package/src/token.ts +162 -198
- package/src/types.ts +15 -0
- package/src/voting/interfaces/i-public-voting.ts +4 -0
- package/src/voting/private-voting.ts +187 -69
- package/src/voting/public-voting.ts +134 -14
- package/src/voting/types.ts +30 -24
- package/test/helpers.js +51 -0
- package/test/public-voting.js +365 -6
- package/test/roles.js +186 -0
- package/test/token.js +211 -0
- package/tsconfig.json +16 -12
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/exports/contract-creator.d.ts +0 -11
- package/exports/contract-creator.js +0 -20
- package/exports/lock.d.ts +0 -37
- package/exports/staking.d.ts +0 -40
- package/exports/voting/interfaces/i-voting.d.ts +0 -5
- package/exports/voting/voting.d.ts +0 -38
- package/exports/voting-C0KVNQO3.js +0 -112
- package/exports/voting-xYjJlN2h.js +0 -112
- package/src/contract-creator.ts +0 -24
- package/src/decorators/time.ts +0 -9
- package/src/interfaces/i-token.ts +0 -9
- package/src/lock.ts +0 -167
- package/src/staking.ts +0 -166
- package/src/voting/interfaces/i-voting.ts +0 -5
- package/src/voting/voting.ts +0 -123
package/.gitattributes
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
# Auto detect text files and perform LF normalization
|
|
2
|
-
* text=LF
|
|
1
|
+
# Auto detect text files and perform LF normalization
|
|
2
|
+
* text=LF
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
node-version: [22.x, latest]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Use Node.js ${{ matrix.node-version }}
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: ${{ matrix.node-version }}
|
|
24
|
+
cache: 'npm'
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Build project
|
|
30
|
+
run: npm run build
|
|
31
|
+
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: npm test
|
package/.prettierrc
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
{
|
|
2
|
-
"tabWidth": 2,
|
|
3
|
-
"semi": false,
|
|
4
|
-
"singleQuote": true,
|
|
5
|
-
"printWidth":
|
|
6
|
-
"trailingComma": "none",
|
|
7
|
-
"bracketSameLine": true
|
|
8
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"tabWidth": 2,
|
|
3
|
+
"semi": false,
|
|
4
|
+
"singleQuote": true,
|
|
5
|
+
"printWidth": 80,
|
|
6
|
+
"trailingComma": "none",
|
|
7
|
+
"bracketSameLine": true
|
|
8
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
# @leofcoin/standards
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Unreleased
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Refactored TokenReceiver to use native `bigint` instead of `BigNumber`
|
|
8
|
+
- Updated comparison operators to use native BigInt comparisons (`>=`, `>`, `===`)
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- GitHub Actions workflow for automated testing across Node.js versions 18.x, 20.x, 22.x
|
|
13
|
+
- Test status badge in README
|
|
14
|
+
- Comprehensive unit tests for helpers, roles, token, and voting modules
|
|
15
|
+
- Meta base class for state management
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
6
18
|
|
|
7
|
-
-
|
|
19
|
+
- Test script glob pattern in package.json
|
|
20
|
+
- Build step added to CI workflow for proper test execution
|
|
8
21
|
|
|
9
22
|
## 0.2.1
|
|
10
23
|
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2022 ArteonToken
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 ArteonToken
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
# standards
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
# standards
|
|
2
|
+
|
|
3
|
+
[](https://github.com/leofcoin/standards/actions/workflows/test.yml)
|
|
4
|
+
|
|
5
|
+
> Contract standards
|
|
6
|
+
|
|
7
|
+
standards used in leofcoin chain kinda like erc20's but the native coin included
|
|
8
|
+
|
|
9
|
+
## install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm i @leofcoin/standards
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## usage
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import { Token } from '@leofcoin/standards'
|
|
19
|
+
|
|
20
|
+
class myCoolToken extends Token {
|
|
21
|
+
constructor(state) {
|
|
22
|
+
super('myCoolToken', 'MCT', 18, state)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
package/exports/helpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// when state is stored it get encoded as a string to so we need to reformat balances back to
|
|
1
|
+
// when state is stored it get encoded as a string to so we need to reformat balances back to BigInts
|
|
2
2
|
const restoreBalances = (balances) => {
|
|
3
3
|
const _balances = {};
|
|
4
4
|
for (const address in balances) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/exports/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export { default as
|
|
1
|
+
export { default as Meta } from './meta.js';
|
|
2
2
|
export { default as Roles } from './roles.js';
|
|
3
|
+
export { default as Token } from './token.js';
|
|
3
4
|
export { default as TokenReceiver } from './token-receiver.js';
|
|
4
5
|
export { default as PublicVoting } from './voting/public-voting.js';
|
|
5
6
|
export { default as PrivateVoting } from './voting/private-voting.js';
|
package/exports/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { M as Meta } from './meta-D7uruGOw.js';
|
|
2
2
|
export { default as Roles } from './roles.js';
|
|
3
|
+
export { default as Token } from './token.js';
|
|
3
4
|
export { default as TokenReceiver } from './token-receiver.js';
|
|
4
5
|
export { default as PublicVoting } from './public-voting.js';
|
|
5
6
|
export { default as PrivateVoting } from './private-voting.js';
|
|
6
7
|
export { restoreApprovals, restoreBalances } from './helpers.js';
|
|
7
|
-
import './contract-creator.js';
|
|
8
|
-
import './voting-xYjJlN2h.js';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class Meta {
|
|
2
|
+
#creator;
|
|
3
|
+
#createdAt = BigInt(Date.now());
|
|
4
|
+
constructor(state) {
|
|
5
|
+
if (state) {
|
|
6
|
+
this.#creator = state.creator;
|
|
7
|
+
this.#createdAt = state.createdAt;
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
this.#creator = msg.sender;
|
|
11
|
+
this.#createdAt = BigInt(Date.now());
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* get state object for snapshotting
|
|
16
|
+
*/
|
|
17
|
+
get state() {
|
|
18
|
+
return { creator: this.#creator, createdAt: this.#createdAt };
|
|
19
|
+
}
|
|
20
|
+
get creator() {
|
|
21
|
+
return this.#creator;
|
|
22
|
+
}
|
|
23
|
+
get createdAt() {
|
|
24
|
+
return this.#createdAt;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Meta as M };
|
|
@@ -1,25 +1,101 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import './contract-creator.js';
|
|
1
|
+
import { M as Meta } from './meta-D7uruGOw.js';
|
|
3
2
|
|
|
4
|
-
class PrivateVoting extends
|
|
3
|
+
class PrivateVoting extends Meta {
|
|
5
4
|
#voters;
|
|
5
|
+
#votes;
|
|
6
|
+
#votingDisabled;
|
|
6
7
|
constructor(state) {
|
|
7
8
|
super(state);
|
|
8
9
|
if (state) {
|
|
9
10
|
this.#voters = state.voters;
|
|
11
|
+
this.#votes = state.votes;
|
|
12
|
+
this.#votingDisabled = state.votingDisabled;
|
|
10
13
|
}
|
|
11
14
|
else {
|
|
12
15
|
this.#voters = [msg.sender];
|
|
13
16
|
}
|
|
14
17
|
}
|
|
18
|
+
get votes() {
|
|
19
|
+
return { ...this.#votes };
|
|
20
|
+
}
|
|
21
|
+
get voters() {
|
|
22
|
+
return { ...this.#voters };
|
|
23
|
+
}
|
|
24
|
+
get votingDisabled() {
|
|
25
|
+
return this.#votingDisabled;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
15
30
|
get state() {
|
|
16
31
|
return {
|
|
17
32
|
...super.state,
|
|
18
|
-
voters: this.#voters
|
|
33
|
+
voters: this.#voters,
|
|
34
|
+
votes: this.#votes,
|
|
35
|
+
votingDisabled: this.#votingDisabled
|
|
19
36
|
};
|
|
20
37
|
}
|
|
21
|
-
|
|
22
|
-
return this.#
|
|
38
|
+
get inProgress() {
|
|
39
|
+
return Object.entries(this.#votes)
|
|
40
|
+
.filter(([id, vote]) => !vote.finished)
|
|
41
|
+
.map(([id, vote]) => {
|
|
42
|
+
return { ...vote, id };
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* create vote
|
|
47
|
+
* @param {string} vote
|
|
48
|
+
* @param {string} description
|
|
49
|
+
* @param {number} endTime
|
|
50
|
+
* @param {string} method function to run when agree amount is bigger
|
|
51
|
+
*/
|
|
52
|
+
createVote(title, description, endTime, method, args = []) {
|
|
53
|
+
if (!this.canVote(msg.sender))
|
|
54
|
+
throw new Error(`Not allowed to create a vote`);
|
|
55
|
+
const id = crypto.randomUUID();
|
|
56
|
+
this.#votes[id] = {
|
|
57
|
+
title,
|
|
58
|
+
description,
|
|
59
|
+
method,
|
|
60
|
+
endTime,
|
|
61
|
+
args
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
canVote(address) {
|
|
65
|
+
return this.#voters.includes(address);
|
|
66
|
+
}
|
|
67
|
+
#enoughVotes(id) {
|
|
68
|
+
return this.#voters.length - 2 <= Object.keys(this.#votes[id]).length;
|
|
69
|
+
}
|
|
70
|
+
#endVoting(voteId) {
|
|
71
|
+
let agree = Object.values(this.#votes[voteId].results).filter((result) => result === 1);
|
|
72
|
+
let disagree = Object.values(this.#votes[voteId].results).filter((result) => result === 0);
|
|
73
|
+
this.#votes[voteId].enoughVotes = this.#enoughVotes(voteId);
|
|
74
|
+
if (agree.length > disagree.length && this.#votes[voteId].enoughVotes)
|
|
75
|
+
this[this.#votes[voteId].method](...this.#votes[voteId].args);
|
|
76
|
+
this.#votes[voteId].finished = true;
|
|
77
|
+
}
|
|
78
|
+
vote(voteId, vote) {
|
|
79
|
+
vote = Number(vote);
|
|
80
|
+
if (vote !== 0 && vote !== 0.5 && vote !== 1)
|
|
81
|
+
throw new Error(`invalid vote value ${vote}`);
|
|
82
|
+
if (!this.#votes[voteId])
|
|
83
|
+
throw new Error(`Nothing found for ${voteId}`);
|
|
84
|
+
const ended = new Date().getTime() > this.#votes[voteId].endTime;
|
|
85
|
+
if (ended && !this.#votes[voteId].finished)
|
|
86
|
+
this.#endVoting(voteId);
|
|
87
|
+
if (ended)
|
|
88
|
+
throw new Error('voting already ended');
|
|
89
|
+
if (!this.canVote(msg.sender))
|
|
90
|
+
throw new Error(`Not allowed to vote`);
|
|
91
|
+
this.#votes[voteId][msg.sender] = vote;
|
|
92
|
+
if (this.#enoughVotes(voteId)) {
|
|
93
|
+
this.#endVoting(voteId);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
#disableVoting() {
|
|
97
|
+
this.#votingDisabled = true;
|
|
98
|
+
this.#voters = [];
|
|
23
99
|
}
|
|
24
100
|
#grantVotingPower(address) {
|
|
25
101
|
this.#voters.push(address);
|
|
@@ -27,22 +103,39 @@ class PrivateVoting extends Voting {
|
|
|
27
103
|
#revokeVotingPower(address) {
|
|
28
104
|
this.#voters.splice(this.#voters.indexOf(address));
|
|
29
105
|
}
|
|
106
|
+
disableVoting() {
|
|
107
|
+
if (!this.canVote(msg.sender))
|
|
108
|
+
throw new Error('not a allowed');
|
|
109
|
+
if (this.#voters.length === 1)
|
|
110
|
+
this.#disableVoting();
|
|
111
|
+
else {
|
|
112
|
+
this.createVote(`disable voting`, `Warning this disables all voting features forever`, new Date().getTime() + 172800000, '#disableVoting', []);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
30
115
|
grantVotingPower(address, voteId) {
|
|
31
|
-
if (this.#voters.length === 1 && this.
|
|
116
|
+
if (this.#voters.length === 1 && this.canVote(msg.sender))
|
|
32
117
|
this.#grantVotingPower(address);
|
|
33
118
|
else {
|
|
34
|
-
this.createVote(`grant voting power to ${address}`, `Should we grant ${address} voting power?`, new Date().getTime() +
|
|
119
|
+
this.createVote(`grant voting power to ${address}`, `Should we grant ${address} voting power?`, new Date().getTime() + 172800000, '#grantVotingPower', [address]);
|
|
35
120
|
}
|
|
36
121
|
}
|
|
37
122
|
revokeVotingPower(address, voteId) {
|
|
38
|
-
if (!this.
|
|
123
|
+
if (!this.canVote(msg.sender))
|
|
39
124
|
throw new Error('not a allowed to vote');
|
|
40
|
-
if (this.#voters.length === 1 &&
|
|
125
|
+
if (this.#voters.length === 1 &&
|
|
126
|
+
address === msg.sender &&
|
|
127
|
+
!this.#votingDisabled)
|
|
41
128
|
throw new Error('only one voter left, disable voting before making this contract voteless');
|
|
42
129
|
if (this.#voters.length === 1)
|
|
43
130
|
this.#revokeVotingPower(address);
|
|
44
131
|
else {
|
|
45
|
-
this.createVote(`revoke voting power for ${address}`, `Should we revoke ${address} it's voting power?`, new Date().getTime() +
|
|
132
|
+
this.createVote(`revoke voting power for ${address}`, `Should we revoke ${address} it's voting power?`, new Date().getTime() + 172800000, '#revokeVotingPower', [address]);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
sync() {
|
|
136
|
+
for (const vote of this.inProgress) {
|
|
137
|
+
if (vote.endTime < new Date().getTime())
|
|
138
|
+
this.#endVoting(vote.id);
|
|
46
139
|
}
|
|
47
140
|
}
|
|
48
141
|
}
|
package/exports/public-voting.js
CHANGED
|
@@ -1,12 +1,111 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import './contract-creator.js';
|
|
1
|
+
import { M as Meta } from './meta-D7uruGOw.js';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
|
-
* allows everybody that has a balance greater or
|
|
4
|
+
* allows everybody that has a balance greater or equal to tokenAmountToReceive to vote
|
|
6
5
|
*/
|
|
7
|
-
class PublicVoting extends
|
|
6
|
+
class PublicVoting extends Meta {
|
|
7
|
+
#votes;
|
|
8
|
+
#votingDisabled;
|
|
9
|
+
#votingDuration = 172800000;
|
|
8
10
|
constructor(state) {
|
|
9
11
|
super(state);
|
|
12
|
+
if (state) {
|
|
13
|
+
this.#votes = state.votes;
|
|
14
|
+
this.#votingDisabled = state.votingDisabled;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
get votes() {
|
|
18
|
+
return { ...this.#votes };
|
|
19
|
+
}
|
|
20
|
+
get votingDuration() {
|
|
21
|
+
return this.#votingDuration;
|
|
22
|
+
}
|
|
23
|
+
get votingDisabled() {
|
|
24
|
+
return this.#votingDisabled;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
get state() {
|
|
30
|
+
return {
|
|
31
|
+
...super.state,
|
|
32
|
+
votes: this.#votes,
|
|
33
|
+
votingDisabled: this.#votingDisabled,
|
|
34
|
+
votingDuration: this.#votingDuration
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
get inProgress() {
|
|
38
|
+
return Object.entries(this.#votes)
|
|
39
|
+
.filter(([id, vote]) => !vote.finished)
|
|
40
|
+
.map(([id, vote]) => {
|
|
41
|
+
return { ...vote, id };
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* create vote
|
|
46
|
+
* @param {string} vote
|
|
47
|
+
* @param {string} description
|
|
48
|
+
* @param {number} endTime
|
|
49
|
+
* @param {string} method function to run when agree amount is bigger
|
|
50
|
+
*/
|
|
51
|
+
createVote(title, description, endTime, method, args = []) {
|
|
52
|
+
if (!this.#canVote())
|
|
53
|
+
throw new Error(`Not allowed to create a vote`);
|
|
54
|
+
const id = crypto.randomUUID();
|
|
55
|
+
this.#votes[id] = {
|
|
56
|
+
title,
|
|
57
|
+
description,
|
|
58
|
+
method,
|
|
59
|
+
endTime,
|
|
60
|
+
args
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
#canVote() {
|
|
64
|
+
// @ts-expect-error
|
|
65
|
+
return this._canVote?.();
|
|
66
|
+
}
|
|
67
|
+
#beforeVote() {
|
|
68
|
+
// @ts-expect-error
|
|
69
|
+
return this._beforeVote?.();
|
|
70
|
+
}
|
|
71
|
+
#endVoting(voteId) {
|
|
72
|
+
let agree = Object.values(this.#votes[voteId].results).filter((result) => result === 1);
|
|
73
|
+
let disagree = Object.values(this.#votes[voteId].results).filter((result) => result === 0);
|
|
74
|
+
if (agree.length > disagree.length && this.#votes[voteId].enoughVotes)
|
|
75
|
+
this[this.#votes[voteId].method](...this.#votes[voteId].args);
|
|
76
|
+
this.#votes[voteId].finished = true;
|
|
77
|
+
}
|
|
78
|
+
async vote(voteId, vote) {
|
|
79
|
+
vote = Number(vote);
|
|
80
|
+
if (vote !== 0 && vote !== 0.5 && vote !== 1)
|
|
81
|
+
throw new Error(`invalid vote value ${vote}`);
|
|
82
|
+
if (!this.#votes[voteId])
|
|
83
|
+
throw new Error(`Nothing found for ${voteId}`);
|
|
84
|
+
const ended = new Date().getTime() > this.#votes[voteId].endTime;
|
|
85
|
+
if (ended && !this.#votes[voteId].finished)
|
|
86
|
+
this.#endVoting(voteId);
|
|
87
|
+
if (ended)
|
|
88
|
+
throw new Error('voting already ended');
|
|
89
|
+
if (!this.#canVote())
|
|
90
|
+
throw new Error(`Not allowed to vote`);
|
|
91
|
+
await this.#beforeVote();
|
|
92
|
+
this.#votes[voteId][msg.sender] = vote;
|
|
93
|
+
}
|
|
94
|
+
#disableVoting() {
|
|
95
|
+
this.#votingDisabled = true;
|
|
96
|
+
}
|
|
97
|
+
disableVoting() {
|
|
98
|
+
if (!this.#canVote())
|
|
99
|
+
throw new Error('not a allowed');
|
|
100
|
+
else {
|
|
101
|
+
this.createVote(`disable voting`, `Warning this disables all voting features forever`, new Date().getTime() + this.#votingDuration, '#disableVoting', []);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
_sync() {
|
|
105
|
+
for (const vote of this.inProgress) {
|
|
106
|
+
if (vote.endTime < new Date().getTime())
|
|
107
|
+
this.#endVoting(vote.id);
|
|
108
|
+
}
|
|
10
109
|
}
|
|
11
110
|
}
|
|
12
111
|
|
package/exports/roles.d.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
export
|
|
4
|
-
roles: {
|
|
5
|
-
[index: string]: address[];
|
|
6
|
-
};
|
|
7
|
-
}
|
|
8
|
-
export default class Roles extends ContractCreator {
|
|
1
|
+
import Meta from './meta.js';
|
|
2
|
+
import { RolesState } from './types.js';
|
|
3
|
+
export default class Roles extends Meta {
|
|
9
4
|
#private;
|
|
10
|
-
constructor(state
|
|
5
|
+
constructor(state?: RolesState);
|
|
11
6
|
/**
|
|
12
7
|
*
|
|
13
8
|
*/
|
|
14
|
-
get state():
|
|
9
|
+
get state(): {};
|
|
15
10
|
get roles(): {};
|
|
16
11
|
/**
|
|
17
12
|
* @param {address} address
|
package/exports/roles.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { M as Meta } from './meta-D7uruGOw.js';
|
|
2
2
|
|
|
3
|
-
class Roles extends
|
|
3
|
+
class Roles extends Meta {
|
|
4
4
|
/**
|
|
5
5
|
* Object => Array
|
|
6
6
|
*/
|
|
@@ -11,13 +11,9 @@ class Roles extends ContractCreator {
|
|
|
11
11
|
};
|
|
12
12
|
constructor(state) {
|
|
13
13
|
super(state);
|
|
14
|
-
// allow devs to set their own roles but always keep the default ones included
|
|
15
|
-
// also allows roles to be loaded from the stateStore
|
|
16
|
-
// carefull when including the roles make sure to add the owner
|
|
17
|
-
// because no roles are granted by default when using custom roles
|
|
18
14
|
if (state?.roles) {
|
|
19
15
|
if (state.roles instanceof Object) {
|
|
20
|
-
this.#roles = { ...state.roles
|
|
16
|
+
this.#roles = { ...state.roles };
|
|
21
17
|
}
|
|
22
18
|
else {
|
|
23
19
|
throw new TypeError(`expected roles to be an object`);
|
|
@@ -32,7 +28,10 @@ class Roles extends ContractCreator {
|
|
|
32
28
|
*
|
|
33
29
|
*/
|
|
34
30
|
get state() {
|
|
35
|
-
return {
|
|
31
|
+
return {
|
|
32
|
+
...super.state,
|
|
33
|
+
roles: this.roles
|
|
34
|
+
};
|
|
36
35
|
}
|
|
37
36
|
get roles() {
|
|
38
37
|
return { ...this.#roles };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
export interface TokenReceiverState extends
|
|
1
|
+
import { IPublicVoting } from './voting/interfaces/i-public-voting.js';
|
|
2
|
+
import PublicVoting from './voting/public-voting.js';
|
|
3
|
+
import { VotingState } from './voting/types.js';
|
|
4
|
+
export interface TokenReceiverState extends VotingState {
|
|
5
5
|
tokenToReceive: address;
|
|
6
6
|
tokenReceiver: address;
|
|
7
7
|
tokenAmountToReceive: bigint;
|
|
8
8
|
voteType: 'burn' | 'transfer';
|
|
9
9
|
}
|
|
10
|
-
export default class TokenReceiver extends PublicVoting implements
|
|
10
|
+
export default class TokenReceiver extends PublicVoting implements IPublicVoting {
|
|
11
11
|
#private;
|
|
12
12
|
constructor(tokenToReceive: address, tokenAmountToReceive: bigint, burns: boolean, state?: TokenReceiverState);
|
|
13
13
|
get tokenToReceive(): string;
|
|
@@ -23,7 +23,6 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
|
|
|
23
23
|
};
|
|
24
24
|
votingDisabled: boolean;
|
|
25
25
|
votingDuration: number;
|
|
26
|
-
contractCreator: string;
|
|
27
26
|
};
|
|
28
27
|
/**
|
|
29
28
|
* check if sender can pay
|
|
@@ -41,7 +40,6 @@ export default class TokenReceiver extends PublicVoting implements IVoting {
|
|
|
41
40
|
* @returns {boolean} promise
|
|
42
41
|
*/
|
|
43
42
|
_burnTokenToReceive(): Promise<boolean>;
|
|
44
|
-
_canPay(): Promise<any>;
|
|
45
43
|
changeVoteType(type: TokenReceiverState['voteType']): Promise<void>;
|
|
46
44
|
getTokensOut(amount: bigint, receiver: address): void;
|
|
47
45
|
changeTokenAmountToReceive(): void;
|