@cheqd/sdk-esm 5.3.7-develop.1 → 5.4.0-develop.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 (179) hide show
  1. package/build/cjs/src/index.d.ts +142 -0
  2. package/build/cjs/src/index.d.ts.map +1 -0
  3. package/build/cjs/src/index.js +184 -0
  4. package/build/cjs/src/index.js.map +1 -0
  5. package/build/cjs/src/modules/_.d.ts +81 -0
  6. package/build/cjs/src/modules/_.d.ts.map +1 -0
  7. package/build/cjs/src/modules/_.js +93 -0
  8. package/build/cjs/src/modules/_.js.map +1 -0
  9. package/build/cjs/src/modules/did.d.ts +488 -0
  10. package/build/cjs/src/modules/did.d.ts.map +1 -0
  11. package/build/cjs/src/modules/did.js +1249 -0
  12. package/build/cjs/src/modules/did.js.map +1 -0
  13. package/build/cjs/src/modules/feeabstraction.d.ts +429 -0
  14. package/build/cjs/src/modules/feeabstraction.d.ts.map +1 -0
  15. package/build/cjs/src/modules/feeabstraction.js +474 -0
  16. package/build/cjs/src/modules/feeabstraction.js.map +1 -0
  17. package/build/cjs/src/modules/feemarket.d.ts +244 -0
  18. package/build/cjs/src/modules/feemarket.d.ts.map +1 -0
  19. package/build/cjs/src/modules/feemarket.js +297 -0
  20. package/build/cjs/src/modules/feemarket.js.map +1 -0
  21. package/build/cjs/src/modules/oracle.d.ts +563 -0
  22. package/build/cjs/src/modules/oracle.d.ts.map +1 -0
  23. package/build/cjs/src/modules/oracle.js +784 -0
  24. package/build/cjs/src/modules/oracle.js.map +1 -0
  25. package/build/cjs/src/modules/resource.d.ts +330 -0
  26. package/build/cjs/src/modules/resource.d.ts.map +1 -0
  27. package/build/cjs/src/modules/resource.js +556 -0
  28. package/build/cjs/src/modules/resource.js.map +1 -0
  29. package/build/cjs/src/querier.d.ts +62 -0
  30. package/build/cjs/src/querier.d.ts.map +1 -0
  31. package/build/cjs/src/querier.js +87 -0
  32. package/build/cjs/src/querier.js.map +1 -0
  33. package/build/cjs/src/registry.d.ts +18 -0
  34. package/build/cjs/src/registry.d.ts.map +1 -0
  35. package/build/cjs/src/registry.js +23 -0
  36. package/build/cjs/src/registry.js.map +1 -0
  37. package/build/cjs/src/signer.d.ts +250 -0
  38. package/build/cjs/src/signer.d.ts.map +1 -0
  39. package/build/cjs/src/signer.js +617 -0
  40. package/build/cjs/src/signer.js.map +1 -0
  41. package/build/cjs/src/types.d.ts +221 -0
  42. package/build/cjs/src/types.d.ts.map +1 -0
  43. package/build/cjs/src/types.js.map +1 -0
  44. package/build/cjs/src/utils.d.ts +233 -0
  45. package/build/cjs/src/utils.d.ts.map +1 -0
  46. package/build/cjs/src/utils.js +571 -0
  47. package/build/cjs/src/utils.js.map +1 -0
  48. package/build/{index.d.ts → esm/src/index.d.ts} +7 -3
  49. package/build/esm/src/index.d.ts.map +1 -0
  50. package/build/{index.js → esm/src/index.js} +3 -1
  51. package/build/esm/src/index.js.map +1 -0
  52. package/build/esm/src/modules/_.d.ts.map +1 -0
  53. package/build/esm/src/modules/_.js.map +1 -0
  54. package/build/{modules → esm/src/modules}/did.d.ts +109 -7
  55. package/build/esm/src/modules/did.d.ts.map +1 -0
  56. package/build/{modules → esm/src/modules}/did.js +212 -6
  57. package/build/esm/src/modules/did.js.map +1 -0
  58. package/build/esm/src/modules/feeabstraction.d.ts.map +1 -0
  59. package/build/esm/src/modules/feeabstraction.js.map +1 -0
  60. package/build/esm/src/modules/feemarket.d.ts.map +1 -0
  61. package/build/esm/src/modules/feemarket.js.map +1 -0
  62. package/build/esm/src/modules/oracle.d.ts +563 -0
  63. package/build/esm/src/modules/oracle.d.ts.map +1 -0
  64. package/build/esm/src/modules/oracle.js +784 -0
  65. package/build/esm/src/modules/oracle.js.map +1 -0
  66. package/build/{modules → esm/src/modules}/resource.d.ts +132 -6
  67. package/build/esm/src/modules/resource.d.ts.map +1 -0
  68. package/build/esm/src/modules/resource.js +556 -0
  69. package/build/esm/src/modules/resource.js.map +1 -0
  70. package/build/esm/src/querier.d.ts.map +1 -0
  71. package/build/esm/src/querier.js.map +1 -0
  72. package/build/esm/src/registry.d.ts.map +1 -0
  73. package/build/esm/src/registry.js.map +1 -0
  74. package/build/esm/src/signer.d.ts.map +1 -0
  75. package/build/esm/src/signer.js.map +1 -0
  76. package/build/{types → esm/src}/types.d.ts +27 -1
  77. package/build/esm/src/types.d.ts.map +1 -0
  78. package/build/esm/src/types.js +43 -0
  79. package/build/esm/src/types.js.map +1 -0
  80. package/build/esm/src/utils.d.ts.map +1 -0
  81. package/build/esm/src/utils.js.map +1 -0
  82. package/build/types/cjs/src/index.d.ts +142 -0
  83. package/build/types/cjs/src/index.d.ts.map +1 -0
  84. package/build/types/cjs/src/modules/_.d.ts +81 -0
  85. package/build/types/cjs/src/modules/_.d.ts.map +1 -0
  86. package/build/types/cjs/src/modules/did.d.ts +488 -0
  87. package/build/types/cjs/src/modules/did.d.ts.map +1 -0
  88. package/build/types/cjs/src/modules/feeabstraction.d.ts +429 -0
  89. package/build/types/cjs/src/modules/feeabstraction.d.ts.map +1 -0
  90. package/build/types/cjs/src/modules/feemarket.d.ts +244 -0
  91. package/build/types/cjs/src/modules/feemarket.d.ts.map +1 -0
  92. package/build/types/cjs/src/modules/oracle.d.ts +563 -0
  93. package/build/types/cjs/src/modules/oracle.d.ts.map +1 -0
  94. package/build/types/cjs/src/modules/resource.d.ts +330 -0
  95. package/build/types/cjs/src/modules/resource.d.ts.map +1 -0
  96. package/build/types/cjs/src/querier.d.ts +62 -0
  97. package/build/types/cjs/src/querier.d.ts.map +1 -0
  98. package/build/types/cjs/src/registry.d.ts +18 -0
  99. package/build/types/cjs/src/registry.d.ts.map +1 -0
  100. package/build/types/cjs/src/signer.d.ts +250 -0
  101. package/build/types/cjs/src/signer.d.ts.map +1 -0
  102. package/build/types/cjs/src/types.d.ts +221 -0
  103. package/build/types/cjs/src/types.d.ts.map +1 -0
  104. package/build/types/cjs/src/utils.d.ts +233 -0
  105. package/build/types/cjs/src/utils.d.ts.map +1 -0
  106. package/build/types/{index.d.ts → esm/src/index.d.ts} +7 -3
  107. package/build/types/esm/src/index.d.ts.map +1 -0
  108. package/build/types/esm/src/modules/_.d.ts.map +1 -0
  109. package/build/types/{modules → esm/src/modules}/did.d.ts +109 -7
  110. package/build/types/esm/src/modules/did.d.ts.map +1 -0
  111. package/build/types/esm/src/modules/feeabstraction.d.ts.map +1 -0
  112. package/build/types/esm/src/modules/feemarket.d.ts.map +1 -0
  113. package/build/types/esm/src/modules/oracle.d.ts +563 -0
  114. package/build/types/esm/src/modules/oracle.d.ts.map +1 -0
  115. package/build/types/{modules → esm/src/modules}/resource.d.ts +132 -6
  116. package/build/types/esm/src/modules/resource.d.ts.map +1 -0
  117. package/build/types/esm/src/querier.d.ts.map +1 -0
  118. package/build/types/esm/src/registry.d.ts.map +1 -0
  119. package/build/types/esm/src/signer.d.ts.map +1 -0
  120. package/build/{types.d.ts → types/esm/src/types.d.ts} +27 -1
  121. package/build/types/esm/src/types.d.ts.map +1 -0
  122. package/build/types/esm/src/utils.d.ts.map +1 -0
  123. package/package.json +2 -2
  124. package/build/index.d.ts.map +0 -1
  125. package/build/index.js.map +0 -1
  126. package/build/modules/_.d.ts.map +0 -1
  127. package/build/modules/_.js.map +0 -1
  128. package/build/modules/did.d.ts.map +0 -1
  129. package/build/modules/did.js.map +0 -1
  130. package/build/modules/feeabstraction.d.ts.map +0 -1
  131. package/build/modules/feeabstraction.js.map +0 -1
  132. package/build/modules/feemarket.d.ts.map +0 -1
  133. package/build/modules/feemarket.js.map +0 -1
  134. package/build/modules/resource.d.ts.map +0 -1
  135. package/build/modules/resource.js +0 -297
  136. package/build/modules/resource.js.map +0 -1
  137. package/build/querier.d.ts.map +0 -1
  138. package/build/querier.js.map +0 -1
  139. package/build/registry.d.ts.map +0 -1
  140. package/build/registry.js.map +0 -1
  141. package/build/signer.d.ts.map +0 -1
  142. package/build/signer.js.map +0 -1
  143. package/build/types/index.d.ts.map +0 -1
  144. package/build/types/modules/_.d.ts.map +0 -1
  145. package/build/types/modules/did.d.ts.map +0 -1
  146. package/build/types/modules/feeabstraction.d.ts.map +0 -1
  147. package/build/types/modules/feemarket.d.ts.map +0 -1
  148. package/build/types/modules/resource.d.ts.map +0 -1
  149. package/build/types/querier.d.ts.map +0 -1
  150. package/build/types/registry.d.ts.map +0 -1
  151. package/build/types/signer.d.ts.map +0 -1
  152. package/build/types/types.d.ts.map +0 -1
  153. package/build/types/utils.d.ts.map +0 -1
  154. package/build/types.d.ts.map +0 -1
  155. package/build/types.js.map +0 -1
  156. package/build/utils.d.ts.map +0 -1
  157. package/build/utils.js.map +0 -1
  158. /package/build/{types.js → cjs/src/types.js} +0 -0
  159. /package/build/{modules → esm/src/modules}/_.d.ts +0 -0
  160. /package/build/{modules → esm/src/modules}/_.js +0 -0
  161. /package/build/{modules → esm/src/modules}/feeabstraction.d.ts +0 -0
  162. /package/build/{modules → esm/src/modules}/feeabstraction.js +0 -0
  163. /package/build/{modules → esm/src/modules}/feemarket.d.ts +0 -0
  164. /package/build/{modules → esm/src/modules}/feemarket.js +0 -0
  165. /package/build/{querier.d.ts → esm/src/querier.d.ts} +0 -0
  166. /package/build/{querier.js → esm/src/querier.js} +0 -0
  167. /package/build/{registry.d.ts → esm/src/registry.d.ts} +0 -0
  168. /package/build/{registry.js → esm/src/registry.js} +0 -0
  169. /package/build/{signer.d.ts → esm/src/signer.d.ts} +0 -0
  170. /package/build/{signer.js → esm/src/signer.js} +0 -0
  171. /package/build/{types → esm/src}/utils.d.ts +0 -0
  172. /package/build/{utils.js → esm/src/utils.js} +0 -0
  173. /package/build/types/{modules → esm/src/modules}/_.d.ts +0 -0
  174. /package/build/types/{modules → esm/src/modules}/feeabstraction.d.ts +0 -0
  175. /package/build/types/{modules → esm/src/modules}/feemarket.d.ts +0 -0
  176. /package/build/types/{querier.d.ts → esm/src/querier.d.ts} +0 -0
  177. /package/build/types/{registry.d.ts → esm/src/registry.d.ts} +0 -0
  178. /package/build/types/{signer.d.ts → esm/src/signer.d.ts} +0 -0
  179. /package/build/{utils.d.ts → types/esm/src/utils.d.ts} +0 -0
