@cheqd/sdk 2.0.2-develop.1 → 2.1.0-develop.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/.github/workflows/test.yml +2 -2
  2. package/CHANGELOG.md +7 -0
  3. package/README.md +1 -1
  4. package/build/index.d.ts +7 -3
  5. package/build/index.d.ts.map +1 -1
  6. package/build/index.js +19 -7
  7. package/build/index.js.map +1 -1
  8. package/build/modules/_.d.ts +7 -11
  9. package/build/modules/_.d.ts.map +1 -1
  10. package/build/modules/_.js +15 -17
  11. package/build/modules/_.js.map +1 -1
  12. package/build/modules/did.d.ts +39 -15
  13. package/build/modules/did.d.ts.map +1 -1
  14. package/build/modules/did.js +187 -54
  15. package/build/modules/did.js.map +1 -1
  16. package/build/modules/resource.d.ts +23 -7
  17. package/build/modules/resource.d.ts.map +1 -1
  18. package/build/modules/resource.js +61 -18
  19. package/build/modules/resource.js.map +1 -1
  20. package/build/querier.d.ts +11 -0
  21. package/build/querier.d.ts.map +1 -0
  22. package/build/querier.js +31 -0
  23. package/build/querier.js.map +1 -0
  24. package/build/signer.d.ts +3 -5
  25. package/build/signer.d.ts.map +1 -1
  26. package/build/signer.js +13 -13
  27. package/build/signer.js.map +1 -1
  28. package/build/types.d.ts +12 -0
  29. package/build/types.d.ts.map +1 -1
  30. package/build/types.js.map +1 -1
  31. package/build/utils.js +13 -15
  32. package/build/utils.js.map +1 -1
  33. package/package.json +2 -2
  34. package/src/index.ts +22 -10
  35. package/src/modules/_.ts +13 -21
  36. package/src/modules/did.ts +207 -51
  37. package/src/modules/resource.ts +74 -12
  38. package/src/querier.ts +33 -0
  39. package/src/signer.ts +3 -6
  40. package/src/types.ts +17 -1
  41. package/src/utils.ts +1 -1
  42. package/tests/index.test.ts +43 -3
  43. package/tests/modules/did.test.ts +483 -50
  44. package/tests/modules/resource.test.ts +576 -30
  45. package/tests/signer.test.ts +2 -2
  46. package/tests/testutils.test.ts +8 -2
  47. package/tsconfig.json +1 -1
@@ -1,25 +1,42 @@
1
- import { createProtobufRpcClient, DeliverTxResponse, QueryClient } from "@cosmjs/stargate"
2
- /* import { QueryClientImpl } from '@cheqd/ts-proto/cheqd/did/v1/query' */
3
- import { CheqdExtension, AbstractCheqdSDKModule, MinimalImportableCheqdSDKModule } from "./_"
1
+ import { createPagination, createProtobufRpcClient, DeliverTxResponse, QueryClient } from "@cosmjs/stargate"
2
+ import { AbstractCheqdSDKModule, MinimalImportableCheqdSDKModule } from './_';
4
3
  import { CheqdSigningStargateClient } from "../signer"
5
- import { DIDDocument, DidStdFee, IContext, ISignInputs, SpecValidationResult, VerificationMethods } from '../types';
4
+ import { DIDDocument, DidStdFee, IContext, ISignInputs, QueryExtensionSetup, SpecValidationResult, VerificationMethods, DIDDocumentWithMetadata } from '../types';
6
5
  import {
7
- MsgCreateDidDoc,
8
- MsgCreateDidDocPayload,
9
- MsgCreateDidDocResponse,
10
- MsgDeactivateDidDoc,
11
- MsgDeactivateDidDocPayload,
12
- MsgDeactivateDidDocResponse,
13
- MsgUpdateDidDoc,
14
- MsgUpdateDidDocPayload,
15
- MsgUpdateDidDocResponse,
16
- protobufPackage,
17
- Service,
6
+ MsgCreateDidDoc,
7
+ MsgCreateDidDocPayload,
8
+ MsgCreateDidDocResponse,
9
+ MsgDeactivateDidDoc,
10
+ MsgDeactivateDidDocPayload,
11
+ MsgDeactivateDidDocResponse,
12
+ MsgUpdateDidDoc,
13
+ MsgUpdateDidDocPayload,
14
+ MsgUpdateDidDocResponse,
15
+ protobufPackage,
16
+ QueryClientImpl,
17
+ Service,
18
18
  SignInfo,
19
- VerificationMethod
19
+ VerificationMethod,
20
+ QueryAllDidDocVersionsMetadataResponse,
21
+ DidDocWithMetadata,
22
+ DidDoc,
23
+ Metadata
20
24
  } from "@cheqd/ts-proto/cheqd/did/v2"
