@ocap/tx-protocols 1.23.0 → 1.24.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.
@@ -30,6 +30,10 @@ const schema = Joi.object({
30
30
  icon: Joi.string().optional().allow(null).valid(''),
31
31
  totalSupply: Joi.BN().greater(0).max(MAX_TOTAL_SUPPLY).required(),
32
32
  initialSupply: Joi.BN().greater(0).max(Joi.ref('totalSupply')).required(),
33
+ maxTotalSupply: Joi.alternatives()
34
+ .try(Joi.BN().greater(0).max(Joi.ref('totalSupply')), Joi.string().valid(''))
35
+ .optional()
36
+ .allow(null),
33
37
  foreignToken: schemas.foreignToken.optional().allow(null).default(null),
34
38
  tokenFactoryAddress: Joi.forbidden(),
35
39
  data: Joi.any().optional().allow(null),
@@ -3,6 +3,7 @@ const { Joi, schemas } = require('@arcblock/validator');
3
3
  const { BN, fromUnitToToken } = require('@ocap/util');
4
4
  const { Runner, pipes } = require('@ocap/tx-pipeline');
5
5
  const { account, tokenFactory, token } = require('@ocap/state');
6
+ const pick = require('lodash/pick');
6
7
 
7
8
  const EnsureTxGas = require('../../pipes/ensure-gas');
8
9
  const EnsureTxCost = require('../../pipes/ensure-cost');
@@ -252,7 +253,7 @@ runner.use(
252
253
  }
253
254
  // Ensure the sender exists in accountUpdates, because even if there is no balance change, we need to update his nonce
254
255
  if (!accountUpdates[tx.from]) {
255
- accountUpdates[tx.from] = {};
256
+ accountUpdates[tx.from] = senderState || {};
256
257
  }
257
258
 
258
259
  // update owner
@@ -281,12 +282,14 @@ runner.use(
281
282
  // We can use updateOrCreate here because the owner and signer have already been validated to exist earlier,
282
283
  // the sender and receiver are allowed to be created in the transaction.
283
284
  const state = [senderState, receiverState, ownerState, ...signerStates].find((x) => x?.address === address);
284
- const senderUpdated = address === tx.from ? { nonce: tx.nonce, pk: tx.pk } : {};
285
- return statedb.account.updateOrCreate(
286
- state,
287
- account.updateOrCreate(state, Object.assign({ address }, senderUpdated, updates), context),
288
- context
289
- );
285
+
286
+ // Should only update nonce and pk for sender and new accounts
287
+ const actualUpdates =
288
+ address === tx.from || !state
289
+ ? { ...updates, address, nonce: tx.nonce, pk: tx.pk }
290
+ : pick(updates, ['tokens']);
291
+
292
+ return statedb.account.updateOrCreate(state, account.updateOrCreate(state, actualUpdates, context), context);
290
293
  })
291
294
  ),
292
295
 
@@ -31,6 +31,7 @@ const schema = Joi.object({
31
31
  unit: Joi.string().min(1).max(6).lowercase().required(),
32
32
  decimal: Joi.number().min(6).max(18).required(),
33
33
  icon: Joi.string().optional().allow(null).valid(''),
34
+ maxTotalSupply: Joi.alternatives().try(Joi.BN().greater(0), Joi.string().valid('')).optional().allow(null),
34
35
  }).required(),
35
36
  data: Joi.any().optional().allow(null),
36
37
  }).options({ stripUnknown: true, noDefaults: false });
