@abtnode/core 1.7.27 → 1.8.2

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/api/node.js CHANGED
@@ -7,6 +7,7 @@ const isGitpod = require('@abtnode/util/lib/is-gitpod');
7
7
  const getFolderSize = require('@abtnode/util/lib/get-folder-size');
8
8
  const canPackageReadWrite = require('@abtnode/util/lib/can-pkg-rw');
9
9
  const { toDelegateAddress } = require('@arcblock/did-util');
10
+ const { STORE_DETAIL_PAGE_PATH_PREFIX } = require('@abtnode/constant');
10
11
 
11
12
  const logger = require('@abtnode/logger')('@abtnode/core:api:node');
12
13
 
@@ -40,7 +41,19 @@ class NodeAPI {
40
41
  // eslint-disable-next-line no-unused-vars
41
42
  async addRegistry({ url }, context) {
42
43
  logger.info('add registry', { url });
43
- const sanitized = sanitizeUrl(url);
44
+
45
+ const urlObj = new URL(url);
46
+ let newUrl = urlObj.origin;
47
+
48
+ // if the pathname is store blocklet list or blocklet detail
49
+ if (urlObj.pathname?.includes(STORE_DETAIL_PAGE_PATH_PREFIX)) {
50
+ const lastIndex = urlObj.pathname.lastIndexOf(STORE_DETAIL_PAGE_PATH_PREFIX);
51
+ const pathnamePrefix = urlObj.pathname.substring(0, lastIndex);
52
+ newUrl = `${newUrl}${pathnamePrefix || ''}`;
53
+ }
54
+
55
+ const sanitized = sanitizeUrl(newUrl);
56
+
44
57
  const info = await this.state.read();
45
58
  const exist = info.blockletRegistryList.find((x) => x.url === sanitized);
46
59
  if (exist) {
@@ -22,6 +22,7 @@ const logger = require('@abtnode/logger')('@abtnode/core:blocklet:manager');
22
22
  const downloadFile = require('@abtnode/util/lib/download-file');
23
23
  const Lock = require('@abtnode/util/lib/lock');
24
24
  const { getVcFromPresentation } = require('@abtnode/util/lib/vc');
25
+ const handleInstanceInStore = require('@abtnode/util/lib/public-to-store');
25
26
  const { VC_TYPE_BLOCKLET_PURCHASE } = require('@abtnode/constant');
26
27
 
27
28
  const getBlockletEngine = require('@blocklet/meta/lib/engine');
@@ -216,6 +217,7 @@ class BlockletManager extends BaseBlockletManager {
216
217
  * @param {{
217
218
  * url: string;
218
219
  * sync: boolean = false;
220
+ * downloadToken: string;
219
221
  * }} params
220
222
  * @param {{
221
223
  * [key: string]: any
@@ -223,9 +225,22 @@ class BlockletManager extends BaseBlockletManager {
223
225
  * @return {*}
224
226
  * @memberof BlockletManager
225
227
  */
226
- async install(params, context) {
228
+ async install(params, context = {}) {
227
229
  logger.debug('install blocklet', { params, context });
228
230
 
231
+ if (params.downloadToken) {
232
+ const info = await states.node.read();
233
+
234
+ context.headers = Object.assign(context?.headers || {}, {
235
+ 'x-server-did': info.did,
236
+ 'x-download-token': params.downloadToken,
237
+ 'x-server-publick-key': info.pk,
238
+ 'x-server-signature': sign(info.did, info.sk, {
239
+ exp: (Date.now() + 5 * 60 * 1000) / 1000,
240
+ }),
241
+ });
242
+ }
243
+
229
244
  const source = getSourceFromInstallParams(params);
230
245
  if (typeof context.startImmediately === 'undefined') {
231
246
  context.startImmediately = !!params.startImmediately;
@@ -319,10 +334,12 @@ class BlockletManager extends BaseBlockletManager {
319
334
  }
320
335
  }
321
336
 
337
+ const { inStore, registryUrl } = await parseSourceUrl(url);
338
+
322
339
  const blocklet = await states.blocklet.getBlocklet(meta.did);
323
340
  const isRunning = blocklet ? blocklet.status === BlockletStatus.running : false;
324
341
 
325
- return { meta, isFree, isInstalled: !!blocklet, isRunning };
342
+ return { meta, isFree, isInstalled: !!blocklet, isRunning, inStore, registryUrl };
326
343
  }
327
344
 
328
345
  async installBlockletFromVc({ vcPresentation, challenge }, context) {
@@ -423,7 +440,7 @@ class BlockletManager extends BaseBlockletManager {
423
440
 
424
441
  await this.deleteProcess({ did });
425
442
  const res = await states.blocklet.setBlockletStatus(did, BlockletStatus.error);
426
- this.emit(BlockletEvents.startFailed, res);
443
+ this.emit(BlockletEvents.startFailed, { ...res, error: { message: error.message } });
427
444
 
428
445
  if (throwOnError) {
429
446
  throw new Error(description);
@@ -601,7 +618,7 @@ class BlockletManager extends BaseBlockletManager {
601
618
  async deleteComponent({ did, rootDid, keepData, keepState }, context) {
602
619
  logger.info('delete blocklet component', { did, rootDid, keepData });
603
620
 
604
- const blocklet = await this.ensureBlocklet(rootDid);
621
+ const blocklet = await this.ensureBlocklet(rootDid, { validateEnv: false });
605
622
  const child = blocklet.children.find((x) => x.meta.did === did);
606
623
  if (!child) {
607
624
  throw new Error('Component does not exist');
@@ -708,7 +725,7 @@ class BlockletManager extends BaseBlockletManager {
708
725
 
709
726
  if (!attachRuntimeInfo) {
710
727
  try {
711
- const blocklet = await this.ensureBlocklet(did);
728
+ const blocklet = await this.ensureBlocklet(did, { throwOnNotExist: false });
712
729
  return blocklet;
713
730
  } catch (e) {
714
731
  logger.error('get blocklet detail error', { error: e.message });
@@ -851,6 +868,18 @@ class BlockletManager extends BaseBlockletManager {
851
868
  return newState;
852
869
  }
853
870
 
871
+ async configPublicToStore({ did, publicToStore = false }) {
872
+ const blocklet = await this.ensureBlocklet(did);
873
+ // publicToStore 由用户传入
874
+ // handleInstanceInStore 方法写在前面,保证向 store 操作成功后才会更改 blocklet 中的 publicToStore值
875
+ // handleInstanceInStore 中会校验修改 publicToStore字段 的条件,不符合则会抛错,就不会执行下面更新 publicToStore 的逻辑
876
+ await handleInstanceInStore(blocklet, { publicToStore });
877
+ await states.blockletExtras.setSettings(did, { publicToStore });
878
+
879
+ const newState = await this.ensureBlocklet(did);
880
+ return newState;
881
+ }
882
+
854
883
  /**
855
884
  * upgrade blocklet from registry
856
885
  */
@@ -1230,14 +1259,17 @@ class BlockletManager extends BaseBlockletManager {
1230
1259
  return rootBlocklet;
1231
1260
  }
1232
1261
 
1233
- async ensureBlocklet(did, { e2eMode = false, validateEnv = true } = {}) {
1262
+ async ensureBlocklet(did, { e2eMode = false, validateEnv = true, throwOnNotExist = true } = {}) {
1234
1263
  if (!isValidDid(did)) {
1235
1264
  throw new Error(`Blocklet did is invalid: ${did}`);
1236
1265
  }
1237
1266
 
1238
1267
  const blocklet = await states.blocklet.getBlocklet(did);
1239
1268
  if (!blocklet) {
1240
- throw new Error(`Can not find blocklet in database by did ${did}`);
1269
+ if (throwOnNotExist) {
1270
+ throw new Error(`Can not find blocklet in database by did ${did}`);
1271
+ }
1272
+ return null;
1241
1273
  }
1242
1274
 
1243
1275
  // app settings
@@ -1272,6 +1304,10 @@ class BlockletManager extends BaseBlockletManager {
1272
1304
  return blocklet;
1273
1305
  }
1274
1306
 
1307
+ async hasBlocklet({ did }) {
1308
+ return states.blocklet.hasBlocklet(did);
1309
+ }
1310
+
1275
1311
  async setInitialized({ did, owner }) {
1276
1312
  if (!validateOwner(owner)) {
1277
1313
  throw new Error('Blocklet owner is invalid');
@@ -1339,7 +1375,12 @@ class BlockletManager extends BaseBlockletManager {
1339
1375
  }
1340
1376
 
1341
1377
  try {
1342
- let blocklet = await this.ensureBlocklet(did);
1378
+ let blocklet = await this.ensureBlocklet(did, { throwOnNotExist: false });
1379
+
1380
+ if (!blocklet) {
1381
+ return null;
1382
+ }
1383
+
1343
1384
  const fromCache = !!cachedBlocklet;
1344
1385
 
1345
1386
  // if from cached data, only use cache data of runtime info (engine, diskInfo, runtimeInfo...)
@@ -1487,7 +1528,12 @@ class BlockletManager extends BaseBlockletManager {
1487
1528
 
1488
1529
  preDownloadLock.release();
1489
1530
 
1490
- this.emit(BlockletEvents.downloadFailed, { meta: did });
1531
+ this.emit(BlockletEvents.downloadFailed, {
1532
+ meta: { did },
1533
+ error: {
1534
+ message: err.message,
1535
+ },
1536
+ });
1491
1537
  states.notification.create({
1492
1538
  title: 'Blocklet Download Failed',
1493
1539
  description: `Blocklet ${name}@${version} download failed with error: ${err.message}`,
@@ -1778,10 +1824,12 @@ class BlockletManager extends BaseBlockletManager {
1778
1824
  throw new Error('Root blocklet does not exist');
1779
1825
  }
1780
1826
 
1827
+ const { inStore } = await parseSourceUrl(url);
1828
+
1781
1829
  const meta = await getBlockletMetaFromUrl(url);
1782
1830
 
1783
- // 如果是一个付费的blocklet,需要携带token才能下载成功
1784
- if (!isFreeBlocklet(meta)) {
1831
+ // 如果是一个付费的blocklet,并且url来源为Store, 需要携带token才能下载成功
1832
+ if (!isFreeBlocklet(meta) && inStore) {
1785
1833
  const info = await states.node.read();
1786
1834
 
1787
1835
  // eslint-disable-next-line no-param-reassign
@@ -2617,7 +2665,12 @@ class BlockletManager extends BaseBlockletManager {
2617
2665
  logger.error('failed to install blocklet', { name, did, version, error: err });
2618
2666
  try {
2619
2667
  await this._rollback('install', did, oldBlocklet);
2620
- this.emit(BlockletEvents.installFailed, { meta: { did } });
2668
+ this.emit(BlockletEvents.installFailed, {
2669
+ meta: { did },
2670
+ error: {
2671
+ message: err.message,
2672
+ },
2673
+ });
2621
2674
  states.notification.create({
2622
2675
  title: 'Blocklet Install Failed',
2623
2676
  description: `Blocklet ${meta.name}@${meta.version} install failed with error: ${err.message}`,
package/lib/cert.js CHANGED
@@ -103,14 +103,16 @@ class Cert extends EventEmitter {
103
103
 
104
104
  async add(data) {
105
105
  if (!data.certificate || !data.privateKey) {
106
- throw new Error('certificate and privateKey is required');
106
+ throw new Error('certificate and privateKey are required');
107
107
  }
108
108
 
109
109
  Cert.fixCertificate(data);
110
110
 
111
- await this.manager.add(data);
112
- logger.info('add certificate result', { name: data.name });
113
- this.emit('cert.added', data);
111
+ const result = await this.manager.add(data);
112
+ logger.info('add certificate result', { name: result.name });
113
+ this.emit('cert.added', result);
114
+
115
+ return result;
114
116
  }
115
117
 
116
118
  async issue({ domain }) {
@@ -120,7 +122,10 @@ class Cert extends EventEmitter {
120
122
  }
121
123
 
122
124
  async upsertByDomain(data) {
123
- return this.manager.upsertByDomain(data);
125
+ const result = await this.manager.upsertByDomain(data);
126
+ this.emit('cert.updated', result);
127
+
128
+ return result;
124
129
  }
125
130
 
126
131
  async update(data) {
package/lib/event.js CHANGED
@@ -5,6 +5,7 @@ const { wipeSensitiveData } = require('@blocklet/meta/lib/util');
5
5
  const logger = require('@abtnode/logger')('@abtnode/core:event');
6
6
  const { BLOCKLET_MODES, BlockletStatus, BlockletSource, BlockletEvents } = require('@blocklet/meta/lib/constants');
7
7
  const { EVENTS } = require('@abtnode/constant');
8
+ const handleInstanceInStore = require('@abtnode/util/lib/public-to-store');
8
9
 
9
10
  const eventHub =
10
11
  process.env.NODE_ENV === 'test' ? require('@arcblock/event-hub/single') : require('@arcblock/event-hub');
@@ -160,6 +161,17 @@ module.exports = ({
160
161
  await handleBlockletUpgrade(eventName, payload);
161
162
  } else if ([BlockletEvents.removed].includes(eventName)) {
162
163
  await handleBlockletRemove(eventName, payload);
164
+ } else if ([BlockletEvents.started].includes(eventName)) {
165
+ try {
166
+ const blocklet = await blockletManager.ensureBlocklet(payload.meta.did);
167
+ const { publicToStore } = blocklet.settings;
168
+ // 如果一个 blocklet 没有设置 publicToStore,启动成功后不应给 store 发请求
169
+ if (publicToStore) {
170
+ await handleInstanceInStore(blocklet, { publicToStore });
171
+ }
172
+ } catch (error) {
173
+ logger.error('BlockletEvents started failed', { error });
174
+ }
163
175
  }
164
176
 
165
177
  if (payload.blocklet && !payload.meta) {
package/lib/index.js CHANGED
@@ -226,6 +226,7 @@ function ABTNode(options) {
226
226
  getLatestBlockletVersion: blockletManager.getLatestBlockletVersion.bind(blockletManager),
227
227
  getBlockletMetaFromUrl: blockletManager.getMetaFromUrl.bind(blockletManager),
228
228
  resetBlocklet: blockletManager.reset.bind(blockletManager),
229
+ configPublicToStore: blockletManager.configPublicToStore.bind(blockletManager),
229
230
 
230
231
  deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
231
232
 
@@ -237,6 +238,7 @@ function ABTNode(options) {
237
238
  getBlocklets: blockletManager.list.bind(blockletManager),
238
239
  getBlocklet: blockletManager.detail.bind(blockletManager),
239
240
  getBlockletDiff: blockletManager.diff.bind(blockletManager),
241
+ hasBlocklet: blockletManager.hasBlocklet.bind(blockletManager),
240
242
  updateAllBlockletEnvironment: blockletManager.updateAllBlockletEnvironment.bind(blockletManager),
241
243
  setBlockletInitialized: blockletManager.setInitialized.bind(blockletManager),
242
244
 
@@ -434,7 +434,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
434
434
  isProtected: true,
435
435
  });
436
436
 
437
- logger.info('dashboard certificate updated');
437
+ logger.info('dashboard certificate updated', { domain });
438
438
  } catch (error) {
439
439
  logger.error('update dashboard certificate failed', { error });
440
440
  throw error;
@@ -1103,6 +1103,7 @@ module.exports = function getRouterHelpers({ dataDirs, routingSnapshot, routerMa
1103
1103
  certManager.on('cert.added', () => providers[providerName].reload());
1104
1104
  certManager.on('cert.removed', () => providers[providerName].reload());
1105
1105
  certManager.on('cert.issued', () => providers[providerName].reload());
1106
+ certManager.on('cert.updated', () => providers[providerName].reload());
1106
1107
 
1107
1108
  await providers[providerName].start();
1108
1109
  }
@@ -8,7 +8,6 @@ const path = require('path');
8
8
  const os = require('os');
9
9
  const fse = require('fs-extra');
10
10
  const get = require('lodash/get');
11
- const { Certificate, PrivateKey } = require('@fidm/x509');
12
11
  const { EventEmitter } = require('events');
13
12
  const uuid = require('uuid');
14
13
  const isUrl = require('is-url');
@@ -564,39 +563,6 @@ class RouterManager extends EventEmitter {
564
563
  }
565
564
  }
566
565
 
567
- validateCertificate(cert, domain) {
568
- const certificate = Certificate.fromPEM(cert.certificate);
569
- const privateKey = PrivateKey.fromPEM(cert.privateKey);
570
-
571
- const data = Buffer.allocUnsafe(100);
572
- const signature = privateKey.sign(data, 'sha512');
573
- if (!certificate.publicKey.verify(data, signature, 'sha512')) {
574
- throw new Error('Invalid certificate: signature verify failed');
575
- }
576
-
577
- const certDomain = get(certificate, 'subject.commonName', '');
578
- if (domain && domain !== certDomain) {
579
- throw new Error('Invalid certificate: domain does not match');
580
- }
581
-
582
- const validFrom = get(certificate, 'validFrom', '');
583
- if (!validFrom || new Date(validFrom).getTime() > Date.now()) {
584
- throw new Error('Invalid certificate: not in valid period');
585
- }
586
- const validTo = get(certificate, 'validTo', '');
587
- if (!validTo || new Date(validTo).getTime() < Date.now()) {
588
- throw new Error('Invalid certificate: not in valid period');
589
- }
590
-
591
- return certificate;
592
- }
593
-
594
- fixCertificate(entity) {
595
- // Hack: this logic exists because gql does not allow line breaks in arg values
596
- entity.privateKey = entity.privateKey.split('|').join('\n');
597
- entity.certificate = entity.certificate.split('|').join('\n');
598
- }
599
-
600
566
  fixRootBlockletRule(rule) {
601
567
  if (!rule.id) {
602
568
  rule.id = uuid.v4();
@@ -114,7 +114,11 @@ const getLogContent = async (action, args, context, result, info, node) => {
114
114
  return `upgraded blocklet ${getBlockletInfo(result, info)} to v${result.meta.version}`;
115
115
  case 'updateChildBlocklets':
116
116
  return `upgraded components for blocklet ${getBlockletInfo(result, info)}`;
117
-
117
+ case 'configPublicToStore':
118
+ if (args.publicToStore) {
119
+ return `set publicToStore to true for blocklet ${getBlockletInfo(result, info)}`;
120
+ }
121
+ return `set publicToStore to false for blocklet ${getBlockletInfo(result, info)}`;
118
122
  // store
119
123
  case 'addBlockletStore':
120
124
  return `added blocklet store ${args.url}`;
@@ -237,6 +241,7 @@ const getLogCategory = (action) => {
237
241
  case 'configBlocklet':
238
242
  case 'upgradeBlocklet':
239
243
  case 'updateChildBlocklets':
244
+ case 'configPublicToStore':
240
245
  return 'blocklet';
241
246
 
242
247
  // store
@@ -102,6 +102,22 @@ class BlockletState extends BaseState {
102
102
  });
103
103
  }
104
104
 
105
+ hasBlocklet(did) {
106
+ return new Promise((resolve, reject) => {
107
+ if (!did) {
108
+ resolve(false);
109
+ }
110
+
111
+ this.db.count({ $or: [{ 'meta.did': did }, { appDid: did }] }, (err, count) => {
112
+ if (err) {
113
+ return reject(err);
114
+ }
115
+
116
+ return resolve(!!count);
117
+ });
118
+ });
119
+ }
120
+
105
121
  getBlocklets(query = {}, projection) {
106
122
  return new Promise((resolve, reject) => {
107
123
  this.db
@@ -10,7 +10,13 @@ class SessionState extends BaseState {
10
10
 
11
11
  this.db.ensureIndex({ fieldName: 'createdAt' }, (error) => {
12
12
  if (error) {
13
- logger.error('ensure index failed', { error });
13
+ logger.error('ensure createdAt index failed', { error });
14
+ }
15
+ });
16
+
17
+ this.db.ensureIndex({ fieldName: 'expireDate', expireAfterSeconds: 0 }, (error) => {
18
+ if (error) {
19
+ logger.error('ensure expireDate index failed', { error });
14
20
  }
15
21
  });
16
22
  }
@@ -309,6 +309,7 @@ const getComponentSystemEnvironments = (blocklet) => {
309
309
  if (ports) {
310
310
  Object.assign(portEnvironments, ports);
311
311
  }
312
+
312
313
  return {
313
314
  BLOCKLET_REAL_DID: blocklet.env.id,
314
315
  BLOCKLET_DATA_DIR: blocklet.env.dataDir,
@@ -328,10 +329,19 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
328
329
  return o;
329
330
  }, {});
330
331
 
332
+ // get devEnvironments, when blocklet is in dev mode
333
+ const devEnvironments =
334
+ blocklet.mode === BLOCKLET_MODES.DEVELOPMENT
335
+ ? {
336
+ BLOCKLET_DEV_MOUNT_POINT: blocklet?.mountPoint || '',
337
+ }
338
+ : {};
339
+
331
340
  return {
332
341
  ...blocklet.configObj,
333
342
  ...getSharedConfigObj(blocklet, ancestors),
334
343
  ...blocklet.environmentObj,
344
+ ...devEnvironments,
335
345
  ...nodeEnvironments,
336
346
  ...safeNodeEnvironments,
337
347
  };
@@ -934,11 +944,6 @@ const pruneBlockletBundle = async ({ blocklets, installDir, blockletSettings })
934
944
 
935
945
  const fillAppDirs = async (dir, level = 'root') => {
936
946
  if (level === 'version') {
937
- if (!fs.existsSync(path.join(dir, 'blocklet.yml'))) {
938
- logger.error('blocklet.yml does not exist in blocklet bundle dir', { dir });
939
- return;
940
- }
941
-
942
947
  appDirs.push({
943
948
  key: path.relative(installDir, dir),
944
949
  dir,
package/lib/util/index.js CHANGED
@@ -398,7 +398,10 @@ const validateUrl = async (url, expectedHttpResTypes = ['application/json', 'tex
398
398
  throw new Error(`Cannot get content-type from ${url}: ${err.message}`);
399
399
  }
400
400
 
401
- if (expectedHttpResTypes.some((x) => res.headers['content-type'].includes(x)) === false) {
401
+ if (
402
+ res.headers['content-type'] &&
403
+ expectedHttpResTypes.some((x) => res.headers['content-type'].includes(x)) === false
404
+ ) {
402
405
  throw new Error(`Unexpected content-type from ${url}: ${res.headers['content-type']}`);
403
406
  }
404
407
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.7.27",
6
+ "version": "1.8.2",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,31 +19,31 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/certificate-manager": "1.7.27",
23
- "@abtnode/constant": "1.7.27",
24
- "@abtnode/cron": "1.7.27",
25
- "@abtnode/db": "1.7.27",
26
- "@abtnode/logger": "1.7.27",
27
- "@abtnode/queue": "1.7.27",
28
- "@abtnode/rbac": "1.7.27",
29
- "@abtnode/router-provider": "1.7.27",
30
- "@abtnode/static-server": "1.7.27",
31
- "@abtnode/timemachine": "1.7.27",
32
- "@abtnode/util": "1.7.27",
33
- "@arcblock/did": "1.17.0",
22
+ "@abtnode/certificate-manager": "1.8.2",
23
+ "@abtnode/constant": "1.8.2",
24
+ "@abtnode/cron": "1.8.2",
25
+ "@abtnode/db": "1.8.2",
26
+ "@abtnode/logger": "1.8.2",
27
+ "@abtnode/queue": "1.8.2",
28
+ "@abtnode/rbac": "1.8.2",
29
+ "@abtnode/router-provider": "1.8.2",
30
+ "@abtnode/static-server": "1.8.2",
31
+ "@abtnode/timemachine": "1.8.2",
32
+ "@abtnode/util": "1.8.2",
33
+ "@arcblock/did": "1.17.2",
34
34
  "@arcblock/did-motif": "^1.1.10",
35
- "@arcblock/did-util": "1.17.0",
36
- "@arcblock/event-hub": "1.17.0",
37
- "@arcblock/jwt": "^1.17.0",
35
+ "@arcblock/did-util": "1.17.2",
36
+ "@arcblock/event-hub": "1.17.2",
37
+ "@arcblock/jwt": "^1.17.2",
38
38
  "@arcblock/pm2-events": "^0.0.5",
39
- "@arcblock/vc": "1.17.0",
40
- "@blocklet/meta": "1.7.27",
39
+ "@arcblock/vc": "1.17.2",
40
+ "@blocklet/meta": "1.8.2",
41
41
  "@fidm/x509": "^1.2.1",
42
- "@nedb/core": "^1.2.2",
43
- "@nedb/multi": "^1.2.2",
44
- "@ocap/mcrypto": "1.17.0",
45
- "@ocap/util": "1.17.0",
46
- "@ocap/wallet": "1.17.0",
42
+ "@nedb/core": "^1.3.1",
43
+ "@nedb/multi": "^1.3.1",
44
+ "@ocap/mcrypto": "1.17.2",
45
+ "@ocap/util": "1.17.2",
46
+ "@ocap/wallet": "1.17.2",
47
47
  "@slack/webhook": "^5.0.3",
48
48
  "axios": "^0.27.2",
49
49
  "axon": "^2.0.3",
@@ -81,5 +81,5 @@
81
81
  "express": "^4.17.1",
82
82
  "jest": "^27.4.5"
83
83
  },
84
- "gitHead": "81a5492df66389b0aede13f033d1e493450833bc"
84
+ "gitHead": "fcbe3c97f3825c507ee16714f49bbf8f58c5b59f"
85
85
  }