@verana-labs/vs-agent-sdk 2.0.0-dev.8 → 2.0.0-dev.80

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.
Files changed (182) hide show
  1. package/README.md +0 -2
  2. package/build/adminApi/AdminApiError.d.ts +28 -0
  3. package/build/adminApi/AdminApiError.js +60 -0
  4. package/build/adminApi/AdminApiError.js.map +1 -0
  5. package/build/adminApi/didcommModules.d.ts +2 -0
  6. package/build/adminApi/didcommModules.js +8 -0
  7. package/build/adminApi/didcommModules.js.map +1 -0
  8. package/build/adminApi/index.d.ts +4 -0
  9. package/build/adminApi/index.js +21 -0
  10. package/build/adminApi/index.js.map +1 -0
  11. package/build/adminApi/moduleEndpoint.d.ts +8 -0
  12. package/build/adminApi/moduleEndpoint.js +28 -0
  13. package/build/adminApi/moduleEndpoint.js.map +1 -0
  14. package/build/adminApi/pagination/PageDto.d.ts +7 -0
  15. package/build/adminApi/pagination/PageDto.js +50 -0
  16. package/build/adminApi/pagination/PageDto.js.map +1 -0
  17. package/build/adminApi/pagination/PaginationQueryDto.d.ts +11 -0
  18. package/build/adminApi/pagination/PaginationQueryDto.js +46 -0
  19. package/build/adminApi/pagination/PaginationQueryDto.js.map +1 -0
  20. package/build/adminApi/pagination/cursor.d.ts +28 -0
  21. package/build/adminApi/pagination/cursor.js +64 -0
  22. package/build/adminApi/pagination/cursor.js.map +1 -0
  23. package/build/adminApi/pagination/index.d.ts +4 -0
  24. package/build/adminApi/pagination/index.js +21 -0
  25. package/build/adminApi/pagination/index.js.map +1 -0
  26. package/build/adminApi/pagination/paginate.d.ts +27 -0
  27. package/build/adminApi/pagination/paginate.js +77 -0
  28. package/build/adminApi/pagination/paginate.js.map +1 -0
  29. package/build/agent/VsAgent.d.ts +22 -34
  30. package/build/agent/VsAgent.js +84 -205
  31. package/build/agent/VsAgent.js.map +1 -1
  32. package/build/agent/createVsAgent.d.ts +5 -6
  33. package/build/agent/createVsAgent.js +3 -5
  34. package/build/agent/createVsAgent.js.map +1 -1
  35. package/build/blockchain/AnonCredsTrustService.d.ts +62 -0
  36. package/build/blockchain/AnonCredsTrustService.js +256 -0
  37. package/build/blockchain/AnonCredsTrustService.js.map +1 -0
  38. package/build/blockchain/AuthorizationService.d.ts +5 -3
  39. package/build/blockchain/AuthorizationService.js +17 -29
  40. package/build/blockchain/AuthorizationService.js.map +1 -1
  41. package/build/blockchain/IndexerWebSocketService.d.ts +7 -1
  42. package/build/blockchain/IndexerWebSocketService.js +68 -36
  43. package/build/blockchain/IndexerWebSocketService.js.map +1 -1
  44. package/build/blockchain/VeranaChainService.d.ts +38 -27
  45. package/build/blockchain/VeranaChainService.js +169 -177
  46. package/build/blockchain/VeranaChainService.js.map +1 -1
  47. package/build/blockchain/VeranaIndexerService.d.ts +14 -1
  48. package/build/blockchain/VeranaIndexerService.js +122 -8
  49. package/build/blockchain/VeranaIndexerService.js.map +1 -1
  50. package/build/blockchain/feePreflight.d.ts +32 -0
  51. package/build/blockchain/feePreflight.js +89 -0
  52. package/build/blockchain/feePreflight.js.map +1 -0
  53. package/build/blockchain/handlers/authorizationHandlers.js +2 -2
  54. package/build/blockchain/handlers/authorizationHandlers.js.map +1 -1
  55. package/build/blockchain/handlers/defaultHandlers.js +6 -1
  56. package/build/blockchain/handlers/defaultHandlers.js.map +1 -1
  57. package/build/blockchain/handlers/index.d.ts +1 -0
  58. package/build/blockchain/handlers/index.js +1 -0
  59. package/build/blockchain/handlers/index.js.map +1 -1
  60. package/build/blockchain/handlers/selfIssuanceHandlers.d.ts +13 -0
  61. package/build/blockchain/handlers/selfIssuanceHandlers.js +76 -0
  62. package/build/blockchain/handlers/selfIssuanceHandlers.js.map +1 -0
  63. package/build/blockchain/handlers/stateMutations.d.ts +26 -3
  64. package/build/blockchain/handlers/stateMutations.js +317 -41
  65. package/build/blockchain/handlers/stateMutations.js.map +1 -1
  66. package/build/blockchain/index.d.ts +4 -0
  67. package/build/blockchain/index.js +4 -0
  68. package/build/blockchain/index.js.map +1 -1
  69. package/build/blockchain/indexerMappers.d.ts +3 -0
  70. package/build/blockchain/indexerMappers.js +53 -0
  71. package/build/blockchain/indexerMappers.js.map +1 -0
  72. package/build/blockchain/triggerResolver.d.ts +26 -0
  73. package/build/blockchain/triggerResolver.js +120 -0
  74. package/build/blockchain/triggerResolver.js.map +1 -0
  75. package/build/blockchain/types.d.ts +13 -70
  76. package/build/blockchain/types.js.map +1 -1
  77. package/build/bootstrap/EcsBootstrapService.d.ts +13 -3
  78. package/build/bootstrap/EcsBootstrapService.js +172 -94
  79. package/build/bootstrap/EcsBootstrapService.js.map +1 -1
  80. package/build/connections/ParentConnectionModule.d.ts +20 -0
  81. package/build/connections/ParentConnectionModule.js +56 -0
  82. package/build/connections/ParentConnectionModule.js.map +1 -0
  83. package/build/credentials/FullTailsFileService.d.ts +0 -1
  84. package/build/credentials/FullTailsFileService.js +0 -49
  85. package/build/credentials/FullTailsFileService.js.map +1 -1
  86. package/build/did/CachedDocumentLoader.d.ts +3 -0
  87. package/build/did/CachedDocumentLoader.js +7 -1
  88. package/build/did/CachedDocumentLoader.js.map +1 -1
  89. package/build/did/CachedWebDidResolver.d.ts +0 -4
  90. package/build/did/CachedWebDidResolver.js +1 -5
  91. package/build/did/CachedWebDidResolver.js.map +1 -1
  92. package/build/did/artifactServices.d.ts +12 -0
  93. package/build/did/artifactServices.js +48 -0
  94. package/build/did/artifactServices.js.map +1 -0
  95. package/build/did/legacyDidWeb.d.ts +6 -4
  96. package/build/did/legacyDidWeb.js +17 -14
  97. package/build/did/legacyDidWeb.js.map +1 -1
  98. package/build/did/publicDid.d.ts +4 -0
  99. package/build/did/publicDid.js +19 -0
  100. package/build/did/publicDid.js.map +1 -0
  101. package/build/events/BaseMessageEvents.js +139 -5
  102. package/build/events/BaseMessageEvents.js.map +1 -1
  103. package/build/events/ConnectionEvents.js +150 -86
  104. package/build/events/ConnectionEvents.js.map +1 -1
  105. package/build/events/VsAgentEvents.d.ts +11 -9
  106. package/build/events/VsAgentEvents.js +8 -1
  107. package/build/events/VsAgentEvents.js.map +1 -1
  108. package/build/events/VtFlowEvents.d.ts +1 -1
  109. package/build/events/VtFlowEvents.js +29 -17
  110. package/build/events/VtFlowEvents.js.map +1 -1
  111. package/build/index.d.ts +7 -1
  112. package/build/index.js +15 -2
  113. package/build/index.js.map +1 -1
  114. package/build/plugins/setupBaseDidComm.js +9 -12
  115. package/build/plugins/setupBaseDidComm.js.map +1 -1
  116. package/build/transports/VsAgentWsInboundTransport.d.ts +1 -1
  117. package/build/transports/VsAgentWsInboundTransport.js +20 -14
  118. package/build/transports/VsAgentWsInboundTransport.js.map +1 -1
  119. package/build/types.d.ts +14 -13
  120. package/build/types.js +1 -2
  121. package/build/types.js.map +1 -1
  122. package/build/utils/agent.d.ts +29 -4
  123. package/build/utils/agent.js +91 -22
  124. package/build/utils/agent.js.map +1 -1
  125. package/build/utils/boundedFetch.d.ts +13 -0
  126. package/build/utils/boundedFetch.js +47 -0
  127. package/build/utils/boundedFetch.js.map +1 -0
  128. package/build/utils/didReadiness.d.ts +9 -0
  129. package/build/utils/didReadiness.js +42 -0
  130. package/build/utils/didReadiness.js.map +1 -0
  131. package/build/utils/ecsClaims.d.ts +46 -0
  132. package/build/utils/ecsClaims.js +115 -0
  133. package/build/utils/ecsClaims.js.map +1 -0
  134. package/build/utils/ecsService.d.ts +8 -0
  135. package/build/utils/ecsService.js +23 -0
  136. package/build/utils/ecsService.js.map +1 -0
  137. package/build/utils/index.d.ts +7 -0
  138. package/build/utils/index.js +7 -0
  139. package/build/utils/index.js.map +1 -1
  140. package/build/utils/publishedDidRecord.d.ts +15 -0
  141. package/build/utils/publishedDidRecord.js +83 -0
  142. package/build/utils/publishedDidRecord.js.map +1 -0
  143. package/build/utils/selfIssuedEcsCredential.d.ts +8 -0
  144. package/build/utils/selfIssuedEcsCredential.js +153 -0
  145. package/build/utils/selfIssuedEcsCredential.js.map +1 -0
  146. package/build/utils/setupSelfTr.d.ts +35 -74
  147. package/build/utils/setupSelfTr.js +93 -312
  148. package/build/utils/setupSelfTr.js.map +1 -1
  149. package/build/utils/trustCredentialStore.d.ts +78 -9
  150. package/build/utils/trustCredentialStore.js +324 -136
  151. package/build/utils/trustCredentialStore.js.map +1 -1
  152. package/build/utils/typeMetadata.d.ts +43 -0
  153. package/build/utils/typeMetadata.js +77 -0
  154. package/build/utils/typeMetadata.js.map +1 -0
  155. package/build/utils/util.d.ts +19 -0
  156. package/build/utils/util.js +24 -0
  157. package/build/utils/util.js.map +1 -1
  158. package/build/utils/vcdm2.d.ts +34 -0
  159. package/build/utils/vcdm2.js +60 -0
  160. package/build/utils/vcdm2.js.map +1 -0
  161. package/build/utils/vtjscResolver.d.ts +23 -0
  162. package/build/utils/vtjscResolver.js +53 -0
  163. package/build/utils/vtjscResolver.js.map +1 -0
  164. package/build/vtFlow/VtFlowOrchestrator.d.ts +107 -15
  165. package/build/vtFlow/VtFlowOrchestrator.js +678 -116
  166. package/build/vtFlow/VtFlowOrchestrator.js.map +1 -1
  167. package/build/vtFlow/assertVerifiableService.d.ts +1 -0
  168. package/build/vtFlow/assertVerifiableService.js +45 -5
  169. package/build/vtFlow/assertVerifiableService.js.map +1 -1
  170. package/build/vtFlow/ecsIssuanceExemption.d.ts +12 -0
  171. package/build/vtFlow/ecsIssuanceExemption.js +84 -0
  172. package/build/vtFlow/ecsIssuanceExemption.js.map +1 -0
  173. package/build/vtFlow/index.d.ts +1 -0
  174. package/build/vtFlow/index.js +1 -0
  175. package/build/vtFlow/index.js.map +1 -1
  176. package/package.json +18 -12
  177. package/build/did/migrateWebVhLog.d.ts +0 -34
  178. package/build/did/migrateWebVhLog.js +0 -230
  179. package/build/did/migrateWebVhLog.js.map +0 -1
  180. package/build/did/migrateWebVhVersionTime.d.ts +0 -9
  181. package/build/did/migrateWebVhVersionTime.js +0 -191
  182. package/build/did/migrateWebVhVersionTime.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.signLinkedDataIntegrityPresentation = signLinkedDataIntegrityPresentation;
3
4
  exports.findMetadataEntry = findMetadataEntry;
4
5
  exports.saveMetadataEntry = saveMetadataEntry;
5
6
  exports.deleteMetadataEntry = deleteMetadataEntry;
@@ -8,22 +9,92 @@ exports.createJsc = createJsc;
8
9
  exports.removeTrustCredential = removeTrustCredential;
9
10
  exports.removeStoredTrustCredential = removeStoredTrustCredential;
10
11
  exports.migrateVtjscServiceIds = migrateVtjscServiceIds;
12
+ exports.detachVtjscPublications = detachVtjscPublications;
13
+ exports.reattachVtjscPublication = reattachVtjscPublication;
11
14
  exports.getTrustMetadata = getTrustMetadata;
15
+ exports.saveVtjscTypeMetadata = saveVtjscTypeMetadata;
16
+ exports.findVtjscTypeMetadata = findVtjscTypeMetadata;
12
17
  exports.rebindEcsCredentialSchema = rebindEcsCredentialSchema;
18
+ exports.withdrawSelfIssuedEcsCredentials = withdrawSelfIssuedEcsCredentials;
13
19
  const core_1 = require("@credo-ts/core");
20
+ // No type definitions available for this library
21
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
22
+ //@ts-expect-error
23
+ const jsonld_signatures_1 = require("@digitalcredentials/jsonld-signatures");
14
24
  const verre_1 = require("@verana-labs/verre");