@@ -81,10 +82,10 @@ runner.use(
81
82
 
82
83
  // Ensure symbol is not internal
83
84
  runner.use((context, next) => {
84
- const { internalSymbols } = context.config;
85
+ const { reservedSymbols } = context.config;
85
86
  const { symbol } = context.itx.token;
86
87
 
87
- if (internalSymbols.includes(symbol.toUpperCase())) {
88
+ if (reservedSymbols.includes(symbol.toUpperCase())) {
88
89
  return next(new Error('INVALID_SYMBOL', `Token symbol can not be ${symbol}`));
89
90
  }
90
91
 
@@ -3,6 +3,7 @@ const { Joi, schemas } = require('@arcblock/validator');
3
3
  const { BN, fromUnitToToken } = require('@ocap/util');
4
4
  const { Runner, pipes } = require('@ocap/tx-pipeline');
5
5
  const { account, tokenFactory, token } = require('@ocap/state');
6
+ const pick = require('lodash/pick');
6
7
 
7
8
  const EnsureTxGas = require('../../pipes/ensure-gas');
8
9
  const EnsureTxCost = require('../../pipes/ensure-cost');
@@ -115,6 +116,26 @@ runner.use(
115
116
  })
116
117
  );
117
118
 
119
+ // verify max supply
120
+ runner.use((context, next) => {
121
+ const { tokenState, itx } = context;
122
+
123
+ if (tokenState.maxTotalSupply) {
124
+ const availableSupply = new BN(tokenState.maxTotalSupply).sub(new BN(tokenState.totalSupply));
125
+
126
+ if (new BN(itx.amount).gt(availableSupply)) {
127
+ return next(
128
+ new Error(
129
+ 'INVALID_TOKEN',
130
+ `Maximum mintable tokens are ${fromUnitToToken(availableSupply, tokenState.decimal)} ${tokenState.symbol}`
131
+ )
132
+ );
133
+ }
134
+ }
135
+
136
+ next();
137
+ });
138
+
118
139
  // verify slippage
119
140
  runner.use((context, next) => {
120
141
  const { reserveAmount, reserveFee, inputs, tokenFactoryState } = context;
@@ -237,7 +258,7 @@ runner.use(
237
258
  }
238
259
  // Ensure the sender exists in accountUpdates, because even if there is no balance change, we need to update his nonce
239
260
  if (!accountUpdates[tx.from]) {
240
- accountUpdates[tx.from] = {};
261
+ accountUpdates[tx.from] = senderState || {};
241
262
  }
242
263
 
243
264
  // update owner
@@ -266,12 +287,14 @@ runner.use(
266
287
  // We can use updateOrCreate here because the owner and signer have already been validated to exist earlier,
267
288
  // the sender and receiver are allowed to be created in the transaction.
268
289
  const state = [senderState, receiverState, ownerState, ...signerStates].find((x) => x?.address === address);
269
- const senderUpdated = address === tx.from ? { nonce: tx.nonce, pk: tx.pk } : {};
270
- return statedb.account.updateOrCreate(
271
- state,
272
- account.updateOrCreate(state, Object.assign({ address }, senderUpdated, updates), context),
273
- context
274
- );
290
+
291
+ // Should only update nonce and pk for sender and new accounts
292
+ const actualUpdates =
293
+ address === tx.from || !state
294
+ ? { ...updates, address, nonce: tx.nonce, pk: tx.pk }
295
+ : pick(updates, ['tokens']);
296
+
297
+ return statedb.account.updateOrCreate(state, account.updateOrCreate(state, actualUpdates, context), context);
275
298
  })
276
299
  ),
277
300
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.23.0",
6
+ "version": "1.24.0",
7
7
  "description": "Predefined tx pipeline sets to execute certain type of transactions",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -18,19 +18,19 @@
18
18
  "empty-value": "^1.0.1",
19
19
  "lodash": "^4.17.21",
20
20
  "url-join": "^4.0.1",
21
- "@arcblock/did": "1.23.0",
22
- "@arcblock/did-util": "1.23.0",
23
- "@arcblock/jwt": "1.23.0",
24
- "@arcblock/validator": "1.23.0",
25
- "@ocap/asset": "1.23.0",
26
- "@ocap/client": "1.23.0",
27
- "@ocap/mcrypto": "1.23.0",
28
- "@ocap/merkle-tree": "1.23.0",
29
- "@ocap/message": "1.23.0",
30
- "@ocap/state": "1.23.0",
31
- "@ocap/tx-pipeline": "1.23.0",
32
- "@ocap/util": "1.23.0",
33
- "@ocap/wallet": "1.23.0"
21
+ "@arcblock/did": "1.24.0",
22
+ "@arcblock/jwt": "1.24.0",
23
+ "@ocap/asset": "1.24.0",
24
+ "@arcblock/validator": "1.24.0",
25
+ "@ocap/client": "1.24.0",
26
+ "@ocap/mcrypto": "1.24.0",
27
+ "@ocap/merkle-tree": "1.24.0",
28
+ "@ocap/message": "1.24.0",
29
+ "@arcblock/did-util": "1.24.0",
30
+ "@ocap/state": "1.24.0",
31
+ "@ocap/tx-pipeline": "1.24.0",
32
+ "@ocap/util": "1.24.0",
33
+ "@ocap/wallet": "1.24.0"
34
34
  },
35
35
  "resolutions": {
36
36
  "bn.js": "5.2.1",
@@ -39,8 +39,8 @@
39
39
  "devDependencies": {
40
40
  "jest": "^29.7.0",
41
41
  "start-server-and-test": "^1.14.0",
42
- "@ocap/e2e-test": "1.23.0",
43
- "@ocap/statedb-memory": "1.23.0"
42
+ "@ocap/e2e-test": "1.24.0",
43
+ "@ocap/statedb-memory": "1.24.0"
44
44
  },
45
45
  "scripts": {
46
46
  "lint": "eslint tests lib",