@abtnode/core 1.16.0-beta-8ee536d7 → 1.16.0-beta-62b42401

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,104 @@
1
+ const { isValid } = require('@arcblock/did');
2
+ const { isEmpty } = require('lodash');
3
+ const merge = require('lodash/merge');
4
+ const { ensureDirSync, existsSync, rmSync, copy } = require('fs-extra');
5
+
6
+ const { getBackupDirs } = require('../utils/disk');
7
+ const { BaseRestore } = require('./base');
8
+ const { BlockletExtrasRestore } = require('./blocklet-extras');
9
+ const { BlockletRestore } = require('./blocklet');
10
+ const { BlockletsRestore } = require('./blocklets');
11
+
12
+ class DiskRestore extends BaseRestore {
13
+ /**
14
+ *
15
+ * @type {import('./base').BaseRestoreInput}
16
+ * @memberof DiskRestore
17
+ */
18
+ input;
19
+
20
+ /**
21
+ * @type {string}
22
+ * @memberof DiskRestore
23
+ */
24
+ restoreDir;
25
+
26
+ /**
27
+ *
28
+ * @description server 的数据目录
29
+ * @type {string}
30
+ * @memberof DiskRestore
31
+ */
32
+ serverDir;
33
+
34
+ storages;
35
+
36
+ /**
37
+ *
38
+ * @param {import('./base').BaseRestoreInput} input
39
+ * @memberof DiskRestore
40
+ */
41
+ constructor(input) {
42
+ super(input);
43
+ this.verify(input);
44
+ this.input = input;
45
+ this.storages = [
46
+ new BlockletExtrasRestore(this.input),
47
+ new BlockletRestore(this.input),
48
+ new BlockletsRestore(this.input),
49
+ ];
50
+ }
51
+
52
+ /**
53
+ *
54
+ * @param {import('./base').BaseRestoreInput} input
55
+ * @returns {void}
56
+ * @memberof DiskRestore
57
+ */
58
+ verify(input) {
59
+ if (isEmpty(input?.appDid) || !isValid(input?.appDid)) {
60
+ throw new Error(`input.appDid(${input?.appDid}) is not a valid did`);
61
+ }
62
+ }
63
+
64
+ async initialize() {
65
+ this.serverDir = process.env.ABT_NODE_DATA_DIR;
66
+ this.restoreDir = getBackupDirs(this.serverDir, this.input.appDid).restoreDir;
67
+ if (existsSync(this.restoreDir)) {
68
+ rmSync(this.restoreDir, { recursive: true });
69
+ }
70
+ ensureDirSync(this.restoreDir);
71
+
72
+ this.storages.map((x) => x.ensureParams(this));
73
+ }
74
+
75
+ async restore() {
76
+ await this.initialize();
77
+ await this.syncFromBackupDir();
78
+
79
+ const params = await Promise.all(this.storages.map((x) => x.getImportParams()));
80
+ await this.import(merge(...params));
81
+
82
+ return this.storages.map((x) => x.getInstallParams());
83
+ }
84
+
85
+ async syncFromBackupDir() {
86
+ const { appDid } = this.input;
87
+
88
+ const { backupDir } = getBackupDirs(this.serverDir, appDid);
89
+
90
+ await copy(backupDir, this.restoreDir);
91
+ }
92
+
93
+ async import(params) {
94
+ await Promise.all(
95
+ this.storages.map((storage) => {
96
+ return storage.import(params);
97
+ })
98
+ );
99
+ }
100
+ }
101
+
102
+ module.exports = {
103
+ DiskRestore,
104
+ };
@@ -13,18 +13,19 @@
13
13
 
14
14
  const validUrl = require('valid-url');
15
15
  const merge = require('lodash/merge');
16
- const { BlockletEvents } = require('@blocklet/constant');
16
+ const { BlockletEvents, RESTORE_PROGRESS_STATUS } = require('@blocklet/constant');
17
17
  const { SpaceClient, RestoreBlockletCommand } = require('@did-space/client');
18
18
  const { ensureDirSync, existsSync, rmSync } = require('fs-extra');
19
- const { join, basename } = require('path');
19
+ const { join } = require('path');
20
20
 
21
21
  const logger = require('@abtnode/logger')('@abtnode/core:storage:restore');
22
22
 
