@cheqd/did-provider-cheqd 3.2.0 → 3.3.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.
- package/build/cjs/agent/ICheqd.d.ts +513 -14
- package/build/cjs/agent/ICheqd.d.ts.map +1 -1
- package/build/cjs/agent/ICheqd.js +1446 -5
- package/build/cjs/agent/ICheqd.js.map +1 -1
- package/build/cjs/did-manager/cheqd-did-provider.d.ts +26 -7
- package/build/cjs/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/cjs/did-manager/cheqd-did-provider.js +30 -8
- package/build/cjs/did-manager/cheqd-did-provider.js.map +1 -1
- package/build/cjs/did-manager/cheqd-did-resolver.d.ts +5 -0
- package/build/cjs/did-manager/cheqd-did-resolver.d.ts.map +1 -1
- package/build/cjs/did-manager/cheqd-did-resolver.js +7 -2
- package/build/cjs/did-manager/cheqd-did-resolver.js.map +1 -1
- package/build/cjs/dkg-threshold/lit-protocol.d.ts +92 -0
- package/build/cjs/dkg-threshold/lit-protocol.d.ts.map +1 -0
- package/build/cjs/dkg-threshold/lit-protocol.js +170 -0
- package/build/cjs/dkg-threshold/lit-protocol.js.map +1 -0
- package/build/cjs/global.d..d.ts +2 -0
- package/build/cjs/global.d..d.ts.map +1 -0
- package/build/cjs/global.d..js +2 -0
- package/build/cjs/global.d..js.map +1 -0
- package/build/cjs/index.js +1 -2
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/utils/env.d.ts +7 -0
- package/build/cjs/utils/env.d.ts.map +1 -0
- package/build/cjs/utils/env.js +10 -0
- package/build/cjs/utils/env.js.map +1 -0
- package/build/cjs/utils/helpers.d.ts +12 -0
- package/build/cjs/utils/helpers.d.ts.map +1 -0
- package/build/cjs/utils/helpers.js +63 -0
- package/build/cjs/utils/helpers.js.map +1 -0
- package/build/esm/agent/ICheqd.d.ts +513 -14
- package/build/esm/agent/ICheqd.d.ts.map +1 -1
- package/build/esm/agent/ICheqd.js +1446 -5
- package/build/esm/agent/ICheqd.js.map +1 -1
- package/build/esm/did-manager/cheqd-did-provider.d.ts +26 -7
- package/build/esm/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/esm/did-manager/cheqd-did-provider.js +29 -7
- package/build/esm/did-manager/cheqd-did-provider.js.map +1 -1
- package/build/esm/did-manager/cheqd-did-resolver.d.ts +5 -0
- package/build/esm/did-manager/cheqd-did-resolver.d.ts.map +1 -1
- package/build/esm/did-manager/cheqd-did-resolver.js +6 -1
- package/build/esm/did-manager/cheqd-did-resolver.js.map +1 -1
- package/build/esm/dkg-threshold/lit-protocol.d.ts +92 -0
- package/build/esm/dkg-threshold/lit-protocol.d.ts.map +1 -0
- package/build/esm/dkg-threshold/lit-protocol.js +166 -0
- package/build/esm/dkg-threshold/lit-protocol.js.map +1 -0
- package/build/esm/global.d..d.ts +2 -0
- package/build/esm/global.d..d.ts.map +1 -0
- package/build/esm/global.d..js +2 -0
- package/build/esm/global.d..js.map +1 -0
- package/build/esm/index.js +1 -1
- package/build/esm/index.js.map +1 -1
- package/build/esm/utils/env.d.ts +7 -0
- package/build/esm/utils/env.d.ts.map +1 -0
- package/build/esm/utils/env.js +7 -0
- package/build/esm/utils/env.js.map +1 -0
- package/build/esm/utils/helpers.d.ts +12 -0
- package/build/esm/utils/helpers.d.ts.map +1 -0
- package/build/esm/utils/helpers.js +51 -0
- package/build/esm/utils/helpers.js.map +1 -0
- package/build/tsconfig.cjs.tsbuildinfo +1 -1
- package/build/tsconfig.esm.tsbuildinfo +1 -1
- package/build/tsconfig.types.tsbuildinfo +1 -1
- package/build/types/agent/ICheqd.d.ts +513 -14
- package/build/types/agent/ICheqd.d.ts.map +1 -1
- package/build/types/did-manager/cheqd-did-provider.d.ts +26 -7
- package/build/types/did-manager/cheqd-did-provider.d.ts.map +1 -1
- package/build/types/did-manager/cheqd-did-resolver.d.ts +5 -0
- package/build/types/did-manager/cheqd-did-resolver.d.ts.map +1 -1
- package/build/types/dkg-threshold/lit-protocol.d.ts +92 -0
- package/build/types/dkg-threshold/lit-protocol.d.ts.map +1 -0
- package/build/types/global.d..d.ts +2 -0
- package/build/types/global.d..d.ts.map +1 -0
- package/build/types/utils/env.d.ts +7 -0
- package/build/types/utils/env.d.ts.map +1 -0
- package/build/types/utils/helpers.d.ts +12 -0
- package/build/types/utils/helpers.d.ts.map +1 -0
- package/package.json +13 -7
- package/src/agent/ICheqd.ts +2209 -232
- package/src/did-manager/cheqd-did-provider.ts +55 -8
- package/src/did-manager/cheqd-did-resolver.ts +7 -1
- package/src/dkg-threshold/lit-protocol.ts +238 -0
- package/src/global.d..ts +1 -0
- package/src/utils/env.ts +6 -0
- package/src/utils/helpers.ts +66 -0
- package/tsconfig.json +1 -0
package/src/agent/ICheqd.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
import {
|
|
6
6
|
CheqdNetwork,
|
|
7
7
|
DIDDocument,
|
|
8
|
+
DidStdFee,
|
|
8
9
|
IKeyPair,
|
|
10
|
+
ISignInputs,
|
|
9
11
|
MethodSpecificIdAlgo,
|
|
10
12
|
VerificationMethods,
|
|
11
13
|
createDidPayload,
|
|
@@ -14,54 +16,412 @@ import {
|
|
|
14
16
|
createKeyPairHex,
|
|
15
17
|
createVerificationKeys
|
|
16
18
|
} from '@cheqd/sdk'
|
|
19
|
+
import {
|
|
20
|
+
Coin,
|
|
21
|
+
DeliverTxResponse
|
|
22
|
+
} from '@cosmjs/stargate'
|
|
17
23
|
import {
|
|
18
24
|
IAgentContext,
|
|
19
25
|
IKeyManager,
|
|
20
26
|
IAgentPlugin,
|
|
21
27
|
IPluginMethodMap,
|
|
22
28
|
IAgentPluginSchema,
|
|
23
|
-
IIdentifier
|
|
29
|
+
IIdentifier,
|
|
30
|
+
VerifiableCredential,
|
|
31
|
+
IVerifyCredentialArgs,
|
|
32
|
+
IVerifyResult,
|
|
33
|
+
VerifiablePresentation,
|
|
34
|
+
IVerifyPresentationArgs,
|
|
35
|
+
IError,
|
|
36
|
+
ICreateVerifiableCredentialArgs,
|
|
37
|
+
ICredentialIssuer,
|
|
38
|
+
IDIDManager,
|
|
39
|
+
IDataStore,
|
|
40
|
+
IResolver
|
|
24
41
|
} from '@veramo/core'
|
|
25
42
|
import {
|
|
26
43
|
CheqdDIDProvider,
|
|
27
44
|
LinkedResource,
|
|
28
|
-
TImportableEd25519Key
|
|
45
|
+
TImportableEd25519Key,
|
|
46
|
+
ResourcePayload,
|
|
47
|
+
StatusList2021ResourcePayload,
|
|
48
|
+
DefaultRESTUrls
|
|
29
49
|
} from '../did-manager/cheqd-did-provider.js'
|
|
30
50
|
import {
|
|
31
51
|
fromString,
|
|
32
52
|
toString
|
|
33
53
|
} from 'uint8arrays'
|
|
54
|
+
import { decodeJWT } from 'did-jwt'
|
|
55
|
+
import { StatusList } from '@digitalbazaar/vc-status-list'
|
|
34
56
|
import { v4 } from 'uuid'
|
|
35
57
|
import fs from 'fs'
|
|
36
58
|
import Debug from 'debug'
|
|
59
|
+
import {
|
|
60
|
+
CosmosAccessControlCondition,
|
|
61
|
+
LitCompatibleCosmosChain,
|
|
62
|
+
LitCompatibleCosmosChains,
|
|
63
|
+
LitNetwork,
|
|
64
|
+
LitProtocol,
|
|
65
|
+
TxNonceFormat
|
|
66
|
+
} from '../dkg-threshold/lit-protocol.js';
|
|
67
|
+
import { blobToHexString, randomFromRange, toBlob, unescapeUnicode } from '../utils/helpers.js'
|
|
68
|
+
import { resolverUrl } from '../did-manager/cheqd-did-resolver.js'
|
|
37
69
|
|
|
38
70
|
const debug = Debug('veramo:did-provider-cheqd')
|
|
39
71
|
|
|
40
|
-
type IContext = IAgentContext<IKeyManager>
|
|
41
|
-
type TExportedDIDDocWithKeys = { didDoc: DIDDocument, keys: TImportableEd25519Key[], versionId?: string }
|
|
42
|
-
type TExportedDIDDocWithLinkedResourceWithKeys = TExportedDIDDocWithKeys & { linkedResource: LinkedResource }
|
|
72
|
+
export type IContext = IAgentContext<IDIDManager & IKeyManager & IDataStore & IResolver & ICredentialIssuer & ICheqd>
|
|
73
|
+
export type TExportedDIDDocWithKeys = { didDoc: DIDDocument, keys: TImportableEd25519Key[], versionId?: string }
|
|
74
|
+
export type TExportedDIDDocWithLinkedResourceWithKeys = TExportedDIDDocWithKeys & { linkedResource: LinkedResource }
|
|
75
|
+
export type LinkedResourceMetadataResolutionResult = { resourceURI: string, resourceCollectionId: string, resourceId: string, resourceName: string, resourceType: string, mediaType: string, resourceVersion?: string, created: string, checksum: string, previousVersionId: string | null, nextVersionId: string | null }
|
|
76
|
+
export type DIDMetadataDereferencingResult = { '@context': 'https://w3id.org/did-resolution/v1', dereferencingMetadata: { contentType: string, retrieved: string, did: { didString: string, methodSpecificId: string, method: string } }, contentStream: { created: string, versionId: string, linkedResourceMetadata: LinkedResourceMetadataResolutionResult[] }, contentMetadata: Record<string, any> }
|
|
77
|
+
export type ShallowTypedTx = { body: { messages: any[], memo: string, timeout_height: string, extension_options: any[], non_critical_extension_options: any[] }, auth_info: { signer_infos: { public_key: { '@type': string, key: string }, mode_info: { single: { mode: string } }, sequence: string }[], fee: { amount: Coin[], gas_limit: string, payer: string, granter: string }, tip: any | null }, signatures: string[] }
|
|
78
|
+
export type ShallowTypedTxTxResponses = { height: string, txhash: string, codespace: string, code: number, data: string, raw_log: string, logs: any[], info: string, gas_wanted: string, gas_used: string, tx: ShallowTypedTx, timestamp: string, events: any[] }
|
|
79
|
+
export type ShallowTypedTxsResponse = { txs: ShallowTypedTx[], tx_responses: ShallowTypedTxTxResponses[], pagination: string | null, total: string } | undefined
|
|
80
|
+
export type VerificationResult = { verified: boolean, revoked?: boolean, suspended?: boolean, error?: IVerifyResult['error'] }
|
|
81
|
+
export type StatusCheckResult = { revoked?: boolean, suspended?: boolean, error?: IError }
|
|
82
|
+
export type RevocationResult = { revoked: boolean, error?: IError, statusList?: Bitstring, encryptedStatusList?: string, encryptedSymmetricKey?: string, symmetricKey?: string, published?: boolean, resourceMetadata?: LinkedResourceMetadataResolutionResult }
|
|
83
|
+
export type SuspensionResult = { suspended: boolean, error?: IError, statusList?: Bitstring, encryptedStatusList?: string, encryptedSymmetricKey?: string, symmetricKey?: string, published?: boolean, resourceMetadata?: LinkedResourceMetadataResolutionResult }
|
|
84
|
+
export type UnsuspensionResult = { unsuspended: boolean, error?: IError, statusList?: Bitstring, encryptedStatusList?: string, encryptedSymmetricKey?: string, symmetricKey?: string, published?: boolean, resourceMetadata?: LinkedResourceMetadataResolutionResult }
|
|
85
|
+
export type Bitstring = string
|
|
86
|
+
export type AccessControlConditionType = typeof AccessControlConditionTypes[keyof typeof AccessControlConditionTypes]
|
|
87
|
+
export type AccessControlConditionReturnValueComparator = typeof AccessControlConditionReturnValueComparators[keyof typeof AccessControlConditionReturnValueComparators]
|
|
88
|
+
export type AccessControlConditionMemoNonceArgs = { senderAddressObserved: string, recipientAddressObserved: string, amountObserved: string, specificNonce?: string, nonceFormat?: TxNonceFormat, type: Extract<AccessControlConditionType, 'memoNonce'> }
|
|
89
|
+
export type AccessControlConditionBalanceArgs = { addressObserved: string, amountObserved: string, comparator: AccessControlConditionReturnValueComparator, type: Extract<AccessControlConditionType, 'balance'>}
|
|
90
|
+
export type CreateEncryptedStatusList2021Result = { created: boolean, error?: Error, encryptedSymmetricKey: string, symmetricKey?: string, encryptedStatusList2021: string, unifiedAccessControlConditions: CosmosAccessControlCondition[] }
|
|
91
|
+
export type GenerateEncryptedStatusList2021Result = { encryptedSymmetricKey: string, encryptedStatusList2021: string, unifiedAccessControlConditions: CosmosAccessControlCondition[] }
|
|
92
|
+
export type TransactionResult = { successful: boolean, transactionHash?: string, events?: DeliverTxResponse['events'], rawLog?: string, txResponse?: DeliverTxResponse, error?: IError }
|
|
93
|
+
export type ObservationResult = { subscribed: boolean, meetsCondition: boolean, transactionHash?: string, events?: DeliverTxResponse['events'], rawLog?: string, txResponse?: ShallowTypedTxTxResponses, error?: IError }
|
|
94
|
+
|
|
95
|
+
export const AccessControlConditionTypes = { memoNonce: 'memoNonce', balance: 'balance' } as const
|
|
96
|
+
export const AccessControlConditionReturnValueComparators = { lessThan: '<', greaterThan: '>', equalTo: '=', lessThanOrEqualTo: '<=', greaterThanOrEqualTo: '>=' } as const
|
|
43
97
|
|
|
44
98
|
const CreateIdentifierMethodName = 'cheqdCreateIdentifier'
|
|
45
99
|
const UpdateIdentifierMethodName = 'cheqdUpdateIdentifier'
|
|
46
100
|
const DeactivateIdentifierMethodName = 'cheqdDeactivateIdentifier'
|
|
47
101
|
const CreateResourceMethodName = 'cheqdCreateLinkedResource'
|
|
102
|
+
const CreateStatusList2021MethodName = 'cheqdCreateStatusList2021'
|
|
103
|
+
const CreateEncryptedStatusList2021MethodName = 'cheqdCreateEncryptedStatusList2021'
|
|
48
104
|
const GenerateDidDocMethodName = 'cheqdGenerateDidDoc'
|
|
49
105
|
const GenerateDidDocWithLinkedResourceMethodName = 'cheqdGenerateDidDocWithLinkedResource'
|
|
50
106
|
const GenerateKeyPairMethodName = 'cheqdGenerateIdentityKeys'
|
|
51
107
|
const GenerateVersionIdMethodName = 'cheqdGenerateVersionId'
|
|
108
|
+
const GenerateStatusList2021MethodName = 'cheqdGenerateStatusList2021'
|
|
109
|
+
const GenerateEncryptedStatusList2021MethodName = 'cheqdGenerateEncryptedStatusList2021'
|
|
110
|
+
const IssueRevocableCredentialWithStatusList2021MethodName = 'cheqdIssueRevocableCredentialWithStatusList2021'
|
|
111
|
+
const IssueSuspendableCredentialWithStatusList2021MethodName = 'cheqdIssueSuspendableCredentialWithStatusList2021'
|
|
112
|
+
const VerifyCredentialMethodName = 'cheqdVerifyCredential'
|
|
113
|
+
const VerifyPresentationMethodName = 'cheqdVerifyPresentation'
|
|
114
|
+
const CheckCredentialStatusMethodName = 'cheqdCheckCredentialStatus'
|
|
115
|
+
const RevokeCredentialMethodName = 'cheqdRevokeCredential'
|
|
116
|
+
const RevokeCredentialsMethodName = 'cheqdRevokeCredentials'
|
|
117
|
+
const SuspendCredentialMethodName = 'cheqdSuspendCredential'
|
|
118
|
+
const SuspendCredentialsMethodName = 'cheqdSuspendCredentials'
|
|
119
|
+
const UnsuspendCredentialMethodName = 'cheqdUnsuspendCredential'
|
|
120
|
+
const UnsuspendCredentialsMethodName = 'cheqdUnsuspendCredentials'
|
|
121
|
+
const TransactVerifierPaysIssuerMethodName = 'cheqdTransactVerifierPaysIssuer'
|
|
122
|
+
const ObserveVerifierPaysIssuerMethodName = 'cheqdObserveVerifierPaysIssuer'
|
|
52
123
|
|
|
53
124
|
const DidPrefix = 'did'
|
|
54
125
|
const CheqdDidMethod = 'cheqd'
|
|
55
126
|
|
|
127
|
+
export interface ICheqdCreateIdentifierArgs {
|
|
128
|
+
kms: string
|
|
129
|
+
alias: string
|
|
130
|
+
document: DIDDocument
|
|
131
|
+
keys?: TImportableEd25519Key[]
|
|
132
|
+
versionId?: string
|
|
133
|
+
fee?: DidStdFee
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface ICheqdUpdateIdentifierArgs {
|
|
137
|
+
kms: string
|
|
138
|
+
document: DIDDocument
|
|
139
|
+
keys?: TImportableEd25519Key[]
|
|
140
|
+
versionId?: string
|
|
141
|
+
fee?: DidStdFee
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface ICheqdDeactivateIdentifierArgs {
|
|
145
|
+
kms: string
|
|
146
|
+
document: DIDDocument
|
|
147
|
+
keys?: TImportableEd25519Key[]
|
|
148
|
+
fee?: DidStdFee
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface ICheqdCreateLinkedResourceArgs {
|
|
152
|
+
kms: string
|
|
153
|
+
payload: ResourcePayload
|
|
154
|
+
network: CheqdNetwork
|
|
155
|
+
file?: string
|
|
156
|
+
signInputs?: ISignInputs[]
|
|
157
|
+
fee?: DidStdFee
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface ICheqdCreateStatusList2021Args {
|
|
161
|
+
kms: string
|
|
162
|
+
payload: StatusList2021ResourcePayload
|
|
163
|
+
network: CheqdNetwork
|
|
164
|
+
file?: string
|
|
165
|
+
signInputs?: ISignInputs[]
|
|
166
|
+
fee?: DidStdFee
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface ICheqdCreateEncryptedStatusList2021Args extends ICheqdCreateStatusList2021Args {
|
|
170
|
+
encryptionOptions: {
|
|
171
|
+
accessControlConditions: (AccessControlConditionMemoNonceArgs | AccessControlConditionBalanceArgs)[]
|
|
172
|
+
returnSymmetricKey?: boolean
|
|
173
|
+
}
|
|
174
|
+
bootstrapOptions: {
|
|
175
|
+
chain?: LitCompatibleCosmosChain,
|
|
176
|
+
litNetwork?: LitNetwork,
|
|
177
|
+
}
|
|
178
|
+
[key: string]: any
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface ICheqdGenerateDidDocArgs {
|
|
182
|
+
verificationMethod: VerificationMethods
|
|
183
|
+
methodSpecificIdAlgo: MethodSpecificIdAlgo
|
|
184
|
+
network: CheqdNetwork
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface ICheqdGenerateDidDocWithLinkedResourceArgs extends ICheqdGenerateDidDocArgs {
|
|
188
|
+
[key: string]: any
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface ICheqdGenerateKeyPairArgs {
|
|
192
|
+
[key: string]: any
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface ICheqdGenerateVersionIdArgs {
|
|
196
|
+
[key: string]: any
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface ICheqdGenerateStatusList2021Args {
|
|
200
|
+
length?: number
|
|
201
|
+
buffer?: Uint8Array
|
|
202
|
+
bitstringEncoding?: 'base64' | 'base64url' | 'hex'
|
|
203
|
+
[key: string]: any
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export interface ICheqdGenerateEncryptedStatusList2021Args extends ICheqdGenerateStatusList2021Args {
|
|
207
|
+
encryptionOptions: {
|
|
208
|
+
accessControlConditions: (AccessControlConditionMemoNonceArgs | AccessControlConditionBalanceArgs)[]
|
|
209
|
+
returnSymmetricKey?: boolean
|
|
210
|
+
}
|
|
211
|
+
bootstrapOptions: {
|
|
212
|
+
chain?: LitCompatibleCosmosChain,
|
|
213
|
+
litNetwork?: LitNetwork,
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface ICheqdIssueRevocableCredentialWithStatusList2021Args {
|
|
218
|
+
issuanceOptions: ICreateVerifiableCredentialArgs
|
|
219
|
+
statusOptions: {
|
|
220
|
+
statusPurpose: 'revocation'
|
|
221
|
+
statusListName: string
|
|
222
|
+
statusListIndex?: number
|
|
223
|
+
statusListVersion?: string
|
|
224
|
+
statusListRangeStart?: number
|
|
225
|
+
statusListRangeEnd?: number
|
|
226
|
+
indexNotIn?: number[]
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface ICheqdIssueSuspendableCredentialWithStatusList2021Args {
|
|
231
|
+
issuanceOptions: ICreateVerifiableCredentialArgs
|
|
232
|
+
statusOptions: {
|
|
233
|
+
statusPurpose: 'suspension'
|
|
234
|
+
statusListName: string
|
|
235
|
+
statusListIndex?: number
|
|
236
|
+
statusListVersion?: string
|
|
237
|
+
statusListRangeStart?: number
|
|
238
|
+
statusListRangeEnd?: number
|
|
239
|
+
indexNotIn?: number[]
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface ICheqdVerifyCredentialWithStatusList2021Args {
|
|
244
|
+
credential: VerifiableCredential
|
|
245
|
+
fetchList?: boolean
|
|
246
|
+
encryptedSymmetricKey?: string
|
|
247
|
+
options?: ICheqdStatusList2021Options
|
|
248
|
+
decryptionOptions: {
|
|
249
|
+
unifiedAccessControlConditions: CosmosAccessControlCondition[]
|
|
250
|
+
}
|
|
251
|
+
bootstrapOptions: {
|
|
252
|
+
chain?: LitCompatibleCosmosChain,
|
|
253
|
+
litNetwork?: LitNetwork,
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface ICheqdVerifyPresentationWithStatusList2021Args {
|
|
258
|
+
presentation: VerifiablePresentation
|
|
259
|
+
fetchList?: boolean
|
|
260
|
+
encryptedSymmetricKey?: string
|
|
261
|
+
options?: ICheqdStatusList2021Options
|
|
262
|
+
decryptionOptions: {
|
|
263
|
+
accessControlConditions: (AccessControlConditionMemoNonceArgs | AccessControlConditionBalanceArgs)[]
|
|
264
|
+
}
|
|
265
|
+
bootstrapOptions: {
|
|
266
|
+
chain?: LitCompatibleCosmosChain,
|
|
267
|
+
litNetwork?: LitNetwork,
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface ICheqdCheckCredentialStatusWithStatusList2021Args {
|
|
272
|
+
credential: VerifiableCredential
|
|
273
|
+
fetchList?: boolean
|
|
274
|
+
encryptedSymmetricKey?: string
|
|
275
|
+
options?: ICheqdStatusList2021Options
|
|
276
|
+
decryptionOptions: {
|
|
277
|
+
accessControlConditions: (AccessControlConditionMemoNonceArgs | AccessControlConditionBalanceArgs)[]
|
|
278
|
+
}
|
|
279
|
+
bootstrapOptions: {
|
|
280
|
+
chain?: LitCompatibleCosmosChain,
|
|
281
|
+
litNetwork?: LitNetwork,
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface ICheqdRevokeCredentialWithStatusList2021Args {
|
|
286
|
+
credential: VerifiableCredential
|
|
287
|
+
fetchList?: boolean
|
|
288
|
+
publish?: boolean
|
|
289
|
+
publishEncrypted?: boolean
|
|
290
|
+
symmetricKey?: string
|
|
291
|
+
writeToFile?: boolean
|
|
292
|
+
returnUpdatedStatusList?: boolean
|
|
293
|
+
returnUpdatedEncryptedStatusList?: boolean
|
|
294
|
+
returnEncryptedSymmetricKey?: boolean
|
|
295
|
+
returnSymmetricKey?: boolean
|
|
296
|
+
returnStatusListMetadata?: boolean
|
|
297
|
+
options?: ICheqdStatusList2021Options
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export interface ICheqdRevokeBulkCredentialsWithStatusList2021Args {
|
|
301
|
+
credentials: VerifiableCredential[]
|
|
302
|
+
fetchList?: boolean
|
|
303
|
+
publish?: boolean
|
|
304
|
+
publishEncrypted?: boolean
|
|
305
|
+
symmetricKey?: string
|
|
306
|
+
writeToFile?: boolean
|
|
307
|
+
returnUpdatedStatusList?: boolean
|
|
308
|
+
returnUpdatedEncryptedStatusList?: boolean
|
|
309
|
+
returnEncryptedSymmetricKey?: boolean
|
|
310
|
+
returnSymmetricKey?: boolean
|
|
311
|
+
returnStatusListMetadata?: boolean
|
|
312
|
+
options?: ICheqdStatusList2021Options
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface ICheqdSuspendCredentialWithStatusList2021Args {
|
|
316
|
+
credential: VerifiableCredential
|
|
317
|
+
fetchList?: boolean
|
|
318
|
+
publish?: boolean
|
|
319
|
+
publishEncrypted?: boolean
|
|
320
|
+
symmetricKey?: string
|
|
321
|
+
writeToFile?: boolean
|
|
322
|
+
returnUpdatedStatusList?: boolean
|
|
323
|
+
returnUpdatedEncryptedStatusList?: boolean
|
|
324
|
+
returnEncryptedSymmetricKey?: boolean
|
|
325
|
+
returnSymmetricKey?: boolean
|
|
326
|
+
returnStatusListMetadata?: boolean
|
|
327
|
+
options?: ICheqdStatusList2021Options
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export interface ICheqdSuspendBulkCredentialsWithStatusList2021Args {
|
|
331
|
+
credentials: VerifiableCredential[]
|
|
332
|
+
fetchList?: boolean
|
|
333
|
+
publish?: boolean
|
|
334
|
+
publishEncrypted?: boolean
|
|
335
|
+
symmetricKey?: string
|
|
336
|
+
writeToFile?: boolean
|
|
337
|
+
returnUpdatedStatusList?: boolean
|
|
338
|
+
returnUpdatedEncryptedStatusList?: boolean
|
|
339
|
+
returnEncryptedSymmetricKey?: boolean
|
|
340
|
+
returnSymmetricKey?: boolean
|
|
341
|
+
returnStatusListMetadata?: boolean
|
|
342
|
+
options?: ICheqdStatusList2021Options
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export interface ICheqdUnsuspendCredentialWithStatusList2021Args {
|
|
346
|
+
credential: VerifiableCredential
|
|
347
|
+
fetchList?: boolean
|
|
348
|
+
publish?: boolean
|
|
349
|
+
publishEncrypted?: boolean
|
|
350
|
+
symmetricKey?: string
|
|
351
|
+
writeToFile?: boolean
|
|
352
|
+
returnUpdatedStatusList?: boolean
|
|
353
|
+
returnUpdatedEncryptedStatusList?: boolean
|
|
354
|
+
returnEncryptedSymmetricKey?: boolean
|
|
355
|
+
returnSymmetricKey?: boolean
|
|
356
|
+
returnStatusListMetadata?: boolean
|
|
357
|
+
options?: ICheqdStatusList2021Options
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export interface ICheqdUnsuspendBulkCredentialsWithStatusList2021Args {
|
|
361
|
+
credentials: VerifiableCredential[]
|
|
362
|
+
fetchList?: boolean
|
|
363
|
+
publish?: boolean
|
|
364
|
+
publishEncrypted?: boolean
|
|
365
|
+
symmetricKey?: string
|
|
366
|
+
writeToFile?: boolean
|
|
367
|
+
returnUpdatedStatusList?: boolean
|
|
368
|
+
returnUpdatedEncryptedStatusList?: boolean
|
|
369
|
+
returnEncryptedSymmetricKey?: boolean
|
|
370
|
+
returnSymmetricKey?: boolean
|
|
371
|
+
returnStatusListMetadata?: boolean
|
|
372
|
+
options?: ICheqdStatusList2021Options
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export interface ICheqdTransactVerifierPaysIssuerArgs {
|
|
376
|
+
recipientAddress: string
|
|
377
|
+
amount: Coin
|
|
378
|
+
memoNonce: string
|
|
379
|
+
txBytes?: Uint8Array
|
|
380
|
+
returnTxResponse?: boolean
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export interface ICheqdObserveVerifierPaysIssuerArgs {
|
|
384
|
+
senderAddress: string
|
|
385
|
+
recipientAddress: string
|
|
386
|
+
amount: Coin
|
|
387
|
+
memoNonce: string
|
|
388
|
+
network?: CheqdNetwork
|
|
389
|
+
unifiedAccessControlCondition?: Required<CosmosAccessControlCondition>
|
|
390
|
+
returnTxResponse?: boolean
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export interface ICheqdStatusList2021Options {
|
|
394
|
+
statusListFile?: string
|
|
395
|
+
statusListInlineBitstring?: string
|
|
396
|
+
[key: string]: any
|
|
397
|
+
}
|
|
398
|
+
|
|
56
399
|
export interface ICheqd extends IPluginMethodMap {
|
|
57
|
-
[CreateIdentifierMethodName]: (args:
|
|
58
|
-
[UpdateIdentifierMethodName]: (args:
|
|
59
|
-
[DeactivateIdentifierMethodName]: (args:
|
|
60
|
-
[CreateResourceMethodName]: (args:
|
|
61
|
-
[
|
|
62
|
-
[
|
|
63
|
-
[
|
|
64
|
-
[
|
|
400
|
+
[CreateIdentifierMethodName]: (args: ICheqdCreateIdentifierArgs, context: IContext) => Promise<Omit<IIdentifier, 'provider'>>
|
|
401
|
+
[UpdateIdentifierMethodName]: (args: ICheqdUpdateIdentifierArgs, context: IContext) => Promise<Omit<IIdentifier, 'provider'>>,
|
|
402
|
+
[DeactivateIdentifierMethodName]: (args: ICheqdDeactivateIdentifierArgs, context: IContext) => Promise<boolean>,
|
|
403
|
+
[CreateResourceMethodName]: (args: ICheqdCreateLinkedResourceArgs, context: IContext) => Promise<boolean>,
|
|
404
|
+
[CreateStatusList2021MethodName]: (args: ICheqdCreateStatusList2021Args, context: IContext) => Promise<boolean>,
|
|
405
|
+
[CreateEncryptedStatusList2021MethodName]: (args: ICheqdCreateEncryptedStatusList2021Args, context: IContext) => Promise<CreateEncryptedStatusList2021Result>,
|
|
406
|
+
[GenerateDidDocMethodName]: (args: ICheqdGenerateDidDocArgs, context: IContext) => Promise<TExportedDIDDocWithKeys>,
|
|
407
|
+
[GenerateDidDocWithLinkedResourceMethodName]: (args: ICheqdGenerateDidDocWithLinkedResourceArgs, context: IContext) => Promise<TExportedDIDDocWithLinkedResourceWithKeys>,
|
|
408
|
+
[GenerateKeyPairMethodName]: (args: ICheqdGenerateKeyPairArgs, context: IContext) => Promise<TImportableEd25519Key>
|
|
409
|
+
[GenerateVersionIdMethodName]: (args: ICheqdGenerateVersionIdArgs, context: IContext) => Promise<string>
|
|
410
|
+
[GenerateStatusList2021MethodName]: (args: ICheqdGenerateStatusList2021Args, context: IContext) => Promise<string>
|
|
411
|
+
[GenerateEncryptedStatusList2021MethodName]: (args: ICheqdGenerateEncryptedStatusList2021Args, context: IContext) => Promise<GenerateEncryptedStatusList2021Result>
|
|
412
|
+
[IssueRevocableCredentialWithStatusList2021MethodName]: (args: ICheqdIssueRevocableCredentialWithStatusList2021Args, context: IContext) => Promise<VerifiableCredential>
|
|
413
|
+
[IssueSuspendableCredentialWithStatusList2021MethodName]: (args: ICheqdIssueSuspendableCredentialWithStatusList2021Args, context: IContext) => Promise<VerifiableCredential>
|
|
414
|
+
[VerifyCredentialMethodName]: (args: ICheqdVerifyCredentialWithStatusList2021Args, context: IContext) => Promise<VerificationResult>
|
|
415
|
+
[VerifyPresentationMethodName]: (args: ICheqdVerifyPresentationWithStatusList2021Args, context: IContext) => Promise<VerificationResult>
|
|
416
|
+
[CheckCredentialStatusMethodName]: (args: ICheqdCheckCredentialStatusWithStatusList2021Args, context: IContext) => Promise<StatusCheckResult>
|
|
417
|
+
[RevokeCredentialMethodName]: (args: ICheqdRevokeCredentialWithStatusList2021Args, context: IContext) => Promise<RevocationResult>
|
|
418
|
+
[RevokeCredentialsMethodName]: (args: ICheqdRevokeBulkCredentialsWithStatusList2021Args, context: IContext) => Promise<RevocationResult[]>
|
|
419
|
+
[SuspendCredentialMethodName]: (args: ICheqdSuspendCredentialWithStatusList2021Args, context: IContext) => Promise<SuspensionResult>
|
|
420
|
+
[SuspendCredentialsMethodName]: (args: ICheqdSuspendBulkCredentialsWithStatusList2021Args, context: IContext) => Promise<SuspensionResult[]>
|
|
421
|
+
[UnsuspendCredentialMethodName]: (args: ICheqdUnsuspendCredentialWithStatusList2021Args, context: IContext) => Promise<UnsuspensionResult>
|
|
422
|
+
[UnsuspendCredentialsMethodName]: (args: ICheqdUnsuspendBulkCredentialsWithStatusList2021Args, context: IContext) => Promise<UnsuspensionResult[]>
|
|
423
|
+
[TransactVerifierPaysIssuerMethodName]: (args: ICheqdTransactVerifierPaysIssuerArgs, context: IContext) => Promise<TransactionResult>
|
|
424
|
+
[ObserveVerifierPaysIssuerMethodName]: (args: ICheqdObserveVerifierPaysIssuerArgs, context: IContext) => Promise<ObservationResult>
|
|
65
425
|
}
|
|
66
426
|
|
|
67
427
|
export class Cheqd implements IAgentPlugin {
|
|
@@ -138,6 +498,42 @@ export class Cheqd implements IAgentPlugin {
|
|
|
138
498
|
"args"
|
|
139
499
|
]
|
|
140
500
|
},
|
|
501
|
+
"returnType": {
|
|
502
|
+
"type": "boolean"
|
|
503
|
+
}
|
|
504
|
+
},
|
|
505
|
+
"cheqdCreateStatusList2021": {
|
|
506
|
+
"description": "Create a new Status List 2021",
|
|
507
|
+
"arguments": {
|
|
508
|
+
"type": "object",
|
|
509
|
+
"properties": {
|
|
510
|
+
"args": {
|
|
511
|
+
"type": "object",
|
|
512
|
+
"description": "A cheqdCreateStatusList2021Args object as any for extensibility"
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
"required": [
|
|
516
|
+
"args"
|
|
517
|
+
]
|
|
518
|
+
},
|
|
519
|
+
"returnType": {
|
|
520
|
+
"type": "boolean"
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
"cheqdCreateEncryptedStatusList2021": {
|
|
524
|
+
"description": "Create a new Encrypted Status List 2021",
|
|
525
|
+
"arguments": {
|
|
526
|
+
"type": "object",
|
|
527
|
+
"properties": {
|
|
528
|
+
"args": {
|
|
529
|
+
"type": "object",
|
|
530
|
+
"description": "A cheqdCreateEncryptedStatusList2021Args object as any for extensibility"
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
"required": [
|
|
534
|
+
"args"
|
|
535
|
+
]
|
|
536
|
+
},
|
|
141
537
|
"returnType": {
|
|
142
538
|
"type": "object"
|
|
143
539
|
}
|
|
@@ -202,248 +598,1808 @@ export class Cheqd implements IAgentPlugin {
|
|
|
202
598
|
"type": "object",
|
|
203
599
|
"description": "A cheqdGenerateVersionIdArgs object as any for extensibility"
|
|
204
600
|
}
|
|
205
|
-
}
|
|
601
|
+
},
|
|
206
602
|
},
|
|
207
603
|
"returnType": {
|
|
208
604
|
"type": "object"
|
|
209
605
|
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
606
|
+
},
|
|
607
|
+
"cheqdGenerateStatusList2021": {
|
|
608
|
+
"description": "Generate a new Status List 2021",
|
|
609
|
+
"arguments": {
|
|
610
|
+
"type": "object",
|
|
611
|
+
"properties": {
|
|
612
|
+
"args": {
|
|
613
|
+
"type": "object",
|
|
614
|
+
"description": "A cheqdGenerateStatusList2021Args object as any for extensibility"
|
|
615
|
+
}
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
"returnType": {
|
|
619
|
+
"type": "string"
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
"cheqdGenerateEncryptedStatusList2021": {
|
|
623
|
+
"description": "Generate a new encrypted Status List 2021",
|
|
624
|
+
"arguments": {
|
|
625
|
+
"type": "object",
|
|
626
|
+
"properties": {
|
|
627
|
+
"args": {
|
|
628
|
+
"type": "object",
|
|
629
|
+
"description": "A cheqdGenerateEncryptedStatusList2021Args object as any for extensibility"
|
|
630
|
+
}
|
|
631
|
+
},
|
|
632
|
+
"required": [
|
|
633
|
+
"args"
|
|
634
|
+
]
|
|
635
|
+
},
|
|
636
|
+
"returnType": {
|
|
637
|
+
"type": "string"
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
"cheqdIssueRevocableCredentialWithStatusList2021": {
|
|
641
|
+
"description": "Issue a revocable credential with a Status List 2021 as credential status registry",
|
|
642
|
+
"arguments": {
|
|
643
|
+
"type": "object",
|
|
644
|
+
"properties": {
|
|
645
|
+
"args": {
|
|
646
|
+
"type": "object",
|
|
647
|
+
"description": "A cheqdIssueCredentialWithStatusList2021Args object as any for extensibility"
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
"required": [
|
|
651
|
+
"args"
|
|
652
|
+
]
|
|
653
|
+
},
|
|
654
|
+
"returnType": {
|
|
655
|
+
"type": "object"
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
"cheqdIssueSuspendableCredentialWithStatusList2021": {
|
|
659
|
+
"description": "Issue a suspendable credential with a Status List 2021 as credential status registry",
|
|
660
|
+
"arguments": {
|
|
661
|
+
"type": "object",
|
|
662
|
+
"properties": {
|
|
663
|
+
"args": {
|
|
664
|
+
"type": "object",
|
|
665
|
+
"description": "A cheqdIssueCredentialWithStatusList2021Args object as any for extensibility"
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
"required": [
|
|
669
|
+
"args"
|
|
670
|
+
]
|
|
671
|
+
},
|
|
672
|
+
"returnType": {
|
|
673
|
+
"type": "object"
|
|
674
|
+
}
|
|
675
|
+
},
|
|
676
|
+
"cheqdVerifyCredential": {
|
|
677
|
+
"description": "Verify a credential, enhanced by revocation / suspension check with a Status List 2021 as credential status registry",
|
|
678
|
+
"arguments": {
|
|
679
|
+
"type": "object",
|
|
680
|
+
"properties": {
|
|
681
|
+
"args": {
|
|
682
|
+
"type": "object",
|
|
683
|
+
"description": "A cheqdVerifyCredentialWithStatusList2021Args object as any for extensibility"
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
"required": [
|
|
687
|
+
"args"
|
|
688
|
+
]
|
|
689
|
+
},
|
|
690
|
+
"returnType": {
|
|
691
|
+
"type": "object"
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
"cheqdVerifyPresentation": {
|
|
695
|
+
"description": "Verify a presentation, enhanced by revocation / suspension check with a Status List 2021 as credential status registry",
|
|
696
|
+
"arguments": {
|
|
697
|
+
"type": "object",
|
|
698
|
+
"properties": {
|
|
699
|
+
"args": {
|
|
700
|
+
"type": "object",
|
|
701
|
+
"description": "A cheqdVerifyPresentationWithStatusList2021Args object as any for extensibility"
|
|
702
|
+
}
|
|
703
|
+
},
|
|
704
|
+
"required": [
|
|
705
|
+
"args"
|
|
706
|
+
]
|
|
707
|
+
},
|
|
708
|
+
"returnType": {
|
|
709
|
+
"type": "object"
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
"cheqdCheckCredentialStatus": {
|
|
713
|
+
"description": "Check the revocation / suspension status of a credential with a Status List 2021 as credential status registry",
|
|
714
|
+
"arguments": {
|
|
715
|
+
"type": "object",
|
|
716
|
+
"properties": {
|
|
717
|
+
"args": {
|
|
718
|
+
"type": "object",
|
|
719
|
+
"description": "A cheqdCheckCredentialStatusWithStatusList2021Args object as any for extensibility"
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
"required": [
|
|
723
|
+
"args"
|
|
724
|
+
]
|
|
725
|
+
},
|
|
726
|
+
"returnType": {
|
|
727
|
+
"type": "object"
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
"cheqdRevokeCredential": {
|
|
731
|
+
"description": "Revoke a credential against a Status List 2021 as credential status registry",
|
|
732
|
+
"arguments": {
|
|
733
|
+
"type": "object",
|
|
734
|
+
"properties": {
|
|
735
|
+
"args": {
|
|
736
|
+
"type": "object",
|
|
737
|
+
"description": "A cheqdRevokeCredentialWithStatusList2021Args object as any for extensibility"
|
|
738
|
+
}
|
|
739
|
+
},
|
|
740
|
+
"required": [
|
|
741
|
+
"args"
|
|
742
|
+
]
|
|
743
|
+
},
|
|
744
|
+
"returnType": {
|
|
745
|
+
"type": "object"
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
"cheqdRevokeCredentials": {
|
|
749
|
+
"description": "Revoke multiple credentials against a Status List 2021 as credential status registry",
|
|
750
|
+
"arguments": {
|
|
751
|
+
"type": "object",
|
|
752
|
+
"properties": {
|
|
753
|
+
"args": {
|
|
754
|
+
"type": "object",
|
|
755
|
+
"description": "A cheqdRevokeBulkCredentialsWithStatusList2021Args object as any for extensibility"
|
|
756
|
+
}
|
|
757
|
+
},
|
|
758
|
+
"required": [
|
|
759
|
+
"args"
|
|
760
|
+
]
|
|
761
|
+
},
|
|
762
|
+
"returnType": {
|
|
763
|
+
"type": "array"
|
|
764
|
+
}
|
|
765
|
+
},
|
|
766
|
+
"cheqdSuspendCredential": {
|
|
767
|
+
"description": "Suspend a credential against a Status List 2021 as credential status registry",
|
|
768
|
+
"arguments": {
|
|
769
|
+
"type": "object",
|
|
770
|
+
"properties": {
|
|
771
|
+
"args": {
|
|
772
|
+
"type": "object",
|
|
773
|
+
"description": "A cheqdSuspendCredentialWithStatusList2021Args object as any for extensibility"
|
|
774
|
+
}
|
|
775
|
+
},
|
|
776
|
+
"required": [
|
|
777
|
+
"args"
|
|
778
|
+
]
|
|
779
|
+
},
|
|
780
|
+
"returnType": {
|
|
781
|
+
"type": "object"
|
|
782
|
+
}
|
|
783
|
+
},
|
|
784
|
+
"cheqdSuspendCredentials": {
|
|
785
|
+
"description": "Suspend multiple credentials against a Status List 2021 as credential status registry",
|
|
786
|
+
"arguments": {
|
|
787
|
+
"type": "object",
|
|
788
|
+
"properties": {
|
|
789
|
+
"args": {
|
|
790
|
+
"type": "object",
|
|
791
|
+
"description": "A cheqdSuspendBulkCredentialsWithStatusList2021Args object as any for extensibility"
|
|
792
|
+
}
|
|
793
|
+
},
|
|
794
|
+
"required": [
|
|
795
|
+
"args"
|
|
796
|
+
]
|
|
797
|
+
},
|
|
798
|
+
"returnType": {
|
|
799
|
+
"type": "array"
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
"cheqdUnsuspendCredential": {
|
|
803
|
+
"description": "Unsuspend a credential against a Status List 2021 as credential status registry",
|
|
804
|
+
"arguments": {
|
|
805
|
+
"type": "object",
|
|
806
|
+
"properties": {
|
|
807
|
+
"args": {
|
|
808
|
+
"type": "object",
|
|
809
|
+
"description": "cheqdUnsuspendCredentialWithStatusList2021Args object as any for extensibility"
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
"required": [
|
|
813
|
+
"args"
|
|
814
|
+
]
|
|
815
|
+
},
|
|
816
|
+
"returnType": {
|
|
817
|
+
"type": "object"
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
"cheqdUnsuspendCredentials": {
|
|
821
|
+
"description": "Unsuspend multiple credentials against a Status List 2021 as credential status registry",
|
|
822
|
+
"arguments": {
|
|
823
|
+
"type": "object",
|
|
824
|
+
"properties": {
|
|
825
|
+
"args": {
|
|
826
|
+
"type": "object",
|
|
827
|
+
"description": "A cheqdUnsuspendBulkCredentialsWithStatusList2021Args object as any for extensibility"
|
|
828
|
+
}
|
|
829
|
+
},
|
|
830
|
+
"required": [
|
|
831
|
+
"args"
|
|
832
|
+
]
|
|
833
|
+
},
|
|
834
|
+
"returnType": {
|
|
835
|
+
"type": "array"
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
"cheqdTransactVerifierPaysIssuer": {
|
|
839
|
+
"description": "Initiate a transaction where the verifier pays the issuer for a credential status check",
|
|
840
|
+
"arguments": {
|
|
841
|
+
"type": "object",
|
|
842
|
+
"properties": {
|
|
843
|
+
"args": {
|
|
844
|
+
"type": "object",
|
|
845
|
+
"description": "A cheqdTransactVerifierPaysIssuerArgs object as any for extensibility"
|
|
846
|
+
}
|
|
847
|
+
},
|
|
848
|
+
"required": [
|
|
849
|
+
"args"
|
|
850
|
+
]
|
|
851
|
+
},
|
|
852
|
+
"returnType": {
|
|
853
|
+
"type": "object"
|
|
854
|
+
}
|
|
855
|
+
},
|
|
856
|
+
"cheqdObserveVerifierPaysIssuer": {
|
|
857
|
+
"description": "Observe a transaction where the verifier pays the issuer for a credential status check",
|
|
858
|
+
"arguments": {
|
|
859
|
+
"type": "object",
|
|
860
|
+
"properties": {
|
|
861
|
+
"args": {
|
|
862
|
+
"type": "object",
|
|
863
|
+
"description": "cheqdObserveVerifierPaysIssuerArgs object as any for extensibility"
|
|
864
|
+
}
|
|
865
|
+
},
|
|
866
|
+
"required": [
|
|
867
|
+
"args"
|
|
868
|
+
]
|
|
869
|
+
},
|
|
870
|
+
"returnType": {
|
|
871
|
+
"type": "object"
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
private readonly supportedDidProviders: CheqdDIDProvider[]
|
|
878
|
+
private didProvider: CheqdDIDProvider;
|
|
879
|
+
private providerId: string;
|
|
880
|
+
static readonly defaultStatusList2021Length: number = 16 * 1024 * 8 // 16KB in bits or 131072 bits / entries
|
|
881
|
+
static readonly defaultContextV1 = 'https://www.w3.org/2018/credentials/v1'
|
|
882
|
+
static readonly statusList2021Context = 'https://w3id.org/vc-status-list-2021/v1'
|
|
883
|
+
|
|
884
|
+
|
|
885
|
+
constructor(args: { providers: CheqdDIDProvider[] }) {
|
|
886
|
+
if (typeof args.providers !== 'object') {
|
|
887
|
+
throw new Error('[did-provider-cheqd]: at least one did provider is required')
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
this.supportedDidProviders = args.providers
|
|
891
|
+
this.didProvider = args.providers[0]
|
|
892
|
+
this.providerId = Cheqd.generateProviderId(this.didProvider.network)
|
|
893
|
+
|
|
894
|
+
this.methods = {
|
|
895
|
+
[CreateIdentifierMethodName]: this.CreateIdentifier.bind(this),
|
|
896
|
+
[UpdateIdentifierMethodName]: this.UpdateIdentifier.bind(this),
|
|
897
|
+
[DeactivateIdentifierMethodName]: this.DeactivateIdentifier.bind(this),
|
|
898
|
+
[CreateResourceMethodName]: this.CreateResource.bind(this),
|
|
899
|
+
[CreateStatusList2021MethodName]: this.CreateStatusList2021.bind(this),
|
|
900
|
+
[CreateEncryptedStatusList2021MethodName]: this.CreateEncryptedStatusList2021.bind(this),
|
|
901
|
+
[GenerateDidDocMethodName]: this.GenerateDidDoc.bind(this),
|
|
902
|
+
[GenerateDidDocWithLinkedResourceMethodName]: this.GenerateDidDocWithLinkedResource.bind(this),
|
|
903
|
+
[GenerateKeyPairMethodName]: this.GenerateIdentityKeys.bind(this),
|
|
904
|
+
[GenerateVersionIdMethodName]: this.GenerateVersionId.bind(this),
|
|
905
|
+
[GenerateStatusList2021MethodName]: this.GenerateStatusList2021.bind(this),
|
|
906
|
+
[GenerateEncryptedStatusList2021MethodName]: this.GenerateEncryptedStatusList2021.bind(this),
|
|
907
|
+
[IssueRevocableCredentialWithStatusList2021MethodName]: this.IssueRevocableCredentialWithStatusList2021.bind(this),
|
|
908
|
+
[IssueSuspendableCredentialWithStatusList2021MethodName]: this.IssueSuspendableCredentialWithStatusList2021.bind(this),
|
|
909
|
+
[VerifyCredentialMethodName]: this.VerifyCredentialWithStatusList2021.bind(this),
|
|
910
|
+
[VerifyPresentationMethodName]: this.VerifyPresentationWithStatusList2021.bind(this),
|
|
911
|
+
[CheckCredentialStatusMethodName]: this.CheckCredentialStatusWithStatusList2021.bind(this),
|
|
912
|
+
[RevokeCredentialMethodName]: this.RevokeCredentialWithStatusList2021.bind(this),
|
|
913
|
+
[RevokeCredentialsMethodName]: this.RevokeBulkCredentialsWithStatusList2021.bind(this),
|
|
914
|
+
[SuspendCredentialMethodName]: this.SuspendCredentialWithStatusList2021.bind(this),
|
|
915
|
+
[SuspendCredentialsMethodName]: this.SuspendBulkCredentialsWithStatusList2021.bind(this),
|
|
916
|
+
[UnsuspendCredentialMethodName]: this.UnsuspendCredentialWithStatusList2021.bind(this),
|
|
917
|
+
[UnsuspendCredentialsMethodName]: this.UnsuspendBulkCredentialsWithStatusList2021.bind(this),
|
|
918
|
+
[TransactVerifierPaysIssuerMethodName]: this.TransactVerifierPaysIssuer.bind(this),
|
|
919
|
+
[ObserveVerifierPaysIssuerMethodName]: this.ObserveVerifierPaysIssuer.bind(this),
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
private async CreateIdentifier(args: ICheqdCreateIdentifierArgs, context: IContext): Promise<Omit<IIdentifier, 'provider'>> {
|
|
924
|
+
if (typeof args.kms !== 'string') {
|
|
925
|
+
throw new Error('[did-provider-cheqd]: kms is required')
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
if (typeof args.alias !== 'string') {
|
|
929
|
+
throw new Error('[did-provider-cheqd]: alias is required')
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
if (typeof args.document !== 'object') {
|
|
933
|
+
throw new Error('[did-provider-cheqd]: document object is required')
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
const provider = await Cheqd.loadProvider(<DIDDocument>args.document, this.supportedDidProviders)
|
|
937
|
+
|
|
938
|
+
this.didProvider = provider
|
|
939
|
+
this.providerId = Cheqd.generateProviderId(this.didProvider.network)
|
|
940
|
+
|
|
941
|
+
return await context.agent.didManagerCreate({
|
|
942
|
+
kms: args.kms,
|
|
943
|
+
alias: args.alias,
|
|
944
|
+
provider: this.providerId,
|
|
945
|
+
options: {
|
|
946
|
+
document: args.document,
|
|
947
|
+
keys: args.keys,
|
|
948
|
+
versionId: args?.versionId,
|
|
949
|
+
fee: args?.fee
|
|
950
|
+
}
|
|
951
|
+
})
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
private async UpdateIdentifier(args: ICheqdUpdateIdentifierArgs, context: IContext): Promise<Omit<IIdentifier, 'provider'>> {
|
|
955
|
+
if (typeof args.kms !== 'string') {
|
|
956
|
+
throw new Error('[did-provider-cheqd]: kms is required')
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
if (typeof args.document !== 'object') {
|
|
960
|
+
throw new Error('[did-provider-cheqd]: document object is required')
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
const provider = await Cheqd.loadProvider(<DIDDocument>args.document, this.supportedDidProviders)
|
|
964
|
+
|
|
965
|
+
this.didProvider = provider
|
|
966
|
+
this.providerId = Cheqd.generateProviderId(this.didProvider.network)
|
|
967
|
+
|
|
968
|
+
return await context.agent.didManagerUpdate({
|
|
969
|
+
did: args.document.id,
|
|
970
|
+
document: args.document,
|
|
971
|
+
options: {
|
|
972
|
+
kms: args.kms,
|
|
973
|
+
keys: args.keys,
|
|
974
|
+
versionId: args?.versionId,
|
|
975
|
+
fee: args?.fee
|
|
976
|
+
}
|
|
977
|
+
})
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
private async DeactivateIdentifier(args: ICheqdDeactivateIdentifierArgs, context: IContext) {
|
|
981
|
+
if (typeof args.kms !== 'string') {
|
|
982
|
+
throw new Error('[did-provider-cheqd]: kms is required')
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (typeof args.document !== 'object') {
|
|
986
|
+
throw new Error('[did-provider-cheqd]: document object is required')
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
const provider = await Cheqd.loadProvider(<DIDDocument>args.document, this.supportedDidProviders)
|
|
990
|
+
|
|
991
|
+
this.didProvider = provider
|
|
992
|
+
this.providerId = Cheqd.generateProviderId(this.didProvider.network)
|
|
993
|
+
|
|
994
|
+
return await this.didProvider.deactivateIdentifier({
|
|
995
|
+
did: args.document.id,
|
|
996
|
+
document: args.document,
|
|
997
|
+
options: {
|
|
998
|
+
keys: args.keys,
|
|
999
|
+
fee: args?.fee
|
|
1000
|
+
}
|
|
1001
|
+
}, context)
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
private async CreateResource(args: ICheqdCreateLinkedResourceArgs, context: IContext) {
|
|
1005
|
+
if (typeof args.kms !== 'string') {
|
|
1006
|
+
throw new Error('[did-provider-cheqd]: kms is required')
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
if (typeof args.payload !== 'object') {
|
|
1010
|
+
throw new Error('[did-provider-cheqd]: payload object is required')
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
if (typeof args.network !== 'string') {
|
|
1014
|
+
throw new Error('[did-provider-cheqd]: network is required')
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
if (args?.file) {
|
|
1018
|
+
args.payload.data = await Cheqd.getFile(args.file)
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (typeof args?.payload?.data === 'string') {
|
|
1022
|
+
args.payload.data = fromString(args.payload.data, 'base64')
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
this.providerId = Cheqd.generateProviderId(args.network)
|
|
1026
|
+
this.didProvider = await Cheqd.loadProvider({ id: this.providerId } as DIDDocument, this.supportedDidProviders)
|
|
1027
|
+
|
|
1028
|
+
return await this.didProvider.createResource({
|
|
1029
|
+
options: {
|
|
1030
|
+
kms: args.kms,
|
|
1031
|
+
payload: args.payload,
|
|
1032
|
+
signInputs: args.signInputs,
|
|
1033
|
+
fee: args?.fee
|
|
1034
|
+
}
|
|
1035
|
+
}, context)
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
private async CreateStatusList2021(args: ICheqdCreateStatusList2021Args, context: IContext) {
|
|
1039
|
+
if (typeof args.kms !== 'string') {
|
|
1040
|
+
throw new Error('[did-provider-cheqd]: kms is required')
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
if (typeof args.payload !== 'object') {
|
|
1044
|
+
throw new Error('[did-provider-cheqd]: payload object is required')
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (typeof args.network !== 'string') {
|
|
1048
|
+
throw new Error('[did-provider-cheqd]: network is required')
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
if (args?.file) {
|
|
1052
|
+
args.payload.data = await Cheqd.getFile(args.file)
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
if (typeof args?.payload?.data === 'string') {
|
|
1056
|
+
args.payload.data = fromString(args.payload.data, 'base64')
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
// TODO: validate data as per bitstring
|
|
1060
|
+
|
|
1061
|
+
// set default resource type in runtime
|
|
1062
|
+
args.payload.resourceType = 'StatusList2021'
|
|
1063
|
+
|
|
1064
|
+
this.providerId = Cheqd.generateProviderId(args.network)
|
|
1065
|
+
this.didProvider = await Cheqd.loadProvider({ id: this.providerId } as DIDDocument, this.supportedDidProviders)
|
|
1066
|
+
|
|
1067
|
+
return await this.didProvider.createResource({
|
|
1068
|
+
options: {
|
|
1069
|
+
kms: args.kms,
|
|
1070
|
+
payload: args.payload,
|
|
1071
|
+
signInputs: args.signInputs,
|
|
1072
|
+
fee: args?.fee
|
|
1073
|
+
}
|
|
1074
|
+
}, context)
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
private async CreateEncryptedStatusList2021(args: ICheqdCreateEncryptedStatusList2021Args, context: IContext): Promise<CreateEncryptedStatusList2021Result> {
|
|
1078
|
+
if (typeof args.kms !== 'string') {
|
|
1079
|
+
throw new Error('[did-provider-cheqd]: kms is required')
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
if (typeof args.payload !== 'object') {
|
|
1083
|
+
throw new Error('[did-provider-cheqd]: payload object is required')
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
if (typeof args.network !== 'string') {
|
|
1087
|
+
throw new Error('[did-provider-cheqd]: network is required')
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
if (args?.file) {
|
|
1091
|
+
args.payload.data = await Cheqd.getFile(args.file)
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
if (typeof args?.payload?.data === 'string') {
|
|
1095
|
+
args.payload.data = fromString(args.payload.data, 'base64')
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
// TODO: validate data as per bitstring
|
|
1099
|
+
|
|
1100
|
+
if (!args?.encryptionOptions) {
|
|
1101
|
+
throw new Error('[did-provider-cheqd]: encryptionOptions is required')
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
if (!args?.bootstrapOptions) {
|
|
1105
|
+
throw new Error('[did-provider-cheqd]: bootstrapOptions is required')
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
if (!args?.encryptionOptions?.accessControlConditions) {
|
|
1109
|
+
throw new Error('[did-provider-cheqd]: accessControlConditions is required')
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
1113
|
+
const lit = await LitProtocol.create({
|
|
1114
|
+
chain: args.bootstrapOptions?.chain,
|
|
1115
|
+
litNetwork: args.bootstrapOptions?.litNetwork
|
|
1116
|
+
})
|
|
1117
|
+
|
|
1118
|
+
// construct access control conditions
|
|
1119
|
+
const unifiedAccessControlConditions = await Promise.all(args.encryptionOptions.accessControlConditions.map(async (condition) => {
|
|
1120
|
+
switch (condition.type) {
|
|
1121
|
+
case AccessControlConditionTypes.memoNonce:
|
|
1122
|
+
return await LitProtocol.generateCosmosAccessControlConditionTransactionMemo({
|
|
1123
|
+
key: '$.txs.*.body.memo',
|
|
1124
|
+
comparator: 'contains',
|
|
1125
|
+
value: condition?.specificNonce || await LitProtocol.generateTxNonce(condition?.nonceFormat)
|
|
1126
|
+
},
|
|
1127
|
+
condition.amountObserved,
|
|
1128
|
+
condition.senderAddressObserved,
|
|
1129
|
+
condition.recipientAddressObserved,
|
|
1130
|
+
args.bootstrapOptions.chain
|
|
1131
|
+
)
|
|
1132
|
+
case AccessControlConditionTypes.balance:
|
|
1133
|
+
return await LitProtocol.generateCosmosAccessControlConditionBalance({
|
|
1134
|
+
key: '$.balances[0].amount',
|
|
1135
|
+
comparator: condition.comparator,
|
|
1136
|
+
value: condition.amountObserved
|
|
1137
|
+
},
|
|
1138
|
+
args.bootstrapOptions.chain,
|
|
1139
|
+
condition.addressObserved
|
|
1140
|
+
)
|
|
1141
|
+
default:
|
|
1142
|
+
throw new Error(`[did-provider-cheqd]: accessControlCondition type is not supported`)
|
|
1143
|
+
}
|
|
1144
|
+
}))
|
|
1145
|
+
|
|
1146
|
+
// encrypt data
|
|
1147
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(toString(args.payload.data!, 'base64url'), unifiedAccessControlConditions, true)
|
|
1148
|
+
|
|
1149
|
+
// set encrypted data
|
|
1150
|
+
args.payload.data = new Uint8Array(await encryptedString.arrayBuffer())
|
|
1151
|
+
|
|
1152
|
+
// set default resource type in runtime
|
|
1153
|
+
args.payload.resourceType = 'StatusList2021'
|
|
1154
|
+
|
|
1155
|
+
this.providerId = Cheqd.generateProviderId(args.network)
|
|
1156
|
+
this.didProvider = await Cheqd.loadProvider({ id: this.providerId } as DIDDocument, this.supportedDidProviders)
|
|
1157
|
+
|
|
1158
|
+
const created = await this.didProvider.createResource({
|
|
1159
|
+
options: {
|
|
1160
|
+
kms: args.kms,
|
|
1161
|
+
payload: args.payload,
|
|
1162
|
+
signInputs: args.signInputs,
|
|
1163
|
+
fee: args?.fee
|
|
1164
|
+
}
|
|
1165
|
+
}, context)
|
|
1166
|
+
|
|
1167
|
+
return {
|
|
1168
|
+
created,
|
|
1169
|
+
encryptedSymmetricKey,
|
|
1170
|
+
encryptedStatusList2021: await blobToHexString(encryptedString),
|
|
1171
|
+
symmetricKey: args?.encryptionOptions?.returnSymmetricKey ? toString(symmetricKey!, 'hex') : undefined,
|
|
1172
|
+
unifiedAccessControlConditions
|
|
1173
|
+
} satisfies CreateEncryptedStatusList2021Result
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
private async GenerateDidDoc(
|
|
1177
|
+
args: ICheqdGenerateDidDocArgs,
|
|
1178
|
+
context: IContext
|
|
1179
|
+
): Promise<TExportedDIDDocWithKeys> {
|
|
1180
|
+
if (typeof args.verificationMethod !== 'string') {
|
|
1181
|
+
throw new Error('[did-provider-cheqd]: verificationMethod is required')
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
if (typeof args.methodSpecificIdAlgo !== 'string') {
|
|
1185
|
+
throw new Error('[did-provider-cheqd]: methodSpecificIdAlgo is required')
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
if (typeof args.network !== 'string') {
|
|
1189
|
+
throw new Error('[did-provider-cheqd]: network is required')
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
const keyPair = createKeyPairBase64()
|
|
1193
|
+
const keyPairHex: IKeyPair = { publicKey: toString(fromString(keyPair.publicKey, 'base64'), 'hex'), privateKey: toString(fromString(keyPair.privateKey, 'base64'), 'hex') }
|
|
1194
|
+
const verificationKeys = createVerificationKeys(keyPair.publicKey, args.methodSpecificIdAlgo, 'key-1', args.network)
|
|
1195
|
+
const verificationMethods = createDidVerificationMethod([args.verificationMethod], [verificationKeys])
|
|
1196
|
+
|
|
1197
|
+
return {
|
|
1198
|
+
didDoc: createDidPayload(verificationMethods, [verificationKeys]),
|
|
1199
|
+
versionId: v4(),
|
|
1200
|
+
keys: [
|
|
1201
|
+
{
|
|
1202
|
+
publicKeyHex: keyPairHex.publicKey,
|
|
1203
|
+
privateKeyHex: keyPairHex.privateKey,
|
|
1204
|
+
kid: keyPairHex.publicKey,
|
|
1205
|
+
type: 'Ed25519'
|
|
1206
|
+
}
|
|
1207
|
+
]
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
private async GenerateDidDocWithLinkedResource(args: any, context: IContext): Promise<TExportedDIDDocWithLinkedResourceWithKeys> {
|
|
1212
|
+
if (typeof args.verificationMethod !== 'string') {
|
|
1213
|
+
throw new Error('[did-provider-cheqd]: verificationMethod is required')
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
if (typeof args.methodSpecificIdAlgo !== 'string') {
|
|
1217
|
+
throw new Error('[did-provider-cheqd]: methodSpecificIdAlgo is required')
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
if (typeof args.network !== 'string') {
|
|
1221
|
+
throw new Error('[did-provider-cheqd]: network is required')
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
const keyPair = createKeyPairBase64()
|
|
1225
|
+
const keyPairHex: IKeyPair = { publicKey: toString(fromString(keyPair.publicKey, 'base64'), 'hex'), privateKey: toString(fromString(keyPair.privateKey, 'base64'), 'hex') }
|
|
1226
|
+
const verificationKeys = createVerificationKeys(keyPair.publicKey, args.methodSpecificIdAlgo, 'key-1', args.network)
|
|
1227
|
+
const verificationMethods = createDidVerificationMethod([args.verificationMethod], [verificationKeys])
|
|
1228
|
+
const payload = createDidPayload(verificationMethods, [verificationKeys])
|
|
1229
|
+
|
|
1230
|
+
return {
|
|
1231
|
+
didDoc: payload,
|
|
1232
|
+
versionId: v4(),
|
|
1233
|
+
keys: [
|
|
1234
|
+
{
|
|
1235
|
+
publicKeyHex: keyPairHex.publicKey,
|
|
1236
|
+
privateKeyHex: keyPairHex.privateKey,
|
|
1237
|
+
kid: keyPairHex.publicKey,
|
|
1238
|
+
type: 'Ed25519'
|
|
1239
|
+
}
|
|
1240
|
+
],
|
|
1241
|
+
linkedResource: {
|
|
1242
|
+
id: v4(),
|
|
1243
|
+
collectionId: payload.id.split(':').reverse()[0],
|
|
1244
|
+
name: 'sample json resource',
|
|
1245
|
+
version: '1.0.0',
|
|
1246
|
+
resourceType: 'SampleResource',
|
|
1247
|
+
alsoKnownAs: [],
|
|
1248
|
+
data: toString(new TextEncoder().encode(
|
|
1249
|
+
JSON.stringify({ sample: 'json' })
|
|
1250
|
+
), 'base64'),
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
private async GenerateIdentityKeys(args: any, context: IContext): Promise<TImportableEd25519Key> {
|
|
1256
|
+
const keyPair = createKeyPairHex()
|
|
1257
|
+
return {
|
|
1258
|
+
publicKeyHex: keyPair.publicKey,
|
|
1259
|
+
privateKeyHex: keyPair.privateKey,
|
|
1260
|
+
kid: keyPair.publicKey,
|
|
1261
|
+
type: 'Ed25519'
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
private async GenerateVersionId(args: any, context: IContext): Promise<string> {
|
|
1266
|
+
return v4()
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
private async GenerateStatusList2021(args: ICheqdGenerateStatusList2021Args, context: IContext): Promise<Bitstring> {
|
|
1270
|
+
const statusList = args?.buffer
|
|
1271
|
+
? new StatusList({ buffer: args.buffer })
|
|
1272
|
+
: new StatusList({ length: args?.length || Cheqd.defaultStatusList2021Length })
|
|
1273
|
+
|
|
1274
|
+
const encoded = await statusList.encode() as Bitstring
|
|
1275
|
+
|
|
1276
|
+
switch (args?.bitstringEncoding) {
|
|
1277
|
+
case 'base64url':
|
|
1278
|
+
return encoded
|
|
1279
|
+
case 'base64':
|
|
1280
|
+
return toString(fromString(encoded, 'base64url'), 'base64')
|
|
1281
|
+
case 'hex':
|
|
1282
|
+
return toString(fromString(encoded, 'base64url'), 'hex')
|
|
1283
|
+
default:
|
|
1284
|
+
return encoded
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
private async GenerateEncryptedStatusList2021(args: ICheqdGenerateEncryptedStatusList2021Args, context: IContext): Promise<GenerateEncryptedStatusList2021Result> {
|
|
1289
|
+
// validate encryptionOptions
|
|
1290
|
+
if (!args.encryptionOptions) {
|
|
1291
|
+
throw new Error('[did-provider-cheqd]: encryptionOptions is required')
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
// validate encryptionOptions.accessControlConditions
|
|
1295
|
+
if (!args.encryptionOptions.accessControlConditions) {
|
|
1296
|
+
throw new Error('[did-provider-cheqd]: encryptionOptions.accessControlConditions is required')
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// generate status list
|
|
1300
|
+
const statusList = args?.buffer
|
|
1301
|
+
? new StatusList({ buffer: args.buffer })
|
|
1302
|
+
: new StatusList({ length: args?.length || Cheqd.defaultStatusList2021Length })
|
|
1303
|
+
|
|
1304
|
+
// encode status list
|
|
1305
|
+
const encoded = await statusList.encode() as Bitstring
|
|
1306
|
+
|
|
1307
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
1308
|
+
const lit = await LitProtocol.create({
|
|
1309
|
+
chain: args.bootstrapOptions.chain,
|
|
1310
|
+
litNetwork: args.bootstrapOptions.litNetwork,
|
|
1311
|
+
})
|
|
1312
|
+
|
|
1313
|
+
// construct access control conditions
|
|
1314
|
+
const unifiedAccessControlConditions = await Promise.all(args.encryptionOptions.accessControlConditions.map(async (condition) => {
|
|
1315
|
+
switch (condition.type) {
|
|
1316
|
+
case AccessControlConditionTypes.memoNonce:
|
|
1317
|
+
return await LitProtocol.generateCosmosAccessControlConditionTransactionMemo({
|
|
1318
|
+
key: '$.txs.*.body.memo',
|
|
1319
|
+
comparator: 'contains',
|
|
1320
|
+
value: condition?.specificNonce || await LitProtocol.generateTxNonce(condition?.nonceFormat)
|
|
1321
|
+
},
|
|
1322
|
+
condition.amountObserved,
|
|
1323
|
+
condition.senderAddressObserved,
|
|
1324
|
+
condition.recipientAddressObserved,
|
|
1325
|
+
args.bootstrapOptions.chain
|
|
1326
|
+
)
|
|
1327
|
+
case AccessControlConditionTypes.balance:
|
|
1328
|
+
return await LitProtocol.generateCosmosAccessControlConditionBalance({
|
|
1329
|
+
key: '$.balances[0].amount',
|
|
1330
|
+
comparator: condition.comparator,
|
|
1331
|
+
value: condition.amountObserved
|
|
1332
|
+
},
|
|
1333
|
+
args.bootstrapOptions.chain,
|
|
1334
|
+
condition.addressObserved
|
|
1335
|
+
)
|
|
1336
|
+
default:
|
|
1337
|
+
throw new Error(`[did-provider-cheqd]: accessControlCondition type is not supported`)
|
|
1338
|
+
}
|
|
1339
|
+
}))
|
|
1340
|
+
|
|
1341
|
+
// encrypt data
|
|
1342
|
+
const { encryptedString, encryptedSymmetricKey } = await lit.encrypt(encoded, unifiedAccessControlConditions)
|
|
1343
|
+
|
|
1344
|
+
// return result
|
|
1345
|
+
return {
|
|
1346
|
+
encryptedStatusList2021: await blobToHexString(encryptedString),
|
|
1347
|
+
encryptedSymmetricKey,
|
|
1348
|
+
unifiedAccessControlConditions
|
|
1349
|
+
} satisfies GenerateEncryptedStatusList2021Result
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
private async IssueRevocableCredentialWithStatusList2021(args: ICheqdIssueRevocableCredentialWithStatusList2021Args, context: IContext): Promise<VerifiableCredential> {
|
|
1353
|
+
// generate index
|
|
1354
|
+
const statusListIndex = args.statusOptions.statusListIndex || await randomFromRange(args.statusOptions.statusListRangeStart || 0, (args.statusOptions.statusListRangeEnd || Cheqd.defaultStatusList2021Length) - 1, args.statusOptions.indexNotIn || [])
|
|
1355
|
+
|
|
1356
|
+
// construct issuer
|
|
1357
|
+
const issuer = ((args.issuanceOptions.credential.issuer as { id: string }).id)
|
|
1358
|
+
? (args.issuanceOptions.credential.issuer as { id: string }).id
|
|
1359
|
+
: args.issuanceOptions.credential.issuer as string
|
|
1360
|
+
|
|
1361
|
+
// generate status list credential
|
|
1362
|
+
const statusListCredential = `${resolverUrl}${issuer}?resourceName=${args.statusOptions.statusListName}`
|
|
1363
|
+
|
|
1364
|
+
// construct credential status
|
|
1365
|
+
const credentialStatus = {
|
|
1366
|
+
id: `${statusListCredential}#${statusListIndex}`,
|
|
1367
|
+
type: 'StatusList2021Entry',
|
|
1368
|
+
statusPurpose: 'revocation',
|
|
1369
|
+
statusListIndex: `${statusListIndex}`,
|
|
1370
|
+
statusListCredential,
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
// add credential status to credential
|
|
1374
|
+
args.issuanceOptions.credential.credentialStatus = credentialStatus
|
|
1375
|
+
|
|
1376
|
+
// add relevant context
|
|
1377
|
+
args.issuanceOptions.credential['@context'] = function() {
|
|
1378
|
+
// if no context is provided, add default context
|
|
1379
|
+
if (!args.issuanceOptions.credential['@context']) {
|
|
1380
|
+
return [Cheqd.defaultContextV1, Cheqd.statusList2021Context]
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// if context is provided as an array, add default context if it is not already present
|
|
1384
|
+
if (Array.isArray(args.issuanceOptions.credential['@context'])) {
|
|
1385
|
+
if (args.issuanceOptions.credential['@context'].length === 0) {
|
|
1386
|
+
return [Cheqd.defaultContextV1, Cheqd.statusList2021Context]
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
if (!args.issuanceOptions.credential['@context'].includes(Cheqd.statusList2021Context)) {
|
|
1390
|
+
return [...args.issuanceOptions.credential['@context'], Cheqd.statusList2021Context]
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
// if context is provided as a string, add default context if it is not already present
|
|
1395
|
+
if (typeof args.issuanceOptions.credential['@context'] === 'string') return [Cheqd.defaultContextV1, Cheqd.statusList2021Context]
|
|
1396
|
+
}()
|
|
1397
|
+
|
|
1398
|
+
// create a credential
|
|
1399
|
+
const credential = await context.agent.createVerifiableCredential(args.issuanceOptions)
|
|
1400
|
+
|
|
1401
|
+
return credential
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
private async IssueSuspendableCredentialWithStatusList2021(args: ICheqdIssueSuspendableCredentialWithStatusList2021Args, context: IContext): Promise<VerifiableCredential> {
|
|
1405
|
+
// generate index
|
|
1406
|
+
const statusListIndex = args.statusOptions.statusListIndex || await randomFromRange(args.statusOptions.statusListRangeStart || 0, (args.statusOptions.statusListRangeEnd || Cheqd.defaultStatusList2021Length) - 1, args.statusOptions.indexNotIn || [])
|
|
1407
|
+
|
|
1408
|
+
// construct issuer
|
|
1409
|
+
const issuer = ((args.issuanceOptions.credential.issuer as { id: string }).id)
|
|
1410
|
+
? (args.issuanceOptions.credential.issuer as { id: string }).id
|
|
1411
|
+
: args.issuanceOptions.credential.issuer as string
|
|
1412
|
+
|
|
1413
|
+
// generate status list credential
|
|
1414
|
+
const statusListCredential = `${resolverUrl}${issuer}?resourceName=${args.statusOptions.statusListName}`
|
|
1415
|
+
|
|
1416
|
+
// construct credential status
|
|
1417
|
+
const credentialStatus = {
|
|
1418
|
+
id: `${statusListCredential}#${statusListIndex}`,
|
|
1419
|
+
type: 'StatusList2021Entry',
|
|
1420
|
+
statusPurpose: 'suspension',
|
|
1421
|
+
statusListIndex: `${statusListIndex}`,
|
|
1422
|
+
statusListCredential,
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// add credential status to credential
|
|
1426
|
+
args.issuanceOptions.credential.credentialStatus = credentialStatus
|
|
1427
|
+
|
|
1428
|
+
// add relevant context
|
|
1429
|
+
args.issuanceOptions.credential['@context'] = function() {
|
|
1430
|
+
// if no context is provided, add default context
|
|
1431
|
+
if (!args.issuanceOptions.credential['@context']) {
|
|
1432
|
+
return [Cheqd.defaultContextV1, Cheqd.statusList2021Context]
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
// if context is provided as an array, add default context if it is not already present
|
|
1436
|
+
if (Array.isArray(args.issuanceOptions.credential['@context'])) {
|
|
1437
|
+
if (args.issuanceOptions.credential['@context'].length === 0) {
|
|
1438
|
+
return [Cheqd.defaultContextV1, Cheqd.statusList2021Context]
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
if (!args.issuanceOptions.credential['@context'].includes(Cheqd.statusList2021Context)) {
|
|
1442
|
+
return [...args.issuanceOptions.credential['@context'], Cheqd.statusList2021Context]
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
// if context is provided as a string, add default context if it is not already present
|
|
1447
|
+
if (typeof args.issuanceOptions.credential['@context'] === 'string') return [Cheqd.defaultContextV1, Cheqd.statusList2021Context]
|
|
1448
|
+
}()
|
|
1449
|
+
|
|
1450
|
+
// create a credential
|
|
1451
|
+
const credential = await context.agent.createVerifiableCredential(args.issuanceOptions)
|
|
1452
|
+
|
|
1453
|
+
return credential
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
private async VerifyCredentialWithStatusList2021(args: ICheqdVerifyCredentialWithStatusList2021Args, context: IContext): Promise<VerificationResult> {
|
|
1457
|
+
// verify default policies
|
|
1458
|
+
const verificationResult = await context.agent.verifyCredential({
|
|
1459
|
+
credential: args.credential,
|
|
1460
|
+
policies: {
|
|
1461
|
+
credentialStatus: false
|
|
1462
|
+
}
|
|
1463
|
+
} satisfies IVerifyCredentialArgs)
|
|
1464
|
+
|
|
1465
|
+
// early return if verification failed
|
|
1466
|
+
if (!verificationResult.verified) {
|
|
1467
|
+
return { verified: false, error: verificationResult.error }
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
// verify credential status
|
|
1471
|
+
switch (args.credential.credentialStatus?.statusPurpose) {
|
|
1472
|
+
case 'revocation':
|
|
1473
|
+
if (await Cheqd.checkRevoked(args.credential, { ...args.options, topArgs: args })) return { verified: false, revoked: true }
|
|
1474
|
+
return { verified: true, revoked: false }
|
|
1475
|
+
case 'suspension':
|
|
1476
|
+
if (await Cheqd.checkSuspended(args.credential, { ...args.options, topArgs: args })) return { verified: false, suspended: true }
|
|
1477
|
+
return { verified: true, suspended: false }
|
|
1478
|
+
default:
|
|
1479
|
+
throw new Error(`[did-provider-cheqd]: verify credential: Unsupported status purpose: ${args.credential.credentialStatus?.statusPurpose}`)
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
private async VerifyPresentationWithStatusList2021(args: ICheqdVerifyPresentationWithStatusList2021Args, context: IContext): Promise<VerificationResult> {
|
|
1484
|
+
// verify default policies
|
|
1485
|
+
const verificationResult = await context.agent.verifyPresentation({
|
|
1486
|
+
presentation: args.presentation,
|
|
1487
|
+
policies: {
|
|
1488
|
+
credentialStatus: false
|
|
1489
|
+
}
|
|
1490
|
+
} satisfies IVerifyPresentationArgs)
|
|
1491
|
+
|
|
1492
|
+
// early return if verification failed
|
|
1493
|
+
if (!verificationResult.verified) {
|
|
1494
|
+
return { verified: false, error: verificationResult.error }
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
if (!args.presentation.verifiableCredential) throw new Error('[did-provider-cheqd]: verify presentation: presentation.verifiableCredential is required')
|
|
1498
|
+
|
|
1499
|
+
// verify credential(s) status(es)
|
|
1500
|
+
for (let credential of args.presentation.verifiableCredential) {
|
|
1501
|
+
// if jwt credential, decode it
|
|
1502
|
+
if (typeof credential === 'string') {
|
|
1503
|
+
const decodedCredential = decodeJWT(credential)
|
|
1504
|
+
|
|
1505
|
+
// validate credential payload
|
|
1506
|
+
if (!decodedCredential.payload) throw new Error('[did-provider-cheqd]: verify presentation: decodedCredential.payload is required')
|
|
1507
|
+
|
|
1508
|
+
// validate credential payload ref as VerifiableCredential
|
|
1509
|
+
if (!decodedCredential.payload.vc) throw new Error('[did-provider-cheqd]: verify presentation: decodedCredential.payload.vc is required')
|
|
1510
|
+
|
|
1511
|
+
credential = decodedCredential.payload.vc as VerifiableCredential
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
switch (credential.credentialStatus?.statusPurpose) {
|
|
1515
|
+
case 'revocation':
|
|
1516
|
+
if (await Cheqd.checkRevoked(credential, { ...args.options, topArgs: args })) return { verified: false, revoked: true }
|
|
1517
|
+
break
|
|
1518
|
+
case 'suspension':
|
|
1519
|
+
if (await Cheqd.checkSuspended(credential, { ...args.options, topArgs: args })) return { verified: false, suspended: true }
|
|
1520
|
+
break
|
|
1521
|
+
default:
|
|
1522
|
+
throw new Error(`[did-provider-cheqd]: verify presentation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`)
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
return { verified: true }
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
private async CheckCredentialStatusWithStatusList2021(args: ICheqdCheckCredentialStatusWithStatusList2021Args, context: IContext): Promise<StatusCheckResult> {
|
|
1530
|
+
switch (args.credential.credentialStatus?.statusPurpose) {
|
|
1531
|
+
case 'revocation':
|
|
1532
|
+
if (await Cheqd.checkRevoked(args.credential, { ...args.options, topArgs: args })) return { revoked: true }
|
|
1533
|
+
return { revoked: false }
|
|
1534
|
+
case 'suspension':
|
|
1535
|
+
if (await Cheqd.checkSuspended(args.credential, { ...args.options, topArgs: args })) return { suspended: true }
|
|
1536
|
+
return { suspended: false }
|
|
1537
|
+
default:
|
|
1538
|
+
throw new Error(`[did-provider-cheqd]: check status: Unsupported status purpose: ${args.credential.credentialStatus?.statusPurpose}`)
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
private async RevokeCredentialWithStatusList2021(args: ICheqdRevokeCredentialWithStatusList2021Args, context: IContext): Promise<RevocationResult> {
|
|
1543
|
+
// validate status purpose
|
|
1544
|
+
if (args.credential.credentialStatus?.statusPurpose !== 'revocation') {
|
|
1545
|
+
throw new Error(`[did-provider-cheqd]: revocation: Unsupported status purpose: ${args.credential.credentialStatus?.statusPurpose}`)
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
// validate args in pairs - case: statusListFile and statusList
|
|
1549
|
+
if (args.options?.statusListFile && args.options?.statusList) {
|
|
1550
|
+
throw new Error('[did-provider-cheqd]: revocation: statusListFile and statusList are mutually exclusive')
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
// validate args in pairs - case: statusListFile and fetchList
|
|
1554
|
+
if (args.options?.statusListFile && args.options?.fetchList) {
|
|
1555
|
+
throw new Error('[did-provider-cheqd]: revocation: statusListFile and fetchList are mutually exclusive')
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
// validate args in pairs - case: statusList and fetchList
|
|
1559
|
+
if (args.options?.statusList && args.options?.fetchList) {
|
|
1560
|
+
throw new Error('[did-provider-cheqd]: revocation: statusList and fetchList are mutually exclusive')
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// validate args in pairs - case: publish
|
|
1564
|
+
if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
|
|
1565
|
+
throw new Error('[did-provider-cheqd]: revocation: publish requires statusListFile or statusList, if fetchList is disabled')
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
// revoke credential
|
|
1569
|
+
return await Cheqd.revokeCredential(args.credential, {
|
|
1570
|
+
...args.options,
|
|
1571
|
+
topArgs: args,
|
|
1572
|
+
publishOptions: {
|
|
1573
|
+
context,
|
|
1574
|
+
resourceId: args?.options?.resourceId,
|
|
1575
|
+
resourceVersion: args?.options?.resourceVersion,
|
|
1576
|
+
signInputs: args?.options?.signInputs,
|
|
1577
|
+
fee: args?.options?.fee
|
|
1578
|
+
}
|
|
1579
|
+
})
|
|
1580
|
+
}
|
|
376
1581
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
1582
|
+
private async RevokeBulkCredentialsWithStatusList2021(args: ICheqdRevokeBulkCredentialsWithStatusList2021Args, context: IContext): Promise<RevocationResult[]> {
|
|
1583
|
+
// TODO: implement
|
|
1584
|
+
throw new Error('[did-provider-cheqd]: revocation: bulk revocation is not implemented yet')
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
private async SuspendCredentialWithStatusList2021(args: ICheqdSuspendCredentialWithStatusList2021Args, context: IContext): Promise<SuspensionResult> {
|
|
1588
|
+
// validate status purpose
|
|
1589
|
+
if (args.credential.credentialStatus?.statusPurpose !== 'suspension') {
|
|
1590
|
+
throw new Error(`[did-provider-cheqd]: suspension: Unsupported status purpose: ${args.credential.credentialStatus?.statusPurpose}`)
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
// validate args in pairs - case: statusListFile and statusList
|
|
1594
|
+
if (args.options?.statusListFile && args.options?.statusList) {
|
|
1595
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile and statusList are mutually exclusive')
|
|
388
1596
|
}
|
|
1597
|
+
|
|
1598
|
+
// validate args in pairs - case: statusListFile and fetchList
|
|
1599
|
+
if (args.options?.statusListFile && args.options?.fetchList) {
|
|
1600
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile and fetchList are mutually exclusive')
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
// validate args in pairs - case: statusList and fetchList
|
|
1604
|
+
if (args.options?.statusList && args.options?.fetchList) {
|
|
1605
|
+
throw new Error('[did-provider-cheqd]: suspension: statusList and fetchList are mutually exclusive')
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
// validate args in pairs - case: publish
|
|
1609
|
+
if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
|
|
1610
|
+
throw new Error('[did-provider-cheqd]: suspension: publish requires statusListFile or statusList, if fetchList is disabled')
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
// suspend credential
|
|
1614
|
+
return await Cheqd.suspendCredential(args.credential, {
|
|
1615
|
+
...args.options,
|
|
1616
|
+
topArgs: args,
|
|
1617
|
+
publishOptions: {
|
|
1618
|
+
context,
|
|
1619
|
+
resourceId: args?.options?.resourceId,
|
|
1620
|
+
resourceVersion: args?.options?.resourceVersion,
|
|
1621
|
+
signInputs: args?.options?.signInputs,
|
|
1622
|
+
fee: args?.options?.fee
|
|
1623
|
+
}
|
|
1624
|
+
})
|
|
389
1625
|
}
|
|
390
1626
|
|
|
391
|
-
private async
|
|
392
|
-
|
|
393
|
-
|
|
1627
|
+
private async SuspendBulkCredentialsWithStatusList2021(args: ICheqdSuspendBulkCredentialsWithStatusList2021Args, context: IContext): Promise<SuspensionResult[]> {
|
|
1628
|
+
// TODO: implement
|
|
1629
|
+
throw new Error('[did-provider-cheqd]: suspension: bulk suspension is not implemented yet')
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
private async UnsuspendCredentialWithStatusList2021(args: ICheqdUnsuspendCredentialWithStatusList2021Args, context: IContext): Promise<UnsuspensionResult> {
|
|
1633
|
+
// validate status purpose
|
|
1634
|
+
if (args.credential.credentialStatus?.statusPurpose !== 'suspension') {
|
|
1635
|
+
throw new Error(`[did-provider-cheqd]: suspension: Unsupported status purpose: ${args.credential.credentialStatus?.statusPurpose}`)
|
|
394
1636
|
}
|
|
395
1637
|
|
|
396
|
-
|
|
397
|
-
|
|
1638
|
+
// validate args in pairs - case: statusListFile and statusList
|
|
1639
|
+
if (args.options?.statusListFile && args.options?.statusList) {
|
|
1640
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile and statusList are mutually exclusive')
|
|
398
1641
|
}
|
|
399
1642
|
|
|
400
|
-
|
|
401
|
-
|
|
1643
|
+
// validate args in pairs - case: statusListFile and fetchList
|
|
1644
|
+
if (args.options?.statusListFile && args.options?.fetchList) {
|
|
1645
|
+
throw new Error('[did-provider-cheqd]: suspension: statusListFile and fetchList are mutually exclusive')
|
|
402
1646
|
}
|
|
403
1647
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const payload = createDidPayload(verificationMethods, [verificationKeys])
|
|
1648
|
+
// validate args in pairs - case: statusList and fetchList
|
|
1649
|
+
if (args.options?.statusList && args.options?.fetchList) {
|
|
1650
|
+
throw new Error('[did-provider-cheqd]: suspension: statusList and fetchList are mutually exclusive')
|
|
1651
|
+
}
|
|
409
1652
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
1653
|
+
// validate args in pairs - case: publish
|
|
1654
|
+
if (args.options?.publish && !args.fetchList && !(args.options?.statusListFile || args.options?.statusList)) {
|
|
1655
|
+
throw new Error('[did-provider-cheqd]: suspension: publish requires statusListFile or statusList, if fetchList is disabled')
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
// suspend credential
|
|
1659
|
+
return await Cheqd.unsuspendCredential(args.credential, {
|
|
1660
|
+
...args.options,
|
|
1661
|
+
topArgs: args,
|
|
1662
|
+
publishOptions: {
|
|
1663
|
+
context,
|
|
1664
|
+
resourceId: args?.options?.resourceId,
|
|
1665
|
+
resourceVersion: args?.options?.resourceVersion,
|
|
1666
|
+
signInputs: args?.options?.signInputs,
|
|
1667
|
+
fee: args?.options?.fee
|
|
1668
|
+
}
|
|
1669
|
+
})
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
private async UnsuspendBulkCredentialsWithStatusList2021(args: ICheqdUnsuspendBulkCredentialsWithStatusList2021Args, context: IContext): Promise<UnsuspensionResult[]> {
|
|
1673
|
+
// TODO: implement
|
|
1674
|
+
throw new Error('[did-provider-cheqd]: suspension: bulk unsuspension is not implemented yet')
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
private async TransactVerifierPaysIssuer(args: ICheqdTransactVerifierPaysIssuerArgs, context: IContext): Promise<TransactionResult> {
|
|
1678
|
+
try {
|
|
1679
|
+
// delegate to provider
|
|
1680
|
+
const transactionResult = await this.didProvider.transactSendTokens({
|
|
1681
|
+
recipientAddress: args.recipientAddress,
|
|
1682
|
+
amount: args.amount,
|
|
1683
|
+
memoNonce: args.memoNonce,
|
|
1684
|
+
txBytes: args.txBytes,
|
|
1685
|
+
})
|
|
1686
|
+
|
|
1687
|
+
// return transaction result
|
|
1688
|
+
return {
|
|
1689
|
+
successful: !transactionResult.code,
|
|
1690
|
+
transactionHash: transactionResult.transactionHash,
|
|
1691
|
+
events: transactionResult.events,
|
|
1692
|
+
rawLog: transactionResult.rawLog,
|
|
1693
|
+
txResponse: args?.returnTxResponse ? transactionResult : undefined
|
|
1694
|
+
} satisfies TransactionResult
|
|
1695
|
+
} catch (error) {
|
|
1696
|
+
// return error
|
|
1697
|
+
return {
|
|
1698
|
+
successful: false,
|
|
1699
|
+
error: error as IError
|
|
1700
|
+
} satisfies TransactionResult
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
private async ObserveVerifierPaysIssuer(args: ICheqdObserveVerifierPaysIssuerArgs, context: IContext): Promise<ObservationResult> {
|
|
1705
|
+
// verify with raw unified access control conditions, if any
|
|
1706
|
+
if (args?.unifiedAccessControlCondition) {
|
|
1707
|
+
try {
|
|
1708
|
+
// define network
|
|
1709
|
+
const network = (function() {
|
|
1710
|
+
switch (args.unifiedAccessControlCondition.chain) {
|
|
1711
|
+
case LitCompatibleCosmosChains.cheqdMainnet:
|
|
1712
|
+
return CheqdNetwork.Mainnet
|
|
1713
|
+
case LitCompatibleCosmosChains.cheqdTestnet:
|
|
1714
|
+
return CheqdNetwork.Testnet
|
|
1715
|
+
default:
|
|
1716
|
+
throw new Error(`[did-provider-cheqd]: observe: Unsupported chain: ${args.unifiedAccessControlCondition.chain}`)
|
|
1717
|
+
}
|
|
1718
|
+
}())
|
|
1719
|
+
|
|
1720
|
+
// construct url
|
|
1721
|
+
const url = `${DefaultRESTUrls[network]}${args.unifiedAccessControlCondition.path}`
|
|
1722
|
+
|
|
1723
|
+
// fetch relevant txs
|
|
1724
|
+
const txs = await (await fetch(url)).json() as ShallowTypedTxsResponse
|
|
1725
|
+
|
|
1726
|
+
// skim through txs for relevant events, in which case memoNonce is present and strict equals to the one provided
|
|
1727
|
+
const meetsConditionTxIndex = txs?.txs?.findIndex(tx => unescapeUnicode(tx.body.memo) === unescapeUnicode(args.unifiedAccessControlCondition!.returnValueTest.value))
|
|
1728
|
+
|
|
1729
|
+
// define meetsCondition
|
|
1730
|
+
const meetsCondition = (typeof meetsConditionTxIndex !== 'undefined' && meetsConditionTxIndex !== -1)
|
|
1731
|
+
|
|
1732
|
+
// return observation result
|
|
1733
|
+
return {
|
|
1734
|
+
subscribed: true,
|
|
1735
|
+
meetsCondition: meetsCondition,
|
|
1736
|
+
transactionHash: meetsCondition ? txs!.tx_responses[meetsConditionTxIndex].txhash : undefined,
|
|
1737
|
+
events: meetsCondition ? txs!.tx_responses[meetsConditionTxIndex].events : undefined,
|
|
1738
|
+
rawLog: meetsCondition ? txs!.tx_responses[meetsConditionTxIndex].raw_log : undefined,
|
|
1739
|
+
txResponse: meetsCondition ? (args?.returnTxResponse ? txs!.tx_responses[meetsConditionTxIndex] : undefined) : undefined
|
|
1740
|
+
} satisfies ObservationResult
|
|
1741
|
+
} catch (error) {
|
|
1742
|
+
// return error
|
|
1743
|
+
return {
|
|
1744
|
+
subscribed: false,
|
|
1745
|
+
meetsCondition: false,
|
|
1746
|
+
error: error as IError
|
|
1747
|
+
} satisfies ObservationResult
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
// validate access control conditions components - case: senderAddress
|
|
1752
|
+
if (!args.senderAddress) {
|
|
1753
|
+
throw new Error('[did-provider-cheqd]: observation: senderAddress is required')
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
// validate access control conditions components - case: recipientAddress
|
|
1757
|
+
if (!args.recipientAddress) {
|
|
1758
|
+
throw new Error('[did-provider-cheqd]: observation: recipientAddress is required')
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
// validate access control conditions components - case: amount
|
|
1762
|
+
if (!args.amount || !args.amount.amount || !args.amount.denom || args.amount.denom !== 'ncheq') {
|
|
1763
|
+
throw new Error('[did-provider-cheqd]: observation: amount is required, and must be an object with amount and denom valid string properties, amongst which denom must be `ncheq`')
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
// validate access control conditions components - case: memoNonce
|
|
1767
|
+
if (!args.memoNonce) {
|
|
1768
|
+
throw new Error('[did-provider-cheqd]: observation: memoNonce is required')
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
// validate access control conditions components - case: network
|
|
1772
|
+
if (!args.network) {
|
|
1773
|
+
throw new Error('[did-provider-cheqd]: observation: network is required')
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
try {
|
|
1777
|
+
// otherwise, construct url, as per components
|
|
1778
|
+
const url = `${DefaultRESTUrls[args.network]}/cosmos/tx/v1beta1/txs?events=transfer.recipient='${args.recipientAddress}'&events=transfer.sender='${args.senderAddress}'&events=transfer.amount='${args.amount.amount}${args.amount.denom}'`
|
|
1779
|
+
|
|
1780
|
+
// fetch relevant txs
|
|
1781
|
+
const txs = await (await fetch(url)).json() as ShallowTypedTxsResponse
|
|
1782
|
+
|
|
1783
|
+
// skim through txs for relevant events, in which case memoNonce is present and strict equals to the one provided
|
|
1784
|
+
const meetsConditionTxIndex = txs?.txs?.findIndex(tx => unescapeUnicode(tx.body.memo) === unescapeUnicode(args.memoNonce))
|
|
1785
|
+
|
|
1786
|
+
// define meetsCondition
|
|
1787
|
+
const meetsCondition = (typeof meetsConditionTxIndex !== 'undefined' && meetsConditionTxIndex !== -1)
|
|
1788
|
+
|
|
1789
|
+
// return observation result
|
|
1790
|
+
return {
|
|
1791
|
+
subscribed: true,
|
|
1792
|
+
meetsCondition: meetsCondition,
|
|
1793
|
+
transactionHash: meetsCondition ? txs!.tx_responses[meetsConditionTxIndex].txhash : undefined,
|
|
1794
|
+
events: meetsCondition ? txs!.tx_responses[meetsConditionTxIndex].events : undefined,
|
|
1795
|
+
rawLog: meetsCondition ? txs!.tx_responses[meetsConditionTxIndex].raw_log : undefined,
|
|
1796
|
+
txResponse: meetsCondition ? (args?.returnTxResponse ? txs!.tx_responses[meetsConditionTxIndex] : undefined) : undefined
|
|
1797
|
+
} satisfies ObservationResult
|
|
1798
|
+
} catch (error) {
|
|
1799
|
+
// return error
|
|
1800
|
+
return {
|
|
1801
|
+
subscribed: false,
|
|
1802
|
+
meetsCondition: false,
|
|
1803
|
+
error: error as IError
|
|
1804
|
+
} satisfies ObservationResult
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
static async revokeCredential(credential: VerifiableCredential, options?: ICheqdStatusList2021Options): Promise<RevocationResult> {
|
|
1809
|
+
try {
|
|
1810
|
+
// validate status purpose
|
|
1811
|
+
if (credential?.credentialStatus?.statusPurpose !== 'revocation') throw new Error('[did-provider-cheqd]: revocation: Invalid status purpose')
|
|
1812
|
+
|
|
1813
|
+
// fetch status list 2021 metadata
|
|
1814
|
+
const metadata = (await Cheqd.fetchStatusList2021Metadata(credential))
|
|
1815
|
+
|
|
1816
|
+
// detect if encrypted
|
|
1817
|
+
const isEncrypted = function() {
|
|
1818
|
+
switch (metadata.mediaType) {
|
|
1819
|
+
case 'application/octet-stream':
|
|
1820
|
+
return true
|
|
1821
|
+
case 'application/gzip':
|
|
1822
|
+
return false
|
|
1823
|
+
default:
|
|
1824
|
+
throw new Error(`[did-provider-cheqd]: revocation: Unsupported media type: ${metadata.mediaType}`)
|
|
419
1825
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
1826
|
+
}()
|
|
1827
|
+
|
|
1828
|
+
// early return, if encrypted and no decryption key provided
|
|
1829
|
+
if (isEncrypted && !options?.topArgs?.symmetricKey) throw new Error('[did-provider-cheqd]: revocation: symmetricKey is required, if status list 2021 is encrypted')
|
|
1830
|
+
|
|
1831
|
+
// fetch status list 2021 inscribed in credential
|
|
1832
|
+
const statusList2021 = options?.topArgs?.fetchList
|
|
1833
|
+
? (await async function () {
|
|
1834
|
+
// if not encrypted, return bitstring
|
|
1835
|
+
if (!isEncrypted) return await Cheqd.fetchStatusList2021(credential)
|
|
1836
|
+
|
|
1837
|
+
// otherwise, decrypt and return bitstring
|
|
1838
|
+
const scopedRawBlob = await toBlob(await Cheqd.fetchStatusList2021(credential, true) as Uint8Array)
|
|
1839
|
+
|
|
1840
|
+
// decrypt
|
|
1841
|
+
return await LitProtocol.decryptDirect(scopedRawBlob, fromString(options?.topArgs?.symmetricKey, 'hex'))
|
|
1842
|
+
}())
|
|
1843
|
+
: (await async function () {
|
|
1844
|
+
// if status list 2021 is not fetched, read from file
|
|
1845
|
+
if (options?.statusListFile) {
|
|
1846
|
+
// if not encrypted, return bitstring
|
|
1847
|
+
if (!isEncrypted) return new StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode()
|
|
1848
|
+
|
|
1849
|
+
// otherwise, decrypt and return bitstring
|
|
1850
|
+
const scopedRawBlob = await toBlob(await Cheqd.getFile(options.statusListFile))
|
|
1851
|
+
|
|
1852
|
+
// decrypt
|
|
1853
|
+
return await LitProtocol.decryptDirect(scopedRawBlob, fromString(options?.topArgs?.symmetricKey, 'hex'))
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
if (!options?.statusListInlineBitstring) throw new Error('[did-provider-cheqd]: revocation: statusListInlineBitstring is required, if statusListFile is not provided')
|
|
1857
|
+
|
|
1858
|
+
// otherwise, read from inline bitstring
|
|
1859
|
+
return options?.statusListInlineBitstring
|
|
1860
|
+
}())
|
|
1861
|
+
|
|
1862
|
+
// parse status list 2021
|
|
1863
|
+
const statusList = await StatusList.decode({ encodedList: statusList2021 })
|
|
1864
|
+
|
|
1865
|
+
// early exit, if credential is already revoked
|
|
1866
|
+
if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex))) return { revoked: false }
|
|
1867
|
+
|
|
1868
|
+
// update revocation status
|
|
1869
|
+
statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true)
|
|
1870
|
+
|
|
1871
|
+
// set in-memory status list ref
|
|
1872
|
+
const bitstring = await statusList.encode() as Bitstring
|
|
1873
|
+
|
|
1874
|
+
// cast top-level args
|
|
1875
|
+
const topArgs = options?.topArgs as ICheqdRevokeCredentialWithStatusList2021Args
|
|
1876
|
+
|
|
1877
|
+
// write status list 2021 to file, if provided
|
|
1878
|
+
if (topArgs?.writeToFile) {
|
|
1879
|
+
await Cheqd.writeFile(fromString(bitstring, 'base64url'), options?.statusListFile)
|
|
431
1880
|
}
|
|
1881
|
+
|
|
1882
|
+
// publish status list 2021, if provided
|
|
1883
|
+
const published = topArgs?.publish
|
|
1884
|
+
? (await async function () {
|
|
1885
|
+
// fetch status list 2021 metadata
|
|
1886
|
+
const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credential)
|
|
1887
|
+
|
|
1888
|
+
// publish status list 2021 as new version
|
|
1889
|
+
const scoped = topArgs.publishEncrypted
|
|
1890
|
+
? (await async function () {
|
|
1891
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
1892
|
+
const lit = await LitProtocol.create({
|
|
1893
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
1894
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
1895
|
+
})
|
|
1896
|
+
|
|
1897
|
+
// encrypt
|
|
1898
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, options?.topArgs?.encryptionOptions?.unifiedAccessControlConditions, true)
|
|
1899
|
+
|
|
1900
|
+
// return tuple of publish result and encryption relevant metadata
|
|
1901
|
+
return [
|
|
1902
|
+
await Cheqd.publishStatusList2021(new Uint8Array(await encryptedString.arrayBuffer()), statusListMetadata, options?.publishOptions),
|
|
1903
|
+
{ encryptedString, encryptedSymmetricKey, symmetricKey: toString(symmetricKey!, 'hex') }
|
|
1904
|
+
]
|
|
1905
|
+
}())
|
|
1906
|
+
: [await Cheqd.publishStatusList2021(fromString(bitstring, 'base64url'), statusListMetadata, options?.publishOptions), undefined]
|
|
1907
|
+
|
|
1908
|
+
// early exit, if publish failed
|
|
1909
|
+
if (!scoped[0]) throw new Error('[did-provider-cheqd]: revocation: Failed to publish status list 2021')
|
|
1910
|
+
|
|
1911
|
+
// return publish result
|
|
1912
|
+
return scoped
|
|
1913
|
+
}())
|
|
1914
|
+
: undefined
|
|
1915
|
+
|
|
1916
|
+
return {
|
|
1917
|
+
revoked: true,
|
|
1918
|
+
published: topArgs?.publish ? true : undefined,
|
|
1919
|
+
statusList: topArgs?.returnUpdatedStatusList ? bitstring : undefined,
|
|
1920
|
+
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await blobToHexString((published?.[1] as { encryptedString: Blob })?.encryptedString) : undefined,
|
|
1921
|
+
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? (published?.[1] as { encryptedSymmetricKey: string })?.encryptedSymmetricKey : undefined,
|
|
1922
|
+
symmetricKey: topArgs?.returnSymmetricKey ? (published?.[1] as { symmetricKey: string })?.symmetricKey : undefined,
|
|
1923
|
+
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credential) : undefined
|
|
1924
|
+
} satisfies RevocationResult
|
|
1925
|
+
} catch (error) {
|
|
1926
|
+
// silent fail + early exit, optimised for parallelisation, use with Promise.allSettled
|
|
1927
|
+
console.error(error)
|
|
1928
|
+
|
|
1929
|
+
return { revoked: false, error: error as IError } satisfies RevocationResult
|
|
432
1930
|
}
|
|
433
1931
|
}
|
|
434
1932
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
1933
|
+
static async suspendCredential(credential: VerifiableCredential, options?: ICheqdStatusList2021Options): Promise<SuspensionResult> {
|
|
1934
|
+
try {
|
|
1935
|
+
// validate status purpose
|
|
1936
|
+
if (credential?.credentialStatus?.statusPurpose !== 'suspension') throw new Error('[did-provider-cheqd]: suspension: Invalid status purpose')
|
|
1937
|
+
|
|
1938
|
+
// fetch status list 2021 metadata
|
|
1939
|
+
const metadata = (await Cheqd.fetchStatusList2021Metadata(credential))
|
|
1940
|
+
|
|
1941
|
+
// detect if encrypted
|
|
1942
|
+
const isEncrypted = function() {
|
|
1943
|
+
switch (metadata.mediaType) {
|
|
1944
|
+
case 'application/octet-stream':
|
|
1945
|
+
return true
|
|
1946
|
+
case 'application/gzip':
|
|
1947
|
+
return false
|
|
1948
|
+
default:
|
|
1949
|
+
throw new Error(`[did-provider-cheqd]: suspension: Unsupported media type: ${metadata.mediaType}`)
|
|
1950
|
+
}
|
|
1951
|
+
}()
|
|
1952
|
+
|
|
1953
|
+
// early return, if encrypted and no decryption key provided
|
|
1954
|
+
if (isEncrypted && !options?.topArgs?.symmetricKey) throw new Error('[did-provider-cheqd]: suspension: symmetricKey is required, if status list 2021 is encrypted')
|
|
1955
|
+
|
|
1956
|
+
// fetch status list 2021 inscribed in credential
|
|
1957
|
+
const statusList2021 = options?.topArgs?.fetchList
|
|
1958
|
+
? (await async function () {
|
|
1959
|
+
// if not encrypted, return bitstring
|
|
1960
|
+
if (!isEncrypted) return await Cheqd.fetchStatusList2021(credential)
|
|
1961
|
+
|
|
1962
|
+
// otherwise, decrypt and return bitstring
|
|
1963
|
+
const scopedRawBlob = await toBlob(await Cheqd.fetchStatusList2021(credential, true) as Uint8Array)
|
|
1964
|
+
|
|
1965
|
+
// decrypt
|
|
1966
|
+
return await LitProtocol.decryptDirect(scopedRawBlob, fromString(options?.topArgs?.symmetricKey, 'hex'))
|
|
1967
|
+
}())
|
|
1968
|
+
: (await async function () {
|
|
1969
|
+
// if status list 2021 is not fetched, read from file
|
|
1970
|
+
if (options?.statusListFile) {
|
|
1971
|
+
// if not encrypted, return bitstring
|
|
1972
|
+
if (!isEncrypted) return new StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode()
|
|
1973
|
+
|
|
1974
|
+
// otherwise, decrypt and return bitstring
|
|
1975
|
+
const scopedRawBlob = await toBlob(await Cheqd.getFile(options.statusListFile))
|
|
1976
|
+
|
|
1977
|
+
// decrypt
|
|
1978
|
+
return await LitProtocol.decryptDirect(scopedRawBlob, fromString(options?.topArgs?.symmetricKey, 'hex'))
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
if (!options?.statusListInlineBitstring) throw new Error('[did-provider-cheqd]: suspension: statusListInlineBitstring is required, if statusListFile is not provided')
|
|
1982
|
+
|
|
1983
|
+
// otherwise, read from inline bitstring
|
|
1984
|
+
return options?.statusListInlineBitstring
|
|
1985
|
+
}())
|
|
1986
|
+
|
|
1987
|
+
// parse status list 2021
|
|
1988
|
+
const statusList = await StatusList.decode({ encodedList: statusList2021 })
|
|
1989
|
+
|
|
1990
|
+
// early exit, if already suspended
|
|
1991
|
+
if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex))) return { suspended: false } satisfies SuspensionResult
|
|
1992
|
+
|
|
1993
|
+
// update suspension status
|
|
1994
|
+
statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true)
|
|
1995
|
+
|
|
1996
|
+
// set in-memory status list ref
|
|
1997
|
+
const bitstring = await statusList.encode() as Bitstring
|
|
1998
|
+
|
|
1999
|
+
// cast top-level args
|
|
2000
|
+
const topArgs = options?.topArgs as ICheqdSuspendCredentialWithStatusList2021Args
|
|
2001
|
+
|
|
2002
|
+
// write status list 2021 to file, if provided
|
|
2003
|
+
if (topArgs?.writeToFile) {
|
|
2004
|
+
await Cheqd.writeFile(fromString(bitstring, 'base64url'), options?.statusListFile)
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
// publish status list 2021, if provided
|
|
2008
|
+
const published = topArgs?.publish
|
|
2009
|
+
? (await async function () {
|
|
2010
|
+
// fetch status list 2021 metadata
|
|
2011
|
+
const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credential)
|
|
2012
|
+
|
|
2013
|
+
// publish status list 2021 as new version
|
|
2014
|
+
const scoped = topArgs.publishEncrypted
|
|
2015
|
+
? (await async function () {
|
|
2016
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2017
|
+
const lit = await LitProtocol.create({
|
|
2018
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
2019
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
2020
|
+
})
|
|
2021
|
+
|
|
2022
|
+
// encrypt
|
|
2023
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, options?.topArgs?.encryptionOptions?.unifiedAccessControlConditions, true)
|
|
2024
|
+
|
|
2025
|
+
// return tuple of publish result and encryption relevant metadata
|
|
2026
|
+
return [
|
|
2027
|
+
await Cheqd.publishStatusList2021(new Uint8Array(await encryptedString.arrayBuffer()), statusListMetadata, options?.publishOptions),
|
|
2028
|
+
{ encryptedString, encryptedSymmetricKey, symmetricKey: toString(symmetricKey!, 'hex') }
|
|
2029
|
+
]
|
|
2030
|
+
}())
|
|
2031
|
+
: [await Cheqd.publishStatusList2021(fromString(bitstring, 'base64url'), statusListMetadata, options?.publishOptions), undefined]
|
|
2032
|
+
|
|
2033
|
+
// early exit, if publish failed
|
|
2034
|
+
if (!scoped[0]) throw new Error('[did-provider-cheqd]: suspension: Failed to publish status list 2021')
|
|
2035
|
+
|
|
2036
|
+
// return publish result
|
|
2037
|
+
return scoped
|
|
2038
|
+
}())
|
|
2039
|
+
: undefined
|
|
2040
|
+
|
|
2041
|
+
return {
|
|
2042
|
+
suspended: true,
|
|
2043
|
+
published: topArgs?.publish ? true : undefined,
|
|
2044
|
+
statusList: topArgs?.returnUpdatedStatusList ? bitstring : undefined,
|
|
2045
|
+
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await blobToHexString((published?.[1] as { encryptedString: Blob })?.encryptedString) : undefined,
|
|
2046
|
+
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? (published?.[1] as { encryptedSymmetricKey: string })?.encryptedSymmetricKey : undefined,
|
|
2047
|
+
symmetricKey: topArgs?.returnSymmetricKey ? (published?.[1] as { symmetricKey: string })?.symmetricKey : undefined,
|
|
2048
|
+
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credential) : undefined
|
|
2049
|
+
} satisfies SuspensionResult
|
|
2050
|
+
} catch (error) {
|
|
2051
|
+
// silent fail + early exit, optimised for parallelisation, use with Promise.allSettled
|
|
2052
|
+
console.error(error)
|
|
2053
|
+
|
|
2054
|
+
return { suspended: false, error: error as IError } satisfies SuspensionResult
|
|
442
2055
|
}
|
|
443
2056
|
}
|
|
444
2057
|
|
|
445
|
-
|
|
446
|
-
|
|
2058
|
+
static async unsuspendCredential(credential: VerifiableCredential, options?: ICheqdStatusList2021Options): Promise<UnsuspensionResult> {
|
|
2059
|
+
try {
|
|
2060
|
+
// validate status purpose
|
|
2061
|
+
if (credential?.credentialStatus?.statusPurpose !== 'suspension') throw new Error('[did-provider-cheqd]: unsuspension: Invalid status purpose')
|
|
2062
|
+
|
|
2063
|
+
// fetch status list 2021 metadata
|
|
2064
|
+
const metadata = (await Cheqd.fetchStatusList2021Metadata(credential))
|
|
2065
|
+
|
|
2066
|
+
// detect if encrypted
|
|
2067
|
+
const isEncrypted = function() {
|
|
2068
|
+
switch (metadata.mediaType) {
|
|
2069
|
+
case 'application/octet-stream':
|
|
2070
|
+
return true
|
|
2071
|
+
case 'application/gzip':
|
|
2072
|
+
return false
|
|
2073
|
+
default:
|
|
2074
|
+
throw new Error(`[did-provider-cheqd]: unsuspension: Unsupported media type: ${metadata.mediaType}`)
|
|
2075
|
+
}
|
|
2076
|
+
}()
|
|
2077
|
+
|
|
2078
|
+
// early return, if encrypted and no decryption key provided
|
|
2079
|
+
if (isEncrypted && !options?.topArgs?.symmetricKey) throw new Error('[did-provider-cheqd]: unsuspension: symmetricKey is required, if status list 2021 is encrypted')
|
|
2080
|
+
|
|
2081
|
+
// fetch status list 2021 inscribed in credential
|
|
2082
|
+
const statusList2021 = options?.topArgs?.fetchList
|
|
2083
|
+
? (await async function () {
|
|
2084
|
+
// if not encrypted, return bitstring
|
|
2085
|
+
if (!isEncrypted) return await Cheqd.fetchStatusList2021(credential)
|
|
2086
|
+
|
|
2087
|
+
// otherwise, decrypt and return bitstring
|
|
2088
|
+
const scopedRawBlob = await toBlob(await Cheqd.fetchStatusList2021(credential, true) as Uint8Array)
|
|
2089
|
+
|
|
2090
|
+
// decrypt
|
|
2091
|
+
return await LitProtocol.decryptDirect(scopedRawBlob, fromString(options?.topArgs?.symmetricKey, 'hex'))
|
|
2092
|
+
}())
|
|
2093
|
+
: (await async function () {
|
|
2094
|
+
// if status list 2021 is not fetched, read from file
|
|
2095
|
+
if (options?.statusListFile) {
|
|
2096
|
+
// if not encrypted, return bitstring
|
|
2097
|
+
if (!isEncrypted) return new StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode()
|
|
2098
|
+
|
|
2099
|
+
// otherwise, decrypt and return bitstring
|
|
2100
|
+
const scopedRawBlob = await toBlob(await Cheqd.getFile(options.statusListFile))
|
|
2101
|
+
|
|
2102
|
+
// decrypt
|
|
2103
|
+
return await LitProtocol.decryptDirect(scopedRawBlob, fromString(options?.topArgs?.symmetricKey, 'hex'))
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
if (!options?.statusListInlineBitstring) throw new Error('[did-provider-cheqd]: unsuspension: statusListInlineBitstring is required, if statusListFile is not provided')
|
|
2107
|
+
|
|
2108
|
+
// otherwise, read from inline bitstring
|
|
2109
|
+
return options?.statusListInlineBitstring
|
|
2110
|
+
}())
|
|
2111
|
+
|
|
2112
|
+
// parse status list 2021
|
|
2113
|
+
const statusList = await StatusList.decode({ encodedList: statusList2021 })
|
|
2114
|
+
|
|
2115
|
+
// early exit, if already suspended
|
|
2116
|
+
if (statusList.getStatus(Number(credential.credentialStatus.statusListIndex))) return { unsuspended: false } satisfies UnsuspensionResult
|
|
2117
|
+
|
|
2118
|
+
// update suspension status
|
|
2119
|
+
statusList.setStatus(Number(credential.credentialStatus.statusListIndex), true)
|
|
2120
|
+
|
|
2121
|
+
// set in-memory status list ref
|
|
2122
|
+
const bitstring = await statusList.encode() as Bitstring
|
|
2123
|
+
|
|
2124
|
+
// cast top-level args
|
|
2125
|
+
const topArgs = options?.topArgs as ICheqdSuspendCredentialWithStatusList2021Args
|
|
2126
|
+
|
|
2127
|
+
// write status list 2021 to file, if provided
|
|
2128
|
+
if (topArgs?.writeToFile) {
|
|
2129
|
+
await Cheqd.writeFile(fromString(bitstring, 'base64url'), options?.statusListFile)
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
// publish status list 2021, if provided
|
|
2133
|
+
const published = topArgs?.publish
|
|
2134
|
+
? (await async function () {
|
|
2135
|
+
// fetch status list 2021 metadata
|
|
2136
|
+
const statusListMetadata = await Cheqd.fetchStatusList2021Metadata(credential)
|
|
2137
|
+
|
|
2138
|
+
// publish status list 2021 as new version
|
|
2139
|
+
const scoped = topArgs.publishEncrypted
|
|
2140
|
+
? (await async function () {
|
|
2141
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2142
|
+
const lit = await LitProtocol.create({
|
|
2143
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
2144
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
2145
|
+
})
|
|
2146
|
+
|
|
2147
|
+
// encrypt
|
|
2148
|
+
const { encryptedString, encryptedSymmetricKey, symmetricKey } = await lit.encrypt(bitstring, options?.topArgs?.encryptionOptions?.unifiedAccessControlConditions, true)
|
|
2149
|
+
|
|
2150
|
+
// return tuple of publish result and encryption relevant metadata
|
|
2151
|
+
return [
|
|
2152
|
+
await Cheqd.publishStatusList2021(new Uint8Array(await encryptedString.arrayBuffer()), statusListMetadata, options?.publishOptions),
|
|
2153
|
+
{ encryptedString, encryptedSymmetricKey, symmetricKey: toString(symmetricKey!, 'hex') }
|
|
2154
|
+
]
|
|
2155
|
+
}())
|
|
2156
|
+
: [await Cheqd.publishStatusList2021(fromString(bitstring, 'base64url'), statusListMetadata, options?.publishOptions), undefined]
|
|
2157
|
+
|
|
2158
|
+
// early exit, if publish failed
|
|
2159
|
+
if (!scoped[0]) throw new Error('[did-provider-cheqd]: unsuspension: Failed to publish status list 2021')
|
|
2160
|
+
|
|
2161
|
+
// return publish result
|
|
2162
|
+
return scoped
|
|
2163
|
+
}())
|
|
2164
|
+
: undefined
|
|
2165
|
+
|
|
2166
|
+
return {
|
|
2167
|
+
unsuspended: true,
|
|
2168
|
+
published: topArgs?.publish ? true : undefined,
|
|
2169
|
+
statusList: topArgs?.returnUpdatedStatusList ? bitstring : undefined,
|
|
2170
|
+
encryptedStatusList: topArgs?.returnUpdatedEncryptedStatusList ? await blobToHexString((published?.[1] as { encryptedString: Blob })?.encryptedString) : undefined,
|
|
2171
|
+
encryptedSymmetricKey: topArgs?.returnEncryptedSymmetricKey ? (published?.[1] as { encryptedSymmetricKey: string })?.encryptedSymmetricKey : undefined,
|
|
2172
|
+
symmetricKey: topArgs?.returnSymmetricKey ? (published?.[1] as { symmetricKey: string })?.symmetricKey : undefined,
|
|
2173
|
+
resourceMetadata: topArgs?.returnStatusListMetadata ? await Cheqd.fetchStatusList2021Metadata(credential) : undefined
|
|
2174
|
+
} satisfies UnsuspensionResult
|
|
2175
|
+
} catch (error) {
|
|
2176
|
+
// silent fail + early exit, optimised for parallelisation, use with Promise.allSettled
|
|
2177
|
+
console.error(error)
|
|
2178
|
+
|
|
2179
|
+
return { unsuspended: false, error: error as IError } satisfies UnsuspensionResult
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
static async checkRevoked(credential: VerifiableCredential, options: ICheqdStatusList2021Options = { fetchList: true }): Promise<boolean> {
|
|
2184
|
+
// validate status purpose
|
|
2185
|
+
if (credential.credentialStatus?.statusPurpose !== 'revocation') {
|
|
2186
|
+
throw new Error(`[did-provider-cheqd]: revocation: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`)
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
// fetch status list 2021 metadata
|
|
2190
|
+
const metadata = (await Cheqd.fetchStatusList2021Metadata(credential))
|
|
2191
|
+
|
|
2192
|
+
// detect if encrypted
|
|
2193
|
+
const isEncrypted = function() {
|
|
2194
|
+
switch (metadata.mediaType) {
|
|
2195
|
+
case 'application/octet-stream':
|
|
2196
|
+
return true
|
|
2197
|
+
case 'application/gzip':
|
|
2198
|
+
return false
|
|
2199
|
+
default:
|
|
2200
|
+
throw new Error(`[did-provider-cheqd]: revocation: Unsupported media type: ${metadata.mediaType}`)
|
|
2201
|
+
}
|
|
2202
|
+
}()
|
|
2203
|
+
|
|
2204
|
+
// early return, if encrypted and decryption key is not provided
|
|
2205
|
+
if (isEncrypted && !options?.topArgs?.encryptedSymmetricKey) throw new Error('[did-provider-cheqd]: revocation: encryptedSymmetricKey is required, if status list 2021 is encrypted')
|
|
2206
|
+
|
|
2207
|
+
// fetch status list 2021 inscribed in credential
|
|
2208
|
+
const statusList2021 = options?.topArgs?.fetchList
|
|
2209
|
+
? (await async function () {
|
|
2210
|
+
// if not encrypted, return bitstring
|
|
2211
|
+
if (!isEncrypted) return await Cheqd.fetchStatusList2021(credential)
|
|
2212
|
+
|
|
2213
|
+
// otherwise, decrypt and return bitstring
|
|
2214
|
+
const scopedRawBlob = await toBlob(await Cheqd.fetchStatusList2021(credential, true) as Uint8Array)
|
|
2215
|
+
|
|
2216
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2217
|
+
const lit = await LitProtocol.create({
|
|
2218
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
2219
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
2220
|
+
})
|
|
2221
|
+
|
|
2222
|
+
// decrypt
|
|
2223
|
+
return await lit.decrypt(scopedRawBlob, options?.topArgs?.encryptedSymmetricKey, options?.topArgs?.decryptionOptions?.unifiedAccessControlConditions)
|
|
2224
|
+
}())
|
|
2225
|
+
: (await async function () {
|
|
2226
|
+
// if status list 2021 is not fetched, read from file
|
|
2227
|
+
if (options?.statusListFile) {
|
|
2228
|
+
// if not encrypted, return bitstring
|
|
2229
|
+
if (!isEncrypted) return new StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode()
|
|
2230
|
+
|
|
2231
|
+
// otherwise, decrypt and return bitstring
|
|
2232
|
+
const scopedRawBlob = await toBlob(await Cheqd.getFile(options.statusListFile))
|
|
2233
|
+
|
|
2234
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2235
|
+
const lit = await LitProtocol.create({
|
|
2236
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
2237
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
2238
|
+
})
|
|
2239
|
+
|
|
2240
|
+
// decrypt
|
|
2241
|
+
return await lit.decrypt(scopedRawBlob, options?.topArgs?.encryptedSymmetricKey, options?.topArgs?.decryptionOptions?.unifiedAccessControlConditions)
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
if (!options?.statusListInlineBitstring) throw new Error(' [did-provider-cheqd]: revocation: statusListInlineBitstring is required, if statusListFile is not provided')
|
|
2245
|
+
|
|
2246
|
+
// otherwise, read from inline bitstring
|
|
2247
|
+
return options?.statusListInlineBitstring
|
|
2248
|
+
}())
|
|
2249
|
+
|
|
2250
|
+
// parse status list 2021
|
|
2251
|
+
const statusList = await StatusList.decode({ encodedList: statusList2021 })
|
|
2252
|
+
|
|
2253
|
+
// get status by index
|
|
2254
|
+
return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex))
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
static async checkSuspended(credential: VerifiableCredential, options: ICheqdStatusList2021Options = { fetchList: true }): Promise<boolean> {
|
|
2258
|
+
// validate status purpose
|
|
2259
|
+
if (credential.credentialStatus?.statusPurpose !== 'suspension') {
|
|
2260
|
+
throw new Error(`[did-provider-cheqd]: suspension: Unsupported status purpose: ${credential.credentialStatus?.statusPurpose}`)
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
// fetch status list 2021 metadata
|
|
2264
|
+
const metadata = (await Cheqd.fetchStatusList2021Metadata(credential))
|
|
2265
|
+
|
|
2266
|
+
// detect if encrypted
|
|
2267
|
+
const isEncrypted = function() {
|
|
2268
|
+
switch (metadata.mediaType) {
|
|
2269
|
+
case 'application/octet-stream':
|
|
2270
|
+
return true
|
|
2271
|
+
case 'application/gzip':
|
|
2272
|
+
return false
|
|
2273
|
+
default:
|
|
2274
|
+
throw new Error(`[did-provider-cheqd]: suspension: Unsupported media type: ${metadata.mediaType}`)
|
|
2275
|
+
}
|
|
2276
|
+
}()
|
|
2277
|
+
|
|
2278
|
+
// early return, if encrypted and decryption key is not provided
|
|
2279
|
+
if (isEncrypted && !options?.topArgs?.encryptedSymmetricKey) throw new Error('[did-provider-cheqd]: suspension: encryptedSymmetricKey is required, if status list 2021 is encrypted')
|
|
2280
|
+
|
|
2281
|
+
// fetch status list 2021 inscribed in credential
|
|
2282
|
+
const statusList2021 = options?.topArgs?.fetchList
|
|
2283
|
+
? (await async function () {
|
|
2284
|
+
// if not encrypted, return bitstring
|
|
2285
|
+
if (!isEncrypted) return await Cheqd.fetchStatusList2021(credential)
|
|
2286
|
+
|
|
2287
|
+
// otherwise, decrypt and return bitstring
|
|
2288
|
+
const scopedRawBlob = await toBlob(await Cheqd.fetchStatusList2021(credential, true) as Uint8Array)
|
|
2289
|
+
|
|
2290
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2291
|
+
const lit = await LitProtocol.create({
|
|
2292
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
2293
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
2294
|
+
})
|
|
2295
|
+
|
|
2296
|
+
// decrypt
|
|
2297
|
+
return await lit.decrypt(scopedRawBlob, options?.topArgs?.encryptedSymmetricKey, options?.topArgs?.decryptionOptions?.unifiedAccessControlConditions)
|
|
2298
|
+
}())
|
|
2299
|
+
: (await async function () {
|
|
2300
|
+
// if status list 2021 is not fetched, read from file
|
|
2301
|
+
if (options?.statusListFile) {
|
|
2302
|
+
// if not encrypted, return bitstring
|
|
2303
|
+
if (!isEncrypted) return new StatusList({ buffer: await Cheqd.getFile(options.statusListFile) }).encode()
|
|
2304
|
+
|
|
2305
|
+
// otherwise, decrypt and return bitstring
|
|
2306
|
+
const scopedRawBlob = await toBlob(await Cheqd.getFile(options.statusListFile))
|
|
2307
|
+
|
|
2308
|
+
// instantiate dkg-threshold client, in which case lit-protocol is used
|
|
2309
|
+
const lit = await LitProtocol.create({
|
|
2310
|
+
chain: options?.topArgs?.bootstrapOptions?.chain,
|
|
2311
|
+
litNetwork: options?.topArgs?.bootstrapOptions?.litNetwork
|
|
2312
|
+
})
|
|
2313
|
+
|
|
2314
|
+
// decrypt
|
|
2315
|
+
return await lit.decrypt(scopedRawBlob, options?.topArgs?.encryptedSymmetricKey, options?.topArgs?.decryptionOptions?.unifiedAccessControlConditions)
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2318
|
+
if (!options?.statusListInlineBitstring) throw new Error(' [did-provider-cheqd]: suspension: statusListInlineBitstring is required, if statusListFile is not provided')
|
|
2319
|
+
|
|
2320
|
+
// otherwise, read from inline bitstring
|
|
2321
|
+
return options?.statusListInlineBitstring
|
|
2322
|
+
}())
|
|
2323
|
+
|
|
2324
|
+
// parse status list 2021
|
|
2325
|
+
const statusList = await StatusList.decode({ encodedList: statusList2021 })
|
|
2326
|
+
|
|
2327
|
+
// get status by index
|
|
2328
|
+
return !!statusList.getStatus(Number(credential.credentialStatus.statusListIndex))
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
static async publishStatusList2021(statusList2021Raw: Uint8Array, statusList2021Metadata: LinkedResourceMetadataResolutionResult, options: { context: IContext, resourceId?: string, resourceVersion?: string, signInputs?: ISignInputs[], fee?: DidStdFee }): Promise<boolean> {
|
|
2332
|
+
// construct status list 2021 payload from previous version + new version
|
|
2333
|
+
const payload = {
|
|
2334
|
+
collectionId: statusList2021Metadata.resourceCollectionId,
|
|
2335
|
+
id: options?.resourceId || v4(),
|
|
2336
|
+
name: statusList2021Metadata.resourceName,
|
|
2337
|
+
version: options?.resourceVersion || new Date().toISOString(),
|
|
2338
|
+
resourceType: 'StatusList2021',
|
|
2339
|
+
data: statusList2021Raw
|
|
2340
|
+
} satisfies StatusList2021ResourcePayload
|
|
2341
|
+
|
|
2342
|
+
return await options.context.agent[CreateStatusList2021MethodName]({
|
|
2343
|
+
kms: (await options.context.agent.keyManagerGetKeyManagementSystems())[0],
|
|
2344
|
+
payload,
|
|
2345
|
+
network: statusList2021Metadata.resourceURI.split(':')[2] as CheqdNetwork,
|
|
2346
|
+
signInputs: options?.signInputs,
|
|
2347
|
+
fee: options?.fee
|
|
2348
|
+
})
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
static async fetchStatusList2021(credential: VerifiableCredential, returnRaw = false): Promise<Bitstring | Uint8Array> {
|
|
2352
|
+
// validate credential status
|
|
2353
|
+
if (!credential.credentialStatus) throw new Error('[did-provider-cheqd]: fetch status list: Credential status is not present')
|
|
2354
|
+
|
|
2355
|
+
// validate credential status type
|
|
2356
|
+
if (credential.credentialStatus.type !== 'StatusList2021Entry') throw new Error('[did-provider-cheqd]: fetch status list: Credential status type is not valid')
|
|
2357
|
+
|
|
2358
|
+
// validate credential status list status purpose
|
|
2359
|
+
if (credential.credentialStatus.statusPurpose !== 'revocation' && credential.credentialStatus.statusPurpose !== 'suspension') throw new Error('[did-provider-cheqd]: fetch status list: Credential status purpose is not valid')
|
|
2360
|
+
|
|
2361
|
+
// validate credential status list status list credential
|
|
2362
|
+
if (!credential.credentialStatus.statusListCredential) throw new Error('[did-provider-cheqd]: fetch status list: Credential status list credential is not present')
|
|
2363
|
+
|
|
2364
|
+
// fetch status list 2021
|
|
2365
|
+
const raw = await (await fetch(credential.credentialStatus.statusListCredential)).arrayBuffer()
|
|
2366
|
+
|
|
2367
|
+
// return raw if requested
|
|
2368
|
+
if (returnRaw) return new Uint8Array(raw)
|
|
2369
|
+
|
|
2370
|
+
// otherwise, parse to bitstring and return
|
|
2371
|
+
const bitstring = toString(new Uint8Array(raw), 'base64url')
|
|
2372
|
+
|
|
2373
|
+
return bitstring
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
static async fetchStatusList2021Metadata(credential: VerifiableCredential): Promise<LinkedResourceMetadataResolutionResult> {
|
|
2377
|
+
// get base url
|
|
2378
|
+
const baseUrl = new URL(credential.credentialStatus?.statusListCredential)
|
|
2379
|
+
|
|
2380
|
+
// get resource name
|
|
2381
|
+
const resourceName = baseUrl.searchParams.get('resourceName')
|
|
2382
|
+
|
|
2383
|
+
// unset resource name
|
|
2384
|
+
baseUrl.searchParams.delete('resourceName')
|
|
2385
|
+
|
|
2386
|
+
// construct metadata url
|
|
2387
|
+
const metadataUrl = `${baseUrl.toString()}/metadata`
|
|
2388
|
+
|
|
2389
|
+
// fetch collection metadata
|
|
2390
|
+
const collectionMetadata = await (await fetch(metadataUrl)).json() as DIDMetadataDereferencingResult
|
|
2391
|
+
|
|
2392
|
+
// early exit if no linked resources
|
|
2393
|
+
if (!collectionMetadata?.contentStream?.linkedResourceMetadata) throw new Error('[did-provider-cheqd]: fetch status list metadata: No linked resources found')
|
|
2394
|
+
|
|
2395
|
+
// find relevant resources by resource name
|
|
2396
|
+
const resourceVersioning = collectionMetadata.contentStream.linkedResourceMetadata.filter((resource) => resource.resourceName === resourceName)
|
|
2397
|
+
|
|
2398
|
+
// early exit if no relevant resources
|
|
2399
|
+
if (!resourceVersioning.length || resourceVersioning.length === 0) throw new Error(`[did-provider-cheqd]: fetch status list metadata: No relevant resources found by resource name ${resourceName}`)
|
|
2400
|
+
|
|
2401
|
+
// get latest resource version by nextVersionId null pointer, or by latest created date as fallback
|
|
2402
|
+
return resourceVersioning.find((resource) => !resource.nextVersionId) || resourceVersioning.sort((a, b) => new Date(b.created).getTime() - new Date(a.created).getTime())[0]
|
|
447
2403
|
}
|
|
448
2404
|
|
|
449
2405
|
static async loadProvider(document: DIDDocument, providers: CheqdDIDProvider[]): Promise<CheqdDIDProvider> {
|
|
@@ -476,4 +2432,25 @@ export class Cheqd implements IAgentPlugin {
|
|
|
476
2432
|
resolve(new Uint8Array(content))
|
|
477
2433
|
})
|
|
478
2434
|
}
|
|
2435
|
+
|
|
2436
|
+
static async writeFile(content: Uint8Array, filename?: string): Promise<void> {
|
|
2437
|
+
if (!filename) {
|
|
2438
|
+
filename = `statusList2021-${v4()}`
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
// alert if file exists
|
|
2442
|
+
if (fs.existsSync(filename)) {
|
|
2443
|
+
debug(`[did-provider-cheqd]: File ${filename} already exists`)
|
|
2444
|
+
console.warn(`[did-provider-cheqd]: File ${filename} already exists. Overwriting...`)
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
return new Promise((resolve, reject) => {
|
|
2448
|
+
fs.writeFile(filename!, content, (err) => {
|
|
2449
|
+
if (err) {
|
|
2450
|
+
reject(new Error(`[did-provider-cheqd]: Error writing file ${filename}: reason: ${err}`))
|
|
2451
|
+
}
|
|
2452
|
+
resolve()
|
|
2453
|
+
})
|
|
2454
|
+
})
|
|
2455
|
+
}
|
|
479
2456
|
}
|