@twin.org/immutable-proof-service 0.0.1-next.3 → 0.0.1-next.5
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/dist/cjs/index.cjs +57 -40
- package/dist/esm/index.mjs +58 -41
- package/dist/types/immutableProofService.d.ts +1 -1
- package/docs/changelog.md +1 -1
- package/package.json +2 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -6,7 +6,6 @@ var standardsW3cDid = require('@twin.org/standards-w3c-did');
|
|
|
6
6
|
var web = require('@twin.org/web');
|
|
7
7
|
var crypto = require('@twin.org/crypto');
|
|
8
8
|
var dataJsonLd = require('@twin.org/data-json-ld');
|
|
9
|
-
var dataSchemaOrg = require('@twin.org/data-schema-org');
|
|
10
9
|
var entity = require('@twin.org/entity');
|
|
11
10
|
var entityStorageModels = require('@twin.org/entity-storage-models');
|
|
12
11
|
var identityModels = require('@twin.org/identity-models');
|
|
@@ -362,7 +361,6 @@ class ImmutableProofService {
|
|
|
362
361
|
this._config = options?.config ?? {};
|
|
363
362
|
this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof";
|
|
364
363
|
this._proofConfigKeyId = this._config.proofConfigKeyId ?? "immutable-proof";
|
|
365
|
-
dataSchemaOrg.SchemaOrgDataTypes.registerRedirects();
|
|
366
364
|
this._processing = false;
|
|
367
365
|
}
|
|
368
366
|
/**
|
|
@@ -393,7 +391,7 @@ class ImmutableProofService {
|
|
|
393
391
|
proofObjectHash: core.Converter.bytesToBase64(hash)
|
|
394
392
|
};
|
|
395
393
|
await this._proofStorage.set(proofEntity);
|
|
396
|
-
this.startProcessingProofs();
|
|
394
|
+
this.startProcessingProofs(0);
|
|
397
395
|
return new core.Urn(ImmutableProofService.NAMESPACE, id).toString();
|
|
398
396
|
}
|
|
399
397
|
catch (error) {
|
|
@@ -507,13 +505,9 @@ class ImmutableProofService {
|
|
|
507
505
|
* @returns The model.
|
|
508
506
|
* @internal
|
|
509
507
|
*/
|
|
510
|
-
|
|
508
|
+
proofEntityToJsonLd(proofEntity) {
|
|
511
509
|
const model = {
|
|
512
|
-
"@context":
|
|
513
|
-
immutableProofModels.ImmutableProofTypes.ContextRoot,
|
|
514
|
-
dataSchemaOrg.SchemaOrgTypes.ContextRoot,
|
|
515
|
-
standardsW3cDid.DidContexts.ContextVCDataIntegrity
|
|
516
|
-
],
|
|
510
|
+
"@context": immutableProofModels.ImmutableProofTypes.ContextRoot,
|
|
517
511
|
type: immutableProofModels.ImmutableProofTypes.ImmutableProof,
|
|
518
512
|
id: proofEntity.id,
|
|
519
513
|
userIdentity: proofEntity.userIdentity,
|
|
@@ -524,14 +518,16 @@ class ImmutableProofService {
|
|
|
524
518
|
}
|
|
525
519
|
/**
|
|
526
520
|
* Start processing proofs.
|
|
521
|
+
* @param interval The interval to process proofs.
|
|
527
522
|
* @returns Nothing.
|
|
528
523
|
* @internal
|
|
529
524
|
*/
|
|
530
|
-
startProcessingProofs() {
|
|
525
|
+
startProcessingProofs(interval) {
|
|
531
526
|
if (!this._processing) {
|
|
527
|
+
this._processing = true;
|
|
532
528
|
setTimeout(async () => {
|
|
533
529
|
await this.processProofs();
|
|
534
|
-
},
|
|
530
|
+
}, interval);
|
|
535
531
|
}
|
|
536
532
|
}
|
|
537
533
|
/**
|
|
@@ -539,32 +535,48 @@ class ImmutableProofService {
|
|
|
539
535
|
* @internal
|
|
540
536
|
*/
|
|
541
537
|
async processProofs() {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
538
|
+
let remainingProofs = 0;
|
|
539
|
+
try {
|
|
540
|
+
// Get the oldest pending proof, plus one more, we can then determine whether to
|
|
541
|
+
// trigger another process after this one
|
|
542
|
+
const pendingProofs = await this._proofStorage.query({
|
|
543
|
+
property: "immutableStorageId",
|
|
544
|
+
comparison: entity.ComparisonOperator.Equals,
|
|
545
|
+
value: undefined
|
|
546
|
+
}, [
|
|
547
|
+
{
|
|
548
|
+
property: "dateCreated",
|
|
549
|
+
sortDirection: entity.SortDirection.Ascending
|
|
550
|
+
}
|
|
551
|
+
], undefined, undefined, 2);
|
|
552
|
+
remainingProofs = pendingProofs.entities.length;
|
|
553
|
+
if (remainingProofs > 0) {
|
|
554
|
+
const proofEntity = pendingProofs.entities[0];
|
|
555
|
+
const immutableProof = this.proofEntityToJsonLd(proofEntity);
|
|
556
|
+
const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
|
|
557
|
+
// As we are adding the proof to the data we update its context
|
|
558
|
+
immutableProof["@context"] = [
|
|
559
|
+
immutableProofModels.ImmutableProofTypes.ContextRoot,
|
|
560
|
+
immutableStorageModels.ImmutableStorageTypes.ContextRoot,
|
|
561
|
+
standardsW3cDid.DidContexts.ContextVCDataIntegrity
|
|
562
|
+
];
|
|
563
|
+
immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
|
|
564
|
+
if (core.Is.stringValue(immutableProof.proof.created)) {
|
|
565
|
+
proofEntity.dateCreated = immutableProof.proof.created;
|
|
566
|
+
}
|
|
567
|
+
const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
|
|
568
|
+
const immutableStoreResult = await this._immutableStorage.store(proofEntity.nodeIdentity, core.ObjectHelper.toBytes(compacted));
|
|
569
|
+
proofEntity.immutableStorageId = immutableStoreResult.id;
|
|
570
|
+
await this._proofStorage.set(proofEntity);
|
|
571
|
+
remainingProofs--;
|
|
552
572
|
}
|
|
553
|
-
], undefined, undefined, 2);
|
|
554
|
-
if (pendingProofs.entities.length > 0) {
|
|
555
|
-
const proofEntity = pendingProofs.entities[0];
|
|
556
|
-
const immutableProof = this.proofEntityToModel(proofEntity);
|
|
557
|
-
const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
|
|
558
|
-
immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
|
|
559
|
-
proofEntity.dateCreated = immutableProof.proof.created ?? new Date(Date.now()).toISOString();
|
|
560
|
-
const compacted = await dataJsonLd.JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
|
|
561
|
-
proofEntity.immutableStorageId = await this._immutableStorage.store(proofEntity.nodeIdentity, core.ObjectHelper.toBytes(compacted));
|
|
562
|
-
await this._proofStorage.set(proofEntity);
|
|
563
573
|
}
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
574
|
+
finally {
|
|
575
|
+
// If there are still remaining proofs, start the timer again
|
|
576
|
+
this._processing = false;
|
|
577
|
+
if (remainingProofs > 0) {
|
|
578
|
+
this.startProcessingProofs(100);
|
|
579
|
+
}
|
|
568
580
|
}
|
|
569
581
|
}
|
|
570
582
|
/**
|
|
@@ -582,14 +594,15 @@ class ImmutableProofService {
|
|
|
582
594
|
if (core.Is.empty(proofEntity)) {
|
|
583
595
|
throw new core.NotFoundError(this.CLASS_NAME, "proofNotFound", id);
|
|
584
596
|
}
|
|
585
|
-
let proofModel = await this.
|
|
597
|
+
let proofModel = await this.proofEntityToJsonLd(proofEntity);
|
|
586
598
|
let verified = false;
|
|
587
599
|
let failure = immutableProofModels.ImmutableProofFailure.NotIssued;
|
|
588
600
|
if (core.Is.stringValue(proofEntity.immutableStorageId)) {
|
|
589
601
|
failure = immutableProofModels.ImmutableProofFailure.ProofMissing;
|
|
590
|
-
const
|
|
591
|
-
if (core.Is.uint8Array(
|
|
592
|
-
proofModel = core.ObjectHelper.fromBytes(
|
|
602
|
+
const immutableResult = await this._immutableStorage.get(proofEntity.immutableStorageId);
|
|
603
|
+
if (core.Is.uint8Array(immutableResult.data)) {
|
|
604
|
+
proofModel = core.ObjectHelper.fromBytes(immutableResult.data);
|
|
605
|
+
proofModel.immutableReceipt = immutableResult.receipt;
|
|
593
606
|
if (core.Is.object(proofModel.proof) && core.Is.object(proofObject)) {
|
|
594
607
|
if (proofModel.proof.cryptosuite !== standardsW3cDid.DidCryptoSuites.EdDSAJcs2022) {
|
|
595
608
|
failure = immutableProofModels.ImmutableProofFailure.CryptoSuiteMismatch;
|
|
@@ -626,7 +639,11 @@ class ImmutableProofService {
|
|
|
626
639
|
* @internal
|
|
627
640
|
*/
|
|
628
641
|
async generateHashData(nodeIdentity, immutableProof) {
|
|
629
|
-
|
|
642
|
+
// We hash the data for the proof with the proof or immutable receipt for the proof
|
|
643
|
+
// without these objects we can simplify the context
|
|
644
|
+
const object = core.ObjectHelper.omit(immutableProof, ["proof", "immutableReceipt"]);
|
|
645
|
+
object["@context"] = immutableProofModels.ImmutableProofTypes.ContextRoot;
|
|
646
|
+
const canonicalDocument = core.JsonHelper.canonicalize(object);
|
|
630
647
|
const proofConfigKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofConfigKeyId}`);
|
|
631
648
|
const proofConfigHash = crypto.Sha256.sum256(proofConfigKey.privateKey);
|
|
632
649
|
const transformedDocumentHash = crypto.Sha256.sum256(core.Converter.utf8ToBytes(canonicalDocument));
|
package/dist/esm/index.mjs
CHANGED
|
@@ -4,11 +4,10 @@ import { DidContexts, DidTypes, DidCryptoSuites } from '@twin.org/standards-w3c-
|
|
|
4
4
|
import { HttpStatusCode, HeaderTypes, MimeTypes } from '@twin.org/web';
|
|
5
5
|
import { Blake2b, Sha256 } from '@twin.org/crypto';
|
|
6
6
|
import { JsonLdHelper, JsonLdProcessor } from '@twin.org/data-json-ld';
|
|
7
|
-
import { SchemaOrgDataTypes, SchemaOrgTypes } from '@twin.org/data-schema-org';
|
|
8
7
|
import { ComparisonOperator, SortDirection, property, entity, EntitySchemaFactory, EntitySchemaHelper } from '@twin.org/entity';
|
|
9
8
|
import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
|
|
10
9
|
import { IdentityConnectorFactory } from '@twin.org/identity-models';
|
|
11
|
-
import { ImmutableStorageConnectorFactory } from '@twin.org/immutable-storage-models';
|
|
10
|
+
import { ImmutableStorageConnectorFactory, ImmutableStorageTypes } from '@twin.org/immutable-storage-models';
|
|
12
11
|
import { VaultConnectorFactory } from '@twin.org/vault-models';
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -360,7 +359,6 @@ class ImmutableProofService {
|
|
|
360
359
|
this._config = options?.config ?? {};
|
|
361
360
|
this._assertionMethodId = this._config.assertionMethodId ?? "immutable-proof";
|
|
362
361
|
this._proofConfigKeyId = this._config.proofConfigKeyId ?? "immutable-proof";
|
|
363
|
-
SchemaOrgDataTypes.registerRedirects();
|
|
364
362
|
this._processing = false;
|
|
365
363
|
}
|
|
366
364
|
/**
|
|
@@ -391,7 +389,7 @@ class ImmutableProofService {
|
|
|
391
389
|
proofObjectHash: Converter.bytesToBase64(hash)
|
|
392
390
|
};
|
|
393
391
|
await this._proofStorage.set(proofEntity);
|
|
394
|
-
this.startProcessingProofs();
|
|
392
|
+
this.startProcessingProofs(0);
|
|
395
393
|
return new Urn(ImmutableProofService.NAMESPACE, id).toString();
|
|
396
394
|
}
|
|
397
395
|
catch (error) {
|
|
@@ -505,13 +503,9 @@ class ImmutableProofService {
|
|
|
505
503
|
* @returns The model.
|
|
506
504
|
* @internal
|
|
507
505
|
*/
|
|
508
|
-
|
|
506
|
+
proofEntityToJsonLd(proofEntity) {
|
|
509
507
|
const model = {
|
|
510
|
-
"@context":
|
|
511
|
-
ImmutableProofTypes.ContextRoot,
|
|
512
|
-
SchemaOrgTypes.ContextRoot,
|
|
513
|
-
DidContexts.ContextVCDataIntegrity
|
|
514
|
-
],
|
|
508
|
+
"@context": ImmutableProofTypes.ContextRoot,
|
|
515
509
|
type: ImmutableProofTypes.ImmutableProof,
|
|
516
510
|
id: proofEntity.id,
|
|
517
511
|
userIdentity: proofEntity.userIdentity,
|
|
@@ -522,14 +516,16 @@ class ImmutableProofService {
|
|
|
522
516
|
}
|
|
523
517
|
/**
|
|
524
518
|
* Start processing proofs.
|
|
519
|
+
* @param interval The interval to process proofs.
|
|
525
520
|
* @returns Nothing.
|
|
526
521
|
* @internal
|
|
527
522
|
*/
|
|
528
|
-
startProcessingProofs() {
|
|
523
|
+
startProcessingProofs(interval) {
|
|
529
524
|
if (!this._processing) {
|
|
525
|
+
this._processing = true;
|
|
530
526
|
setTimeout(async () => {
|
|
531
527
|
await this.processProofs();
|
|
532
|
-
},
|
|
528
|
+
}, interval);
|
|
533
529
|
}
|
|
534
530
|
}
|
|
535
531
|
/**
|
|
@@ -537,32 +533,48 @@ class ImmutableProofService {
|
|
|
537
533
|
* @internal
|
|
538
534
|
*/
|
|
539
535
|
async processProofs() {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
536
|
+
let remainingProofs = 0;
|
|
537
|
+
try {
|
|
538
|
+
// Get the oldest pending proof, plus one more, we can then determine whether to
|
|
539
|
+
// trigger another process after this one
|
|
540
|
+
const pendingProofs = await this._proofStorage.query({
|
|
541
|
+
property: "immutableStorageId",
|
|
542
|
+
comparison: ComparisonOperator.Equals,
|
|
543
|
+
value: undefined
|
|
544
|
+
}, [
|
|
545
|
+
{
|
|
546
|
+
property: "dateCreated",
|
|
547
|
+
sortDirection: SortDirection.Ascending
|
|
548
|
+
}
|
|
549
|
+
], undefined, undefined, 2);
|
|
550
|
+
remainingProofs = pendingProofs.entities.length;
|
|
551
|
+
if (remainingProofs > 0) {
|
|
552
|
+
const proofEntity = pendingProofs.entities[0];
|
|
553
|
+
const immutableProof = this.proofEntityToJsonLd(proofEntity);
|
|
554
|
+
const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
|
|
555
|
+
// As we are adding the proof to the data we update its context
|
|
556
|
+
immutableProof["@context"] = [
|
|
557
|
+
ImmutableProofTypes.ContextRoot,
|
|
558
|
+
ImmutableStorageTypes.ContextRoot,
|
|
559
|
+
DidContexts.ContextVCDataIntegrity
|
|
560
|
+
];
|
|
561
|
+
immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
|
|
562
|
+
if (Is.stringValue(immutableProof.proof.created)) {
|
|
563
|
+
proofEntity.dateCreated = immutableProof.proof.created;
|
|
564
|
+
}
|
|
565
|
+
const compacted = await JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
|
|
566
|
+
const immutableStoreResult = await this._immutableStorage.store(proofEntity.nodeIdentity, ObjectHelper.toBytes(compacted));
|
|
567
|
+
proofEntity.immutableStorageId = immutableStoreResult.id;
|
|
568
|
+
await this._proofStorage.set(proofEntity);
|
|
569
|
+
remainingProofs--;
|
|
550
570
|
}
|
|
551
|
-
], undefined, undefined, 2);
|
|
552
|
-
if (pendingProofs.entities.length > 0) {
|
|
553
|
-
const proofEntity = pendingProofs.entities[0];
|
|
554
|
-
const immutableProof = this.proofEntityToModel(proofEntity);
|
|
555
|
-
const hashData = await this.generateHashData(proofEntity.nodeIdentity, immutableProof);
|
|
556
|
-
immutableProof.proof = await this._identityConnector.createProof(proofEntity.nodeIdentity, `${proofEntity.nodeIdentity}#${this._assertionMethodId}`, hashData);
|
|
557
|
-
proofEntity.dateCreated = immutableProof.proof.created ?? new Date(Date.now()).toISOString();
|
|
558
|
-
const compacted = await JsonLdProcessor.compact(immutableProof, immutableProof["@context"]);
|
|
559
|
-
proofEntity.immutableStorageId = await this._immutableStorage.store(proofEntity.nodeIdentity, ObjectHelper.toBytes(compacted));
|
|
560
|
-
await this._proofStorage.set(proofEntity);
|
|
561
571
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
572
|
+
finally {
|
|
573
|
+
// If there are still remaining proofs, start the timer again
|
|
574
|
+
this._processing = false;
|
|
575
|
+
if (remainingProofs > 0) {
|
|
576
|
+
this.startProcessingProofs(100);
|
|
577
|
+
}
|
|
566
578
|
}
|
|
567
579
|
}
|
|
568
580
|
/**
|
|
@@ -580,14 +592,15 @@ class ImmutableProofService {
|
|
|
580
592
|
if (Is.empty(proofEntity)) {
|
|
581
593
|
throw new NotFoundError(this.CLASS_NAME, "proofNotFound", id);
|
|
582
594
|
}
|
|
583
|
-
let proofModel = await this.
|
|
595
|
+
let proofModel = await this.proofEntityToJsonLd(proofEntity);
|
|
584
596
|
let verified = false;
|
|
585
597
|
let failure = ImmutableProofFailure.NotIssued;
|
|
586
598
|
if (Is.stringValue(proofEntity.immutableStorageId)) {
|
|
587
599
|
failure = ImmutableProofFailure.ProofMissing;
|
|
588
|
-
const
|
|
589
|
-
if (Is.uint8Array(
|
|
590
|
-
proofModel = ObjectHelper.fromBytes(
|
|
600
|
+
const immutableResult = await this._immutableStorage.get(proofEntity.immutableStorageId);
|
|
601
|
+
if (Is.uint8Array(immutableResult.data)) {
|
|
602
|
+
proofModel = ObjectHelper.fromBytes(immutableResult.data);
|
|
603
|
+
proofModel.immutableReceipt = immutableResult.receipt;
|
|
591
604
|
if (Is.object(proofModel.proof) && Is.object(proofObject)) {
|
|
592
605
|
if (proofModel.proof.cryptosuite !== DidCryptoSuites.EdDSAJcs2022) {
|
|
593
606
|
failure = ImmutableProofFailure.CryptoSuiteMismatch;
|
|
@@ -624,7 +637,11 @@ class ImmutableProofService {
|
|
|
624
637
|
* @internal
|
|
625
638
|
*/
|
|
626
639
|
async generateHashData(nodeIdentity, immutableProof) {
|
|
627
|
-
|
|
640
|
+
// We hash the data for the proof with the proof or immutable receipt for the proof
|
|
641
|
+
// without these objects we can simplify the context
|
|
642
|
+
const object = ObjectHelper.omit(immutableProof, ["proof", "immutableReceipt"]);
|
|
643
|
+
object["@context"] = ImmutableProofTypes.ContextRoot;
|
|
644
|
+
const canonicalDocument = JsonHelper.canonicalize(object);
|
|
628
645
|
const proofConfigKey = await this._vaultConnector.getKey(`${nodeIdentity}/${this._proofConfigKeyId}`);
|
|
629
646
|
const proofConfigHash = Sha256.sum256(proofConfigKey.privateKey);
|
|
630
647
|
const transformedDocumentHash = Sha256.sum256(Converter.utf8ToBytes(canonicalDocument));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IJsonLdNodeObject } from "@twin.org/data-json-ld";
|
|
2
|
-
import { type
|
|
2
|
+
import { type IImmutableProof, type IImmutableProofComponent, type IImmutableProofVerification } from "@twin.org/immutable-proof-models";
|
|
3
3
|
import type { IImmutableProofServiceConfig } from "./models/IImmutableProofServiceConfig";
|
|
4
4
|
/**
|
|
5
5
|
* Class for performing immutable proof operations.
|
package/docs/changelog.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/immutable-proof-service",
|
|
3
|
-
"version": "0.0.1-next.
|
|
3
|
+
"version": "0.0.1-next.5",
|
|
4
4
|
"description": "Immutable proof contract implementation and REST endpoint definitions",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@twin.org/entity": "next",
|
|
23
23
|
"@twin.org/entity-storage-models": "next",
|
|
24
24
|
"@twin.org/identity-models": "next",
|
|
25
|
-
"@twin.org/immutable-proof-models": "0.0.1-next.
|
|
25
|
+
"@twin.org/immutable-proof-models": "0.0.1-next.5",
|
|
26
26
|
"@twin.org/immutable-storage-models": "next",
|
|
27
27
|
"@twin.org/nameof": "next",
|
|
28
28
|
"@twin.org/standards-w3c-did": "next",
|