21
25
  import { EncodeObject, GeneratedType } from "@cosmjs/proto-signing"
22
26
  import { v4 } from "uuid"
27
+ import { assert } from "@cosmjs/utils";
28
+ import { PageRequest } from "@cheqd/ts-proto/cosmos/base/query/v1beta1/pagination";
29
+ import { CheqdQuerier } from "../querier";
30
+ import { DIDDocumentMetadata } from "did-resolver";
31
+
32
+ export const defaultDidExtensionKey = "did" as const
33
+
34
+ export const contexts = {
35
+ W3CDIDv1: "https://www.w3.org/ns/did/v1",
36
+ W3CSuiteEd255192020: "https://w3id.org/security/suites/ed25519-2020/v1",
37
+ W3CSuiteEd255192018: "https://w3id.org/security/suites/ed25519-2018/v1",
38
+ W3CSuiteJws2020: "https://w3id.org/security/suites/jws-2020/v1",
39
+ } as const
23
40
 
24
41
  export const protobufLiterals = {
25
42
  MsgCreateDidDoc: "MsgCreateDidDoc",
@@ -90,6 +107,42 @@ export function MsgDeactiveDidDocResponseEncodeObject(obj: EncodeObject): obj is
90
107
  return obj.typeUrl === typeUrlMsgUpdateDidDocResponse
91
108
  }
92
109
 