23
+ const { BaseRestore } = require('./base');
23
24
  const { BlockletExtrasRestore } = require('./blocklet-extras');
24
25
  const { BlockletRestore } = require('./blocklet');
25
26
  const { BlockletsRestore } = require('./blocklets');
26
27
 
27
- class SpacesRestore {
28
+ class SpacesRestore extends BaseRestore {
28
29
  /**
29
30
  *
30
31
  * @type {SpaceRestoreInput}
@@ -55,6 +56,7 @@ class SpacesRestore {
55
56
  * @memberof SpacesRestore
56
57
  */
57
58
  constructor(input) {
59
+ super(input);
58
60
  this.verify(input);
59
61
  this.input = input;
60
62
  this.storages = [
@@ -120,7 +122,8 @@ class SpacesRestore {
120
122
  logger.info('restore progress', { appDid: this.input.appDid, data });
121
123
  this.input.event.emit(BlockletEvents.restoreProgress, {
122
124
  appDid: this.input.appDid,
123
- message: `Downloaded file ${basename(data.key)} (${data.completed}/${data.total})`,
125
+ status: RESTORE_PROGRESS_STATUS.downloading,
126
+ data,
124
127
  });
125
128
  },
126
129
 
@@ -137,8 +140,9 @@ class SpacesRestore {
137
140
  async import(params) {
138
141
  this.input.event.emit(BlockletEvents.restoreProgress, {
139
142
  appDid: this.input.appDid,
140
- message: 'Preparing to import data...',
143
+ status: RESTORE_PROGRESS_STATUS.importData,
141
144
  });
145
+
142
146
  await Promise.all(
143
147
  this.storages.map((storage) => {
144
148
  return storage.import(params);
@@ -146,7 +150,7 @@ class SpacesRestore {
146
150
  );
147
151
  this.input.event.emit(BlockletEvents.restoreProgress, {
148
152
  appDid: this.input.appDid,
149
- message: 'Importing data successfully...',
153
+ status: RESTORE_PROGRESS_STATUS.importDataSuccess,
150
154
  });
151
155
  }
152
156
  }
@@ -0,0 +1,61 @@
1
+ const path = require('path');
2
+ const fs = require('fs-extra');
3
+
4
+ const logger = require('@abtnode/logger')('@abtnode/core:storage:utils:disk');
5
+
6
+ const backupDirName = '_abtnode/backup';
7
+ const restoreDirName = 'tmp/restore-disk';
8
+
9
+ const getBackupList = (dataDir) => {
10
+ const baseBackupDir = path.join(dataDir, backupDirName);
11
+ const backupList = [];
12
+ const appDidList = fs.readdirSync(baseBackupDir);
13
+
14
+ appDidList.forEach((appDid) => {
15
+ const metaFile = path.join(baseBackupDir, appDid, 'meta.json');
16
+ if (fs.existsSync(metaFile)) {
17
+ try {
18
+ const meta = fs.readJsonSync(metaFile);
19
+ if (meta.appDid === appDid) {
20
+ backupList.push(meta);
21
+ }
22
+ } catch (error) {
23
+ logger.error('read meta.json error', error);
24
+ }
25
+ }
26
+ });
27
+
28
+ return backupList;
29
+ };
30
+
31
+ const removeBackup = async (dataDir, appDid) => {
32
+ try {
33
+ const baseBackupDir = path.join(dataDir, backupDirName);
34
+ const backupDir = path.join(baseBackupDir, appDid);
35
+ if (fs.existsSync(backupDir)) {
36
+ await fs.remove(backupDir);
37
+ return true;
38
+ }
39
+ return false;
40
+ } catch (error) {
41
+ logger.error('remove backup error', error);
42
+ return false;
43
+ }
44
+ };
45
+
46
+ const getBackupDirs = (serverDir, appDid) => {
47
+ const baseBackupDir = path.join(serverDir, 'data', backupDirName, appDid);
48
+ const backupDir = path.join(baseBackupDir, appDid);
49
+ const restoreDir = path.join(serverDir, restoreDirName, appDid);
50
+ return {
51
+ baseBackupDir,
52
+ backupDir,
53
+ restoreDir,
54
+ };
55
+ };
56
+
57
+ module.exports = {
58
+ getBackupList,
59
+ removeBackup,
60
+ getBackupDirs,
61
+ };
package/lib/event.js CHANGED
@@ -257,7 +257,13 @@ module.exports = ({
257
257
  }
258
258
 
259
259
  if (
260
- ![BlockletEvents.removed, BlockletEvents.dataCleaned].includes(eventName) &&
260
+ [
261
+ BlockletEvents.started,
262
+ BlockletEvents.startFailed,
263
+ BlockletEvents.stopped,
264
+ BlockletEvents.reloaded,
265
+ BlockletEvents.statusChange,
266
+ ].includes(eventName) &&
261
267
  blocklet.status &&
262
268
  !isBeforeInstalled(blocklet.status)
263
269
  ) {
package/lib/index.js CHANGED
@@ -230,11 +230,12 @@ function ABTNode(options) {
230
230
  deleteBlockletProcess: blockletManager.deleteProcess.bind(blockletManager),
231
231
  configPublicToStore: blockletManager.configPublicToStore.bind(blockletManager),
232
232
  configNavigations: blockletManager.configNavigations.bind(blockletManager),
233
+ configOAuth: blockletManager.configOAuth.bind(blockletManager),
233
234
  updateWhoCanAccess: blockletManager.updateWhoCanAccess.bind(blockletManager),
234
235
  updateComponentTitle: blockletManager.updateComponentTitle.bind(blockletManager),
235
236
  updateComponentMountPoint: blockletManager.updateComponentMountPoint.bind(blockletManager),
236
- backupToSpaces: blockletManager.backupToSpaces.bind(blockletManager),
237
- restoreFromSpaces: blockletManager.restoreFromSpaces.bind(blockletManager),
237
+ backupBlocklet: blockletManager.backup.bind(blockletManager),
238
+ restoreBlocklet: blockletManager.restore.bind(blockletManager),
238
239
  migrateApplicationToStructV2: blockletManager.migrateApplicationToStructV2.bind(blockletManager),
239
240
 
240
241
  // For diagnose purpose
@@ -243,6 +244,7 @@ function ABTNode(options) {
243
244
  updateBlockletStatus: states.blocklet.setBlockletStatus.bind(states.blocklet),
244
245
 
245
246
  getBlocklets: blockletManager.list.bind(blockletManager),
247
+ getBlockletsFromBackup: blockletManager.listBackups.bind(blockletManager),
246
248
  getBlocklet: blockletManager.detail.bind(blockletManager),
247
249
  getBlockletDiff: blockletManager.diff.bind(blockletManager),
248
250
  hasBlocklet: blockletManager.hasBlocklet.bind(blockletManager),
@@ -127,6 +127,8 @@ const getLogContent = async (action, args, context, result, info, node) => {
127
127
  return `updated following navigations for blocklet ${getBlockletInfo(result, info)}:\n${args.navigations.map(
128
128
  (x) => `- ${x.title}: ${x.link}\n`
129
129
  )}`;
130
+ case 'configOAuth':
131
+ return `updated following OAuth for blocklet ${getBlockletInfo(result, info)}:\n${args.oauth}`;
130
132
  case 'updateComponentTitle':
131
133
  return `update component title to **${args.title}** for blocklet ${getBlockletInfo(result, info)}`;
132
134
  case 'updateComponentMountPoint':
@@ -271,6 +273,7 @@ const getLogCategory = (action) => {
271
273
  case 'upgradeComponents':
272
274
  case 'configPublicToStore':
273
275
  case 'configNavigations':
276
+ case 'configOAuth':
274
277
  case 'updateComponentTitle':
275
278
  case 'updateComponentMountPoint':
276
279
  return 'blocklet';
@@ -9,6 +9,42 @@ const { validateOwner } = require('../util');
9
9
 
10
10
  const isNullOrUndefined = (x) => x === undefined || x === null;
11
11
 
12
+ /**
13
+ * UserPassport
14
+ * @typedef {Object} UserPassport
15
+ * @property {string} id - id
16
+ * @property {string[]} [type] - passport's type
17
+ * @property {string[]} [issuer] - passport's issuer
18
+ * @property {Date} [issuanceDate] - passport's issuanceDate
19
+ * @property {string} [specVersion] - passport's specVersion
20
+ * @property {string} name - passport's name
21
+ * @property {string} [title] - passport's title
22
+ * @property {string} [endpoint] - passport's endpoint
23
+ * @property {string} [status] - passport's status
24
+ * @property {string} role - passport's role
25
+ */
26
+
27
+ /**
28
+ * The Data structure of blocklet-service user
29
+ * @typedef {Object} BlockletUser - Blocklet Service User Table
30
+ * @property {string} _id - id
31
+ * @property {('profile')} type - type of user
32
+ * @property {string} fullName - user profile's name
33
+ * @property {string} avatar - url of user's avatar, eg: bn://avatar/7f8848569405f8cdf8b1b2788ebf7d0f.jpg
34
+ * @property {string} did - user's did
35
+ * @property {('owner'|'admin'|'member'|'guest'|string)} role - user's role
36
+ * @property {UserPassport[]} passports - user's passport list
37
+ * @property {string} pk - user's publicKey
38
+ * @property {boolean} approved - enable user to login
39
+ * @property {string} locale - locale
40
+ * @property {Object} extra - extra data of user
41
+ * @property {Date} firstLoginAt - firstLoginAt
42
+ * @property {Date} lastLoginAt - lastLoginAt
43
+ * @property {string} lastLoginIp - lastLoginIp
44
+ * @property {Date} createdAt - createdAt
45
+ * @property {Date} updatedAt - updatedAt
46
+ */
47
+
12
48
  class User extends BaseState {
13
49
  constructor(baseDir, config = {}) {
14
50
  super(baseDir, { filename: 'user.db', ...config });
@@ -22,6 +58,11 @@ class User extends BaseState {
22
58
  });
23
59
  }
24
60
 
61
+ /**
62
+ * Add a new user
63
+ * @param {BlockletUser} user - user data
64
+ * @returns {Promise<number>}
65
+ */
25
66
  async add(user) {
26
67
  if (!validateOwner(user)) {
27
68
  throw new Error('user is invalid');
@@ -33,7 +74,14 @@ class User extends BaseState {
33
74
  });
34
75
  }
35
76
 
77
+ /**
78
+ * Update a user
79
+ * @param {BlockletUser} user - user data
80
+ * @returns {BlockletUser}
81
+ */
36
82
  async update(user) {
83
+ // FIXME: @zhanghan 这里为什么要限制?
84
+ // 限制后也无法更新 lastLoginAt ?
37
85
  if (!validateOwner(user)) {
38
86
  throw new Error('user is invalid');
39
87
  }
@@ -59,6 +107,11 @@ class User extends BaseState {
59
107
  return this._setPassportStatusById({ did, id, status: PASSPORT_STATUS.VALID });
60
108
  }
61
109
 
110
+ /**
111
+ * remove a user by user's did
112
+ * @param {string} did - the did of user
113
+ * @returns {number} deleted count
114
+ */
62
115
  async remove({ did }) {
63
116
  const num = await super.remove({ did });
64
117
 
@@ -69,6 +122,12 @@ class User extends BaseState {
69
122
  return num;
70
123
  }
71
124
 
125
+ /**
126
+ * enable/disable user login
127
+ * @param {string} did user's did
128
+ * @param {boolean} approved enable/disable user login
129
+ * @returns {BlockletUser}
130
+ */
72
131
  async updateApproved({ did, approved }) {
73
132
  const [num, doc] = await super.update({ did }, { $set: { approved } });
74
133
 
@@ -79,6 +138,12 @@ class User extends BaseState {
79
138
  return doc;
80
139
  }
81
140
 
141
+ /**
142
+ * update user's role
143
+ * @param {string} did user's did
144
+ * @param {BlockletUser.role} role user's rolel
145
+ * @returns {BlockletUser}
146
+ */
82
147
  async updateRole({ did, role }) {
83
148
  const [num, doc] = await super.update({ did }, { $set: { role } });
84
149
 
@@ -89,8 +154,15 @@ class User extends BaseState {
89
154
  return doc;
90
155
  }
91
156
 
157
+ /**
158
+ * Get blocklet service user list
159
+ * @param {Object} query query params
160
+ * @param {('asc'|'desc')} sort query sort
161
+ * @param {any} paging query paging
162
+ * @returns {{list: BlockletUser[]; paging: any;}}
163
+ */
92
164
  async getUsers({ query, sort, paging: inputPaging } = {}) {
93
- const { approved, role, search } = query || {};
165
+ const { approved, role, search, derivedDid } = query || {};
94
166
 
95
167
  // make query param
96
168
  const queryParam = {};
@@ -121,6 +193,11 @@ class User extends BaseState {
121
193
  }
122
194
  }
123
195
 
196
+ // 根据 derivedDid 查询 user 信息(wallet 账户绑定 oauth 账户后,会有该字段)
197
+ if (derivedDid) {
198
+ queryParam['derivedAccount.did'] = derivedDid;
199
+ }
200
+
124
201
  const sortParam = pickBy(sort, (x) => !isNullOrUndefined(x));
125
202
 
126
203
  if (!Object.keys(sortParam).length) {
@@ -136,6 +213,11 @@ class User extends BaseState {
136
213
  };
137
214
  }
138
215
 
216
+ /**
217
+ * get user list by did list
218
+ * @param {string[]} dids user did list
219
+ * @returns {BlockletUser[]}
220
+ */
139
221
  async getUsersByDids({ dids, query } = {}) {
140
222
  const { approved } = query || {};
141
223
  const didList = dids || [];
@@ -152,6 +234,11 @@ class User extends BaseState {
152
234
  return this.find(queryParam);
153
235
  }
154
236
 
237
+ /**
238
+ * get user by did
239
+ * @param {string} did user's did
240
+ * @returns {BlockletUser}
241
+ */
155
242
  async getUser(did) {
156
243
  const doc = await this.findOne({ did });
157
244
  return doc;
@@ -72,6 +72,7 @@ const {
72
72
  getSharedConfigObj,
73
73
  getComponentName,
74
74
  isEnvShareable,
75
+ getBlockletAppIdList,
75
76
  } = require('@blocklet/meta/lib/util');
76
77
  const toBlockletDid = require('@blocklet/meta/lib/did');
77
78
  const { titleSchema, descriptionSchema, logoSchema } = require('@blocklet/meta/lib/schema');
@@ -429,6 +430,8 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
429
430
  ? getBlockletWallet(blocklet.meta.did, nodeEnvironments.ABT_NODE_SK, undefined, 1)
430
431
  : null;
431
432
 
433
+ const BLOCKLET_APP_IDS = getBlockletAppIdList(root).join(',');
434
+
432
435
  const env = {
433
436
  ...blocklet.configObj,
434
437
  ...getSharedConfigObj(blocklet, ancestors),
@@ -439,6 +442,7 @@ const getRuntimeEnvironments = (blocklet, nodeEnvironments, ancestors) => {
439
442
  BLOCKLET_MODE: blocklet.mode || BLOCKLET_MODES.PRODUCTION,
440
443
  BLOCKLET_APP_EK: tmp?.secretKey,
441
444
  BLOCKLET_APP_VERSION: root.meta.version,
445
+ BLOCKLET_APP_IDS,
442
446
  ...nodeEnvironments,
443
447
  ...safeNodeEnvironments,
444
448
  };
@@ -1825,6 +1829,38 @@ const getBlockletKnownAs = (blocklet) => {
1825
1829
  return alsoKnownAs.filter(Boolean).map(toDid);
1826
1830
  };
1827
1831
 
1832
+ const getFixedBundleSource = (component) => {
1833
+ if (!component) {
1834
+ return null;
1835
+ }
1836
+
1837
+ if (component.bundleSource) {
1838
+ return component.bundleSource;
1839
+ }
1840
+
1841
+ const { source, deployedFrom, meta: { bundleName } = {} } = component;
1842
+
1843
+ if (!deployedFrom) {
1844
+ return null;
1845
+ }
1846
+
1847
+ if (source === BlockletSource.registry && bundleName) {
1848
+ return {
1849
+ store: deployedFrom,
1850
+ name: bundleName,
1851
+ version: 'latest',
1852
+ };
1853
+ }
1854
+
1855
+ if (source === BlockletSource.url) {
1856
+ return {
1857
+ url: deployedFrom,
1858
+ };
1859
+ }
1860
+
1861
+ return null;
1862
+ };
1863
+
1828
1864
  module.exports = {
1829
1865
  consumeServerlessNFT,
1830
1866
  forEachBlocklet,
@@ -1879,4 +1915,5 @@ module.exports = {
1879
1915
  checkVersionCompatibility,
1880
1916
  validateBlockletMeta,
1881
1917
  getBlockletKnownAs,
1918
+ getFixedBundleSource,
1882
1919
  };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.0-beta-8ee536d7",
6
+ "version": "1.16.0-beta-62b42401",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,34 +19,34 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "MIT",
21
21
  "dependencies": {
22
- "@abtnode/auth": "1.16.0-beta-8ee536d7",
23
- "@abtnode/certificate-manager": "1.16.0-beta-8ee536d7",
24
- "@abtnode/constant": "1.16.0-beta-8ee536d7",
25
- "@abtnode/cron": "1.16.0-beta-8ee536d7",
26
- "@abtnode/db": "1.16.0-beta-8ee536d7",
27
- "@abtnode/logger": "1.16.0-beta-8ee536d7",
28
- "@abtnode/queue": "1.16.0-beta-8ee536d7",
29
- "@abtnode/rbac": "1.16.0-beta-8ee536d7",
30
- "@abtnode/router-provider": "1.16.0-beta-8ee536d7",
31
- "@abtnode/static-server": "1.16.0-beta-8ee536d7",
32
- "@abtnode/timemachine": "1.16.0-beta-8ee536d7",
33
- "@abtnode/util": "1.16.0-beta-8ee536d7",
34
- "@arcblock/did": "1.18.62",
22
+ "@abtnode/auth": "1.16.0-beta-62b42401",
23
+ "@abtnode/certificate-manager": "1.16.0-beta-62b42401",
24
+ "@abtnode/constant": "1.16.0-beta-62b42401",
25
+ "@abtnode/cron": "1.16.0-beta-62b42401",
26
+ "@abtnode/db": "1.16.0-beta-62b42401",
27
+ "@abtnode/logger": "1.16.0-beta-62b42401",
28
+ "@abtnode/queue": "1.16.0-beta-62b42401",
29
+ "@abtnode/rbac": "1.16.0-beta-62b42401",
30
+ "@abtnode/router-provider": "1.16.0-beta-62b42401",
31
+ "@abtnode/static-server": "1.16.0-beta-62b42401",
32
+ "@abtnode/timemachine": "1.16.0-beta-62b42401",
33
+ "@abtnode/util": "1.16.0-beta-62b42401",
34
+ "@arcblock/did": "1.18.63",
35
35
  "@arcblock/did-motif": "^1.1.10",
36
- "@arcblock/did-util": "1.18.62",
37
- "@arcblock/event-hub": "1.18.62",
38
- "@arcblock/jwt": "^1.18.62",
36
+ "@arcblock/did-util": "1.18.63",
37
+ "@arcblock/event-hub": "1.18.63",
38
+ "@arcblock/jwt": "^1.18.63",
39
39
  "@arcblock/pm2-events": "^0.0.5",
40
- "@arcblock/vc": "1.18.62",
41
- "@blocklet/constant": "1.16.0-beta-8ee536d7",
42
- "@blocklet/meta": "1.16.0-beta-8ee536d7",
43
- "@blocklet/sdk": "1.16.0-beta-8ee536d7",
44
- "@did-space/client": "^0.2.33",
40
+ "@arcblock/vc": "1.18.63",
41
+ "@blocklet/constant": "1.16.0-beta-62b42401",
42
+ "@blocklet/meta": "1.16.0-beta-62b42401",
43
+ "@blocklet/sdk": "1.16.0-beta-62b42401",
44
+ "@did-space/client": "^0.2.40",
45
45
  "@fidm/x509": "^1.2.1",
46
- "@ocap/client": "1.18.62",
47
- "@ocap/mcrypto": "1.18.62",
48
- "@ocap/util": "1.18.62",
49
- "@ocap/wallet": "1.18.62",
46
+ "@ocap/client": "1.18.63",
47
+ "@ocap/mcrypto": "1.18.63",
48
+ "@ocap/util": "1.18.63",
49
+ "@ocap/wallet": "1.18.63",
50
50
  "@slack/webhook": "^5.0.4",
51
51
  "archiver": "^5.3.1",
52
52
  "axios": "^0.27.2",
@@ -91,5 +91,5 @@
91
91
  "express": "^4.18.2",
92
92
  "jest": "^27.5.1"
93
93
  },
94
- "gitHead": "57d0c45be311a5fbc1c0fffa2814b62c1a3ee34c"
94
+ "gitHead": "6ef1c3601d0cfdcf5da0b55b4c54ef1fa9fce7d2"
95
95
  }