@@ -0,0 +1,1249 @@
1
+ import { createPagination, createProtobufRpcClient } from '@cosmjs/stargate-cjs';
2
+ import { AbstractCheqdSDKModule } from './_';
3
+ import { ISignInputs, VerificationMethods, } from '../types';
4
+ import { MsgCreateDidDoc, MsgCreateDidDocPayload, MsgCreateDidDocResponse, MsgDeactivateDidDoc, MsgDeactivateDidDocPayload, MsgDeactivateDidDocResponse, MsgUpdateDidDoc, MsgUpdateDidDocPayload, MsgUpdateDidDocResponse, protobufPackage, QueryClientImpl, VerificationMethod, } from '@cheqd/ts-proto-cjs/cheqd/did/v2/index';
5
+ import { parseCoins } from '@cosmjs/proto-signing-cjs';
6
+ import { v4 } from 'uuid-cjs';
7
+ import { assert } from '@cosmjs/utils-cjs';
8
+ import { denormalizeService, normalizeAuthentication, normalizeController, normalizeService } from '../utils';
9
+ import { defaultOracleExtensionKey, MovingAverages, WMAStrategies } from './oracle';
10
+ import { Coin } from 'cosmjs-types/cosmos/base/v1beta1/coin';
11
+ /** Default extension key for DID-related query operations */
12
+ export const defaultDidExtensionKey = 'did';
13
+ /**
14
+ * Standard W3C and DID-related context URIs used in DID documents.
15
+ * These contexts define the semantic meaning of properties in DID documents.
16
+ */
17
+ export const contexts = {
18
+ /** W3C DID Core v1 context */
19
+ W3CDIDv1: 'https://www.w3.org/ns/did/v1',
20
+ /** Ed25519 Signature Suite 2020 context */
21
+ W3CSuiteEd255192020: 'https://w3id.org/security/suites/ed25519-2020/v1',
22
+ /** Ed25519 Signature Suite 2018 context */
23
+ W3CSuiteEd255192018: 'https://w3id.org/security/suites/ed25519-2018/v1',
24
+ /** JSON Web Signature Suite 2020 context */
25
+ W3CSuiteJws2020: 'https://w3id.org/security/suites/jws-2020/v1',
26
+ /** Linked Domains context for domain verification */
27
+ LinkedDomainsContext: 'https://identity.foundation/.well-known/did-configuration/v1',
28
+ };
29
+ /**
30
+ * Protobuf message type literals for DID operations.
31
+ * Used for consistent message type identification across the module.
32
+ */
33
+ export const protobufLiterals = {
34
+ /** Create DID document message type */
35
+ MsgCreateDidDoc: 'MsgCreateDidDoc',
36
+ /** Create DID document response message type */
37
+ MsgCreateDidDocResponse: 'MsgCreateDidDocResponse',
38
+ /** Update DID document message type */
39
+ MsgUpdateDidDoc: 'MsgUpdateDidDoc',
40
+ /** Update DID document response message type */
41
+ MsgUpdateDidDocResponse: 'MsgUpdateDidDocResponse',
42
+ /** Deactivate DID document message type */
43
+ MsgDeactivateDidDoc: 'MsgDeactivateDidDoc',
44
+ /** Deactivate DID document response message type */
45
+ MsgDeactivateDidDocResponse: 'MsgDeactivateDidDocResponse',
46
+ };
47
+ /** Type URL for MsgCreateDidDoc messages */
48
+ export const typeUrlMsgCreateDidDoc = `/${protobufPackage}.${protobufLiterals.MsgCreateDidDoc}`;
49
+ /** Type URL for MsgCreateDidDocResponse messages */
50
+ export const typeUrlMsgCreateDidDocResponse = `/${protobufPackage}.${protobufLiterals.MsgCreateDidDocResponse}`;
51
+ /** Type URL for MsgUpdateDidDoc messages */
52
+ export const typeUrlMsgUpdateDidDoc = `/${protobufPackage}.${protobufLiterals.MsgUpdateDidDoc}`;
53
+ /** Type URL for MsgUpdateDidDocResponse messages */
54
+ export const typeUrlMsgUpdateDidDocResponse = `/${protobufPackage}.${protobufLiterals.MsgUpdateDidDocResponse}`;
55
+ /** Type URL for MsgDeactivateDidDoc messages */
56
+ export const typeUrlMsgDeactivateDidDoc = `/${protobufPackage}.${protobufLiterals.MsgDeactivateDidDoc}`;
57
+ /** Type URL for MsgDeactivateDidDocResponse messages */
58
+ export const typeUrlMsgDeactivateDidDocResponse = `/${protobufPackage}.${protobufLiterals.MsgDeactivateDidDocResponse}`;
59
+ /**
60
+ * Type guard function to check if an object is a MsgCreateDidDocEncodeObject.
61
+ *
62
+ * @param obj - EncodeObject to check
63
+ * @returns True if the object is a MsgCreateDidDocEncodeObject
64
+ */
65
+ export function isMsgCreateDidDocEncodeObject(obj) {
66
+ return obj.typeUrl === typeUrlMsgCreateDidDoc;
67
+ }
68
+ /**
69
+ * Type guard function to check if an object is a MsgUpdateDidDocEncodeObject.
70
+ *
71
+ * @param obj - EncodeObject to check
72
+ * @returns True if the object is a MsgUpdateDidDocEncodeObject
73
+ */
74
+ export function isMsgUpdateDidDocEncodeObject(obj) {
75
+ return obj.typeUrl === typeUrlMsgUpdateDidDoc;
76
+ }
77
+ /**
78
+ * Type guard function to check if an object is a MsgDeactivateDidDocEncodeObject.
79
+ *
80
+ * @param obj - EncodeObject to check
81
+ * @returns True if the object is a MsgDeactivateDidDocEncodeObject
82
+ */
83
+ export function isMsgDeactivateDidDocEncodeObject(obj) {
84
+ return obj.typeUrl === typeUrlMsgDeactivateDidDoc;
85
+ }
86
+ /**
87
+ * Type guard function to check if an object is a MsgCreateDidDocResponseEncodeObject.
88
+ *
89
+ * @param obj - EncodeObject to check
90
+ * @returns True if the object is a MsgCreateDidDocResponseEncodeObject
91
+ */
92
+ export function MsgCreateDidDocResponseEncodeObject(obj) {
93
+ return obj.typeUrl === typeUrlMsgCreateDidDocResponse;
94
+ }
95
+ /**
96
+ * Type guard function to check if an object is a MsgUpdateDidDocEncodeObject.
97
+ *
98
+ * @param obj - EncodeObject to check
99
+ * @returns True if the object is a MsgUpdateDidDocEncodeObject
100
+ */
101
+ export function MsgUpdateDidDocEncodeObject(obj) {
102
+ return obj.typeUrl === typeUrlMsgUpdateDidDoc;
103
+ }
104
+ /**
105
+ * Type guard function to check if an object is a MsgUpdateDidDocResponseEncodeObject.
106
+ *
107
+ * @param obj - EncodeObject to check
108
+ * @returns True if the object is a MsgUpdateDidDocResponseEncodeObject
109
+ */
110
+ export function MsgUpdateDidDocResponseEncodeObject(obj) {
111
+ return obj.typeUrl === typeUrlMsgUpdateDidDocResponse;
112
+ }
113
+ /**
114
+ * Type guard function to check if an object is a MsgDeactivateDidDocEncodeObject.
115
+ *
116
+ * @param obj - EncodeObject to check
117
+ * @returns True if the object is a MsgDeactivateDidDocEncodeObject
118
+ */
119
+ export function MsgDeactivateDidDocEncodeObject(obj) {
120
+ return obj.typeUrl === typeUrlMsgDeactivateDidDoc;
121
+ }
122
+ /**
123
+ * Type guard function to check if an object is a MsgDeactivateDidDocResponseEncodeObject.
124
+ *
125
+ * @param obj - EncodeObject to check
126
+ * @returns True if the object is a MsgDeactivateDidDocResponseEncodeObject
127
+ */
128
+ export function MsgDeactiveDidDocResponseEncodeObject(obj) {
129
+ return obj.typeUrl === typeUrlMsgUpdateDidDocResponse;
130
+ }
131
+ /**
132
+ * Sets up the DID extension for the querier client.
133
+ * Creates and configures the DID-specific query methods.
134
+ *
135
+ * @param base - Base QueryClient to extend
136
+ * @returns Configured DID extension with query methods
137
+ */
138
+ export const setupDidExtension = (base) => {
139
+ const rpc = createProtobufRpcClient(base);
140
+ const queryService = new QueryClientImpl(rpc);
141
+ return {
142
+ [defaultDidExtensionKey]: {
143
+ didDoc: async (id) => {
144
+ const { value } = await queryService.DidDoc({ id });
145
+ assert(value);
146
+ return value;
147
+ },
148
+ didDocVersion: async (id, versionId) => {
149
+ const { value } = await queryService.DidDocVersion({ id, version: versionId });
150
+ assert(value);
151
+ return value;
152
+ },
153
+ allDidDocVersionsMetadata: async (id, paginationKey) => {
154
+ const response = await queryService.AllDidDocVersionsMetadata({
155
+ id,
156
+ pagination: createPagination(paginationKey),
157
+ });
158
+ return response;
159
+ },
160
+ params: async () => {
161
+ const response = await queryService.Params({});
162
+ assert(response.params);
163
+ return response;
164
+ },
165
+ },
166
+ };
167
+ };
168
+ /**
169
+ * DID Module class providing comprehensive DID document management functionality.
170
+ * Handles creation, updates, deactivation, and querying of DID documents on the Cheqd blockchain.
171
+ */
172
+ export class DIDModule extends AbstractCheqdSDKModule {
173
+ // @ts-expect-error underlying type `GeneratedType` is intentionally wider
174
+ static registryTypes = [
175
+ [typeUrlMsgCreateDidDoc, MsgCreateDidDoc],
176
+ [typeUrlMsgCreateDidDocResponse, MsgCreateDidDocResponse],
177
+ [typeUrlMsgUpdateDidDoc, MsgUpdateDidDoc],
178
+ [typeUrlMsgUpdateDidDocResponse, MsgUpdateDidDocResponse],
179
+ [typeUrlMsgDeactivateDidDoc, MsgDeactivateDidDoc],
180
+ [typeUrlMsgDeactivateDidDocResponse, MsgDeactivateDidDocResponse],
181
+ ];
182
+ /** Base denomination for Cheqd network transactions */
183
+ static baseMinimalDenom = 'ncheq';
184
+ /** Base denomination in USD for Cheqd network transactions */
185
+ static baseUsdDenom = 'usd';
186
+ /** Default slippage tolerance in base points (BPS) */
187
+ static defaultSlippageBps = 500n;
188
+ /**
189
+ * Standard fee amounts for DID operations.
190
+ * These represent the default costs for different DID document operations.
191
+ */
192
+ static fees = {
193
+ /** Default fee for creating a new DID document */
194
+ DefaultCreateDidDocFee: { amount: '50000000000', denom: DIDModule.baseMinimalDenom },
195
+ /** Default fee for updating an existing DID document */
196
+ DefaultUpdateDidDocFee: { amount: '25000000000', denom: DIDModule.baseMinimalDenom },
197
+ /** Default fee for deactivating a DID document */
198
+ DefaultDeactivateDidDocFee: { amount: '10000000000', denom: DIDModule.baseMinimalDenom },
199
+ /** Default fee for creating a new DID document in USD */
200
+ DefaultCreateDidDocFeeUSD: { amount: '2000000000000000000', denom: DIDModule.baseUsdDenom },
201
+ /** Default fee for updating an existing DID document in USD */
202
+ DefaultUpdateDidDocFeeUSD: { amount: '1000000000000000000', denom: DIDModule.baseUsdDenom },
203
+ /** Default fee for deactivating a DID document in USD */
204
+ DefaultDeactivateDidDocFeeUSD: { amount: '400000000000000000', denom: DIDModule.baseUsdDenom },
205
+ };
206
+ /**
207
+ * Standard gas limits for DID operations.
208
+ * These represent the default gas limits for different DID document operations.
209
+ */
210
+ static gasLimits = {
211
+ /** Gas limit for creating a new DID document */
212
+ CreateDidDocGasLimit: '360000',
213
+ /** Gas limit for updating an existing DID document */
214
+ UpdateDidDocGasLimit: '360000',
215
+ /** Gas limit for deactivating a DID document */
216
+ DeactivateDidDocGasLimit: '360000',
217
+ };
218
+ /** Querier extension setup function for DID operations */
219
+ static querierExtensionSetup = setupDidExtension;
220
+ /** Querier instance with DID extension capabilities */
221
+ querier;
222
+ /**
223
+ * Constructs a new DID module instance.
224
+ *
225
+ * @param signer - Signing client for blockchain transactions
226
+ * @param querier - Querier client with DID extension for data retrieval
227
+ */
228
+ constructor(signer, querier) {
229
+ super(signer, querier);
230
+ this.querier = querier;
231
+ this.methods = {
232
+ createDidDocTx: this.createDidDocTx.bind(this),
233
+ updateDidDocTx: this.updateDidDocTx.bind(this),
234
+ deactivateDidDocTx: this.deactivateDidDocTx.bind(this),
235
+ queryDidDoc: this.queryDidDoc.bind(this),
236
+ queryDidDocVersion: this.queryDidDocVersion.bind(this),
237
+ queryAllDidDocVersionsMetadata: this.queryAllDidDocVersionsMetadata.bind(this),
238
+ queryParams: this.queryParams.bind(this),
239
+ generateCreateDidDocFees: this.generateCreateDidDocFees.bind(this),
240
+ };
241
+ }
242
+ /**
243
+ * Gets the registry types for DID message encoding/decoding.
244
+ *
245
+ * @returns Iterable of [typeUrl, GeneratedType] pairs for the registry
246
+ */
247
+ getRegistryTypes() {
248
+ return DIDModule.registryTypes;
249
+ }
250
+ /**
251
+ * Gets the querier extension setup for DID operations.
252
+ *
253
+ * @returns Query extension setup function for DID functionality
254
+ */
255
+ getQuerierExtensionSetup() {
256
+ return DIDModule.querierExtensionSetup;
257
+ }
258
+ /**
259
+ * Creates a new DID document transaction on the blockchain.
260
+ * Validates the DID payload and authentication before submission.
261
+ *
262
+ * @param signInputs - Signing inputs or pre-computed signatures for the transaction
263
+ * @param didPayload - DID document payload to create
264
+ * @param address - Address of the account submitting the transaction
265
+ * @param fee - Transaction fee configuration or 'auto' for automatic calculation
266
+ * @param memo - Optional transaction memo
267
+ * @param versionId - Optional version identifier for the DID document
268
+ * @param feeOptions - Optional fee options for the transaction
269
+ * @param context - Optional SDK context for accessing clients
270
+ * @returns Promise resolving to the transaction response
271
+ * @throws Error if DID payload is not spec compliant or authentication is invalid
272
+ */
273
+ async createDidDocTx(signInputs, didPayload, address, fee, memo, versionId, feeOptions, context) {
274
+ if (!this._signer) {
275
+ this._signer = context.sdk.signer;
276
+ }
277
+ if (!this.querier) {
278
+ this.querier = context.sdk.querier;
279
+ }
280
+ if (!versionId || versionId === '') {
281
+ versionId = v4();
282
+ }
283
+ const { valid, error, protobufVerificationMethod, protobufService } = await DIDModule.validateSpecCompliantPayload(didPayload);
284
+ if (!valid) {
285
+ throw new Error(`DID payload is not spec compliant: ${error}`);
286
+ }
287
+ const { valid: authenticationValid, error: authenticationError } = await DIDModule.validateAuthenticationAgainstSignatures(didPayload, signInputs, this.querier);
288
+ if (!authenticationValid) {
289
+ throw new Error(`DID authentication is not valid: ${authenticationError}`);
290
+ }
291
+ const payload = MsgCreateDidDocPayload.fromPartial({
292
+ context: didPayload?.['@context'],
293
+ id: didPayload.id,
294
+ controller: didPayload.controller,
295
+ verificationMethod: protobufVerificationMethod,
296
+ authentication: didPayload.authentication,
297
+ assertionMethod: didPayload.assertionMethod,
298
+ capabilityInvocation: didPayload.capabilityInvocation,
299
+ capabilityDelegation: didPayload.capabilityDelegation,
300
+ keyAgreement: didPayload.keyAgreement,
301
+ service: protobufService,
302
+ alsoKnownAs: didPayload.alsoKnownAs,
303
+ versionId: versionId,
304
+ });
305
+ let signatures;
306
+ if (ISignInputs.isSignInput(signInputs)) {
307
+ signatures = await this._signer.signCreateDidDocTx(signInputs, payload);
308
+ }
309
+ else {
310
+ signatures = signInputs;
311
+ }
312
+ const value = {
313
+ payload,
314
+ signatures,
315
+ };
316
+ const createDidMsg = {
317
+ typeUrl: typeUrlMsgCreateDidDoc,
318
+ value,
319
+ };
320
+ if (address === '') {
321
+ address = (await context.sdk.options.wallet.getAccounts())[0].address;
322
+ }
323
+ if (!fee) {
324
+ fee = await this.generateCreateDidDocFees(address, undefined, feeOptions, context);
325
+ }
326
+ return this._signer.signAndBroadcast(address, [createDidMsg], fee, memo);
327
+ }
328
+ /**
329
+ * Updates an existing DID document transaction on the blockchain.
330
+ * Validates the updated DID payload and handles key rotation scenarios.
331
+ *
332
+ * @param signInputs - Signing inputs or pre-computed signatures for the transaction
333
+ * @param didPayload - Updated DID document payload
334
+ * @param address - Address of the account submitting the transaction
335
+ * @param fee - Transaction fee configuration or 'auto' for automatic calculation
336
+ * @param memo - Optional transaction memo
337
+ * @param versionId - Optional version identifier for the updated DID document
338
+ * @param feeOptions - Optional fee options for the transaction
339
+ * @param context - Optional SDK context for accessing clients
340
+ * @returns Promise resolving to the transaction response
341
+ * @throws Error if DID payload is not spec compliant or authentication is invalid
342
+ */
343
+ async updateDidDocTx(signInputs, didPayload, address, fee, memo, versionId, feeOptions, context) {
344
+ if (!this._signer) {
345
+ this._signer = context.sdk.signer;
346
+ }
347
+ if (!this.querier) {
348
+ this.querier = context.sdk.querier;
349
+ }
350
+ if (!versionId || versionId === '') {
351
+ versionId = v4();
352
+ }
353
+ const { valid, error, protobufVerificationMethod, protobufService } = await DIDModule.validateSpecCompliantPayload(didPayload);
354
+ if (!valid) {
355
+ throw new Error(`DID payload is not spec compliant: ${error}`);
356
+ }
357
+ const { valid: authenticationValid, error: authenticationError, externalControllersDocuments, previousDidDocument, } = await DIDModule.validateAuthenticationAgainstSignaturesKeyRotation(didPayload, signInputs, this.querier);
358
+ if (!authenticationValid) {
359
+ throw new Error(`DID authentication is not valid: ${authenticationError}`);
360
+ }
361
+ const payload = MsgUpdateDidDocPayload.fromPartial({
362
+ context: didPayload?.['@context'],
363
+ id: didPayload.id,
364
+ controller: didPayload.controller,
365
+ verificationMethod: protobufVerificationMethod,
366
+ authentication: didPayload.authentication,
367
+ assertionMethod: didPayload.assertionMethod,
368
+ capabilityInvocation: didPayload.capabilityInvocation,
369
+ capabilityDelegation: didPayload.capabilityDelegation,
370
+ keyAgreement: didPayload.keyAgreement,
371
+ service: protobufService,
372
+ alsoKnownAs: didPayload.alsoKnownAs,
373
+ versionId: versionId,
374
+ });
375
+ let signatures;
376
+ if (ISignInputs.isSignInput(signInputs)) {
377
+ signatures = await this._signer.signUpdateDidDocTx(signInputs, payload, externalControllersDocuments, previousDidDocument);
378
+ }
379
+ else {
380
+ signatures = signInputs;
381
+ }
382
+ const value = {
383
+ payload,
384
+ signatures,
385
+ };
386
+ const updateDidMsg = {
387
+ typeUrl: typeUrlMsgUpdateDidDoc,
388
+ value,
389
+ };
390
+ if (address === '') {
391
+ address = (await context.sdk.options.wallet.getAccounts())[0].address;
392
+ }
393
+ if (!fee) {
394
+ fee = await this.generateUpdateDidDocFees(address, undefined, feeOptions, context);
395
+ }
396
+ return this._signer.signAndBroadcast(address, [updateDidMsg], fee, memo);
397
+ }
398
+ /**
399
+ * Deactivates an existing DID document transaction on the blockchain.
400
+ * Validates authentication and creates a deactivation transaction.
401
+ *
402
+ * @param signInputs - Signing inputs or pre-computed signatures for the transaction
403
+ * @param didPayload - DID document payload containing the ID to deactivate
404
+ * @param address - Address of the account submitting the transaction
405
+ * @param fee - Transaction fee configuration or 'auto' for automatic calculation
406
+ * @param memo - Optional transaction memo
407
+ * @param versionId - Optional version identifier for the deactivation
408
+ * @param feeOptions - Optional fee options for the transaction
409
+ * @param context - Optional SDK context for accessing clients
410
+ * @returns Promise resolving to the transaction response
411
+ * @throws Error if DID payload is not spec compliant or authentication is invalid
412
+ */
413
+ async deactivateDidDocTx(signInputs, didPayload, address, fee, memo, versionId, feeOptions, context) {
414
+ if (!this._signer) {
415
+ this._signer = context.sdk.signer;
416
+ }
417
+ if (!versionId || versionId === '') {
418
+ versionId = v4();
419
+ }
420
+ const { valid, error, protobufVerificationMethod } = await DIDModule.validateSpecCompliantPayload(didPayload);
421
+ if (!valid) {
422
+ throw new Error(`DID payload is not spec compliant: ${error}`);
423
+ }
424
+ const { valid: authenticationValid, error: authenticationError } = await DIDModule.validateAuthenticationAgainstSignatures(didPayload, signInputs, this.querier);
425
+ if (!authenticationValid) {
426
+ throw new Error(`DID authentication is not valid: ${authenticationError}`);
427
+ }
428
+ const payload = MsgDeactivateDidDocPayload.fromPartial({
429
+ id: didPayload.id,
430
+ versionId: versionId,
431
+ });
432
+ let signatures;
433
+ if (ISignInputs.isSignInput(signInputs)) {
434
+ signatures = await this._signer.signDeactivateDidDocTx(signInputs, payload, protobufVerificationMethod);
435
+ }
436
+ else {
437
+ signatures = signInputs;
438
+ }
439
+ const value = {
440
+ payload,
441
+ signatures,
442
+ };
443
+ const deactivateDidMsg = {
444
+ typeUrl: typeUrlMsgDeactivateDidDoc,
445
+ value,
446
+ };
447
+ if (address === '') {
448
+ address = (await context.sdk.options.wallet.getAccounts())[0].address;
449
+ }
450
+ if (!fee) {
451
+ fee = await this.generateDeactivateDidDocFees(address, undefined, feeOptions, context);
452
+ }
453
+ return this._signer.signAndBroadcast(address, [deactivateDidMsg], fee, memo);
454
+ }
455
+ /**
456
+ * Queries a DID document by its identifier.
457
+ * Retrieves the latest version of the DID document with metadata.
458
+ *
459
+ * @param id - DID identifier to query
460
+ * @param context - Optional SDK context for accessing clients
461
+ * @returns Promise resolving to the DID document with metadata
462
+ */
463
+ async queryDidDoc(id, context) {
464
+ if (!this.querier) {
465
+ this.querier = context.sdk.querier;
466
+ }
467
+ const { didDoc, metadata } = await this.querier[defaultDidExtensionKey].didDoc(id);
468
+ return {
469
+ didDocument: await DIDModule.toSpecCompliantPayload(didDoc),
470
+ didDocumentMetadata: await DIDModule.toSpecCompliantMetadata(metadata),
471
+ };
472
+ }
473
+ /**
474
+ * Queries a specific version of a DID document by its identifier and version ID.
475
+ *
476
+ * @param id - DID identifier to query
477
+ * @param versionId - Specific version identifier to retrieve
478
+ * @param context - Optional SDK context for accessing clients
479
+ * @returns Promise resolving to the DID document version with metadata
480
+ */
481
+ async queryDidDocVersion(id, versionId, context) {
482
+ if (!this.querier) {
483
+ this.querier = context.sdk.querier;
484
+ }
485
+ const { didDoc, metadata } = await this.querier[defaultDidExtensionKey].didDocVersion(id, versionId);
486
+ return {
487
+ didDocument: await DIDModule.toSpecCompliantPayload(didDoc),
488
+ didDocumentMetadata: await DIDModule.toSpecCompliantMetadata(metadata),
489
+ };
490
+ }
491
+ /**
492
+ * Queries metadata for all versions of a DID document.
493
+ * Retrieves version history information for a specific DID.
494
+ *
495
+ * @param id - DID identifier to query version metadata for
496
+ * @param context - Optional SDK context for accessing clients
497
+ * @returns Promise resolving to array of version metadata and pagination info
498
+ */
499
+ async queryAllDidDocVersionsMetadata(id, context) {
500
+ if (!this.querier) {
501
+ this.querier = context.sdk.querier;
502
+ }
503
+ const { versions, pagination } = await this.querier[defaultDidExtensionKey].allDidDocVersionsMetadata(id);
504
+ return {
505
+ didDocumentVersionsMetadata: await Promise.all(versions.map(async (m) => await DIDModule.toSpecCompliantMetadata(m))),
506
+ pagination,
507
+ };
508
+ }
509
+ /**
510
+ * Queries the DID module parameters from the blockchain.
511
+ * @param context - Optional SDK context for accessing clients
512
+ * @returns Promise resolving to the DID module parameters
513
+ */
514
+ async queryParams(context) {
515
+ if (!this.querier) {
516
+ this.querier = context.sdk.querier;
517
+ }
518
+ return this.querier[defaultDidExtensionKey].params();
519
+ }
520
+ /**
521
+ * Generates oracle-powered fees for creating a DID document.
522
+ *
523
+ * @param feePayer - Address of the account that will pay the transaction fees
524
+ * @param granter - Optional address of the account granting fee payment permissions
525
+ * @param feeOptions - Options for fetching oracle fees
526
+ * @param context - Optional SDK context for accessing clients
527
+ * @returns Promise resolving to the fee configuration for DID document creation with oracle fees
528
+ */
529
+ async generateCreateDidDocFees(feePayer, granter, feeOptions, context) {
530
+ if (!this.querier) {
531
+ this.querier = context.sdk.querier;
532
+ }
533
+ // fetch fee parameters from the DID module
534
+ const feeParams = await this.queryParams(context);
535
+ // get the price range for the create operation
536
+ const priceRange = await this.getPriceRangeFromParams(feeParams, 'create', feeOptions);
537
+ // calculate the oracle fee amount based on the price range and options
538
+ return {
539
+ amount: [await this.calculateOracleFeeAmount(priceRange, feeOptions, context)],
540
+ gas: feeOptions?.gasLimit || DIDModule.gasLimits.CreateDidDocGasLimit,
541
+ payer: feePayer,
542
+ granter,
543
+ };
544
+ }
545
+ /**
546
+ * Generates oracle-powered fees for updating a DID document.
547
+ *
548
+ * @param feePayer - Address of the account that will pay the transaction fees
549
+ * @param granter - Optional address of the account granting fee payment permissions
550
+ * @param feeOptions - Options for fetching oracle fees
551
+ * @param context - Optional SDK context for accessing clients
552
+ * @returns Promise resolving to the fee configuration for DID document update with oracle fees
553
+ */
554
+ async generateUpdateDidDocFees(feePayer, granter, fetchOptions, context) {
555
+ if (!this.querier) {
556
+ this.querier = context.sdk.querier;
557
+ }
558
+ // fetch fee parameters from the DID module
559
+ const feeParams = await this.queryParams(context);
560
+ // get the price range for the update operation
561
+ const priceRange = await this.getPriceRangeFromParams(feeParams, 'update', fetchOptions);
562
+ // calculate the oracle fee amount based on the price range and options
563
+ return {
564
+ amount: [await this.calculateOracleFeeAmount(priceRange, fetchOptions, context)],
565
+ gas: fetchOptions?.gasLimit || DIDModule.gasLimits.UpdateDidDocGasLimit,
566
+ payer: feePayer,
567
+ granter,
568
+ };
569
+ }
570
+ /** Generates oracle-powered fees for deactivating a DID document.
571
+ *
572
+ * @param feePayer - Address of the account that will pay the transaction fees
573
+ * @param granter - Optional address of the account granting fee payment permissions
574
+ * @param feeOptions - Options for fetching oracle fees
575
+ * @param context - Optional SDK context for accessing clients
576
+ * @returns Promise resolving to the fee configuration for DID document deactivation with oracle fees
577
+ */
578
+ async generateDeactivateDidDocFees(feePayer, granter, feeOptions, context) {
579
+ if (!this.querier) {
580
+ this.querier = context.sdk.querier;
581
+ }
582
+ // fetch fee parameters from the DID module
583
+ const feeParams = await this.queryParams(context);
584
+ // get the price range for the deactivate operation
585
+ const priceRange = await this.getPriceRangeFromParams(feeParams, 'deactivate', feeOptions);
586
+ // calculate the oracle fee amount based on the price range and options
587
+ return {
588
+ amount: [await this.calculateOracleFeeAmount(priceRange, feeOptions, context)],
589
+ gas: feeOptions?.gasLimit || DIDModule.gasLimits.DeactivateDidDocGasLimit,
590
+ payer: feePayer,
591
+ granter,
592
+ };
593
+ }
594
+ /**
595
+ * Gets the fee range for a specific DID operation from the module parameters.
596
+ * @param feeParams - DID module fee parameters
597
+ * @param operation - DID operation type ('create', 'update', 'deactivate')
598
+ * @param feeOptions - Options for fee retrieval
599
+ * @returns Promise resolving to the fee range for the specified operation
600
+ */
601
+ async getPriceRangeFromParams(feeParams, operation, feeOptions) {
602
+ const operationFees = (() => {
603
+ switch (operation) {
604
+ case 'create':
605
+ return feeParams.params?.createDid.find((fee) => fee.denom === (feeOptions?.feeDenom ?? DIDModule.baseUsdDenom));
606
+ case 'update':
607
+ return feeParams.params?.updateDid.find((fee) => fee.denom === (feeOptions?.feeDenom ?? DIDModule.baseUsdDenom));
608
+ case 'deactivate':
609
+ return feeParams.params?.deactivateDid.find((fee) => fee.denom === (feeOptions?.feeDenom ?? DIDModule.baseUsdDenom));
610
+ default:
611
+ throw new Error('Unsupported operation for fee retrieval');
612
+ }
613
+ })();
614
+ if (!operationFees) {
615
+ throw new Error(`Fee parameters not found for operation: ${operation}`);
616
+ }
617
+ return operationFees;
618
+ }
619
+ /**
620
+ * Calculates the oracle fee amount based on the provided fee range and options.
621
+ * @param feeRange - Fee range for the DID operation
622
+ * @param feeOptions - Options for fee calculation
623
+ * @param context - Optional SDK context for accessing clients
624
+ * @returns Promise resolving to the calculated fee amount as a Coin
625
+ */
626
+ async calculateOracleFeeAmount(feeRange, feeOptions, context) {
627
+ if (!this.querier) {
628
+ this.querier = context.sdk.querier;
629
+ }
630
+ if (feeRange.denom !== feeOptions?.feeDenom && feeOptions?.feeDenom !== undefined) {
631
+ throw new Error(`Fee denomination mismatch: expected ${feeRange.denom}, got ${feeOptions.feeDenom}`);
632
+ }
633
+ const wantedFeeAmount = feeRange.denom === DIDModule.baseUsdDenom
634
+ ? (feeOptions?.wantedAmountUsd ?? DIDModule.isFixedRange(feeRange))
635
+ ? feeRange.minAmount
636
+ : feeRange.minAmount
637
+ : feeRange.minAmount;
638
+ // override fee options, if unassigned - case: moving average type
639
+ feeOptions = {
640
+ ...feeOptions,
641
+ movingAverageType: feeOptions?.movingAverageType || MovingAverages.WMA,
642
+ };
643
+ // override fee options, if unassigned - case: WMA strategy
644
+ feeOptions = {
645
+ ...feeOptions,
646
+ wmaStrategy: feeOptions?.wmaStrategy || feeOptions?.movingAverageType === MovingAverages.WMA
647
+ ? WMAStrategies.BALANCED
648
+ : undefined,
649
+ };
650
+ const convertedFeeAmount = feeRange.denom === DIDModule.baseUsdDenom
651
+ ? parseCoins((await this.querier[defaultOracleExtensionKey].convertUSDtoCHEQ(wantedFeeAmount, feeOptions?.movingAverageType, feeOptions?.wmaStrategy, feeOptions?.wmaWeights?.map((w) => BigInt(w)))).amount)[0]
652
+ : Coin.fromPartial({ amount: wantedFeeAmount, denom: feeRange.denom });
653
+ return feeOptions?.slippageBps
654
+ ? DIDModule.applySlippageToCoin(convertedFeeAmount, feeOptions.slippageBps)
655
+ : convertedFeeAmount;
656
+ }
657
+ /**
658
+ * Applies slippage to a given coin amount based on the specified basis points.
659
+ * @param coin - Coin amount to apply slippage to
660
+ * @param slippageBps - Slippage in basis points (bps)
661
+ * @returns Coin with adjusted amount after applying slippage
662
+ */
663
+ static applySlippageToCoin(coin, slippageBps) {
664
+ const base = BigInt(coin.amount);
665
+ const delta = (base * BigInt(slippageBps)) / BigInt(10_000);
666
+ const adjustedAmount = base + delta;
667
+ return Coin.fromPartial({ amount: adjustedAmount.toString(), denom: coin.denom });
668
+ }
669
+ /**
670
+ * Checks if a fee range represents a fixed fee (minAmount equals maxAmount).
671
+ * @param feeRange - Fee range to check
672
+ * @returns True if the fee range is fixed, false otherwise
673
+ */
674
+ static isFixedRange(feeRange) {
675
+ return feeRange.minAmount === feeRange.maxAmount;
676
+ }
677
+ /**
678
+ * Validates a DID document against the Cheqd specification requirements.
679
+ * Ensures all required fields are present and verification methods are supported.
680
+ *
681
+ * @param didDocument - DID document to validate
682
+ * @returns Promise resolving to validation result with protobuf conversion or error details
683
+ */
684
+ static async validateSpecCompliantPayload(didDocument) {
685
+ // id is required, validated on both compile and runtime
686
+ if (!didDocument?.id)
687
+ return { valid: false, error: 'id is required' };
688
+ // verificationMethod is required
689
+ if (!didDocument?.verificationMethod)
690
+ return { valid: false, error: 'verificationMethod is required' };
691
+ // verificationMethod must be an array
692
+ if (!Array.isArray(didDocument?.verificationMethod))
693
+ return { valid: false, error: 'verificationMethod must be an array' };
694
+ // verificationMethod types must be supported
695
+ const protoVerificationMethod = didDocument.verificationMethod.map((vm) => {
696
+ switch (vm?.type) {
697
+ case VerificationMethods.Ed255192020:
698
+ if (!vm?.publicKeyMultibase)
699
+ throw new Error('publicKeyMultibase is required');
700
+ return VerificationMethod.fromPartial({
701
+ id: vm.id,
702
+ controller: vm.controller,
703
+ verificationMethodType: VerificationMethods.Ed255192020,
704
+ verificationMaterial: vm.publicKeyMultibase,
705
+ });
706
+ case VerificationMethods.JWK:
707
+ if (!vm?.publicKeyJwk)
708
+ throw new Error('publicKeyJwk is required');
709
+ return VerificationMethod.fromPartial({
710
+ id: vm.id,
711
+ controller: vm.controller,
712
+ verificationMethodType: VerificationMethods.JWK,
713
+ verificationMaterial: JSON.stringify(vm.publicKeyJwk),
714
+ });
715
+ case VerificationMethods.Ed255192018:
716
+ if (!vm?.publicKeyBase58)
717
+ throw new Error('publicKeyBase58 is required');
718
+ return VerificationMethod.fromPartial({
719
+ id: vm.id,
720
+ controller: vm.controller,
721
+ verificationMethodType: VerificationMethods.Ed255192018,
722
+ verificationMaterial: vm.publicKeyBase58,
723
+ });
724
+ default:
725
+ throw new Error('Unsupported verificationMethod type');
726
+ }
727
+ });
728
+ const protoService = normalizeService(didDocument);
729
+ return {
730
+ valid: true,
731
+ protobufVerificationMethod: protoVerificationMethod,
732
+ protobufService: protoService,
733
+ };
734
+ }
735
+ /**
736
+ * Converts a protobuf DID document to a specification-compliant DID document format.
737
+ * Handles context inclusion, verification method formatting, and service denormalization.
738
+ *
739
+ * @param protobufDidDocument - Protobuf DID document to convert
740
+ * @returns Promise resolving to a spec-compliant DID document
741
+ */
742
+ static async toSpecCompliantPayload(protobufDidDocument) {
743
+ const verificationMethod = protobufDidDocument.verificationMethod.map((vm) => {
744
+ switch (vm.verificationMethodType) {
745
+ case VerificationMethods.Ed255192020:
746
+ if (!protobufDidDocument.context.includes(contexts.W3CSuiteEd255192020))
747
+ protobufDidDocument.context = [...protobufDidDocument.context, contexts.W3CSuiteEd255192020];
748
+ return {
749
+ id: vm.id,
750
+ type: vm.verificationMethodType,
751
+ controller: vm.controller,
752
+ publicKeyMultibase: vm.verificationMaterial,
753
+ };
754
+ case VerificationMethods.JWK:
755
+ if (!protobufDidDocument.context.includes(contexts.W3CSuiteJws2020))
756
+ protobufDidDocument.context = [...protobufDidDocument.context, contexts.W3CSuiteJws2020];
757
+ return {
758
+ id: vm.id,
759
+ type: vm.verificationMethodType,
760
+ controller: vm.controller,
761
+ publicKeyJwk: JSON.parse(vm.verificationMaterial),
762
+ };
763
+ case VerificationMethods.Ed255192018:
764
+ if (!protobufDidDocument.context.includes(contexts.W3CSuiteEd255192018))
765
+ protobufDidDocument.context = [...protobufDidDocument.context, contexts.W3CSuiteEd255192018];
766
+ return {
767
+ id: vm.id,
768
+ type: vm.verificationMethodType,
769
+ controller: vm.controller,
770
+ publicKeyBase58: vm.verificationMaterial,
771
+ };
772
+ default:
773
+ throw new Error('Unsupported verificationMethod type'); // should never happen
774
+ }
775
+ });
776
+ const service = denormalizeService(protobufDidDocument);
777
+ const context = (function () {
778
+ if (protobufDidDocument.context.includes(contexts.W3CDIDv1))
779
+ return protobufDidDocument.context;
780
+ return [contexts.W3CDIDv1, ...protobufDidDocument.context];
781
+ })();
782
+ const assertionMethod = protobufDidDocument.assertionMethod.map((am) => {
783
+ try {
784
+ // Check if the assertionMethod is a DID URL
785
+ if (!am.startsWith('did:cheqd:')) {
786
+ // Parse once if it's a stringified JSON
787
+ const parsedAm = JSON.parse(am);
788
+ if (typeof parsedAm === 'string') {
789
+ // Parse again only if necessary
790
+ return JSON.parse(parsedAm);
791
+ }
792
+ return parsedAm;
793
+ }
794
+ return am;
795
+ }
796
+ catch (error) {
797
+ throw new Error(`Unsupported assertionMethod type: ${am}`);
798
+ }
799
+ });
800
+ const specCompliant = {
801
+ '@context': context,
802
+ id: protobufDidDocument.id,
803
+ controller: protobufDidDocument.controller,
804
+ verificationMethod: verificationMethod,
805
+ authentication: protobufDidDocument.authentication,
806
+ assertionMethod: assertionMethod,
807
+ capabilityInvocation: protobufDidDocument.capabilityInvocation,
808
+ capabilityDelegation: protobufDidDocument.capabilityDelegation,
809
+ keyAgreement: protobufDidDocument.keyAgreement,
810
+ service: service,
811
+ alsoKnownAs: protobufDidDocument.alsoKnownAs,
812
+ };
813
+ if (!protobufDidDocument.authentication?.length)
814
+ delete specCompliant.authentication;
815
+ if (!protobufDidDocument.assertionMethod?.length)
816
+ delete specCompliant.assertionMethod;
817
+ if (!protobufDidDocument.capabilityInvocation?.length)
818
+ delete specCompliant.capabilityInvocation;
819
+ if (!protobufDidDocument.capabilityDelegation?.length)
820
+ delete specCompliant.capabilityDelegation;
821
+ if (!protobufDidDocument.keyAgreement?.length)
822
+ delete specCompliant.keyAgreement;
823
+ if (!protobufDidDocument.service?.length)
824
+ delete specCompliant.service;
825
+ if (!protobufDidDocument.alsoKnownAs?.length)
826
+ delete specCompliant.alsoKnownAs;
827
+ return specCompliant;
828
+ }
829
+ /**
830
+ * Converts protobuf metadata to specification-compliant DID document metadata format.
831
+ * Handles date formatting and optional field normalization.
832
+ *
833
+ * @param protobufDidDocument - Protobuf metadata to convert
834
+ * @returns Promise resolving to spec-compliant DID document metadata
835
+ */
836
+ static async toSpecCompliantMetadata(protobufDidDocument) {
837
+ return {
838
+ created: protobufDidDocument.created?.toISOString(),
839
+ updated: protobufDidDocument.updated?.toISOString(),
840
+ deactivated: protobufDidDocument.deactivated,
841
+ versionId: protobufDidDocument.versionId,
842
+ nextVersionId: protobufDidDocument?.nextVersionId,
843
+ previousVersionId: protobufDidDocument?.previousVersionId,
844
+ };
845
+ }
846
+ /**
847
+ * Validates that provided signatures match the authentication requirements in a DID document.
848
+ * Checks signature count, authentication presence, and controller authorization.
849
+ *
850
+ * @param didDocument - DID document containing authentication requirements
851
+ * @param signatures - Array of signatures to validate against authentication
852
+ * @param querier - Optional querier for retrieving external controller documents
853
+ * @param externalControllersDidDocuments - Optional pre-loaded external controller documents
854
+ * @returns Promise resolving to validation result with error details if invalid
855
+ */
856
+ static async validateAuthenticationAgainstSignatures(didDocument, signatures, querier, externalControllersDidDocuments) {
857
+ // validate signatures - case: no signatures
858
+ if (!signatures || !signatures.length)
859
+ return { valid: false, error: 'signatures are required' };
860
+ // validate authentication - case: no authentication when at least one verificationMethod
861
+ if ((!didDocument.authentication || !didDocument.authentication.length) &&
862
+ didDocument.verificationMethod?.length)
863
+ return { valid: false, error: 'authentication is required' };
864
+ const normalizedAuthentication = normalizeAuthentication(didDocument);
865
+ // define unique authentication
866
+ const uniqueAuthentication = new Set(normalizedAuthentication);
867
+ // validate authentication - case: authentication contains duplicates
868
+ if (uniqueAuthentication.size < normalizedAuthentication.length)
869
+ return {
870
+ valid: false,
871
+ error: `authentication contains duplicate key references: duplicate key reference ${Array.from(uniqueAuthentication).find((a) => normalizeAuthentication(didDocument).filter((aa) => aa === a).length > 1)}`,
872
+ };
873
+ // define unique signatures - shallow, only verificationMethodId, no signature
874
+ const uniqueSignatures = new Set(signatures.map((s) => s.verificationMethodId));
875
+ // validate signatures - case: signatures contain duplicates
876
+ if (uniqueSignatures.size < signatures.length)
877
+ return {
878
+ valid: false,
879
+ error: `signatures contain duplicates: duplicate signature for key reference ${Array.from(uniqueSignatures).find((s) => signatures.filter((ss) => ss.verificationMethodId === s).length > 1)}`,
880
+ };
881
+ // validate authentication - case: authentication contains invalid key references
882
+ if (!Array.from(uniqueAuthentication).every((a) => didDocument.verificationMethod?.some((vm) => vm.id === a)))
883
+ return {
884
+ valid: false,
885
+ error: `authentication contains invalid key references: invalid key reference ${Array.from(uniqueAuthentication).find((a) => !didDocument.verificationMethod?.some((vm) => vm.id === a))}`,
886
+ };
887
+ // define whether external controller or not
888
+ const externalController = normalizeController(didDocument).some((c) => c !== didDocument.id);
889
+ // validate authentication - case: authentication matches signatures, unique, if no external controller
890
+ if (!Array.from(uniqueAuthentication).every((a) => uniqueSignatures.has(a)) && !externalController)
891
+ return {
892
+ valid: false,
893
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueAuthentication).find((a) => !uniqueSignatures.has(a))} is missing`,
894
+ };
895
+ // validate signatures - case: authentication matches signatures, unique, excessive signatures, no external controller
896
+ if (!Array.from(uniqueSignatures).every((s) => uniqueAuthentication.has(s)) && !externalController)
897
+ return {
898
+ valid: false,
899
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueSignatures).find((s) => !uniqueAuthentication.has(s))} is not required`,
900
+ };
901
+ // return, if no external controller
902
+ if (!externalController)
903
+ return { valid: true };
904
+ // require querier
905
+ if (!querier)
906
+ throw new Error('querier is required for external controller validation');
907
+ // get external controllers
908
+ const externalControllers = normalizeController(didDocument).filter((c) => c !== didDocument.id);
909
+ // get external controllers' documents
910
+ const externalControllersDocuments = await Promise.all(externalControllers?.map(async (c) => {
911
+ // compute index of external controller's document, if provided
912
+ const externalControllerDocumentIndex = externalControllersDidDocuments?.findIndex((d) => d.id === c);
913
+ // get external controller's document, if provided
914
+ if (externalControllerDocumentIndex !== undefined && externalControllerDocumentIndex !== -1)
915
+ return externalControllersDidDocuments?.[externalControllerDocumentIndex];
916
+ // fetch external controller's document
917
+ const protobufDocument = await querier[defaultDidExtensionKey].didDoc(c);
918
+ // throw, if not found
919
+ if (!protobufDocument || !protobufDocument.didDoc)
920
+ throw new Error(`Document for controller ${c} not found`);
921
+ // convert to spec compliant payload
922
+ return await DIDModule.toSpecCompliantPayload(protobufDocument.didDoc);
923
+ }));
924
+ // define unique required signatures
925
+ const uniqueRequiredSignatures = new Set(externalControllersDocuments.concat(didDocument).flatMap((d) => (d ? normalizeAuthentication(d) : [])));
926
+ // validate authentication - case: authentication matches signatures, unique, if external controller
927
+ if (!Array.from(uniqueRequiredSignatures).every((a) => uniqueSignatures.has(a)))
928
+ return {
929
+ valid: false,
930
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueRequiredSignatures).find((a) => !uniqueSignatures.has(a))} is missing`,
931
+ };
932
+ // validate authentication - case: authentication matches signatures, unique, excessive signatures, if external controller
933
+ if (uniqueRequiredSignatures.size < uniqueSignatures.size)
934
+ return {
935
+ valid: false,
936
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueSignatures).find((s) => !uniqueRequiredSignatures.has(s))} is not required`,
937
+ };
938
+ // return valid
939
+ return { valid: true };
940
+ }
941
+ /**
942
+ * Validates authentication against signatures for key rotation scenarios.
943
+ * Handles validation during DID document updates where keys may have changed.
944
+ *
945
+ * @param didDocument - Updated DID document to validate
946
+ * @param signatures - Array of signatures to validate
947
+ * @param querier - Querier for retrieving previous DID document and controllers
948
+ * @param previousDidDocument - Optional previous version of the DID document
949
+ * @param externalControllersDidDocuments - Optional pre-loaded external controller documents
950
+ * @returns Promise resolving to validation result with controller documents and previous document
951
+ */
952
+ static async validateAuthenticationAgainstSignaturesKeyRotation(didDocument, signatures, querier, previousDidDocument, externalControllersDidDocuments) {
953
+ // validate signatures - case: no signatures
954
+ if (!signatures || !signatures.length)
955
+ return { valid: false, error: 'signatures are required' };
956
+ // validate authentication - case: no authentication when at least one verificationMethod
957
+ if ((!didDocument.authentication || !didDocument.authentication.length) &&
958
+ didDocument.verificationMethod?.length)
959
+ return { valid: false, error: 'authentication is required' };
960
+ // define unique authentication
961
+ const authentication = normalizeAuthentication(didDocument);
962
+ const uniqueAuthentication = new Set(authentication);
963
+ // validate authentication - case: authentication contains duplicates
964
+ if (uniqueAuthentication.size < authentication.length)
965
+ return {
966
+ valid: false,
967
+ error: `authentication contains duplicate key references: duplicate key reference ${Array.from(uniqueAuthentication).find((a) => normalizeAuthentication(didDocument).filter((aa) => aa === a).length > 1)}`,
968
+ };
969
+ // define unique signatures
970
+ const uniqueSignatures = new Set(signatures.map((s) => s.verificationMethodId));
971
+ // validate authentication - case: authentication contains invalid key references
972
+ if (!Array.from(uniqueAuthentication).every((a) => didDocument.verificationMethod?.some((vm) => vm.id === a)))
973
+ return {
974
+ valid: false,
975
+ error: `authentication contains invalid key references: invalid key reference ${Array.from(uniqueAuthentication).find((a) => !didDocument.verificationMethod?.some((vm) => vm.id === a))}`,
976
+ };
977
+ // lookup previous document
978
+ if (!previousDidDocument) {
979
+ // get previous document
980
+ const previousDocument = await querier[defaultDidExtensionKey].didDoc(didDocument.id);
981
+ // throw, if not found
982
+ if (!previousDocument || !previousDocument.didDoc)
983
+ throw new Error('Previous did document not found');
984
+ previousDidDocument = await DIDModule.toSpecCompliantPayload(previousDocument.didDoc);
985
+ }
986
+ const controllers = normalizeController(didDocument);
987
+ const previousControllers = normalizeController(previousDidDocument);
988
+ // define whether external controller or not
989
+ const externalController = controllers.concat(previousControllers).some((c) => c !== didDocument.id);
990
+ // define whether key rotation or not (same ID, different material)
991
+ const keyRotation = !!didDocument.verificationMethod?.some((vm) => previousDidDocument?.verificationMethod?.some((pvm) => pvm.id === vm.id &&
992
+ (pvm.publicKeyBase58 !== vm.publicKeyBase58 ||
993
+ pvm.publicKeyMultibase !== vm.publicKeyMultibase ||
994
+ pvm.publicKeyJwk?.x !== vm.publicKeyJwk?.x)));
995
+ // define whether key replacement or not (different IDs in authentication)
996
+ const currentAuthenticationIds = new Set(normalizeAuthentication(didDocument));
997
+ const previousAuthenticationIds = new Set(normalizeAuthentication(previousDidDocument));
998
+ const removedKeys = Array.from(previousAuthenticationIds).filter((id) => !currentAuthenticationIds.has(id));
999
+ const addedKeys = Array.from(currentAuthenticationIds).filter((id) => !previousAuthenticationIds.has(id));
1000
+ const keyReplacement = removedKeys.length > 0 && addedKeys.length > 0;
1001
+ // define controller rotation
1002
+ const controllerRotation = !controllers.every((c) => previousControllers.includes(c)) ||
1003
+ !previousControllers.every((c) => controllers.includes(c));
1004
+ // define rotated controllers
1005
+ const rotatedControllers = controllerRotation
1006
+ ? previousControllers.filter((c) => !controllers.includes(c))
1007
+ : [];
1008
+ // define unique union of authentication
1009
+ const previousAuthentication = normalizeAuthentication(previousDidDocument);
1010
+ const uniqueUnionAuthentication = new Set([...uniqueAuthentication, ...previousAuthentication]);
1011
+ // validate authentication - case: authentication matches signatures, unique, if no external controller, no key rotation, no key replacement
1012
+ if (!Array.from(uniqueUnionAuthentication).every((a) => uniqueSignatures.has(a)) &&
1013
+ !externalController &&
1014
+ !keyRotation &&
1015
+ !keyReplacement)
1016
+ return {
1017
+ valid: false,
1018
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueAuthentication).find((a) => !uniqueSignatures.has(a))} is missing`,
1019
+ };
1020
+ // define rotated keys
1021
+ const rotatedKeys = keyRotation
1022
+ ? didDocument.verificationMethod?.filter((vm) => previousDidDocument?.verificationMethod?.some((pvm) => pvm.id === vm.id &&
1023
+ (pvm.publicKeyBase58 !== vm.publicKeyBase58 ||
1024
+ pvm.publicKeyMultibase !== vm.publicKeyMultibase ||
1025
+ pvm.publicKeyJwk?.x !== vm.publicKeyJwk?.x)))
1026
+ : [];
1027
+ // define unique union of signatures required, including key replacement logic
1028
+ let uniqueUnionSignaturesRequired = new Set();
1029
+ if (keyRotation && keyReplacement) {
1030
+ // Combined operation: Both key rotation AND key replacement happening
1031
+ // Need signatures from:
1032
+ // 1. All rotated keys (both old and new material for same ID)
1033
+ // 2. All added keys (new keys being added)
1034
+ // 3. All removed keys (old keys being removed)
1035
+ const rotatedKeySignatures = authentication
1036
+ .filter((a) => rotatedKeys?.find((rk) => a === rk.id))
1037
+ .map((a) => `${a}(document0)`);
1038
+ const previousRotatedKeySignatures = previousAuthentication
1039
+ .filter((a) => rotatedKeys?.find((rk) => a === rk.id))
1040
+ .map((a) => `${a}(document1)`);
1041
+ const newKeySignatures = addedKeys
1042
+ .filter((keyId) => !rotatedKeys?.find((rk) => keyId === rk.id))
1043
+ .map((keyId) => `${keyId}(document0)`);
1044
+ const oldKeySignatures = removedKeys
1045
+ .filter((keyId) => previousAuthentication.includes(keyId))
1046
+ .map((keyId) => `${keyId}(document1)`);
1047
+ uniqueUnionSignaturesRequired = new Set([
1048
+ ...rotatedKeySignatures,
1049
+ ...previousRotatedKeySignatures,
1050
+ ...newKeySignatures,
1051
+ ...oldKeySignatures,
1052
+ ]);
1053
+ }
1054
+ else if (keyRotation) {
1055
+ // Key rotation only (same ID, different material)
1056
+ uniqueUnionSignaturesRequired = new Set([
1057
+ ...authentication.filter((a) => rotatedKeys?.find((rk) => a === rk.id)).map((a) => `${a}(document0)`),
1058
+ ...previousAuthentication.map((a) => `${a}(document1)`),
1059
+ ]);
1060
+ }
1061
+ else if (keyReplacement) {
1062
+ // Key replacement only (different IDs in authentication)
1063
+ // For key replacement, we need signatures from:
1064
+ // 1. The new keys (from current document)
1065
+ // 2. The old keys that are being replaced (from previous document)
1066
+ const newKeySignatures = addedKeys.map((keyId) => `${keyId}(document0)`);
1067
+ const oldKeySignatures = removedKeys
1068
+ .filter((keyId) => previousAuthentication.includes(keyId)) // Only if they were in authentication
1069
+ .map((keyId) => `${keyId}(document1)`);
1070
+ uniqueUnionSignaturesRequired = new Set([...newKeySignatures, ...oldKeySignatures]);
1071
+ }
1072
+ else {
1073
+ // No rotation or replacement
1074
+ uniqueUnionSignaturesRequired = new Set([...authentication.map((a) => `${a}(document0)`)]);
1075
+ }
1076
+ // define frequency of unique union of signatures required
1077
+ const uniqueUnionSignaturesRequiredFrequency = new Map([...uniqueUnionSignaturesRequired].map((s) => [s.replace(new RegExp(/\(document\d+\)/), ''), 0]));
1078
+ // count frequency of unique union of signatures required
1079
+ uniqueUnionSignaturesRequired.forEach((s) => {
1080
+ // define key
1081
+ const key = s.replace(new RegExp(/\(document\d+\)/), '');
1082
+ // increment frequency
1083
+ uniqueUnionSignaturesRequiredFrequency.set(key, uniqueUnionSignaturesRequiredFrequency.get(key) + 1);
1084
+ });
1085
+ // define frequency of signatures provided
1086
+ const uniqueSignaturesFrequency = new Map(signatures.map((s) => [s.verificationMethodId, 0]));
1087
+ // count frequency of signatures provided
1088
+ signatures.forEach((s) => {
1089
+ // increment frequency
1090
+ uniqueSignaturesFrequency.set(s.verificationMethodId, uniqueSignaturesFrequency.get(s.verificationMethodId) + 1);
1091
+ });
1092
+ // validate signatures - case: authentication matches signatures, unique, excessive signatures, no external controller
1093
+ if (Array.from(uniqueSignaturesFrequency).filter(([k, f]) => uniqueUnionSignaturesRequiredFrequency.get(k) === undefined ||
1094
+ (uniqueUnionSignaturesRequiredFrequency.get(k) &&
1095
+ uniqueUnionSignaturesRequiredFrequency.get(k) < f)).length &&
1096
+ !externalController)
1097
+ return {
1098
+ valid: false,
1099
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueSignaturesFrequency).find(([k, f]) => uniqueUnionSignaturesRequiredFrequency.get(k) === undefined || uniqueUnionSignaturesRequiredFrequency.get(k) < f)?.[0]} is not required`,
1100
+ };
1101
+ // validate signatures - case: authentication matches signatures, unique, missing signatures, no external controller
1102
+ if (Array.from(uniqueSignaturesFrequency).filter(([k, f]) => uniqueUnionSignaturesRequiredFrequency.get(k) && uniqueUnionSignaturesRequiredFrequency.get(k) > f).length &&
1103
+ !externalController)
1104
+ return {
1105
+ valid: false,
1106
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueSignaturesFrequency).find(([k, f]) => uniqueUnionSignaturesRequiredFrequency.get(k) > f)?.[0]} is missing`,
1107
+ };
1108
+ // validate signatures - case: all required keys must have signatures provided (check for completely missing keys)
1109
+ if (!externalController) {
1110
+ const missingKeys = Array.from(uniqueUnionSignaturesRequiredFrequency.keys()).filter((requiredKey) => !uniqueSignaturesFrequency.has(requiredKey));
1111
+ if (missingKeys.length > 0) {
1112
+ return {
1113
+ valid: false,
1114
+ error: `authentication does not match signatures: signature from key ${missingKeys[0]} is missing`,
1115
+ };
1116
+ }
1117
+ }
1118
+ // require querier
1119
+ if (!querier)
1120
+ throw new Error('querier is required for external controller validation');
1121
+ // get external controllers
1122
+ // Only include rotated controllers if they are external (not the current DID itself)
1123
+ const externalRotatedControllers = rotatedControllers.filter((c) => c !== didDocument.id);
1124
+ const externalControllers = controllers?.filter((c) => c !== didDocument.id).concat(externalRotatedControllers);
1125
+ // get external controllers' documents
1126
+ const externalControllersDocuments = await Promise.all(externalControllers?.map(async (c) => {
1127
+ // compute index of external controller's document, if provided
1128
+ const externalControllerDocumentIndex = externalControllersDidDocuments?.findIndex((d) => d.id === c);
1129
+ // get external controller's document, if provided
1130
+ if (externalControllerDocumentIndex !== undefined && externalControllerDocumentIndex !== -1)
1131
+ return externalControllersDidDocuments[externalControllerDocumentIndex];
1132
+ // fetch external controller's document
1133
+ const protobufDocument = await querier[defaultDidExtensionKey].didDoc(c);
1134
+ // throw, if not found
1135
+ if (!protobufDocument || !protobufDocument.didDoc)
1136
+ throw new Error(`Document for controller ${c} not found`);
1137
+ // convert to spec compliant payload
1138
+ return await DIDModule.toSpecCompliantPayload(protobufDocument.didDoc);
1139
+ }));
1140
+ // define unique required signatures, delimited, with external controllers
1141
+ const uniqueUnionSignaturesRequiredWithExternalControllers = new Set([
1142
+ ...uniqueUnionSignaturesRequired,
1143
+ ...externalControllersDocuments
1144
+ .flatMap((d) => normalizeAuthentication(d))
1145
+ .map((a) => `${a}(document${externalControllersDocuments.findIndex((d) => normalizeAuthentication(d).includes(a))})`),
1146
+ ]);
1147
+ // add rotated controller keys to unique required signatures, if any
1148
+ if (controllerRotation) {
1149
+ // walk through rotated controllers
1150
+ rotatedControllers.forEach((c) => {
1151
+ // get rotated controller's document index
1152
+ const rotatedControllerDocumentIndex = externalControllersDocuments.findIndex((d) => d?.id === c);
1153
+ // early return, if no document
1154
+ if (rotatedControllerDocumentIndex === -1)
1155
+ return;
1156
+ // get rotated controller's document
1157
+ const rotatedControllerDocument = externalControllersDocuments[rotatedControllerDocumentIndex];
1158
+ // add rotated controller's authentication to unique required signatures
1159
+ rotatedControllerDocument.authentication?.forEach((a) => uniqueUnionSignaturesRequiredWithExternalControllers.add(`${a}(document${rotatedControllerDocumentIndex})`));
1160
+ });
1161
+ }
1162
+ // define frequency of unique union of signatures required, with external controllers
1163
+ const uniqueUnionSignaturesRequiredWithExternalControllersFrequency = new Map([...uniqueUnionSignaturesRequiredWithExternalControllers].map((s) => [
1164
+ s.replace(new RegExp(/\(document\d+\)/), ''),
1165
+ 0,
1166
+ ]));
1167
+ // count frequency of unique union of signatures required, with external controllers
1168
+ uniqueUnionSignaturesRequiredWithExternalControllers.forEach((s) => {
1169
+ // define key
1170
+ const key = s.replace(new RegExp(/\(document\d+\)/), '');
1171
+ // increment frequency
1172
+ uniqueUnionSignaturesRequiredWithExternalControllersFrequency.set(key, uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(key) + 1);
1173
+ });
1174
+ // define frequency of signatures provided, with external controllers
1175
+ const uniqueSignaturesFrequencyWithExternalControllers = new Map(signatures.map((s) => [s.verificationMethodId, 0]));
1176
+ // count frequency of signatures provided, with external controllers
1177
+ signatures.forEach((s) => {
1178
+ // increment frequency
1179
+ uniqueSignaturesFrequencyWithExternalControllers.set(s.verificationMethodId, uniqueSignaturesFrequencyWithExternalControllers.get(s.verificationMethodId) + 1);
1180
+ });
1181
+ // validate signatures - case: authentication matches signatures, unique, excessive signatures, with external controllers
1182
+ if (Array.from(uniqueSignaturesFrequencyWithExternalControllers).filter(([k, f]) => uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) === undefined ||
1183
+ (uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) &&
1184
+ uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) < f)).length &&
1185
+ externalController)
1186
+ return {
1187
+ valid: false,
1188
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueSignaturesFrequencyWithExternalControllers).find(([k, f]) => uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) === undefined || uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) < f)?.[0]} is not required`,
1189
+ };
1190
+ // validate signatures - case: authentication matches signatures, unique, missing signatures, with external controllers
1191
+ if (Array.from(uniqueSignaturesFrequencyWithExternalControllers).filter(([k, f]) => uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) &&
1192
+ uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) > f).length &&
1193
+ externalController)
1194
+ return {
1195
+ valid: false,
1196
+ error: `authentication does not match signatures: signature from key ${Array.from(uniqueSignaturesFrequencyWithExternalControllers).find(([k, f]) => uniqueUnionSignaturesRequiredWithExternalControllersFrequency.get(k) > f)?.[0]} is missing`,
1197
+ };
1198
+ // return valid
1199
+ return { valid: true, previousDidDocument, externalControllersDocuments };
1200
+ }
1201
+ /**
1202
+ * Generates standard fees for creating a DID document.
1203
+ *
1204
+ * @param feePayer - Address of the account that will pay the transaction fees
1205
+ * @param granter - Optional address of the account granting fee payment permissions
1206
+ * @returns Promise resolving to the fee configuration for DID document creation
1207
+ */
1208
+ static async generateCreateDidDocFees(feePayer, granter) {
1209
+ return {
1210
+ amount: [DIDModule.fees.DefaultCreateDidDocFee],
1211
+ gas: '360000',
1212
+ payer: feePayer,
1213
+ granter: granter,
1214
+ };
1215
+ }
1216
+ /**
1217
+ * Generates fee configuration for DID document update transactions.
1218
+ * Uses default update fees and gas requirements.
1219
+ *
1220
+ * @param feePayer - Address of the account that will pay the transaction fees
1221
+ * @param granter - Optional address of the account granting fee payment permissions
1222
+ * @returns Promise resolving to the fee configuration for DID document updates
1223
+ */
1224
+ static async generateUpdateDidDocFees(feePayer, granter) {
1225
+ return {
1226
+ amount: [DIDModule.fees.DefaultUpdateDidDocFee],
1227
+ gas: '360000',
1228
+ payer: feePayer,
1229
+ granter: granter,
1230
+ };
1231
+ }
1232
+ /**
1233
+ * Generates fee configuration for DID document deactivation transactions.
1234
+ * Uses default deactivation fees and gas requirements.
1235
+ *
1236
+ * @param feePayer - Address of the account that will pay the transaction fees
1237
+ * @param granter - Optional address of the account granting fee payment permissions
1238
+ * @returns Promise resolving to the fee configuration for DID document deactivation
1239
+ */
1240
+ static async generateDeactivateDidDocFees(feePayer, granter) {
1241
+ return {
1242
+ amount: [DIDModule.fees.DefaultDeactivateDidDocFee],
1243
+ gas: '360000',
1244
+ payer: feePayer,
1245
+ granter: granter,
1246
+ };
1247
+ }
1248
+ }
1249
+ //# sourceMappingURL=did.js.map