110
+
111
+ export type MinimalImportableDIDModule = MinimalImportableCheqdSDKModule<DIDModule>
112
+
113
+ export type DidExtension = {
114
+ readonly [defaultDidExtensionKey]: {
115
+ readonly didDoc: (id: string) => Promise<DidDocWithMetadata>
116
+ readonly didDocVersion: (id: string, versionId: string) => Promise<DidDocWithMetadata>
117
+ readonly allDidDocVersionsMetadata: (id: string, paginationKey?: Uint8Array) => Promise<QueryAllDidDocVersionsMetadataResponse>
118
+ }
119
+ }
120
+
121
+ export const setupDidExtension = (base: QueryClient): DidExtension => {
122
+ const rpc = createProtobufRpcClient(base)
123
+
124
+ const queryService = new QueryClientImpl(rpc)
125
+
126
+ return {
127
+ [defaultDidExtensionKey]: {
128
+ didDoc: async (id: string) => {
129
+ const { value } = await queryService.DidDoc({ id })
130
+ assert(value)
131
+ return value
132
+ },
133
+ didDocVersion: async (id: string, versionId: string) => {
134
+ const { value } = await queryService.DidDocVersion({ id, version: versionId })
135
+ assert(value)
136
+ return value
137
+ },
138
+ allDidDocVersionsMetadata: async (id: string, paginationKey?: Uint8Array) => {
139
+ const response = await queryService.AllDidDocVersionsMetadata({ id, pagination: createPagination(paginationKey) as PageRequest | undefined })
140
+ return response
141
+ }
142
+ }
143
+ } as DidExtension
144
+ }
145
+
93
146
  export class DIDModule extends AbstractCheqdSDKModule {
94
147
  static readonly registryTypes: Iterable<[string, GeneratedType]> = [
95
148
  [typeUrlMsgCreateDidDoc, MsgCreateDidDoc],
@@ -103,17 +156,25 @@ export class DIDModule extends AbstractCheqdSDKModule {
103
156
  static readonly baseMinimalDenom = 'ncheq' as const
104
157
 
105
158
  static readonly fees = {
106
- DefaultCreateDidFee: { amount: '50000000000', denom: DIDModule.baseMinimalDenom } as const,
107
- DefaultUpdateDidFee: { amount: '25000000000', denom: DIDModule.baseMinimalDenom } as const,
108
- DefaultDeactivateDidFee: { amount: '10000000000', denom: DIDModule.baseMinimalDenom } as const,
159
+ DefaultCreateDidDocFee: { amount: '50000000000', denom: DIDModule.baseMinimalDenom } as const,
160
+ DefaultUpdateDidDocFee: { amount: '25000000000', denom: DIDModule.baseMinimalDenom } as const,
161
+ DefaultDeactivateDidDocFee: { amount: '10000000000', denom: DIDModule.baseMinimalDenom } as const,
109
162
  } as const
110
163
 
111
- constructor(signer: CheqdSigningStargateClient) {
112
- super(signer)
164
+ static readonly querierExtensionSetup: QueryExtensionSetup<DidExtension> = setupDidExtension
165
+
166
+ readonly querier: CheqdQuerier & DidExtension
167
+
168
+ constructor(signer: CheqdSigningStargateClient, querier: CheqdQuerier & DidExtension) {
169
+ super(signer, querier)
170
+ this.querier = querier
113
171
  this.methods = {
114
- createDidTx: this.createDidTx.bind(this),
115
- updateDidTx: this.updateDidTx.bind(this),
116
- deactivateDidTx: this.deactivateDidTx.bind(this),
172
+ createDidDocTx: this.createDidDocTx.bind(this),
173
+ updateDidDocTx: this.updateDidDocTx.bind(this),
174
+ deactivateDidDocTx: this.deactivateDidDocTx.bind(this),
175
+ queryDidDoc: this.querier.did.didDoc.bind(this),
176
+ queryDidDocVersion: this.querier.did.didDocVersion.bind(this),
177
+ queryAllDidDocVersionsMetadata: this.querier.did.allDidDocVersionsMetadata.bind(this),
117
178
  }
118
179
  }
119
180
 
@@ -121,7 +182,11 @@ export class DIDModule extends AbstractCheqdSDKModule {
121
182
  return DIDModule.registryTypes
122
183
  }
123
184
 
124
- async createDidTx(signInputs: ISignInputs[] | SignInfo[], didPayload: DIDDocument, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, versionId?: string, context?: IContext): Promise<DeliverTxResponse> {
185
+ public getQuerierExtensionSetup(): QueryExtensionSetup<DidExtension> {
186
+ return DIDModule.querierExtensionSetup
187
+ }
188
+
189
+ async createDidDocTx(signInputs: ISignInputs[] | SignInfo[], didPayload: DIDDocument, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, versionId?: string, context?: IContext): Promise<DeliverTxResponse> {
125
190
  if (!this._signer) {
126
191
  this._signer = context!.sdk!.signer
127
192
  }
@@ -153,7 +218,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
153
218
 
154
219
  let signatures: SignInfo[]
155
220
  if(ISignInputs.isSignInput(signInputs)) {
156
- signatures = await this._signer.signCreateDidTx(signInputs, payload)
221
+ signatures = await this._signer.signcreateDidDocTx(signInputs, payload)
157
222
  } else {
158
223
  signatures = signInputs
159
224
  }
@@ -184,7 +249,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
184
249
  )
185
250
  }
186
251
 
187
- async updateDidTx(signInputs: ISignInputs[] | SignInfo[], didPayload: DIDDocument, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, versionId?: string, context?: IContext): Promise<DeliverTxResponse> {
252
+ async updateDidDocTx(signInputs: ISignInputs[] | SignInfo[], didPayload: DIDDocument, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, versionId?: string, context?: IContext): Promise<DeliverTxResponse> {
188
253
  if (!this._signer) {
189
254
  this._signer = context!.sdk!.signer
190
255
  }
@@ -215,7 +280,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
215
280
  })
216
281
  let signatures: SignInfo[]
217
282
  if(ISignInputs.isSignInput(signInputs)) {
218
- signatures = await this._signer.signUpdateDidTx(signInputs, payload)
283
+ signatures = await this._signer.signupdateDidDocTx(signInputs, payload)
219
284
  } else {
220
285
  signatures = signInputs
221
286
  }
@@ -246,7 +311,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
246
311
  )
247
312
  }
248
313
 
249
- async deactivateDidTx(signInputs: ISignInputs[] | SignInfo[], didPayload: DIDDocument, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, versionId?: string, context?: IContext): Promise<DeliverTxResponse> {
314
+ async deactivateDidDocTx(signInputs: ISignInputs[] | SignInfo[], didPayload: DIDDocument, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, versionId?: string, context?: IContext): Promise<DeliverTxResponse> {
250
315
  if (!this._signer) {
251
316
  this._signer = context!.sdk!.signer
252
317
  }
@@ -268,7 +333,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
268
333
 
269
334
  let signatures: SignInfo[]
270
335
  if(ISignInputs.isSignInput(signInputs)) {
271
- signatures = await this._signer.signDeactivateDidTx(signInputs, payload, protobufVerificationMethod!)
336
+ signatures = await this._signer.signdeactivateDidDocTx(signInputs, payload, protobufVerificationMethod!)
272
337
  } else {
273
338
  signatures = signInputs
274
339
  }
@@ -299,6 +364,30 @@ export class DIDModule extends AbstractCheqdSDKModule {
299
364
  )
300
365
  }
301
366
 
367
+ async queryDidDoc(id: string, context?: IContext): Promise<DIDDocumentWithMetadata> {
368
+ const { didDoc, metadata } = await this.querier[defaultDidExtensionKey].didDoc(id)
369
+ return {
370
+ didDocument: await DIDModule.toSpecCompliantPayload(didDoc!),
371
+ didDocumentMetadata: await DIDModule.toSpecCompliantMetadata(metadata!)
372
+ } as DIDDocumentWithMetadata
373
+ }
374
+
375
+ async queryDidDocVersion(id: string, versionId: string, context?: IContext): Promise<DIDDocumentWithMetadata> {
376
+ const { didDoc, metadata } = await this.querier[defaultDidExtensionKey].didDocVersion(id, versionId)
377
+ return {
378
+ didDocument: await DIDModule.toSpecCompliantPayload(didDoc!),
379
+ didDocumentMetadata: await DIDModule.toSpecCompliantMetadata(metadata!)
380
+ } as DIDDocumentWithMetadata
381
+ }
382
+
383
+ async queryAllDidDocVersionsMetadata(id: string, context?: IContext): Promise<{ didDocumentVersionsMetadata: DIDDocumentMetadata[], pagination: QueryAllDidDocVersionsMetadataResponse['pagination']}> {
384
+ const { versions, pagination } = await this.querier[defaultDidExtensionKey].allDidDocVersionsMetadata(id)
385
+ return {
386
+ didDocumentVersionsMetadata: await Promise.all(versions.map(async (m) => await DIDModule.toSpecCompliantMetadata(m))),
387
+ pagination
388
+ }
389
+ }
390
+
302
391
  static async validateSpecCompliantPayload(didDocument: DIDDocument): Promise<SpecValidationResult> {
303
392
  // id is required, validated on both compile and runtime
304
393
  if (!didDocument?.id) return { valid: false, error: 'id is required' }
@@ -355,10 +444,95 @@ export class DIDModule extends AbstractCheqdSDKModule {
355
444
  return { valid: true, protobufVerificationMethod: protoVerificationMethod, protobufService: protoService } as SpecValidationResult
356
445
  }
357
446
 
447
+ static async toSpecCompliantPayload(protobufDidDocument: DidDoc): Promise<DIDDocument> {
448
+ const verificationMethod = protobufDidDocument.verificationMethod.map((vm) => {
449
+ switch (vm.verificationMethodType) {
450
+ case VerificationMethods.Ed255192020:
451
+ if (!protobufDidDocument.context.includes(contexts.W3CSuiteEd255192020))
452
+ protobufDidDocument.context = [...protobufDidDocument.context, contexts.W3CSuiteEd255192020]
453
+ return {
454
+ id: vm.id,
455
+ type: vm.verificationMethodType,
456
+ controller: vm.controller,
457
+ publicKeyMultibase: vm.verificationMaterial,
458
+ }
459
+ case VerificationMethods.JWK:
460
+ if (!protobufDidDocument.context.includes(contexts.W3CSuiteJws2020))
461
+ protobufDidDocument.context = [...protobufDidDocument.context, contexts.W3CSuiteJws2020]
462
+ return {
463
+ id: vm.id,
464
+ type: vm.verificationMethodType,
465
+ controller: vm.controller,
466
+ publicKeyJwk: JSON.parse(vm.verificationMaterial),
467
+ }
468
+ case VerificationMethods.Ed255192018:
469
+ if (!protobufDidDocument.context.includes(contexts.W3CSuiteEd255192018))
470
+ protobufDidDocument.context = [...protobufDidDocument.context, contexts.W3CSuiteEd255192018]
471
+ return {
472
+ id: vm.id,
473
+ type: vm.verificationMethodType,
474
+ controller: vm.controller,
475
+ publicKeyBase58: vm.verificationMaterial,
476
+ }
477
+ default:
478
+ throw new Error('Unsupported verificationMethod type') // should never happen
479
+ }
480
+ })
481
+
482
+ const service = protobufDidDocument.service.map((s) => {
483
+ return {
484
+ id: s.id,
485
+ type: s.serviceType,
486
+ serviceEndpoint: s.serviceEndpoint,
487
+ }
488
+ })
489
+
490
+ const context = function () {
491
+ if (protobufDidDocument.context.includes(contexts.W3CDIDv1))
492
+ return protobufDidDocument.context
493
+
494
+ return [contexts.W3CDIDv1, ...protobufDidDocument.context]
495
+ }()
496
+
497
+ const specCompliant = {
498
+ '@context': context,
499
+ id: protobufDidDocument.id,
500
+ controller: protobufDidDocument.controller,
501
+ verificationMethod: verificationMethod,
502
+ authentication: protobufDidDocument.authentication,
503
+ assertionMethod: protobufDidDocument.assertionMethod,
504
+ capabilityInvocation: protobufDidDocument.capabilityInvocation,
505
+ capabilityDelegation: protobufDidDocument.capabilityDelegation,
506
+ keyAgreement: protobufDidDocument.keyAgreement,
507
+ service: service,
508
+ alsoKnownAs: protobufDidDocument.alsoKnownAs,
509
+ } as DIDDocument
510
+
511
+ if (!protobufDidDocument.authentication?.length) delete specCompliant.authentication
512
+ if (!protobufDidDocument.assertionMethod?.length) delete specCompliant.assertionMethod
513
+ if (!protobufDidDocument.capabilityInvocation?.length) delete specCompliant.capabilityInvocation
514
+ if (!protobufDidDocument.capabilityDelegation?.length) delete specCompliant.capabilityDelegation
515
+ if (!protobufDidDocument.keyAgreement?.length) delete specCompliant.keyAgreement
516
+ if (!protobufDidDocument.service?.length) delete specCompliant.service
517
+ if (!protobufDidDocument.alsoKnownAs?.length) delete specCompliant.alsoKnownAs
518
+
519
+ return specCompliant
520
+ }
521
+
522
+ static async toSpecCompliantMetadata(protobufDidDocument: Metadata): Promise<DIDDocumentMetadata> {
523
+ return {
524
+ created: protobufDidDocument.created?.toISOString(),
525
+ updated: protobufDidDocument.updated?.toISOString(),
526
+ deactivated: protobufDidDocument.deactivated,
527
+ versionId: protobufDidDocument.versionId,
528
+ nextVersionId: protobufDidDocument?.nextVersionId,
529
+ }
530
+ }
531
+
358
532
  static async generateCreateDidDocFees(feePayer: string, granter?: string): Promise<DidStdFee> {
359
533
  return {
360
534
  amount: [
361
- DIDModule.fees.DefaultCreateDidFee
535
+ DIDModule.fees.DefaultCreateDidDocFee
362
536
  ],
363
537
  gas: '360000',
364
538
  payer: feePayer,
@@ -369,7 +543,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
369
543
  static async generateUpdateDidDocFees(feePayer: string, granter?: string): Promise<DidStdFee> {
370
544
  return {
371
545
  amount: [
372
- DIDModule.fees.DefaultUpdateDidFee
546
+ DIDModule.fees.DefaultUpdateDidDocFee
373
547
  ],
374
548
  gas: '360000',
375
549
  payer: feePayer,
@@ -380,7 +554,7 @@ export class DIDModule extends AbstractCheqdSDKModule {
380
554
  static async generateDeactivateDidDocFees(feePayer: string, granter?: string): Promise<DidStdFee> {
381
555
  return {
382
556
  amount: [
383
- DIDModule.fees.DefaultDeactivateDidFee
557
+ DIDModule.fees.DefaultDeactivateDidDocFee
384
558
  ],
385
559
  gas: '360000',
386
560
  payer: feePayer,
@@ -388,21 +562,3 @@ export class DIDModule extends AbstractCheqdSDKModule {
388
562
  } as DidStdFee
389
563
  }
390
564
  }
391
-
392
- export type MinimalImportableDIDModule = MinimalImportableCheqdSDKModule<DIDModule>
393
-
394
- export interface DidExtension extends CheqdExtension<string, {}> {
395
- did: {}
396
- }
397
-
398
- export const setupDidExtension = (base: QueryClient): DidExtension => {
399
- const rpc = createProtobufRpcClient(base)
400
-
401
- /* const queryService = new QueryClientImpl(rpc) */
402
-
403
- return {
404
- did: {
405
- //...
406
- }
407
- }
408
- }
@@ -1,11 +1,16 @@
1
- import { AbstractCheqdSDKModule, MinimalImportableCheqdSDKModule } from "./_"
1
+ import { AbstractCheqdSDKModule, MinimalImportableCheqdSDKModule } from './_';
2
2
  import { CheqdSigningStargateClient } from "../signer"
3
3
  import { EncodeObject, GeneratedType } from "@cosmjs/proto-signing"
4
- import { DidStdFee, IContext, ISignInputs } from '../types';
5
- import { MsgCreateResource, MsgCreateResourcePayload, MsgCreateResourceResponse, protobufPackage } from "@cheqd/ts-proto/cheqd/resource/v2"
6
- import { DeliverTxResponse } from "@cosmjs/stargate"
4
+ import { DidStdFee, IContext, ISignInputs, QueryExtensionSetup } from '../types';
5
+ import { Metadata, MsgCreateResource, MsgCreateResourcePayload, MsgCreateResourceResponse, QueryClientImpl, QueryCollectionResourcesResponse, ResourceWithMetadata, protobufPackage } from "@cheqd/ts-proto/cheqd/resource/v2"
6
+ import { DeliverTxResponse, QueryClient, createPagination, createProtobufRpcClient } from "@cosmjs/stargate"
7
7
  import { SignInfo } from "@cheqd/ts-proto/cheqd/did/v2";
8
8
  import { fromBuffer } from "file-type";
9
+ import { assert } from '@cosmjs/utils';
10
+ import { PageRequest } from '@cheqd/ts-proto/cosmos/base/query/v1beta1/pagination';
11
+ import { CheqdQuerier } from '../querier';
12
+
13
+ export const defaultResourceExtensionKey = 'resource' as const
9
14
 
10
15
  export const protobufLiterals = {
11
16
  MsgCreateResource: 'MsgCreateResource',
@@ -24,6 +29,41 @@ export function isMsgCreateResourceEncodeObject(obj: EncodeObject): obj is MsgCr
24
29
  return obj.typeUrl === typeUrlMsgCreateResource
25
30
  }
26
31
 
32
+ export type MinimalImportableResourceModule = MinimalImportableCheqdSDKModule<ResourceModule>
33
+
34
+ export type ResourceExtension = {
35
+ readonly [defaultResourceExtensionKey]: {
36
+ readonly resource: (collectionId: string, resourceId: string) => Promise<ResourceWithMetadata>
37
+ readonly resourceMetadata: (collectionId: string, resourceId: string) => Promise<Metadata>
38
+ readonly collectionResources: (collectionId: string, paginationKey?: Uint8Array) => Promise<QueryCollectionResourcesResponse>
39
+ }
40
+ }
41
+
42
+ export const setupResourceExtension = (base: QueryClient): ResourceExtension => {
43
+ const rpc = createProtobufRpcClient(base)
44
+
45
+ const queryService = new QueryClientImpl(rpc)
46
+
47
+ return {
48
+ [defaultResourceExtensionKey]: {
49
+ resource: async (collectionId: string, resourceId: string) => {
50
+ const { resource } = await queryService.Resource({ collectionId, id: resourceId })
51
+ assert(resource)
52
+ return resource
53
+ },
54
+ resourceMetadata: async (collectionId: string, resourceId: string) => {
55
+ const { resource } = await queryService.ResourceMetadata({ collectionId, id: resourceId })
56
+ assert(resource)
57
+ return resource
58
+ },
59
+ collectionResources: async (collectionId: string, paginationKey?: Uint8Array) => {
60
+ const response = await queryService.CollectionResources({ collectionId, pagination: createPagination(paginationKey) as PageRequest | undefined })
61
+ return response
62
+ }
63
+ }
64
+ } as ResourceExtension
65
+ }
66
+
27
67
  export class ResourceModule extends AbstractCheqdSDKModule {
28
68
  static readonly registryTypes: Iterable<[string, GeneratedType]> = [
29
69
  [typeUrlMsgCreateResource, MsgCreateResource],
@@ -38,15 +78,27 @@ export class ResourceModule extends AbstractCheqdSDKModule {
38
78
  DefaultCreateResourceDefaultFee: { amount: '5000000000', denom: ResourceModule.baseMinimalDenom } as const,
39
79
  } as const
40
80
 
41
- constructor(signer: CheqdSigningStargateClient) {
42
- super(signer)
81
+ static readonly querierExtensionSetup: QueryExtensionSetup<ResourceExtension> = setupResourceExtension
82
+
83
+ readonly querier: CheqdQuerier & ResourceExtension
84
+
85
+ constructor(signer: CheqdSigningStargateClient, querier: CheqdQuerier & ResourceExtension) {
86
+ super(signer, querier)
87
+ this.querier = querier
43
88
  this.methods = {
44
- createResourceTx: this.createResourceTx.bind(this)
89
+ createLinkedResourceTx: this.createLinkedResourceTx.bind(this),
90
+ queryLinkedResource: this.queryLinkedResource.bind(this),
91
+ queryLinkedResourceMetadata: this.queryLinkedResourceMetadata.bind(this),
92
+ queryLinkedResources: this.queryLinkedResources.bind(this),
45
93
  }
46
94
  }
47
95
 
48
96
  public getRegistryTypes(): Iterable<[string, GeneratedType]> {
49
- return []
97
+ return ResourceModule.registryTypes
98
+ }
99
+
100
+ public getQuerierExtensionSetup(): QueryExtensionSetup<ResourceExtension> {
101
+ return ResourceModule.querierExtensionSetup
50
102
  }
51
103
 
52
104
  static async signPayload(payload: MsgCreateResourcePayload, signInputs: ISignInputs[] | SignInfo[]): Promise<MsgCreateResource> {
@@ -57,14 +109,14 @@ export class ResourceModule extends AbstractCheqdSDKModule {
57
109
  } else {
58
110
  signatures = signInputs
59
111
  }
60
-
112
+
61
113
  return {
62
114
  payload,
63
115
  signatures
64
116
  }
65
117
  }
66
118
 
67
- async createResourceTx(signInputs: ISignInputs[] | SignInfo[], resourcePayload: Partial<MsgCreateResourcePayload>, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, context?: IContext): Promise<DeliverTxResponse> {
119
+ async createLinkedResourceTx(signInputs: ISignInputs[] | SignInfo[], resourcePayload: Partial<MsgCreateResourcePayload>, address: string, fee?: DidStdFee | 'auto' | number, memo?: string, context?: IContext): Promise<DeliverTxResponse> {
68
120
  if (!this._signer) {
69
121
  this._signer = context!.sdk!.signer
70
122
  }
@@ -110,6 +162,18 @@ export class ResourceModule extends AbstractCheqdSDKModule {
110
162
  )
111
163
  }
112
164
 
165
+ async queryLinkedResource(collectionId: string, resourceId: string, context?: IContext): Promise<ResourceWithMetadata> {
166
+ return await this.querier[defaultResourceExtensionKey].resource(collectionId, resourceId)
167
+ }
168
+
169
+ async queryLinkedResourceMetadata(collectionId: string, resourceId: string, context?: IContext): Promise<Metadata> {
170
+ return await this.querier[defaultResourceExtensionKey].resourceMetadata(collectionId, resourceId)
171
+ }
172
+
173
+ async queryLinkedResources(collectionId: string, context?: IContext): Promise<QueryCollectionResourcesResponse> {
174
+ return await this.querier[defaultResourceExtensionKey].collectionResources(collectionId)
175
+ }
176
+
113
177
  static async readMimeType(content: Uint8Array): Promise<string> {
114
178
  return (await fromBuffer(content))?.mime ?? 'application/octet-stream'
115
179
  }
@@ -147,5 +211,3 @@ export class ResourceModule extends AbstractCheqdSDKModule {
147
211
  } as DidStdFee
148
212
  }
149
213
  }
150
-
151
- export type MinimalImportableResourcesModule = MinimalImportableCheqdSDKModule<ResourceModule>
package/src/querier.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { QueryClient } from "@cosmjs/stargate";
2
+ import { Tendermint34Client } from "@cosmjs/tendermint-rpc";
3
+ import { QueryExtensionSetup, CheqdExtensions } from "./types";
4
+
5
+ export class CheqdQuerier extends QueryClient {
6
+ constructor(tmClient: Tendermint34Client) {
7
+ super(tmClient)
8
+ }
9
+
10
+ static async connect(url: string): Promise<CheqdQuerier> {
11
+ const tmClient = await Tendermint34Client.connect(url);
12
+ return new CheqdQuerier(tmClient);
13
+ }
14
+
15
+ static async fromClient(client: Tendermint34Client): Promise<CheqdQuerier> {
16
+ return new CheqdQuerier(client);
17
+ }
18
+
19
+ static async connectWithExtension(url: string, extension: QueryExtensionSetup<CheqdExtensions>): Promise<CheqdQuerier & CheqdExtensions> {
20
+ const tmClient = await Tendermint34Client.connect(url);
21
+ return CheqdQuerier.withExtensions(tmClient, extension);
22
+ }
23
+
24
+ static async connectWithExtensions(url: string, ...extensions: QueryExtensionSetup<CheqdExtensions>[]): Promise<CheqdQuerier & CheqdExtensions> {
25
+ if (extensions.length === 1) {
26
+ return CheqdQuerier.connectWithExtension(url, extensions[0]);
27
+ }
28
+
29
+ const tmClient = await Tendermint34Client.connect(url);
30
+ const tupleLike = extensions as [QueryExtensionSetup<CheqdExtensions>, QueryExtensionSetup<CheqdExtensions>];
31
+ return CheqdQuerier.withExtensions(tmClient, ...tupleLike);
32
+ }
33
+ }
package/src/signer.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { CheqdExtensions } from './modules/_'
2
1
  import { EncodeObject, isOfflineDirectSigner, OfflineSigner, encodePubkey, TxBodyEncodeObject, makeSignDoc } from "@cosmjs/proto-signing"
3
2
  import { DeliverTxResponse, GasPrice, HttpEndpoint, SigningStargateClient, SigningStargateClientOptions, calculateFee, SignerData } from "@cosmjs/stargate"
4
3
  import { Tendermint34Client } from "@cosmjs/tendermint-rpc"
@@ -53,9 +52,7 @@ export function makeDidAuthInfoBytes(
53
52
  return AuthInfo.encode(AuthInfo.fromPartial(authInfo)).finish()
54
53
  }
55
54
 
56
-
57
55
  export class CheqdSigningStargateClient extends SigningStargateClient {
58
- public readonly cheqdExtensions: CheqdExtensions | undefined
59
56
  private didSigners: TSignerAlgo = {}
60
57
  private readonly _gasPrice: GasPrice | undefined
61
58
  private readonly _signer: OfflineSigner
@@ -184,7 +181,7 @@ export class CheqdSigningStargateClient extends SigningStargateClient {
184
181
  return this.didSigners[verificationMethod]!
185
182
  }
186
183
 
187
- async signCreateDidTx(signInputs: ISignInputs[], payload: MsgCreateDidDocPayload): Promise<SignInfo[]> {
184
+ async signcreateDidDocTx(signInputs: ISignInputs[], payload: MsgCreateDidDocPayload): Promise<SignInfo[]> {
188
185
  await this.checkDidSigners(payload?.verificationMethod)
189
186
 
190
187
  const signBytes = MsgCreateDidDocPayload.encode(payload).finish()
@@ -198,7 +195,7 @@ export class CheqdSigningStargateClient extends SigningStargateClient {
198
195
  return signInfos
199
196
  }
200
197
 
201
- async signUpdateDidTx(signInputs: ISignInputs[], payload: MsgUpdateDidDocPayload): Promise<SignInfo[]> {
198
+ async signupdateDidDocTx(signInputs: ISignInputs[], payload: MsgUpdateDidDocPayload): Promise<SignInfo[]> {
202
199
  await this.checkDidSigners(payload?.verificationMethod)
203
200
 
204
201
  const signBytes = MsgUpdateDidDocPayload.encode(payload).finish()
@@ -212,7 +209,7 @@ export class CheqdSigningStargateClient extends SigningStargateClient {
212
209
  return signInfos
213
210
  }
214
211
 
215
- async signDeactivateDidTx(signInputs: ISignInputs[], payload: MsgDeactivateDidDocPayload, verificationMethod: VerificationMethod[]): Promise<SignInfo[]> {
212
+ async signdeactivateDidDocTx(signInputs: ISignInputs[], payload: MsgDeactivateDidDocPayload, verificationMethod: VerificationMethod[]): Promise<SignInfo[]> {
216
213
  await this.checkDidSigners(verificationMethod)
217
214
 
218
215
  const signBytes = MsgDeactivateDidDocPayload.encode(payload).finish()
package/src/types.ts CHANGED
@@ -2,6 +2,10 @@ import { Service as ProtobufService, VerificationMethod as ProtobufVerificationM
2
2
  import { CheqdSDK } from "."
3
3
  import { Coin } from "@cosmjs/proto-signing"
4
4
  import { Signer } from "did-jwt"
5
+ import { QueryClient } from "@cosmjs/stargate"
6
+ import { DIDResolutionResult } from "did-resolver"
7
+ import { DidExtension } from "./modules/did"
8
+ import { ResourceExtension } from './modules/resource';
5
9
  export { DIDDocument, VerificationMethod, Service, ServiceEndpoint, JsonWebKey } from "did-resolver"
6
10
 
7
11
  export enum CheqdNetwork {
@@ -9,6 +13,16 @@ export enum CheqdNetwork {
9
13
  Testnet = 'testnet',
10
14
  }
11
15
 
16
+ export type QueryExtensionSetup<T> = (base: QueryClient) => T
17
+
18
+ export type CheqdExtension<K extends string, V = any> = {
19
+ [P in K]: (Record<P, V> & Partial<Record<Exclude<K, P>, never>>) extends infer O
20
+ ? { [Q in keyof O]: O[Q] }
21
+ : never
22
+ }[K]
23
+
24
+ export type CheqdExtensions = DidExtension | ResourceExtension
25
+
12
26
  export interface IModuleMethod {
13
27
  (...args: any[]): Promise<any>
14
28
  }
@@ -19,6 +33,8 @@ export interface IContext {
19
33
  sdk: CheqdSDK
20
34
  }
21
35
 
36
+ export type DIDDocumentWithMetadata = Pick<DIDResolutionResult, 'didDocument' | 'didDocumentMetadata'>
37
+
22
38
  export type SpecValidationResult = {
23
39
  valid: boolean
24
40
  error?: string
@@ -79,7 +95,7 @@ export interface DidStdFee {
79
95
  }
80
96
 
81
97
  export const ISignInputs = {
82
- isSignInput(object: Object[]): object is ISignInputs[] {
98
+ isSignInput(object: Object[]): object is ISignInputs[] {
83
99
  return object.some((x)=> 'privateKeyHex' in x)
84
100
  }
85
101
  }
package/src/utils.ts CHANGED
@@ -102,7 +102,7 @@ export function createKeyPairHex(seed?: string): IKeyPair {
102
102
  export function createVerificationKeys(publicKey: string, algo: MethodSpecificIdAlgo, key: TVerificationKey<TVerificationKeyPrefix, number>, network: CheqdNetwork = CheqdNetwork.Testnet): IVerificationKeys {
103
103
  let methodSpecificId: TMethodSpecificId
104
104
  let didUrl: IVerificationKeys['didUrl']
105
-
105
+
106
106
  publicKey = publicKey.length == 43 ? publicKey : toString(fromString(publicKey, 'hex'), 'base64')
107
107
  switch (algo) {
108
108
  case MethodSpecificIdAlgo.Base58: