@verana-labs/vs-agent-sdk 2.0.0-dev.9 → 2.0.0-pr.767.1

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