dkg.js 6.0.6 → 6.0.7

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.
@@ -24,10 +24,13 @@ jobs:
24
24
  - name: Checkout repository
25
25
  uses: actions/checkout@v3
26
26
 
27
- - name: Set up environment
28
- uses: ./.github/actions/setup
27
+ - name: Set up Node.js
28
+ uses: actions/setup-node@v3
29
+ with:
30
+ node-version: '16.x'
31
+ registry-url: 'https://registry.npmjs.org'
29
32
 
30
33
  - name: Publish npm package
31
34
  run: npm publish
32
35
  env:
33
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
36
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/examples/demo.js CHANGED
@@ -111,7 +111,7 @@ function divider() {
111
111
 
112
112
  divider();
113
113
 
114
- let getLatestAssetResult = await DkgClient.asset.get(createAssetResult.UAL);
114
+ const getLatestAssetResult = await DkgClient.asset.get(createAssetResult.UAL);
115
115
  console.log('======================== ASSET LATEST RESOLVED');
116
116
  console.log(JSON.stringify(getLatestAssetResult, null, 2));
117
117
 
@@ -138,6 +138,36 @@ function divider() {
138
138
 
139
139
  divider();
140
140
 
141
+ const getFirstStateByIndex = await DkgClient.asset.get(createAssetResult.UAL, {
142
+ state: 0,
143
+ });
144
+ console.log('======================== ASSET FIRST STATE (GET BY STATE INDEX) RESOLVED');
145
+ console.log(JSON.stringify(getFirstStateByIndex, null, 2));
146
+
147
+ divider();
148
+
149
+ const getSecondStateByIndex = await DkgClient.asset.get(createAssetResult.UAL, {
150
+ state: 1,
151
+ });
152
+ console.log('======================== ASSET SECOND STATE (GET BY STATE INDEX) RESOLVED');
153
+ console.log(JSON.stringify(getSecondStateByIndex, null, 2));
154
+
155
+ divider();
156
+
157
+ const getFirstStateByHash = await DkgClient.asset.get(createAssetResult.UAL, {
158
+ state: createAssetResult.publicAssertionId,
159
+ });
160
+ console.log('======================== ASSET FIRST STATE (GET BY STATE HASH) RESOLVED');
161
+ console.log(JSON.stringify(getFirstStateByHash, null, 2));
162
+
163
+ divider();
164
+
165
+ const getSecondStateByHash = await DkgClient.asset.get(createAssetResult.UAL, {
166
+ state: updateAssetResult.publicAssertionId,
167
+ });
168
+ console.log('======================== ASSET SECOND STATE (GET BY STATE HASH) RESOLVED');
169
+ console.log(JSON.stringify(getSecondStateByHash, null, 2));
170
+
141
171
  let queryResult = await DkgClient.graph.query(
142
172
  'construct { ?s ?p ?o } where { ?s ?p ?o . <uuid:1> ?p ?o }',
143
173
  'CONSTRUCT',
@@ -1,5 +1,5 @@
1
1
  const { assertionMetadata, formatAssertion, calculateRoot } = require('assertion-tools');
2
- const { ethers } = require('ethers');
2
+ const { ethers, ZeroHash } = require('ethers');
3
3
  const {
4
4
  isEmptyObject,
5
5
  deriveUAL,
@@ -307,7 +307,7 @@ class AssetOperationsManager {
307
307
  * @async
308
308
  * @param {string} UAL - The Universal Asset Locator
309
309
  * @param {Object} [options={}] - Optional parameters for the asset get operation.
310
- * @param {string} [options.state] - The state of the asset, "latest" or "finalized".
310
+ * @param {string} [options.state] - The state or state index of the asset, "latest", "finalized", numerical, hash.
311
311
  * @param {string} [options.contentType] - The type of content to retrieve, either "public", "private" or "all".
312
312
  * @param {boolean} [options.validate] - Whether to validate the retrieved assertion.
313
313
  * @param {string} [options.outputFormat] - The format of the retrieved assertion output, either "n-quads" or "json-ld".
@@ -344,21 +344,56 @@ class AssetOperationsManager {
344
344
  );
345
345
 
346
346
  const { tokenId } = resolveUAL(UAL);
347
- let hasPendingUpdate = false;
348
- if (state === ASSET_STATES.LATEST) {
349
- hasPendingUpdate = await this.blockchainService.hasPendingUpdate(tokenId, blockchain);
347
+
348
+ let publicAssertionId;
349
+ if(state === ASSET_STATES.LATEST) {
350
+ const unfinalizedState = await this.blockchainService.getUnfinalizedState(
351
+ tokenId,
352
+ blockchain,
353
+ );
354
+
355
+ if (unfinalizedState != null && unfinalizedState !== ZeroHash) {
356
+ publicAssertionId = unfinalizedState;
357
+ }
350
358
  }
351
359
 
352
- const publicAssertionId = hasPendingUpdate
353
- ? await this.blockchainService.getUnfinalizedState(tokenId, blockchain)
354
- : await this.blockchainService.getLatestAssertionId(tokenId, blockchain);
360
+ let assertionIds = [];
361
+ const isEnumState = Object.values(ASSET_STATES).includes(state);
362
+ if(!publicAssertionId) {
363
+ assertionIds = await this.blockchainService.getAssertionIds(tokenId, blockchain);
364
+
365
+ if (isEnumState) {
366
+ publicAssertionId = assertionIds[assertionIds.length - 1];
367
+ } else if (typeof state === 'number') {
368
+ if (state >= assertionIds.length) {
369
+ throw Error('State index is out of range.');
370
+ }
371
+
372
+ publicAssertionId = assertionIds[state];
373
+ } else if (assertionIds.includes(state)) {
374
+ publicAssertionId = state;
375
+ } else if (/^0x[a-fA-F0-9]{64}$/.test(state)) {
376
+ const unfinalizedState = await this.blockchainService.getUnfinalizedState(
377
+ tokenId,
378
+ blockchain,
379
+ );
380
+
381
+ if (unfinalizedState != null && unfinalizedState !== ZeroHash && state === unfinalizedState) {
382
+ publicAssertionId = unfinalizedState;
383
+ } else {
384
+ throw Error('Given state hash isn\'t a part of the Knowledge Asset.')
385
+ }
386
+ } else {
387
+ throw Error('Incorrect state option.');
388
+ }
389
+ }
355
390
 
356
391
  const getPublicOperationId = await this.nodeApiService.get(
357
392
  endpoint,
358
393
  port,
359
394
  authToken,
360
395
  UAL,
361
- state,
396
+ isEnumState ? state : publicAssertionId,
362
397
  hashFunctionId,
363
398
  );
364
399
 
@@ -373,9 +408,21 @@ class AssetOperationsManager {
373
408
  );
374
409
 
375
410
  if (!getPublicOperationResult.data.assertion) {
411
+ if (getPublicOperationResult.status !== 'FAILED') {
412
+ getPublicOperationResult.data = {
413
+ errorType: 'DKG_CLIENT_ERROR',
414
+ errorMessage: 'Unable to find assertion on the network!',
415
+ };
416
+ getPublicOperationResult.status = 'FAILED';
417
+ }
418
+
376
419
  return {
377
- errorType: 'DKG_CLIENT_ERROR',
378
- errorMessage: 'Unable to find assertion on the network!',
420
+ operation: {
421
+ publicGet: getOperationStatusObject(
422
+ getPublicOperationResult,
423
+ getPublicOperationId,
424
+ ),
425
+ },
379
426
  };
380
427
  }
381
428
 
@@ -914,12 +961,12 @@ class AssetOperationsManager {
914
961
  const blockchain = this.inputService.getBlockchain(options);
915
962
  const tokenAmount = this.inputService.getTokenAmount(options);
916
963
 
917
- this.validationService.validateExtendAssetStoringPeriod(
918
- UAL,
919
- epochsNumber,
920
- tokenAmount,
921
- blockchain,
922
- );
964
+ this.validationService.validateExtendAssetStoringPeriod(
965
+ UAL,
966
+ epochsNumber,
967
+ tokenAmount,
968
+ blockchain,
969
+ );
923
970
 
924
971
  const { tokenId, contract } = resolveUAL(UAL);
925
972
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dkg.js",
3
- "version": "6.0.6",
3
+ "version": "6.0.7",
4
4
  "description": "Javascript library for interaction with the OriginTrail Decentralized Knowledge Graph",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -186,13 +186,22 @@ class ValidationService {
186
186
  if (param == null) throw Error(`${paramName} is missing.`);
187
187
  }
188
188
 
189
- validateParamType(paramName, param, type) {
189
+ validateParamType(paramName, param, typeOrTypes) {
190
+ const isTypesArray = Array.isArray(typeOrTypes);
191
+
190
192
  let parameter = param;
191
- if (type === 'number') {
193
+ if (isTypesArray && typeOrTypes.includes('number')) {
194
+ const parsed = parseInt(param, 10);
195
+ parameter = Number.isNaN(parsed) ? param : parsed;
196
+ } else if (typeOrTypes === 'number') {
192
197
  parameter = parseInt(param, 10);
193
198
  }
199
+ const types = isTypesArray ? typeOrTypes : [typeOrTypes];
200
+
194
201
  // eslint-disable-next-line valid-typeof
195
- if (typeof parameter !== type) throw Error(`${paramName} must be of type ${type}.`);
202
+ if (!types.some(type => typeof parameter === type)) {
203
+ throw new Error(`${paramName} must be of type ${types.join(" or ")}.`);
204
+ }
196
205
  }
197
206
 
198
207
  validateQueryString(queryString) {
@@ -288,10 +297,14 @@ class ValidationService {
288
297
 
289
298
  validateState(state) {
290
299
  this.validateRequiredParam('state', state);
291
- this.validateParamType('state', state, 'string');
292
- const validStates = Object.values(ASSET_STATES);
293
- if (!validStates.includes(state.toUpperCase()))
294
- throw Error(`Invalid state, available states: ${validStates}`);
300
+ this.validateParamType('state', state, ['number', 'string']);
301
+ const validStatesEnum = Object.values(ASSET_STATES);
302
+ if (
303
+ (typeof state === 'string' && !validStatesEnum.includes(state.toUpperCase())) &&
304
+ typeof state !== 'number' &&
305
+ !/^0x[a-fA-F0-9]{64}$/.test(state)
306
+ )
307
+ throw Error(`Invalid state, available states: ${validStatesEnum},numerical or hash.`);
295
308
  }
296
309
 
297
310
  validateContentType(contentType) {