15
- const adminApiService_1 = require("../did/adminApiService");
25
+ const feePreflight_1 = require("../blockchain/feePreflight");
16
26
  const setupSelfTr_1 = require("./setupSelfTr");
27
+ const selfIssuedEcsCredential_1 = require("./selfIssuedEcsCredential");
28
+ const publishedDidRecord_1 = require("./publishedDidRecord");
17
29
  const data_1 = require("./data");
18
30
  async function getDidRecord(agent) {
19
31
  const [didRecord] = await agent.dids.getCreatedDids({ did: agent.did });
20
32
  return didRecord;
21
33
  }
22
- async function updateDidRecord(agent, didRecord) {
23
- const repo = agent.context.dependencyManager.resolve(core_1.DidRepository);
24
- (0, adminApiService_1.applyAdminApiServiceEntry)(didRecord.didDocument, agent.adminApiServiceEndpoint);
25
- await repo.update(agent.context, didRecord);
26
- await agent.dids.update({ did: didRecord.did, didDocument: didRecord.didDocument });
34
+ /** The credential fields shared by both data models: id, credentialSchema and credentialSubject */
35
+ function trustCredentialFields(credential) {
36
+ return credential instanceof core_1.W3cV2DataIntegrityVerifiableCredential
37
+ ? credential.resolvedCredential
38
+ : credential;
39
+ }
40
+ /**
41
+ * What the metadata entry stores and the DID Document service endpoint serves. A data model 1.1
42
+ * presentation is kept as its class instance, which serializes to JSON-LD when the DID record is
43
+ * saved; a Data Integrity one wraps the secured JSON, so that is what gets stored.
44
+ */
45
+ function trustCredentialEntry(credential) {
46
+ return credential instanceof core_1.W3cV2DataIntegrityVerifiableCredential
47
+ ? credential.securedCredential
48
+ : credential.jsonCredential;
49
+ }
50
+ function trustPresentationEntry(presentation) {
51
+ return presentation instanceof core_1.W3cV2DataIntegrityVerifiablePresentation
52
+ ? presentation.securedPresentation
53
+ : presentation;
54
+ }
55
+ function trustPresentationId(presentation) {
56
+ return presentation instanceof core_1.W3cV2DataIntegrityVerifiablePresentation
57
+ ? presentation.securedPresentation.id
58
+ : presentation.id;
59
+ }
60
+ /**
61
+ * Wraps a VC Data Model 2.0 credential in a data model 2.0 presentation secured with a
62
+ * DataIntegrityProof under the cryptosuite the agent is configured with, the counterpart of the
63
+ * linked data proof a data model 1.1 linked VP carries. The presentation is published from the DID
64
+ * Document rather than presented to a verifier, so there is no challenge to bind; its proof purpose
65
+ * is `authentication`, as Data Integrity defines for presentations.
66
+ */
67
+ async function signLinkedDataIntegrityPresentation(agent, options) {
68
+ const presentation = new core_1.W3cV2Presentation({
69
+ id: options.id,
70
+ holder: options.holder,
71
+ verifiableCredential: [options.credential],
72
+ });
73
+ // The options type requires a challenge for every presentation format, while a Data Integrity
74
+ // proof only carries one when it is given
75
+ return await agent.w3cV2Credentials.signPresentation({
76
+ format: core_1.ClaimFormat.DiVp,
77
+ presentation,
78
+ cryptosuite: (0, setupSelfTr_1.getDataIntegrityCryptosuite)(agent),
79
+ verificationMethod: options.verificationMethodId,
80
+ });
81
+ }
82
+ /**
83
+ * Wraps a VC Data Model 1.1 credential in a data model 1.1 presentation carrying an
84
+ * Ed25519Signature2020 linked data proof, for credentials received from issuers that still use it.
85
+ */
86
+ async function signLinkedDataProofPresentation(agent, options) {
87
+ return await agent.w3cCredentials.signPresentation({
88
+ format: core_1.ClaimFormat.LdpVp,
89
+ presentation: new core_1.W3cPresentation({
90
+ id: options.id,
91
+ holder: options.holder,
92
+ verifiableCredential: [options.credential],
93
+ }),
94
+ proofType: 'Ed25519Signature2020',
95
+ verificationMethod: options.verificationMethodId,
96
+ proofPurpose: new jsonld_signatures_1.purposes.AssertionProofPurpose(),
97
+ });
27
98
  }
28
99
  function findMetadataEntry(didRecord, key, id, jsonSchemaRef) {
29
100
  var _a, _b;
@@ -32,59 +103,53 @@ function findMetadataEntry(didRecord, key, id, jsonSchemaRef) {
32
103
  return null;
33
104
  if (!id && !jsonSchemaRef)
34
105
  return { schemaId: '', data: metadata, didDocumentServiceId: '' };
35
- for (const [schemaId, entry] of Object.entries(metadata)) {
36
- if (schemaId === jsonSchemaRef) {
37
- return Object.assign(Object.assign({ schemaId }, entry), { data: entry.verifiablePresentation });
38
- }
39
- const credId = (_a = entry.credential) === null || _a === void 0 ? void 0 : _a.id;
40
- const presId = (_b = entry.verifiablePresentation) === null || _b === void 0 ? void 0 : _b.id;
41
- if (credId === id) {
106
+ const entries = Object.entries(metadata);
107
+ // the metadata key identifies one entry, so it answers before any preference between entries
108
+ const exact = jsonSchemaRef ? entries.find(([schemaId]) => schemaId === jsonSchemaRef) : undefined;
109
+ if (exact)
110
+ return Object.assign(Object.assign({ schemaId: exact[0] }, exact[1]), { data: exact[1].verifiablePresentation });
111
+ const match = ([schemaId, entry]) => {
112
+ var _a, _b;
113
+ if (((_a = entry.credential) === null || _a === void 0 ? void 0 : _a.id) === id)
42
114
  return Object.assign(Object.assign({ schemaId }, entry), { data: entry.credential });
43
- }
44
- if (presId === id) {
115
+ if (((_b = entry.verifiablePresentation) === null || _b === void 0 ? void 0 : _b.id) === id)
45
116
  return Object.assign(Object.assign({ schemaId }, entry), { data: entry.verifiablePresentation });
46
- }
47
- }
48
- return null;
117
+ return null;
118
+ };
119
+ // several entries can carry the same presentation URL while a binding is replaced, so the entry
120
+ // the DID Document announces wins over a detached leftover
121
+ const matched = entries.map(match).filter(entry => entry !== null);
122
+ return (_b = (_a = matched.find(entry => entry.attached !== false)) !== null && _a !== void 0 ? _a : matched[0]) !== null && _b !== void 0 ? _b : null;
49
123
  }
50
- async function saveMetadataEntry(agent, didRecord, credential, verifiablePresentation, didDocumentServiceId, key, publicApiBaseUrl) {
51
- var _a, _b, _c, _d, _e, _f, _g, _h;
52
- const schema = key === '_vt/vtc' ? credential.credentialSchema : credential.credentialSubject;
124
+ async function saveMetadataEntry(agent, didRecord, credential, verifiablePresentation, didDocumentServiceId, key) {
125
+ var _a, _b, _c, _d, _e, _f;
126
+ const fields = trustCredentialFields(credential);
127
+ const schema = key === '_vt/vtc' ? fields.credentialSchema : fields.credentialSubject;
53
128
  const ref = Array.isArray(schema) ? (_a = schema[0]) === null || _a === void 0 ? void 0 : _a.id : schema === null || schema === void 0 ? void 0 : schema.id;
54
129
  if (!ref) {
55
130
  throw new Error('No ID was found in credentialSubject');
56
131
  }
57
132
  const record = (_b = didRecord.metadata.get(key)) !== null && _b !== void 0 ? _b : {};
58
133
  // Remove previous entry for this credential ID (if exists)
59
- const found = findMetadataEntry(didRecord, key, credential.id, ref);
134
+ const found = findMetadataEntry(didRecord, key, fields.id, ref);
135
+ // [VSA-PUB-VT-5]: the Type Metadata of a schema outlives every re-issue of its VTJSC
136
+ const typeMetadata = (found === null || found === void 0 ? void 0 : found.schemaId) === ref ? (_c = record[ref]) === null || _c === void 0 ? void 0 : _c.typeMetadata : undefined;
60
137
  if (found) {
61
- if ((_c = didRecord.didDocument) === null || _c === void 0 ? void 0 : _c.service) {
138
+ if ((_d = didRecord.didDocument) === null || _d === void 0 ? void 0 : _d.service) {
62
139
  didRecord.didDocument.service = didRecord.didDocument.service.filter(s => s.id !== found.didDocumentServiceId);
63
140
  }
64
141
  delete record[found.schemaId];
65
142
  }
66
- record[ref] = {
67
- credential: credential.jsonCredential,
68
- verifiablePresentation,
69
- didDocumentServiceId,
70
- };
71
- (_e = (_d = didRecord.didDocument) === null || _d === void 0 ? void 0 : _d.service) === null || _e === void 0 ? void 0 : _e.push(new core_1.DidDocumentService({
143
+ record[ref] = Object.assign(Object.assign({}, (typeof typeMetadata === 'string' ? { typeMetadata } : {})), { credential: trustCredentialEntry(credential), verifiablePresentation: trustPresentationEntry(verifiablePresentation), didDocumentServiceId });
144
+ (_f = (_e = didRecord.didDocument) === null || _e === void 0 ? void 0 : _e.service) === null || _f === void 0 ? void 0 : _f.push(new core_1.DidDocumentService({
72
145
  id: didDocumentServiceId,
73
- serviceEndpoint: verifiablePresentation.id,
146
+ serviceEndpoint: trustPresentationId(verifiablePresentation),
74
147
  type: 'LinkedVerifiablePresentation',
75
148
  }));
76
149
  didRecord.metadata.set(key, record);
77
- // Update #whois with new endpoint
78
- const service = (_g = (_f = didRecord.didDocument) === null || _f === void 0 ? void 0 : _f.service) === null || _g === void 0 ? void 0 : _g.find(s => s.id === `${agent.did}#whois`);
79
- if (service && ((_h = verifiablePresentation.id) === null || _h === void 0 ? void 0 : _h.includes('service')))
80
- service.serviceEndpoint = verifiablePresentation.id;
81
- // A JSON schema credential says nothing about this agent's own ECS identity, so only a real
82
- // trust credential replaces the self-issued ones.
83
- if (key === '_vt/vtc')
84
- updateVtcEntries(didRecord, false, publicApiBaseUrl);
85
- await updateDidRecord(agent, didRecord);
150
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, didRecord);
86
151
  }
87
- async function deleteMetadataEntry(agent, id, didRecord, key, publicApiBaseUrl) {
152
+ async function deleteMetadataEntry(agent, id, didRecord, key) {
88
153
  const found = findMetadataEntry(didRecord, key, id, id);
89
154
  if (!found)
90
155
  return null;
@@ -93,66 +158,22 @@ async function deleteMetadataEntry(agent, id, didRecord, key, publicApiBaseUrl)
93
158
  return null;
94
159
  delete metadata[found.schemaId];
95
160
  didRecord.metadata.set(key, metadata);
96
- // If the last entry is removed, restore defaults
97
- restoreDefaultVtcEntries(didRecord, publicApiBaseUrl);
98
- await updateDidRecord(agent, didRecord);
161
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, didRecord);
99
162
  return { schemaId: found.schemaId };
100
163
  }
101
- function restoreDefaultVtcEntries(didRecord, publicApiBaseUrl) {
102
- var _a, _b;
103
- const vtc = (_a = didRecord.metadata.get('_vt/vtc')) !== null && _a !== void 0 ? _a : {};
104
- const jsc = (_b = didRecord.metadata.get('_vt/jsc')) !== null && _b !== void 0 ? _b : {};
105
- // By default we have 2 Self-trusted VTCs
106
- if (Object.keys(vtc).length < 3 && Object.keys(jsc).length < 3) {
107
- updateVtcEntries(didRecord, true, publicApiBaseUrl);
108
- }
109
- }
110
- function updateVtcEntries(didRecord, attach, publicApiBaseUrl) {
111
- var _a;
112
- const record = (_a = didRecord.metadata.get('_vt/vtc')) !== null && _a !== void 0 ? _a : {};
113
- setupSelfTr_1.presentations.forEach(p => {
114
- var _a, _b, _c, _d;
115
- const schemaId = (0, setupSelfTr_1.mapToSelfTr)(p.schemaUrl, publicApiBaseUrl);
116
- const current = record[schemaId];
117
- if ((current === null || current === void 0 ? void 0 : current.attached) === attach)
118
- return;
119
- record[schemaId] = Object.assign(Object.assign({}, current), { attached: attach });
120
- const serviceId = current === null || current === void 0 ? void 0 : current.didDocumentServiceId;
121
- const serviceEndpoint = (_a = current === null || current === void 0 ? void 0 : current.verifiablePresentation) === null || _a === void 0 ? void 0 : _a.id;
122
- if (!((_b = didRecord.didDocument) === null || _b === void 0 ? void 0 : _b.service))
123
- return;
124
- if (attach) {
125
- const alreadyExists = didRecord.didDocument.service.some(s => s.id === serviceId);
126
- if (!alreadyExists && serviceId && serviceEndpoint) {
127
- didRecord.didDocument.service.push(new core_1.DidDocumentService({
128
- id: serviceId,
129
- serviceEndpoint,
130
- type: 'LinkedVerifiablePresentation',
131
- }));
132
- }
133
- // Return to self-trusted VTC in #whois endpoint
134
- const service = (_d = (_c = didRecord.didDocument) === null || _c === void 0 ? void 0 : _c.service) === null || _d === void 0 ? void 0 : _d.find(s => s.id === `${didRecord.did}#whois`);
135
- if (service && (serviceEndpoint === null || serviceEndpoint === void 0 ? void 0 : serviceEndpoint.includes('service')))
136
- service.serviceEndpoint = serviceEndpoint;
137
- }
138
- else {
139
- didRecord.didDocument.service = didRecord.didDocument.service.filter(s => s.id !== serviceId);
140
- }
141
- });
142
- didRecord.metadata.set('_vt/vtc', record);
143
- }
144
164
  async function createVtc(agent, publicApiBaseUrl, id, credential) {
145
165
  const didRecord = await getDidRecord(agent);
146
166
  const schemaId = `schemas-${id}-vtc-vp.json`;
147
167
  const didDocumentServiceId = `${agent.did}#vpr-${schemaId.replace('.json', '')}`;
148
168
  const serviceEndpoint = `${publicApiBaseUrl}/vt/${schemaId}`;
149
- const unsignedPresentation = (0, setupSelfTr_1.createPresentation)({
150
- id: serviceEndpoint,
151
- holder: agent.did,
152
- verifiableCredential: [credential],
153
- });
154
- const verifiablePresentation = await (0, setupSelfTr_1.signerW3c)(agent, unsignedPresentation, (0, setupSelfTr_1.getVerificationMethodId)(agent.config.logger, didRecord));
155
- await saveMetadataEntry(agent, didRecord, credential, verifiablePresentation, didDocumentServiceId, '_vt/vtc', publicApiBaseUrl);
169
+ const verificationMethodId = (0, setupSelfTr_1.getVerificationMethodId)(agent.config.logger, didRecord);
170
+ // The linked VP takes the data model of the credential it carries: a Data Integrity credential
171
+ // cannot be embedded in a data model 1.1 presentation, nor the other way round
172
+ const linkedVp = { id: serviceEndpoint, holder: agent.did, verificationMethodId };
173
+ const verifiablePresentation = credential instanceof core_1.W3cV2DataIntegrityVerifiableCredential
174
+ ? await signLinkedDataIntegrityPresentation(agent, Object.assign(Object.assign({}, linkedVp), { credential }))
175
+ : await signLinkedDataProofPresentation(agent, Object.assign(Object.assign({}, linkedVp), { credential }));
176
+ await saveMetadataEntry(agent, didRecord, credential, verifiablePresentation, didDocumentServiceId, '_vt/vtc');
156
177
  return verifiablePresentation;
157
178
  }
158
179
  async function createJsc(agent, publicApiBaseUrl, ecsSchemas, options) {
@@ -161,53 +182,69 @@ async function createJsc(agent, publicApiBaseUrl, ecsSchemas, options) {
161
182
  const { id: subjectId, claims } = (0, setupSelfTr_1.createJsonSubjectRef)(jsonSchemaRef);
162
183
  const subjectClaims = precomputedDigestSRI
163
184
  ? Object.assign(Object.assign({}, claims), { digestSRI: precomputedDigestSRI }) : await (0, setupSelfTr_1.addDigestSRI)(subjectId, claims, ecsSchemas);
164
- const credentialSubject = {
165
- id: subjectId,
166
- claims: subjectClaims,
167
- };
185
+ const credentialSubject = Object.assign(Object.assign({}, subjectClaims), { id: subjectId });
168
186
  const schemaPresentation = `schemas-${schemaBaseId}-vtjsc-vp.json`;
169
187
  const schemaCredential = `schemas-${schemaBaseId}-jsc.json`;
170
188
  const serviceEndpoint = `${publicApiBaseUrl}/vt/${schemaPresentation}`;
171
189
  const didDocumentServiceId = `${agent.did}#vpr-schemas-${schemaBaseId}-vtjsc-vp`;
190
+ const credentialId = `${publicApiBaseUrl}/vt/${schemaCredential}`;
172
191
  const unsignedCredential = (0, setupSelfTr_1.createCredential)({
173
- id: `${publicApiBaseUrl}/vt/${schemaCredential}`,
192
+ id: credentialId,
174
193
  type: ['VerifiableCredential', 'JsonSchemaCredential'],
175
194
  issuer: agent.did,
176
195
  credentialSubject,
196
+ credentialSchema: await (0, setupSelfTr_1.addDigestSRI)(setupSelfTr_1.createJsonSchema.id, { id: setupSelfTr_1.createJsonSchema.id, type: setupSelfTr_1.createJsonSchema.type }, ecsSchemas),
177
197
  });
178
- unsignedCredential.credentialSchema = await (0, setupSelfTr_1.addDigestSRI)(setupSelfTr_1.createJsonSchema.id, setupSelfTr_1.createJsonSchema, ecsSchemas);
179
198
  const verificationMethodId = (0, setupSelfTr_1.getVerificationMethodId)(agent.config.logger, didRecord);
180
- const credential = await (0, setupSelfTr_1.signerW3c)(agent, core_1.JsonTransformer.fromJSON(unsignedCredential, core_1.W3cCredential), verificationMethodId);
181
- const unsignedPresentation = (0, setupSelfTr_1.createPresentation)({
199
+ const credential = await (0, setupSelfTr_1.signerW3c)(agent, unsignedCredential, verificationMethodId);
200
+ const verifiablePresentation = await signLinkedDataIntegrityPresentation(agent, {
182
201
  id: serviceEndpoint,
183
202
  holder: agent.did,
184
- verifiableCredential: [credential],
203
+ credential,
204
+ verificationMethodId,
185
205
  });
186
- const verifiablePresentation = await (0, setupSelfTr_1.signerW3c)(agent, unsignedPresentation, verificationMethodId);
187
- await saveMetadataEntry(agent, didRecord, credential, verifiablePresentation, didDocumentServiceId, '_vt/jsc', publicApiBaseUrl);
188
- return credential.jsonCredential;
206
+ await saveMetadataEntry(agent, didRecord, credential, verifiablePresentation, didDocumentServiceId, '_vt/jsc');
207
+ // the credential as published; its id is the one assigned above
208
+ return credential.securedCredential;
189
209
  }
190
- async function removeTrustCredential(agent, publicApiBaseUrl, schemaId, key) {
210
+ async function removeTrustCredential(agent, schemaId, key) {
191
211
  var _a;
192
212
  const didRecord = await getDidRecord(agent);
193
- const record = findMetadataEntry(didRecord, key, schemaId);
213
+ // same lookup deleteMetadataEntry performs: a self-issued entry carries the agent DID as
214
+ // credential id, so only its metadata key reaches it
215
+ const record = findMetadataEntry(didRecord, key, schemaId, schemaId);
194
216
  // Currently, we only use one serviceEndpoint per ID.
195
217
  // In the future, if multiple serviceEndpoints exist for the same ID,
196
218
  // we should review the serviceEndpoint content and remove only the specific one.
197
219
  if ((record === null || record === void 0 ? void 0 : record.didDocumentServiceId) && ((_a = didRecord.didDocument) === null || _a === void 0 ? void 0 : _a.service)) {
198
220
  didRecord.didDocument.service = didRecord.didDocument.service.filter(s => s.id !== record.didDocumentServiceId);
199
221
  }
200
- return await deleteMetadataEntry(agent, schemaId, didRecord, key, publicApiBaseUrl);
222
+ return await deleteMetadataEntry(agent, schemaId, didRecord, key);
201
223
  }
202
- async function removeStoredTrustCredential(agent, publicApiBaseUrl, credentialExchangeRecordId) {
203
- var _a, _b;
224
+ /**
225
+ * Removes the linked VP and the stored credential an exchange delivered, as
226
+ * [VSA-VTI-FLOW-OP-REVOKE] requires of the applicant. The credential is read from the RFC 0809
227
+ * format data of the exchange; exchanges earlier versions completed over other formats are not
228
+ * migrated. Returns the credential id, or `undefined` when none is found, in which case nothing is
229
+ * removed.
230
+ */
231
+ async function removeStoredTrustCredential(agent, credentialExchangeRecordId) {
232
+ var _a, _b, _c;
204
233
  const formatData = await agent.didcomm.credentials.getFormatData(credentialExchangeRecordId);
205
- const credentialId = (_b = (_a = formatData.credential) === null || _a === void 0 ? void 0 : _a.jsonld) === null || _b === void 0 ? void 0 : _b.id;
206
- if (!credentialId)
234
+ const credentialId = (_c = (_b = (_a = formatData.credential) === null || _a === void 0 ? void 0 : _a.dataIntegrity) === null || _b === void 0 ? void 0 : _b.credential) === null || _c === void 0 ? void 0 : _c.id;
235
+ if (typeof credentialId !== 'string') {
236
+ agent.config.logger.warn(`[trust-credential] Credential exchange ${credentialExchangeRecordId} carries no RFC 0809 credential id; its linked VP and stored credential are left in place`);
207
237
  return undefined;
208
- await removeTrustCredential(agent, publicApiBaseUrl, credentialId, '_vt/vtc');
209
- const stored = await agent.w3cCredentials.getAll();
210
- for (const storedRecord of stored) {
238
+ }
239
+ await removeTrustCredential(agent, credentialId, '_vt/vtc');
240
+ // The RFC 0809 format holds a data model 2.0 credential in a W3cV2CredentialRecord and a data
241
+ // model 1.1 one in a W3cCredentialRecord; the credential id is tagged on both
242
+ for (const storedRecord of await agent.w3cV2Credentials.getAll()) {
243
+ if (storedRecord.getTags().givenId === credentialId) {
244
+ await agent.w3cV2Credentials.deleteById(storedRecord.id);
245
+ }
246
+ }
247
+ for (const storedRecord of await agent.w3cCredentials.getAll()) {
211
248
  if (storedRecord.getTags().givenId === credentialId) {
212
249
  await agent.w3cCredentials.deleteById(storedRecord.id);
213
250
  }
@@ -239,69 +276,220 @@ async function migrateVtjscServiceIds(agent) {
239
276
  if (!changed)
240
277
  return;
241
278
  didRecord.metadata.set('_vt/jsc', metadata);
242
- await updateDidRecord(agent, didRecord);
279
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, didRecord);
243
280
  agent.config.logger.info('[VTJSC] migrated stored service ids to the -vtjsc-vp naming');
244
281
  }
282
+ /**
283
+ * Takes the linked VPs of the given `_vt/jsc` entries out of the DID Document, publishing it once.
284
+ *
285
+ * The entries stay: `SelfTrController` serves them, and issued credentials name that URL in
286
+ * `credentialSchema.id`. Dropping one would 404 it and leave those credentials unverifiable.
287
+ */
288
+ async function detachVtjscPublications(agent, schemaRefs) {
289
+ var _a, _b;
290
+ if (schemaRefs.length === 0)
291
+ return [];
292
+ const didRecord = await getDidRecord(agent);
293
+ if (!((_a = didRecord === null || didRecord === void 0 ? void 0 : didRecord.didDocument) === null || _a === void 0 ? void 0 : _a.service))
294
+ return [];
295
+ const metadata = didRecord.metadata.get('_vt/jsc');
296
+ if (!metadata)
297
+ return [];
298
+ const detached = [];
299
+ for (const schemaRef of schemaRefs) {
300
+ const serviceId = (_b = metadata[schemaRef]) === null || _b === void 0 ? void 0 : _b.didDocumentServiceId;
301
+ if (!serviceId || !didRecord.didDocument.service.some(s => s.id === serviceId))
302
+ continue;
303
+ didRecord.didDocument.service = didRecord.didDocument.service.filter(s => s.id !== serviceId);
304
+ detached.push(schemaRef);
305
+ }
306
+ if (detached.length === 0)
307
+ return [];
308
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, didRecord);
309
+ return detached;
310
+ }
311
+ /**
312
+ * Puts a detached `_vt/jsc` entry back in the DID Document.
313
+ *
314
+ * The publication pass skips an entry whose digest still matches, so without this the agent would
315
+ * keep serving a VTJSC it never announces again.
316
+ */
317
+ async function reattachVtjscPublication(agent, schemaRef) {
318
+ var _a, _b, _c;
319
+ const didRecord = await getDidRecord(agent);
320
+ if (!(didRecord === null || didRecord === void 0 ? void 0 : didRecord.didDocument))
321
+ return false;
322
+ const entry = (_a = didRecord.metadata.get('_vt/jsc')) === null || _a === void 0 ? void 0 : _a[schemaRef];
323
+ const serviceId = entry === null || entry === void 0 ? void 0 : entry.didDocumentServiceId;
324
+ const serviceEndpoint = (_b = entry === null || entry === void 0 ? void 0 : entry.verifiablePresentation) === null || _b === void 0 ? void 0 : _b.id;
325
+ if (!serviceId || !serviceEndpoint)
326
+ return false;
327
+ const services = (_c = didRecord.didDocument.service) !== null && _c !== void 0 ? _c : [];
328
+ if (services.some(s => s.id === serviceId))
329
+ return false;
330
+ didRecord.didDocument.service = [
331
+ ...services,
332
+ new core_1.DidDocumentService({ id: serviceId, serviceEndpoint, type: 'LinkedVerifiablePresentation' }),
333
+ ];
334
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, didRecord);
335
+ return true;
336
+ }
245
337
  function getTrustMetadata(didRecord, key, schemaId) {
246
338
  return findMetadataEntry(didRecord, key, schemaId);
247
339
  }
248
- async function anchorCredentialDigest(agent, schemaId, credential) {
249
- if (!agent.veranaChain)
340
+ /**
341
+ * Stores the serialized SD-JWT VC Type Metadata of a VTJSC with its `_vt/jsc` entry, once. A
342
+ * stored document is never replaced: [VSA-PUB-VT-5] serves identical bytes while the schema exists.
343
+ * Returns false when the entry does not exist or already carries a document.
344
+ */
345
+ async function saveVtjscTypeMetadata(agent, schemaRef, typeMetadata) {
346
+ const didRecord = await getDidRecord(agent);
347
+ const metadata = didRecord === null || didRecord === void 0 ? void 0 : didRecord.metadata.get('_vt/jsc');
348
+ const entry = metadata === null || metadata === void 0 ? void 0 : metadata[schemaRef];
349
+ if (!entry || typeof entry.typeMetadata === 'string')
350
+ return false;
351
+ entry.typeMetadata = typeMetadata;
352
+ didRecord.metadata.set('_vt/jsc', metadata);
353
+ // the DID Document does not change, so the record is saved without a DID update
354
+ const repo = agent.context.dependencyManager.resolve(core_1.DidRepository);
355
+ await repo.update(agent.context, didRecord);
356
+ return true;
357
+ }
358
+ /**
359
+ * The stored Type Metadata of the `CredentialSchema` with the given on-chain id, as serialized.
360
+ * The `_vt/jsc` key of such a schema is `vpr:verana:{chainId}:cs:{id}`.
361
+ */
362
+ function findVtjscTypeMetadata(didRecord, chainId, credentialSchemaId) {
363
+ var _a;
364
+ const entry = (_a = didRecord.metadata.get('_vt/jsc')) === null || _a === void 0 ? void 0 : _a[`vpr:verana:${chainId}:cs:${credentialSchemaId}`];
365
+ return typeof (entry === null || entry === void 0 ? void 0 : entry.typeMetadata) === 'string' ? entry.typeMetadata : undefined;
366
+ }
367
+ /**
368
+ * Anchors a self-issued ECS credential, the same way as any other issuance: through
369
+ * CreateOrUpdateParticipantSession, which stores the digest in the `di` module keeper-to-keeper.
370
+ *
371
+ * `issuerParticipantId` must name an active ISSUER participant of this agent for the schema, whose
372
+ * vs_operator is this agent's account — the chain accepts the session from no other signer. The
373
+ * caller resolves it, because it already lists the agent's participants to decide what to rebind.
374
+ */
375
+ async function anchorCredentialDigest(agent, schemaId, credential, issuerParticipantId) {
376
+ const chain = agent.veranaChain;
377
+ if (!chain)
250
378
  return;
251
379
  if (!credential)
252
380
  throw new Error(`[DigestAnchor] The presentation for schema ${schemaId} has no credential`);
253
- const schema = await agent.veranaChain.getCredentialSchema(schemaId);
381
+ if (!agent.did)
382
+ throw new Error('[DigestAnchor] The agent has no public DID');
383
+ const schema = await agent.indexer.getCredentialSchema(schemaId).catch(() => undefined);
254
384
  if (!schema)
255
385
  throw new Error(`[DigestAnchor] Credential schema ${schemaId} is not on chain`);
256
- const digest = (0, verre_1.computeCredentialDigestJCS)(credential, schema.digestAlgorithm);
386
+ // the credential as published, which is what a verifier digests
387
+ const digest = (0, verre_1.computeCredentialDigestJCS)(credential, schema.digest_algorithm);
257
388
  // the same credential gives the same digest on each run, so an anchored digest needs no second transaction
258
- if (await agent.veranaChain.getDigest(digest))
389
+ if (await agent.indexer.getDigest(digest))
259
390
  return;
260
- const { txHash } = await agent.veranaChain.storeDigest(digest);
261
- agent.config.logger.info(`[DigestAnchor] Anchored digest ${digest} for schema ${schemaId} (tx ${txHash})`);
391
+ // A self-issued credential has no counterparty, so the session names only the issuer.
392
+ const { txHash } = await chain.createOrUpdateParticipantSession({
393
+ id: core_1.utils.uuid(),
394
+ issuerParticipantId,
395
+ agentParticipantId: 0,
396
+ walletAgentParticipantId: 0,
397
+ digest,
398
+ }, { granter: (0, feePreflight_1.feeGranterFor)(agent, issuerParticipantId) });
399
+ agent.config.logger.info(`[DigestAnchor] Anchored digest ${digest} for schema ${schemaId} against issuer participant ${issuerParticipantId} (tx ${txHash})`);
400
+ await agent.indexer.waitForDigest(digest);
262
401
  }
263
402
  // replaces the self-TR example JSC binding with the on-chain VTJSC so resolvers can link the credential to the VPR
264
- async function rebindEcsCredentialSchema(agent, publicApiBaseUrl, schemaId, schemaKey, defaults) {
265
- var _a, _b, _c, _d;
266
- if (!['ecs-service', 'ecs-org'].includes(schemaKey) || !agent.did)
403
+ /**
404
+ * @param jsonSchemaCredentialId the VTJSC the Ecosystem published for this schema. Only the
405
+ * Ecosystem publishes it, so an agent that issues against another Corporation's Ecosystem must
406
+ * resolve it there — see resolveJsonSchemaCredentialId.
407
+ * @param issuerParticipantId this agent's ISSUER participant for the schema, which anchors the
408
+ * credential digest.
409
+ * @param schemaKey the ECS schema this agent issues against. Every ECS key is accepted; the caller
410
+ * reaches this function only for a schema the agent holds an active ISSUER entry on.
411
+ */
412
+ async function rebindEcsCredentialSchema(agent, publicApiBaseUrl, schemaId, schemaKey, ecsClaims, jsonSchemaCredentialId, issuerParticipantId, onChainJsonSchema, effectiveUntil) {
413
+ var _a, _b, _c, _d, _e, _f, _g, _h;
414
+ if (!agent.did)
267
415
  return;
268
416
  const vpUrl = `${publicApiBaseUrl}/vt/${schemaKey}-vtc-vp.json`;
269
- const jscUrl = `${publicApiBaseUrl}/vt/schemas-${schemaId}-jsc.json`;
417
+ const jscUrl = jsonSchemaCredentialId;
270
418
  const didRecord = await getDidRecord(agent);
271
419
  const record = (_a = didRecord.metadata.get('_vt/vtc')) !== null && _a !== void 0 ? _a : {};
420
+ const stored = record[jscUrl];
421
+ const storedIssuer = typeof ((_b = stored === null || stored === void 0 ? void 0 : stored.credential) === null || _b === void 0 ? void 0 : _b.issuer) === 'string' ? stored.credential.issuer : (_d = (_c = stored === null || stored === void 0 ? void 0 : stored.credential) === null || _c === void 0 ? void 0 : _c.issuer) === null || _d === void 0 ? void 0 : _d.id;
422
+ if ((stored === null || stored === void 0 ? void 0 : stored.credential) && !stored.integrityData && storedIssuer !== agent.did) {
423
+ agent.config.logger.debug(`[SelfTR] Keeping the ${schemaKey} credential issued by ${storedIssuer} instead of rebinding a self-issued one`);
424
+ return;
425
+ }
272
426
  let removedStale = false;
273
427
  for (const [key, entry] of Object.entries(record)) {
274
428
  // findMetadataEntry serves the first entry matching the VP url, so stale bindings must go
275
429
  if (key !== jscUrl &&
276
- ((_b = entry.verifiablePresentation) === null || _b === void 0 ? void 0 : _b.id) === vpUrl) {
430
+ ((_e = entry.verifiablePresentation) === null || _e === void 0 ? void 0 : _e.id) === vpUrl) {
277
431
  delete record[key];
278
432
  removedStale = true;
279
433
  }
280
434
  }
281
435
  if (removedStale) {
282
436
  didRecord.metadata.set('_vt/vtc', record);
283
- await updateDidRecord(agent, didRecord);
437
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, didRecord);
284
438
  }
285
- await (0, setupSelfTr_1.generateVerifiablePresentation)(agent, vpUrl, (0, data_1.getEcsSchemas)(publicApiBaseUrl), schemaKey, ['VerifiableCredential', 'VerifiableTrustCredential'], { id: jscUrl, type: 'JsonSchemaCredential' }, defaults, async (verifiablePresentation) => {
286
- var _a;
287
- return await anchorCredentialDigest(agent, Number(schemaId), (_a = verifiablePresentation === null || verifiablePresentation === void 0 ? void 0 : verifiablePresentation.verifiableCredential) === null || _a === void 0 ? void 0 : _a[0]);
288
- });
439
+ await (0, selfIssuedEcsCredential_1.publishSelfIssuedEcsPresentation)(agent, vpUrl, Object.assign(Object.assign({}, (0, data_1.getEcsSchemas)(publicApiBaseUrl)), (onChainJsonSchema ? { [schemaKey]: onChainJsonSchema } : {})), schemaKey, ['VerifiableCredential', 'VerifiableTrustCredential'], { id: jscUrl, type: 'JsonSchemaCredential' }, ecsClaims, async (verifiablePresentation) => await anchorCredentialDigest(agent, Number(schemaId), verifiablePresentation.verifiableCredential[0], issuerParticipantId), effectiveUntil);
289
440
  const freshRecord = await getDidRecord(agent);
441
+ let recordChanged = false;
442
+ const vtc = (_f = freshRecord.metadata.get('_vt/vtc')) !== null && _f !== void 0 ? _f : {};
443
+ const entry = vtc[jscUrl];
444
+ if (entry && (entry.issuerParticipantId !== issuerParticipantId || entry.schemaKey !== schemaKey)) {
445
+ vtc[jscUrl] = Object.assign(Object.assign({}, entry), { issuerParticipantId, schemaKey });
446
+ freshRecord.metadata.set('_vt/vtc', vtc);
447
+ recordChanged = true;
448
+ }
290
449
  const doc = freshRecord.didDocument;
291
450
  if (doc) {
292
451
  // resolvers match the [VT-CRED-W3C-LINKED-VP] fragment; #whois alone is not enough
293
452
  const expectedServiceId = `${agent.did}#${(0, setupSelfTr_1.linkedVpFragment)(schemaKey)}`;
294
- const linked = (_c = doc.service) === null || _c === void 0 ? void 0 : _c.some(s => s.id === expectedServiceId);
453
+ const linked = (_g = doc.service) === null || _g === void 0 ? void 0 : _g.some(s => s.id === expectedServiceId);
295
454
  if (!linked) {
296
- doc.service = (_d = doc.service) !== null && _d !== void 0 ? _d : [];
455
+ doc.service = (_h = doc.service) !== null && _h !== void 0 ? _h : [];
297
456
  doc.service.push(new core_1.DidDocumentService({
298
457
  id: expectedServiceId,
299
458
  serviceEndpoint: vpUrl,
300
459
  type: 'LinkedVerifiablePresentation',
301
460
  }));
302
- await updateDidRecord(agent, freshRecord);
461
+ recordChanged = true;
303
462
  }
463
+ if (recordChanged)
464
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, freshRecord);
304
465
  }
305
466
  agent.config.logger.info(`[SelfTR] Rebound ${schemaKey} credential to VTJSC ${jscUrl}`);
306
467
  }
468
+ /**
469
+ * Withdraws the ECS credentials anchored against `issuerParticipantId`, and the #whois entry
470
+ * when the Service credential is among them.
471
+ */
472
+ async function withdrawSelfIssuedEcsCredentials(agent, issuerParticipantId) {
473
+ var _a, _b;
474
+ const didRecord = await getDidRecord(agent);
475
+ const withdrawn = [];
476
+ let whoisWithdrawn = false;
477
+ for (const [jscUrl, value] of Object.entries((_a = didRecord.metadata.get('_vt/vtc')) !== null && _a !== void 0 ? _a : {})) {
478
+ const entry = value;
479
+ if (entry.issuerParticipantId !== issuerParticipantId)
480
+ continue;
481
+ await removeTrustCredential(agent, jscUrl, '_vt/vtc');
482
+ withdrawn.push(jscUrl);
483
+ if (entry.schemaKey === 'ecs-service')
484
+ whoisWithdrawn = true;
485
+ }
486
+ if (whoisWithdrawn) {
487
+ const record = await getDidRecord(agent);
488
+ if ((_b = record.didDocument) === null || _b === void 0 ? void 0 : _b.service) {
489
+ record.didDocument.service = record.didDocument.service.filter(s => s.id !== `${agent.did}#whois`);
490
+ await (0, publishedDidRecord_1.updateDidRecord)(agent, record);
491
+ }
492
+ }
493
+ return withdrawn;
494
+ }
307
495
  //# sourceMappingURL=trustCredentialStore.js.map