@ocap/state 1.21.3 → 1.22.1
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/lib/index.js +4 -0
- package/lib/states/token-factory.js +72 -0
- package/lib/states/token.js +7 -1
- package/lib/states/tx.js +66 -0
- package/package.json +9 -9
package/lib/index.js
CHANGED
|
@@ -9,6 +9,7 @@ const stake = require('./states/stake');
|
|
|
9
9
|
const rollup = require('./states/rollup');
|
|
10
10
|
const rollupBlock = require('./states/rollup-block');
|
|
11
11
|
const evidence = require('./states/evidence');
|
|
12
|
+
const tokenFactory = require('./states/token-factory');
|
|
12
13
|
|
|
13
14
|
const Blacklist = require('./states/blacklist');
|
|
14
15
|
|
|
@@ -24,6 +25,7 @@ module.exports = {
|
|
|
24
25
|
rollup,
|
|
25
26
|
rollupBlock,
|
|
26
27
|
evidence,
|
|
28
|
+
tokenFactory,
|
|
27
29
|
|
|
28
30
|
// indexes of the statedb to speed up reading
|
|
29
31
|
indexes: [
|
|
@@ -38,6 +40,7 @@ module.exports = {
|
|
|
38
40
|
'rollupBlock',
|
|
39
41
|
'rollupValidator',
|
|
40
42
|
'tokenDistribution',
|
|
43
|
+
'tokenFactory',
|
|
41
44
|
],
|
|
42
45
|
|
|
43
46
|
tables: [
|
|
@@ -53,6 +56,7 @@ module.exports = {
|
|
|
53
56
|
'rollupBlock',
|
|
54
57
|
'evidence', // a simple key-value store
|
|
55
58
|
'balance',
|
|
59
|
+
'tokenFactory',
|
|
56
60
|
],
|
|
57
61
|
|
|
58
62
|
Blacklist,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const pick = require('lodash/pick');
|
|
2
|
+
const { Joi, schemas } = require('@arcblock/validator');
|
|
3
|
+
|
|
4
|
+
const { create: createStateContext, update: updateStateContext } = require('../contexts/state');
|
|
5
|
+
|
|
6
|
+
const curveSchema = Joi.alternatives().try(
|
|
7
|
+
Joi.object({
|
|
8
|
+
type: Joi.string().valid('linear').required(),
|
|
9
|
+
basePrice: Joi.BN().greater(0).required(),
|
|
10
|
+
slope: Joi.BN().greater(0).required(),
|
|
11
|
+
}),
|
|
12
|
+
Joi.object({
|
|
13
|
+
type: Joi.string().valid('constant').required(),
|
|
14
|
+
fixedPrice: Joi.BN().greater(0).required(),
|
|
15
|
+
}),
|
|
16
|
+
Joi.object({
|
|
17
|
+
type: Joi.string().valid('quadratic').required(),
|
|
18
|
+
basePrice: Joi.BN().greater(0).required(),
|
|
19
|
+
constant: Joi.number().greater(0).required(),
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const stateSchema = Joi.object({
|
|
24
|
+
address: Joi.DID().prefix().role('ROLE_TOKEN_FACTORY').required(),
|
|
25
|
+
owner: Joi.DID().prefix().role('ROLE_ACCOUNT').required(),
|
|
26
|
+
tokenAddress: Joi.DID().prefix().role('ROLE_TOKEN').required(),
|
|
27
|
+
reserveAddress: Joi.DID().prefix().role('ROLE_TOKEN').required(),
|
|
28
|
+
currentSupply: Joi.BN().min(0).required(),
|
|
29
|
+
reserveBalance: Joi.BN().min(0).required(),
|
|
30
|
+
status: Joi.string().valid('ACTIVE', 'PAUSED').required(),
|
|
31
|
+
feeRate: Joi.number().min(0).max(2000).required(),
|
|
32
|
+
curve: curveSchema.required(),
|
|
33
|
+
context: schemas.context,
|
|
34
|
+
data: Joi.any().optional().allow(null),
|
|
35
|
+
}).options({
|
|
36
|
+
stripUnknown: true,
|
|
37
|
+
noDefaults: false,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const create = (attrs, context) => {
|
|
41
|
+
const tokenFactory = {
|
|
42
|
+
context: createStateContext(context),
|
|
43
|
+
currentSupply: '0',
|
|
44
|
+
reserveBalance: '0',
|
|
45
|
+
status: 'ACTIVE',
|
|
46
|
+
...pick(attrs, ['address', 'owner', 'tokenAddress', 'reserveAddress', 'curve', 'feeRate', 'data']),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
if (!tokenFactory.data) {
|
|
50
|
+
tokenFactory.data = null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return validate(tokenFactory);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const update = (state, attrs, context) =>
|
|
57
|
+
validate({
|
|
58
|
+
...state,
|
|
59
|
+
...pick(attrs, ['currentSupply', 'reserveBalance', 'feeRate']),
|
|
60
|
+
context: updateStateContext(state.context, context),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const validate = (state) => {
|
|
64
|
+
const { value, error } = stateSchema.validate(state);
|
|
65
|
+
if (error) {
|
|
66
|
+
throw new Error(`Invalid token factory: ${error.details.map((x) => x.message).join(', ')}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return value;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
module.exports = { create, update, validate, curveSchema };
|
package/lib/states/token.js
CHANGED
|
@@ -20,6 +20,7 @@ const create = (attrs, context) => {
|
|
|
20
20
|
'foreignToken',
|
|
21
21
|
'data',
|
|
22
22
|
'issuer',
|
|
23
|
+
'tokenFactoryAddress',
|
|
23
24
|
]),
|
|
24
25
|
};
|
|
25
26
|
|
|
@@ -37,4 +38,9 @@ const create = (attrs, context) => {
|
|
|
37
38
|
return token;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
const update = (state, attrs) => ({
|
|
42
|
+
...state,
|
|
43
|
+
...pick(attrs, ['totalSupply']),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
module.exports = { create, update };
|
package/lib/states/tx.js
CHANGED
|
@@ -340,6 +340,66 @@ const getCreateTokenReceipts = (tx) => {
|
|
|
340
340
|
return [issuerReceipt];
|
|
341
341
|
};
|
|
342
342
|
|
|
343
|
+
const getMintTokenReceipts = (tx, ctx) => {
|
|
344
|
+
const { reserveAddress, tokenAddress, owner } = ctx.tokenFactoryState;
|
|
345
|
+
const hasFee = ctx.reserveFee && new BN(ctx.reserveFee).gt(ZERO);
|
|
346
|
+
|
|
347
|
+
return [
|
|
348
|
+
{
|
|
349
|
+
address: tx.from,
|
|
350
|
+
changes: [
|
|
351
|
+
{
|
|
352
|
+
target: reserveAddress,
|
|
353
|
+
action: 'swap',
|
|
354
|
+
value: `-${ctx.reserveAmount}`,
|
|
355
|
+
},
|
|
356
|
+
hasFee && {
|
|
357
|
+
target: reserveAddress,
|
|
358
|
+
action: 'fee',
|
|
359
|
+
value: `-${ctx.reserveFee}`,
|
|
360
|
+
},
|
|
361
|
+
].filter(Boolean),
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
address: tx.itxJson.receiver,
|
|
365
|
+
changes: [
|
|
366
|
+
{
|
|
367
|
+
target: tokenAddress,
|
|
368
|
+
action: 'mint',
|
|
369
|
+
value: `${tx.itxJson.amount}`,
|
|
370
|
+
},
|
|
371
|
+
],
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
address: owner,
|
|
375
|
+
changes: hasFee ? [{ target: reserveAddress, action: 'fee', value: `${ctx.reserveFee}` }] : [],
|
|
376
|
+
},
|
|
377
|
+
];
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const getBurnTokenReceipts = (tx, ctx) => {
|
|
381
|
+
const { reserveAddress, tokenAddress, owner } = ctx.tokenFactoryState;
|
|
382
|
+
const hasFee = ctx.reserveFee && new BN(ctx.reserveFee).gt(ZERO);
|
|
383
|
+
|
|
384
|
+
return [
|
|
385
|
+
{
|
|
386
|
+
address: tx.from,
|
|
387
|
+
changes: [
|
|
388
|
+
{ target: tokenAddress, action: 'burn', value: `-${tx.itxJson.amount}` },
|
|
389
|
+
hasFee && { target: reserveAddress, action: 'fee', value: `-${ctx.reserveFee}` },
|
|
390
|
+
].filter(Boolean),
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
address: tx.itxJson.receiver,
|
|
394
|
+
changes: [{ target: reserveAddress, action: 'swap', value: `${ctx.reserveAmount}` }],
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
address: owner,
|
|
398
|
+
changes: hasFee ? [{ target: reserveAddress, action: 'fee', value: `${ctx.reserveFee}` }] : [],
|
|
399
|
+
},
|
|
400
|
+
];
|
|
401
|
+
};
|
|
402
|
+
|
|
343
403
|
// Following only exist for legacy support purpose
|
|
344
404
|
const getDepositTokenReceipts = (tx) => [
|
|
345
405
|
{
|
|
@@ -580,6 +640,8 @@ const verifyTxReceipts = (receipts, typeUrl, ctx = {}) => {
|
|
|
580
640
|
SetupSwapTx: ['swap'],
|
|
581
641
|
RevokeSwapTx: ['swap'],
|
|
582
642
|
RetrieveSwapTx: ['swap'],
|
|
643
|
+
MintTokenTx: ['swap', 'mint'],
|
|
644
|
+
BurnTokenTx: ['burn', 'swap'],
|
|
583
645
|
}[typeUrl] || [];
|
|
584
646
|
|
|
585
647
|
for (const [target, changes] of Object.entries(targets)) {
|
|
@@ -661,6 +723,10 @@ const getTxReceipts = ({ tx, code }, ctx = {}) => {
|
|
|
661
723
|
receipts = receipts.concat(getAcquireAssetV3Receipts(tx, ctx));
|
|
662
724
|
} else if (['CreateTokenTx'].includes(typeUrl)) {
|
|
663
725
|
receipts = receipts.concat(getCreateTokenReceipts(tx, ctx));
|
|
726
|
+
} else if (['MintTokenTx'].includes(typeUrl)) {
|
|
727
|
+
receipts = receipts.concat(getMintTokenReceipts(tx, ctx));
|
|
728
|
+
} else if (['BurnTokenTx'].includes(typeUrl)) {
|
|
729
|
+
receipts = receipts.concat(getBurnTokenReceipts(tx, ctx));
|
|
664
730
|
} else if (['DepositTokenTx'].includes(typeUrl)) {
|
|
665
731
|
receipts = receipts.concat(getDepositTokenReceipts(tx, ctx));
|
|
666
732
|
} else if (['WithdrawTokenTx'].includes(typeUrl)) {
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.22.1",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"bloom-filters": "^1.3.9",
|
|
14
14
|
"lodash": "^4.17.21",
|
|
15
|
-
"@arcblock/did": "1.
|
|
16
|
-
"@arcblock/validator": "1.
|
|
17
|
-
"@ocap/contract": "1.
|
|
18
|
-
"@ocap/mcrypto": "1.
|
|
19
|
-
"@ocap/
|
|
20
|
-
"@ocap/
|
|
21
|
-
"@ocap/
|
|
15
|
+
"@arcblock/did": "1.22.1",
|
|
16
|
+
"@arcblock/validator": "1.22.1",
|
|
17
|
+
"@ocap/contract": "1.22.1",
|
|
18
|
+
"@ocap/mcrypto": "1.22.1",
|
|
19
|
+
"@ocap/message": "1.22.1",
|
|
20
|
+
"@ocap/util": "1.22.1",
|
|
21
|
+
"@ocap/wallet": "1.22.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"jest": "^29.7.0",
|
|
25
25
|
"start-server-and-test": "^1.14.0",
|
|
26
|
-
"@ocap/e2e-test": "1.
|
|
26
|
+
"@ocap/e2e-test": "1.22.1"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [],
|
|
29
29
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|