@ocap/state 1.13.45 → 1.13.49

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.
@@ -0,0 +1,130 @@
1
+ const { BN } = require('@ocap/util');
2
+
3
+ module.exports = (Joi) => ({
4
+ type: 'BN',
5
+ base: Joi.any(),
6
+ messages: {
7
+ 'bn.nan': '{{#label}} is not a big number',
8
+ 'bn.max': '{{#label}} needs to be less than or equal to "{{#threshold}}"',
9
+ 'bn.min': '{{#label}} needs to be greater than or equal to "{{#threshold}}"',
10
+ 'bn.less': '{{#label}} needs to be less than "{{#threshold}}"',
11
+ 'bn.greater': '{{#label}} needs to be greater than "{{#threshold}}"',
12
+ 'bn.positive': '{{#label}} needs to be positive',
13
+ 'bn.negative': '{{#label}} needs to be negative',
14
+ },
15
+
16
+ prepare(value, helpers) {
17
+ try {
18
+ return { value: new BN(value) };
19
+ } catch (err) {
20
+ return { errors: helpers.error('bn.nan') };
21
+ }
22
+ },
23
+ coerce(value) {
24
+ return { value: value.toString(10) };
25
+ },
26
+
27
+ validate(value) {
28
+ return { value };
29
+ },
30
+
31
+ rules: {
32
+ gt: {
33
+ args: [
34
+ {
35
+ name: 'threshold',
36
+ ref: true,
37
+ assert: (v) => BN.isBN(v),
38
+ message: 'must be a big number',
39
+ normalize: (v) => new BN(v),
40
+ },
41
+ {
42
+ name: 'equal',
43
+ assert: (v) => typeof v === 'boolean',
44
+ message: 'must be a boolean',
45
+ },
46
+ ],
47
+ // The rule return structure is different from the root
48
+ // eslint-disable-next-line consistent-return
49
+ validate(value, helpers, args) {
50
+ const v = new BN(value);
51
+ if (args.equal && v.lt(args.threshold)) {
52
+ return helpers.error('bn.min', args);
53
+ }
54
+ if (!args.equal && v.lte(args.threshold)) {
55
+ return helpers.error('bn.greater', args);
56
+ }
57
+
58
+ // must return value when valid
59
+ return value;
60
+ },
61
+ },
62
+
63
+ lt: {
64
+ args: [
65
+ {
66
+ name: 'threshold',
67
+ ref: true,
68
+ assert: (v) => BN.isBN(v),
69
+ message: 'must be a big number',
70
+ normalize: (v) => new BN(v),
71
+ },
72
+ {
73
+ name: 'equal',
74
+ assert: (v) => typeof v === 'boolean',
75
+ message: 'must be a boolean',
76
+ },
77
+ ],
78
+ // The rule return structure is different from the root
79
+ // eslint-disable-next-line consistent-return
80
+ validate(value, helpers, args) {
81
+ const v = new BN(value);
82
+ if (args.equal && v.gt(args.threshold)) {
83
+ return helpers.error('bn.max', args);
84
+ }
85
+ if (!args.equal && v.gte(args.threshold)) {
86
+ return helpers.error('bn.less', args);
87
+ }
88
+
89
+ // must return value when valid
90
+ return value;
91
+ },
92
+ },
93
+
94
+ min: {
95
+ alias: 'gte',
96
+ method(threshold) {
97
+ return this.$_addRule({ name: 'gt', args: { threshold, equal: true } });
98
+ },
99
+ },
100
+ max: {
101
+ alias: 'lte',
102
+ method(threshold) {
103
+ return this.$_addRule({ name: 'lt', args: { threshold, equal: true } });
104
+ },
105
+ },
106
+ greater: {
107
+ alias: 'gt',
108
+ method(threshold) {
109
+ return this.$_addRule({ name: 'gt', args: { threshold, equal: false } });
110
+ },
111
+ },
112
+ less: {
113
+ alias: 'lt',
114
+ method(threshold) {
115
+ return this.$_addRule({ name: 'lt', args: { threshold, equal: false } });
116
+ },
117
+ },
118
+
119
+ positive: {
120
+ method() {
121
+ return this.$_addRule({ name: 'gt', args: { threshold: 0, equal: false } });
122
+ },
123
+ },
124
+ negative: {
125
+ method() {
126
+ return this.$_addRule({ name: 'lt', args: { threshold: 0, equal: false } });
127
+ },
128
+ },
129
+ },
130
+ });
@@ -0,0 +1,100 @@
1
+ const isEqual = require('lodash/isEqual');
2
+ const { types } = require('@ocap/mcrypto');
3
+ const { isValid, toTypeInfo, DID_TYPE_ARCBLOCK, DID_TYPE_ETHEREUM } = require('@arcblock/did');
4
+
5
+ const ruleTypes = {
6
+ wallet: ['arcblock', 'ethereum', 'default', 'eth'],
7
+ pk: Object.keys(types.KeyType),
8
+ hash: Object.keys(types.HashType),
9
+ role: Object.keys(types.RoleType),
10
+ };
11
+
12
+ module.exports = (Joi) => ({
13
+ type: 'DID',
14
+ base: Joi.string().trim(),
15
+ messages: {
16
+ 'did.empty': 'Expect {{#label}} to be non-empty string, got "{{#value}}"',
17
+ 'did.invalid': 'Expect {{#label}} to be valid did, got "{{#value}}"',
18
+ 'did.wallet': 'Expect wallet type of {{#label}} to be "{{#expected}}" wallet, got "{{#actual}}"',
19
+ 'did.pk': 'Expect pk type of {{#label}} to be "{{#expected}}", got "{{#actual}}"',
20
+ 'did.hash': 'Expect hash type of {{#label}} to be "{{#expected}}", got "{{#actual}}"',
21
+ 'did.role': 'Expect role type of {{#label}} to be "{{#expected}}", got "{{#actual}}"',
22
+ },
23
+
24
+ validate(value, helpers) {
25
+ if (!value || typeof value !== 'string') {
26
+ return { errors: helpers.error('did.empty', { value }) };
27
+ }
28
+
29
+ if (isValid(value) === false) {
30
+ return { errors: helpers.error('did.invalid', { value }) };
31
+ }
32
+
33
+ return { value };
34
+ },
35
+
36
+ rules: {
37
+ type: {
38
+ args: [
39
+ {
40
+ name: 'key',
41
+ ref: true,
42
+ assert: (v) => Object.keys(ruleTypes).includes(v),
43
+ message: `must be one of ${Object.keys(ruleTypes).join(', ')}`,
44
+ },
45
+ {
46
+ name: 'expected',
47
+ assert: (v) => Object.keys(ruleTypes).some((x) => ruleTypes[x].includes(v)),
48
+ message: 'must be valid type',
49
+ },
50
+ ],
51
+ // The rule return structure is different from the root
52
+ // eslint-disable-next-line consistent-return
53
+ validate(value, helpers, args) {
54
+ const type = toTypeInfo(value);
55
+ const typeStr = toTypeInfo(value, true);
56
+
57
+ if (args.key === 'wallet') {
58
+ if (['ethereum', 'eth'].includes(args.expected) && isEqual(type, DID_TYPE_ETHEREUM) === false) {
59
+ return helpers.error('did.wallet', { ...args, actual: JSON.stringify(typeStr) });
60
+ }
61
+ if (['arcblock', 'default'].includes(args.expected) && isEqual(type, DID_TYPE_ARCBLOCK) === false) {
62
+ return helpers.error('did.wallet', { ...args, actual: JSON.stringify(typeStr) });
63
+ }
64
+ }
65
+ if (args.key === 'pk' && typeStr.pk !== args.expected) {
66
+ return helpers.error('did.pk', { ...args, actual: typeStr.pk });
67
+ }
68
+ if (args.key === 'hash' && typeStr.hash !== args.expected) {
69
+ return helpers.error('did.hash', { ...args, actual: typeStr.hash });
70
+ }
71
+ if (args.key === 'role' && typeStr.role !== args.expected) {
72
+ return helpers.error('did.role', { ...args, actual: typeStr.role });
73
+ }
74
+
75
+ return value;
76
+ },
77
+ },
78
+
79
+ wallet: {
80
+ method(type) {
81
+ return this.$_addRule({ name: 'type', args: { key: 'wallet', expected: type } });
82
+ },
83
+ },
84
+ pk: {
85
+ method(type) {
86
+ return this.$_addRule({ name: 'type', args: { key: 'pk', expected: type } });
87
+ },
88
+ },
89
+ hash: {
90
+ method(type) {
91
+ return this.$_addRule({ name: 'type', args: { key: 'hash', expected: type } });
92
+ },
93
+ },
94
+ role: {
95
+ method(type) {
96
+ return this.$_addRule({ name: 'type', args: { key: 'role', expected: type } });
97
+ },
98
+ },
99
+ },
100
+ });
@@ -0,0 +1,53 @@
1
+ const JOI = require('joi');
2
+
3
+ const bnExtension = require('./extension/bn');
4
+ const didExtension = require('./extension/did');
5
+
6
+ const Joi = JOI.extend(didExtension).extend(bnExtension);
7
+
8
+ const hashRegexp = /^(0x)?([A-Fa-f0-9]{64})$/;
9
+
10
+ const contextSchema = Joi.object({
11
+ genesisTime: Joi.date().iso().required().raw(),
12
+ genesisTx: Joi.string().regex(hashRegexp).required(),
13
+ renaissanceTime: Joi.date().iso().required().raw(),
14
+ renaissanceTx: Joi.string().regex(hashRegexp).required(),
15
+ });
16
+
17
+ const tokenInputSchema = Joi.object({
18
+ address: Joi.DID().role('ROLE_TOKEN').required(),
19
+ value: Joi.BN().positive().required(),
20
+ });
21
+
22
+ const indexedTokenInputSchema = Joi.object({
23
+ address: Joi.DID().role('ROLE_TOKEN').required(),
24
+ value: Joi.BN().positive().required(),
25
+ decimal: Joi.number().integer().greater(0).required(),
26
+ symbol: Joi.string().required(),
27
+ unit: Joi.string().required(),
28
+ });
29
+
30
+ const multiSigSchema = Joi.array().items({
31
+ signer: Joi.DID().required(),
32
+ pk: Joi.any().required(),
33
+ signature: Joi.any().required(),
34
+ delegator: Joi.DID().valid('').optional(),
35
+ data: Joi.any().optional(),
36
+ });
37
+
38
+ const foreignTokenSchema = Joi.object({
39
+ type: Joi.string().min(1).max(32).required(),
40
+ contractAddress: Joi.DID().wallet('ethereum').required(),
41
+ chainType: Joi.string().min(1).max(32).required(),
42
+ chainName: Joi.string().min(1).max(32).required(),
43
+ chainId: Joi.number().positive().required(),
44
+ });
45
+
46
+ module.exports = Joi;
47
+
48
+ module.exports.contextSchema = contextSchema;
49
+ module.exports.tokenInputSchema = tokenInputSchema;
50
+ module.exports.indexedTokenInputSchema = indexedTokenInputSchema;
51
+ module.exports.multiSigSchema = multiSigSchema;
52
+ module.exports.foreignTokenSchema = foreignTokenSchema;
53
+ module.exports.hashRegexp = hashRegexp;
@@ -15,14 +15,14 @@ const schema = Joi.object({
15
15
  txHash: Joi.string().regex(Joi.hashRegexp).required(),
16
16
  txs: Joi.array().items(Joi.string().regex(Joi.hashRegexp).required()).min(1).unique().required(),
17
17
 
18
- proposer: Joi.DID().required(),
18
+ proposer: Joi.DID().wallet('ethereum').required(),
19
19
  signatures: Joi.multiSigSchema.min(1).required(),
20
20
 
21
- rollup: Joi.DID().required(),
21
+ rollup: Joi.DID().role('ROLE_ROLLUP').required(),
22
22
 
23
- blockReward: Joi.BN().optional(),
24
- mintedAmount: Joi.BN().optional(),
25
- burnedAmount: Joi.BN().optional(),
23
+ blockReward: Joi.BN().positive().optional(),
24
+ mintedAmount: Joi.BN().min(0).optional(),
25
+ burnedAmount: Joi.BN().min(0).optional(),
26
26
 
27
27
  context: Joi.contextSchema,
28
28
  data: Joi.any().optional(),
@@ -12,25 +12,25 @@ const validator = Joi.object({
12
12
  });
13
13
 
14
14
  const schema = Joi.object({
15
- address: Joi.DID().required(),
16
- tokenAddress: Joi.DID().required(),
17
- erc20TokenAddress: Joi.DID().required(),
18
- contractAddress: Joi.DID().required(),
15
+ address: Joi.DID().role('ROLE_ROLLUP').required(),
16
+ tokenAddress: Joi.DID().role('ROLE_TOKEN').required(),
17
+ contractAddress: Joi.DID().wallet('ethereum').required(),
18
+ paused: Joi.boolean().default(false),
19
19
 
20
20
  seedValidators: Joi.array().items(validator).min(1).required(),
21
21
  validators: Joi.array().items(validator).default([]),
22
22
 
23
- minStakeAmount: Joi.BN().required(),
24
- maxStakeAmount: Joi.BN().required(),
23
+ minStakeAmount: Joi.BN().positive().required(),
24
+ maxStakeAmount: Joi.BN().min(Joi.ref('minStakeAmount')).required(),
25
25
 
26
26
  minSignerCount: Joi.number()
27
27
  .integer()
28
28
  .min(Joi.ref('seedValidators', { adjust: (v) => v.length }))
29
29
  .required(),
30
- maxSignerCount: Joi.number().integer().min(1).max(8).greater(Joi.ref('minSignerCount')).required(),
30
+ maxSignerCount: Joi.number().integer().min(1).max(8).min(Joi.ref('minSignerCount')).required(),
31
31
 
32
32
  minBlockSize: Joi.number().integer().min(1).required(),
33
- maxBlockSize: Joi.number().integer().min(1).max(10).greater(Joi.ref('minBlockSize')).required(),
33
+ maxBlockSize: Joi.number().integer().min(1).max(10).min(Joi.ref('minBlockSize')).required(),
34
34
 
35
35
  minBlockInterval: Joi.number()
36
36
  .integer()
@@ -39,15 +39,18 @@ const schema = Joi.object({
39
39
  .required(), // in seconds
40
40
  minBlockConfirmation: Joi.number().integer().min(1).max(100).required(),
41
41
 
42
- minDepositAmount: Joi.BN().required(),
43
- minWithdrawAmount: Joi.BN().required(),
42
+ minDepositAmount: Joi.BN().positive().required(),
43
+ maxDepositAmount: Joi.BN().greater(Joi.ref('minDepositAmount')).required(),
44
+ minWithdrawAmount: Joi.BN().positive().required(),
45
+ maxWithdrawAmount: Joi.BN().greater(Joi.ref('minWithdrawAmount')).required(),
44
46
 
45
47
  depositFeeRate: Joi.number().integer().min(1).max(10000).required(),
46
48
  withdrawFeeRate: Joi.number().integer().min(1).max(10000).required(),
47
49
  proposerFeeShare: Joi.number().integer().min(1).max(10000).required(),
48
-
49
- foreignChainType: Joi.string().required(),
50
- foreignChainId: Joi.string().required(),
50
+ minDepositFee: Joi.BN().positive().required(),
51
+ maxDepositFee: Joi.BN().min(Joi.ref('minDepositFee')).required(),
52
+ minWithdrawFee: Joi.BN().positive().required(),
53
+ maxWithdrawFee: Joi.BN().min(Joi.ref('minWithdrawFee')).required(),
51
54
 
52
55
  blockHeight: Joi.number().integer().min(0).required(),
53
56
  blockHash: Joi.string().regex(Joi.hashRegexp).optional().allow(''),
@@ -64,8 +67,8 @@ const create = (attrs, context) => {
64
67
  blockHash: '',
65
68
  ...pick(attrs, [
66
69
  'address',
70
+ 'paused',
67
71
  'tokenAddress',
68
- 'erc20TokenAddress',
69
72
  'contractAddress',
70
73
  'seedValidators',
71
74
  'validators',
@@ -77,13 +80,17 @@ const create = (attrs, context) => {
77
80
  'maxBlockSize',
78
81
  'minBlockInterval',
79
82
  'minBlockConfirmation',
80
- 'foreignChainType',
81
- 'foreignChainId',
82
83
  'minDepositAmount',
84
+ 'maxDepositAmount',
83
85
  'minWithdrawAmount',
86
+ 'maxWithdrawAmount',
84
87
  'depositFeeRate',
85
88
  'withdrawFeeRate',
86
89
  'proposerFeeShare',
90
+ 'minDepositFee',
91
+ 'maxDepositFee',
92
+ 'minWithdrawFee',
93
+ 'maxWithdrawFee',
87
94
  'issuer',
88
95
  'data',
89
96
  ]),
@@ -120,6 +127,7 @@ const update = (state, updates, context) => {
120
127
  const rollup = {
121
128
  ...state,
122
129
  ...pick(updates, [
130
+ 'paused',
123
131
  'validators',
124
132
  'minStakeAmount',
125
133
  'maxStakeAmount',
@@ -130,10 +138,16 @@ const update = (state, updates, context) => {
130
138
  'minBlockInterval',
131
139
  'minBlockConfirmation',
132
140
  'minDepositAmount',
141
+ 'maxDepositAmount',
133
142
  'minWithdrawAmount',
143
+ 'maxWithdrawAmount',
134
144
  'depositFeeRate',
135
145
  'withdrawFeeRate',
136
146
  'proposerFeeShare',
147
+ 'minDepositFee',
148
+ 'maxDepositFee',
149
+ 'minWithdrawFee',
150
+ 'maxWithdrawFee',
137
151
  'blockHeight',
138
152
  'blockHash',
139
153
  'data',
@@ -4,11 +4,11 @@ const Joi = require('../joi');
4
4
  const { create: createStateContext, update: updateStateContext } = require('./contexts/state');
5
5
 
6
6
  const schema = Joi.object({
7
- address: Joi.DID().trim().required(),
7
+ address: Joi.DID().role('ROLE_STAKE').trim().required(),
8
8
  sender: Joi.DID().trim().required(),
9
9
  receiver: Joi.DID().trim().required(),
10
10
  tokens: Joi.object().default({}),
11
- assets: Joi.array().items(Joi.DID()).default([]),
11
+ assets: Joi.array().items(Joi.DID().role('ROLE_ASSET')).default([]),
12
12
  revocable: Joi.boolean().default(true),
13
13
  message: Joi.string().trim().min(1).max(256).required(),
14
14
  context: Joi.contextSchema,
@@ -13,8 +13,9 @@ const create = (attrs, context) => {
13
13
  'decimal',
14
14
  'icon',
15
15
  'totalSupply',
16
+ 'initialSupply',
16
17
  'address',
17
- 'erc20ContractAddress',
18
+ 'foreignToken',
18
19
  'data',
19
20
  'issuer',
20
21
  ]),
@@ -23,6 +24,9 @@ const create = (attrs, context) => {
23
24
  if (!token.data) {
24
25
  token.data = null;
25
26
  }
27
+ if (!token.foreignToken) {
28
+ token.foreignToken = null;
29
+ }
26
30
 
27
31
  return token;
28
32
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.13.45",
6
+ "version": "1.13.49",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -16,20 +16,20 @@
16
16
  "coverage": "npm run test -- --coverage"
17
17
  },
18
18
  "dependencies": {
19
- "@arcblock/did": "1.13.45",
20
- "@ocap/contract": "1.13.45",
21
- "@ocap/message": "1.13.45",
22
- "@ocap/util": "1.13.45",
19
+ "@arcblock/did": "1.13.49",
20
+ "@ocap/contract": "1.13.49",
21
+ "@ocap/message": "1.13.49",
22
+ "@ocap/util": "1.13.49",
23
23
  "bloom-filters": "^1.3.1",
24
24
  "debug": "^4.3.2",
25
25
  "joi": "^17.4.2",
26
26
  "lodash": "^4.17.21"
27
27
  },
28
28
  "devDependencies": {
29
- "@ocap/mcrypto": "1.13.45"
29
+ "@ocap/mcrypto": "1.13.49"
30
30
  },
31
31
  "keywords": [],
32
32
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
33
33
  "license": "MIT",
34
- "gitHead": "36bd0bfdf2381ecdb4a5cc38c555428328820a99"
34
+ "gitHead": "c0af0d1ba7ead95f2224ff29aaebb635f6969a94"
35
35
  }
package/lib/joi.js DELETED
@@ -1,89 +0,0 @@
1
- const JOI = require('joi');
2
- const { BN } = require('@ocap/util');
3
- const { isValid } = require('@arcblock/did');
4
-
5
- const didExtension = (joi) => ({
6
- type: 'DID',
7
- base: joi.string().trim(),
8
- validate(value, { error }) {
9
- if (!value || typeof value !== 'string') {
10
- return { errors: error('did.empty', { value }) };
11
- }
12
-
13
- if (isValid(value) === false) {
14
- return { errors: error('did.invalid', { value }) };
15
- }
16
-
17
- return { value };
18
- },
19
- messages: {
20
- 'did.empty': 'Expect {{#label}} to be non-empty string, got "{{#value}}"',
21
- 'did.invalid': 'Expect {{#label}} to be valid did, got "{{#value}}"',
22
- },
23
- });
24
-
25
- const ZERO = new BN(0);
26
- const bnExtension = (joi) => ({
27
- type: 'BN',
28
- base: joi.string().trim(),
29
- validate(value, { error }) {
30
- if (!value || typeof value !== 'string') {
31
- return { errors: error('bn.empty', { value }) };
32
- }
33
-
34
- try {
35
- const bn = new BN(value);
36
- if (bn.lt(ZERO)) {
37
- return { errors: error('bn.negative', { value }) };
38
- }
39
- } catch (err) {
40
- return { errors: error('bn.invalid', { value }) };
41
- }
42
-
43
- return { value };
44
- },
45
- messages: {
46
- 'bn.empty': 'Expect {{#label}} to be non-empty string, got "{{#value}}"',
47
- 'bn.invalid': 'Expect {{#label}} to be valid big number string, got "{{#value}}"',
48
- 'bn.negative': 'Expect {{#label}} to be positive, got "{{#value}}"',
49
- },
50
- });
51
-
52
- const Joi = JOI.extend(didExtension).extend(bnExtension);
53
-
54
- const contextSchema = Joi.object({
55
- genesisTime: Joi.date().iso().required().raw(),
56
- genesisTx: Joi.string().required(),
57
- renaissanceTime: Joi.date().iso().required().raw(),
58
- renaissanceTx: Joi.string().required(),
59
- });
60
-
61
- const tokenInputSchema = Joi.object({
62
- address: Joi.DID().required(),
63
- value: Joi.BN().required(),
64
- });
65
-
66
- const indexedTokenInputSchema = Joi.object({
67
- address: Joi.DID().required(),
68
- value: Joi.BN().required(),
69
- decimal: Joi.number().integer().greater(0).required(),
70
- symbol: Joi.string().required(),
71
- unit: Joi.string().required(),
72
- key: Joi.string().optional(),
73
- });
74
-
75
- const multiSigSchema = Joi.array().items({
76
- signer: Joi.DID().required(),
77
- pk: Joi.any().required(),
78
- signature: Joi.any().required(),
79
- delegator: Joi.DID().valid('').optional(),
80
- data: Joi.any().optional(),
81
- });
82
-
83
- module.exports = Joi;
84
-
85
- module.exports.contextSchema = contextSchema;
86
- module.exports.tokenInputSchema = tokenInputSchema;
87
- module.exports.indexedTokenInputSchema = indexedTokenInputSchema;
88
- module.exports.multiSigSchema = multiSigSchema;
89
- module.exports.hashRegexp = /^(0x)?([A-Fa-f0-9]{64})$/;
@@ -1,13 +0,0 @@
1
- // StakeContext: just exist for compatibility
2
-
3
- const create = () => ({
4
- totalStakes: 0,
5
- totalUnstakes: 0,
6
- totalReceivedStakes: 0,
7
- recentStakes: [],
8
- recentReceivedStakes: [],
9
- });
10
-
11
- const update = (context) => ({ ...context });
12
-
13
- module.exports = { create, update };