@docknetwork/wallet-sdk-wasm 1.5.11 → 1.7.0

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 (97) hide show
  1. package/generate-docs.js +49 -0
  2. package/jsdoc.conf.json +29 -6
  3. package/lib/index.js +8 -1
  4. package/lib/index.mjs +8 -1
  5. package/lib/rpc-server.js +10 -1
  6. package/lib/rpc-server.mjs +10 -1
  7. package/lib/services/blockchain/cached-did-resolver.js +113 -0
  8. package/lib/services/blockchain/cached-did-resolver.mjs +109 -0
  9. package/lib/services/blockchain/index.js +11 -0
  10. package/lib/services/blockchain/index.mjs +11 -0
  11. package/lib/services/blockchain/service-rpc.js +16 -0
  12. package/lib/services/blockchain/service-rpc.mjs +16 -0
  13. package/lib/services/blockchain/service.js +144 -12
  14. package/lib/services/blockchain/service.mjs +144 -12
  15. package/lib/services/credential/bbs-revocation.js +11 -0
  16. package/lib/services/credential/bbs-revocation.mjs +11 -0
  17. package/lib/services/credential/config.js +4 -1
  18. package/lib/services/credential/config.mjs +4 -1
  19. package/lib/services/credential/index.js +14 -0
  20. package/lib/services/credential/index.mjs +14 -0
  21. package/lib/services/credential/pex-helpers.js +20 -0
  22. package/lib/services/credential/pex-helpers.mjs +20 -1
  23. package/lib/services/credential/sd-jwt.js +214 -0
  24. package/lib/services/credential/sd-jwt.mjs +200 -0
  25. package/lib/services/credential/service-rpc.js +9 -0
  26. package/lib/services/credential/service-rpc.mjs +9 -0
  27. package/lib/services/credential/service.js +325 -8
  28. package/lib/services/credential/service.mjs +326 -9
  29. package/lib/services/edv/service.js +145 -1
  30. package/lib/services/edv/service.mjs +145 -1
  31. package/lib/services/index.js +13 -0
  32. package/lib/services/index.mjs +13 -0
  33. package/lib/services/relay-service/service.js +124 -1
  34. package/lib/services/relay-service/service.mjs +124 -1
  35. package/lib/services/rpc-service-client.js +0 -3
  36. package/lib/services/rpc-service-client.mjs +0 -3
  37. package/lib/services/storage/index.js +19 -2
  38. package/lib/services/storage/index.mjs +24 -1
  39. package/lib/services/storage/service-rpc.js +7 -3
  40. package/lib/services/storage/service-rpc.mjs +7 -3
  41. package/lib/services/storage/service.js +4 -0
  42. package/lib/services/storage/service.mjs +4 -0
  43. package/lib/setup-nodejs.js +8 -1
  44. package/lib/setup-nodejs.mjs +8 -1
  45. package/lib/setup-tests.js +8 -1
  46. package/lib/setup-tests.mjs +8 -1
  47. package/lib/src/services/blockchain/cached-did-resolver.d.ts +28 -0
  48. package/lib/src/services/blockchain/cached-did-resolver.d.ts.map +1 -0
  49. package/lib/src/services/blockchain/cached-did-resolver.test.d.ts +2 -0
  50. package/lib/src/services/blockchain/cached-did-resolver.test.d.ts.map +1 -0
  51. package/lib/src/services/blockchain/service.d.ts +115 -17
  52. package/lib/src/services/blockchain/service.d.ts.map +1 -1
  53. package/lib/src/services/credential/config.d.ts.map +1 -1
  54. package/lib/src/services/credential/index.d.ts +3 -0
  55. package/lib/src/services/credential/index.d.ts.map +1 -1
  56. package/lib/src/services/credential/pex-helpers.d.ts +13 -1
  57. package/lib/src/services/credential/pex-helpers.d.ts.map +1 -1
  58. package/lib/src/services/credential/sd-jwt.test.d.ts +2 -0
  59. package/lib/src/services/credential/sd-jwt.test.d.ts.map +1 -0
  60. package/lib/src/services/credential/service.d.ts +274 -4
  61. package/lib/src/services/credential/service.d.ts.map +1 -1
  62. package/lib/src/services/edv/service.d.ts +151 -1
  63. package/lib/src/services/edv/service.d.ts.map +1 -1
  64. package/lib/src/services/relay-service/service.d.ts +129 -1
  65. package/lib/src/services/relay-service/service.d.ts.map +1 -1
  66. package/lib/src/services/rpc-service-client.d.ts +2 -2
  67. package/lib/src/services/rpc-service-client.d.ts.map +1 -1
  68. package/lib/src/services/storage/index.d.ts +1 -1
  69. package/lib/src/services/storage/index.d.ts.map +1 -1
  70. package/lib/src/services/storage/service-rpc.d.ts +9 -0
  71. package/lib/src/services/storage/service-rpc.d.ts.map +1 -0
  72. package/lib/src/services/storage/service.d.ts +1 -0
  73. package/lib/src/services/storage/service.d.ts.map +1 -1
  74. package/lib/src/services/util-crypto/service.d.ts +1 -1
  75. package/lib/tsconfig.tsbuildinfo +1 -1
  76. package/lib/wallet/rpc-storage-interface.js +13 -3
  77. package/lib/wallet/rpc-storage-interface.mjs +11 -1
  78. package/lib/wallet/rpc-storage-wallet.js +10 -0
  79. package/lib/wallet/rpc-storage-wallet.mjs +10 -0
  80. package/package.json +13 -8
  81. package/src/services/blockchain/cached-did-resolver.test.ts +288 -0
  82. package/src/services/blockchain/cached-did-resolver.ts +126 -0
  83. package/src/services/blockchain/service-rpc.js +16 -0
  84. package/src/services/blockchain/service.ts +146 -12
  85. package/src/services/credential/config.ts +7 -1
  86. package/src/services/credential/pex-helpers.js +20 -1
  87. package/src/services/credential/pex-helpers.test.js +114 -0
  88. package/src/services/credential/sd-jwt.test.ts +718 -0
  89. package/src/services/credential/sd-jwt.ts +231 -0
  90. package/src/services/credential/service-rpc.js +9 -0
  91. package/src/services/credential/service.ts +330 -9
  92. package/src/services/edv/service.ts +153 -1
  93. package/src/services/relay-service/service.ts +130 -1
  94. package/src/services/rpc-service-client.js +0 -3
  95. package/src/services/storage/index.js +15 -1
  96. package/src/services/storage/service-rpc.js +7 -3
  97. package/src/services/storage/service.ts +5 -0
@@ -1,5 +1,12 @@
1
1
  // @ts-nocheck
2
2
 
3
+ /**
4
+ * @module blockchain-service
5
+ * @description Blockchain connectivity and DID resolution service for the Wallet SDK.
6
+ * This module provides functionality for connecting to Cheqd blockchain, resolving DIDs,
7
+ * and managing accumulator-related operations.
8
+ */
9
+
3
10
  import {DirectSecp256k1HdWallet} from '@cosmjs/proto-signing';
4
11
  import {CheqdAPI} from '@docknetwork/cheqd-blockchain-api';
5
12
  import {CheqdCoreModules} from '@docknetwork/cheqd-blockchain-modules';
@@ -18,6 +25,10 @@ import {once} from '../../modules/event-manager';
18
25
  import {utilCryptoService} from '../util-crypto';
19
26
  import {InitParams} from './configs';
20
27
 
28
+ /**
29
+ * Universal resolver URL for DID resolution fallback
30
+ * @constant {string}
31
+ */
21
32
  export const universalResolverUrl = 'https://uniresolver.truvera.io';
22
33
 
23
34
  import {
@@ -25,13 +36,23 @@ import {
25
36
  AccumulatorId,
26
37
  AccumulatorPublicKey,
27
38
  } from '@docknetwork/credential-sdk/types';
39
+ import { CachedDIDResolver } from './cached-did-resolver';
28
40
 
41
+ /**
42
+ * Resolver that accepts any DID method using wildcard matching
43
+ * @class
44
+ * @extends ResolverRouter
45
+ * @private
46
+ */
29
47
  class AnyDIDResolver extends ResolverRouter {
30
48
  method = WILDCARD;
31
49
  }
32
50
 
33
51
  /**
34
- *
52
+ * Main blockchain service class for managing blockchain connections and DID resolution
53
+ * @class
54
+ * @description Provides methods for connecting to Cheqd blockchain, resolving DIDs,
55
+ * and managing blockchain-related operations
35
56
  */
36
57
  export class BlockchainService {
37
58
  dock;
@@ -40,6 +61,12 @@ export class BlockchainService {
40
61
  cheqdApiUrl;
41
62
  isBlockchainReady = false;
42
63
  resolver: any;
64
+ /**
65
+ * Event names emitted by the blockchain service
66
+ * @static
67
+ * @readonly
68
+ * @property {string} BLOCKCHAIN_READY - Emitted when blockchain connection is established
69
+ */
43
70
  static Events = {
44
71
  BLOCKCHAIN_READY: 'blockchain-ready',
45
72
  };
@@ -50,8 +77,16 @@ export class BlockchainService {
50
77
  BlockchainService.prototype.init,
51
78
  BlockchainService.prototype.isApiConnected,
52
79
  BlockchainService.prototype.getAddress,
80
+ BlockchainService.prototype.resolveDID,
81
+ BlockchainService.prototype.getCachedDIDs,
82
+ BlockchainService.prototype.clearCache,
83
+ BlockchainService.prototype.getCacheEntry,
53
84
  ];
54
85
 
86
+ /**
87
+ * Creates a new BlockchainService instance
88
+ * @constructor
89
+ */
55
90
  constructor() {
56
91
  this.name = 'blockchain';
57
92
  this.cheqdApi = new CheqdAPI();
@@ -61,6 +96,15 @@ export class BlockchainService {
61
96
  this.resolver = this.createDIDResolver();
62
97
  }
63
98
 
99
+ /**
100
+ * Gets the types and modules needed for DID or accumulator operations
101
+ * @param {string} didOrRegistryId - DID or registry identifier
102
+ * @returns {Object} Object containing accumulator-related types and modules
103
+ * @returns {typeof AccumulatorPublicKey} returns.PublicKey - Accumulator public key type
104
+ * @returns {typeof AccumulatorId} returns.AccumulatorId - Accumulator ID type
105
+ * @returns {typeof AccumulatorCommon} returns.AccumulatorCommon - Common accumulator type
106
+ * @returns {Object} returns.AccumulatorModule - Accumulator module instance
107
+ */
64
108
  getTypesForDIDOrAccumulator(didOrRegistryId) {
65
109
  return {
66
110
  PublicKey: AccumulatorPublicKey,
@@ -71,28 +115,74 @@ export class BlockchainService {
71
115
  }
72
116
 
73
117
  /**
74
- *
75
- * @returns
118
+ * Ensures the blockchain connection is ready before proceeding
119
+ * @returns {Promise<void>} Resolves when blockchain is ready
120
+ * @example
121
+ * await blockchainService.ensureBlockchainReady();
122
+ * // Blockchain is now connected and ready
76
123
  */
77
124
  async ensureBlockchainReady() {
78
- if (this.isBlockchainReady) {
125
+ if (await this.isApiConnected()) {
79
126
  return;
80
127
  }
81
128
 
82
129
  return once(this.emitter, BlockchainService.Events.BLOCKCHAIN_READY);
83
130
  }
84
131
 
132
+
133
+ /**
134
+ * Gets the cached DIDs
135
+ * @returns {Promise<string[]>} Cached DIDs
136
+ */
137
+ getCachedDIDs() {
138
+ return this.resolver.getCachedDIDs();
139
+ }
140
+
141
+ /**
142
+ * Gets the cached DID resolution data
143
+ * @param {string} did - The DID to get the cache entry for
144
+ * @returns {Promise<any>} Cached DID resolution data
145
+ */
146
+ getCacheEntry(did) {
147
+ return this.resolver.getCacheEntry(did);
148
+ }
149
+
150
+ /**
151
+ * Clears cached data for a specific DID
152
+ * @param {string} did - The DID to clear from cache
153
+ * @returns {void}
154
+ */
155
+ clearCache(did) {
156
+ return this.resolver.clearCache(did);
157
+ }
158
+
159
+ /**
160
+ * Creates a DID resolver with caching support
161
+ * @private
162
+ * @returns {CachedDIDResolver} Cached DID resolver instance
163
+ */
85
164
  createDIDResolver() {
86
- return new AnyDIDResolver([
165
+ const router = new AnyDIDResolver([
87
166
  new DIDKeyResolver(),
88
167
  new CoreResolver(this.modules),
89
168
  new UniversalResolver(universalResolverUrl),
90
169
  ]);
170
+
171
+ return new CachedDIDResolver(router);
91
172
  }
92
173
  /**
93
- *
94
- * @param {*} params
95
- * @returns
174
+ * Initializes the blockchain service with connection parameters
175
+ * @param {InitParams} params - Initialization parameters
176
+ * @param {string} params.cheqdApiUrl - URL of the Cheqd API endpoint
177
+ * @param {string} [params.networkId] - Cheqd network identifier
178
+ * @param {string} [params.cheqdMnemonic] - Mnemonic for Cheqd wallet (auto-generated if not provided)
179
+ * @returns {Promise<boolean>} True if initialization successful
180
+ * @throws {Error} If cheqdApiUrl is not provided
181
+ * @example
182
+ * await blockchainService.init({
183
+ * cheqdApiUrl: 'https://api.cheqd.network',
184
+ * networkId: 'mainnet'
185
+ * });
96
186
  */
97
187
  async init(params: InitParams) {
98
188
  if (!params?.cheqdApiUrl) {
@@ -151,8 +241,10 @@ export class BlockchainService {
151
241
  }
152
242
 
153
243
  /**
154
- *
155
- * @returns
244
+ * Disconnects from the blockchain
245
+ * @returns {Promise<void>} Resolves when disconnection is complete
246
+ * @example
247
+ * await blockchainService.disconnect();
156
248
  */
157
249
  async disconnect() {
158
250
  let result;
@@ -166,6 +258,11 @@ export class BlockchainService {
166
258
  return result;
167
259
  }
168
260
 
261
+ /**
262
+ * Waits for the blockchain to be ready
263
+ * @returns {Promise<void>} Resolves when blockchain is ready
264
+ * @private
265
+ */
169
266
  async waitBlockchainReady() {
170
267
  return new Promise(resolve => {
171
268
  if (this.isBlockchainReady) {
@@ -177,17 +274,40 @@ export class BlockchainService {
177
274
  }
178
275
 
179
276
  /**
180
- *
181
- * @returns
277
+ * Resolves a DID to its document
278
+ * @param {string} did - The DID to resolve
279
+ * @returns {Promise<Object>} The resolved DID document
280
+ * @example
281
+ * const didDoc = await blockchainService.resolveDID('did:key:z6Mk...');
282
+ */
283
+ async resolveDID(did: string) {
284
+ return this.resolver.resolve(did);
285
+ }
286
+ /**
287
+ * Checks if the blockchain API is connected
288
+ * @returns {Promise<boolean>} True if connected, false otherwise
289
+ * @example
290
+ * const isConnected = await blockchainService.isApiConnected();
182
291
  */
183
292
  async isApiConnected() {
184
293
  return this.cheqdApi.isInitialized();
185
294
  }
186
295
 
296
+ /**
297
+ * Gets the current Cheqd API URL
298
+ * @returns {Promise<string>} The Cheqd API URL
299
+ * @example
300
+ * const apiUrl = await blockchainService.getAddress();
301
+ */
187
302
  async getAddress() {
188
303
  return this.cheqdApiUrl;
189
304
  }
190
305
 
306
+ /**
307
+ * Sets the blockchain ready state and emits events
308
+ * @private
309
+ * @param {boolean} isBlockchainReady - Whether blockchain is ready
310
+ */
191
311
  _setBlockchainReady(isBlockchainReady) {
192
312
  this.isBlockchainReady = isBlockchainReady;
193
313
 
@@ -197,4 +317,18 @@ export class BlockchainService {
197
317
  }
198
318
  }
199
319
 
320
+ /**
321
+ * Singleton instance of the blockchain service
322
+ * @type {BlockchainService}
323
+ * @example
324
+ * import { blockchainService } from '@docknetwork/wallet-sdk-wasm/services/blockchain';
325
+ *
326
+ * // Initialize the service
327
+ * await blockchainService.init({
328
+ * cheqdApiUrl: 'https://api.cheqd.network'
329
+ * });
330
+ *
331
+ * // Resolve a DID
332
+ * const didDoc = await blockchainService.resolveDID('did:key:z6Mk...');
333
+ */
200
334
  export const blockchainService: BlockchainService = new BlockchainService();
@@ -12,7 +12,13 @@ export const validation = {
12
12
  },
13
13
  verifyCredential: params => {
14
14
  const {credential} = params;
15
- assert(typeof credential === 'object', 'invalid credential');
15
+ assert(
16
+ typeof credential === 'object' || typeof credential === 'string',
17
+ 'invalid credential',
18
+ );
19
+ if (typeof credential === 'object') {
20
+ assert(Object.keys(credential).length > 0, 'invalid credential');
21
+ }
16
22
  },
17
23
  createBBSPresentation: params => {
18
24
  const {credentials} = params;
@@ -60,6 +60,17 @@ function getAttributeName({field, selectedCredentials, index}) {
60
60
  return attributeName;
61
61
  }
62
62
 
63
+ /**
64
+ * Convert PEX request to bounds for each descriptor
65
+ * @param {*} pexRequest - The PEX request object containing input descriptors and constraints
66
+ * @param {*} selectedCredentials - Array of selected credentials corresponding to the input descriptors
67
+ * @param {*} removeFromRequest - if true, removes range proofs fields from the request. it might be dangerous if you will be using the proof request later
68
+ * because it will not have the range proofs fields anymore.
69
+ * @returns {Array} - Array of bounds for each descriptor, where each bound is an object with attributeName, min, and max
70
+ * @throws {Error} - If a field path is missing or empty
71
+ * @throws {Error} - If an unsupported format or type is encountered
72
+ * @throws {Error} - If a selected credential is expected but not found at the given index
73
+ */
63
74
  export function pexToBounds(
64
75
  pexRequest,
65
76
  selectedCredentials = [],
@@ -162,6 +173,9 @@ export function pexToBounds(
162
173
  : formatMinimum
163
174
  : minimum;
164
175
 
176
+ const proofRequestMax = max;
177
+ const proofRequestMin = min;
178
+
165
179
  if (max === undefined && min === undefined) {
166
180
  return;
167
181
  }
@@ -236,6 +250,10 @@ export function pexToBounds(
236
250
  attributeName,
237
251
  min,
238
252
  max,
253
+ proofRequestMax,
254
+ proofRequestMin,
255
+ format,
256
+ type,
239
257
  });
240
258
  });
241
259
 
@@ -258,9 +276,10 @@ const attributesToSkip = [
258
276
  /^@context/,
259
277
  /^proof/,
260
278
  /^credentialSchema/,
279
+ /^issuanceDate/,
261
280
  ];
262
281
 
263
- const shouldSkipAttribute = attributeName =>
282
+ export const shouldSkipAttribute = attributeName =>
264
283
  attributesToSkip.some(regex => regex.test(attributeName));
265
284
 
266
285
  export function getPexRequiredAttributes(pexRequest, selectedCredentials = []) {
@@ -230,6 +230,31 @@ describe('pex helpers', () => {
230
230
 
231
231
  expect(result).toEqual(['credentialSubject.id']);
232
232
  });
233
+
234
+ it('should skip issuanceDate', () => {
235
+ const result = getPexRequiredAttributes(
236
+ {
237
+ id: 'test-issuanceDate',
238
+ input_descriptors: [
239
+ {
240
+ constraints: {
241
+ fields: [
242
+ {
243
+ path: ['$.issuanceDate'],
244
+ },
245
+ ],
246
+ },
247
+ },
248
+ ],
249
+ },
250
+ [
251
+ {
252
+ issuanceDate: '2021-01-01',
253
+ },
254
+ ],
255
+ );
256
+ expect(result).toEqual([]);
257
+ });
233
258
  });
234
259
 
235
260
  describe('pexToBounds', () => {
@@ -278,11 +303,19 @@ describe('pex helpers', () => {
278
303
  attributeName: 'credentialSubject.age',
279
304
  min: 0,
280
305
  max: 10000000000,
306
+ proofRequestMax: undefined,
307
+ proofRequestMin: 0,
308
+ format: undefined,
309
+ type: 'number',
281
310
  },
282
311
  {
283
312
  attributeName: 'credentialSubject.dateOfBirth',
284
313
  min: new Date('2021-01-01'),
285
314
  max: new Date(884541351600000),
315
+ proofRequestMax: undefined,
316
+ proofRequestMin: '2021-01-01',
317
+ format: 'date',
318
+ type: undefined,
286
319
  },
287
320
  ],
288
321
  ]);
@@ -325,6 +358,10 @@ describe('pex helpers', () => {
325
358
  attributeName: 'credentialSubject.age',
326
359
  min: 0,
327
360
  max: 10000000000,
361
+ proofRequestMax: undefined,
362
+ proofRequestMin: 0,
363
+ format: undefined,
364
+ type: 'number',
328
365
  },
329
366
  ],
330
367
  ]);
@@ -361,6 +398,10 @@ describe('pex helpers', () => {
361
398
  attributeName: 'expirationDate',
362
399
  min: new Date('2021-01-01T00:00:00Z'),
363
400
  max: new Date('2022-01-01T00:00:00Z'),
401
+ proofRequestMax: '2022-01-01T00:00:00Z',
402
+ proofRequestMin: '2021-01-01T00:00:00Z',
403
+ format: 'date-time',
404
+ type: undefined,
364
405
  },
365
406
  ],
366
407
  ]);
@@ -398,6 +439,10 @@ describe('pex helpers', () => {
398
439
  attributeName: 'amount',
399
440
  min: 0,
400
441
  max: 100,
442
+ proofRequestMax: 100,
443
+ proofRequestMin: 0,
444
+ format: undefined,
445
+ type: 'number',
401
446
  },
402
447
  ],
403
448
  ]);
@@ -444,11 +489,19 @@ describe('pex helpers', () => {
444
489
  attributeName: 'startDate',
445
490
  min: new Date('2021-01-01'),
446
491
  max: new Date('2022-01-01'),
492
+ proofRequestMax: '2022-01-01',
493
+ proofRequestMin: '2021-01-01',
494
+ format: 'date',
495
+ type: undefined,
447
496
  },
448
497
  {
449
498
  attributeName: 'amount',
450
499
  min: 0,
451
500
  max: 100,
501
+ proofRequestMax: 100,
502
+ proofRequestMin: 0,
503
+ format: undefined,
504
+ type: 'number',
452
505
  },
453
506
  ],
454
507
  ]);
@@ -464,6 +517,67 @@ describe('pex helpers', () => {
464
517
  expect(bounds).toEqual([]);
465
518
  });
466
519
 
520
+ it('should preserve original proof request values in new metadata fields', () => {
521
+ const pexRequest = {
522
+ input_descriptors: [
523
+ {
524
+ constraints: {
525
+ fields: [
526
+ {
527
+ filter: {
528
+ type: 'number',
529
+ minimum: 18,
530
+ maximum: 65,
531
+ },
532
+ path: ['$.credentialSubject.age'],
533
+ },
534
+ {
535
+ filter: {
536
+ format: 'date',
537
+ formatMinimum: '2020-01-01',
538
+ formatMaximum: '2025-12-31',
539
+ },
540
+ path: ['$.credentialSubject.graduationDate'],
541
+ },
542
+ ],
543
+ },
544
+ },
545
+ ],
546
+ };
547
+
548
+ const bounds = pexToBounds(pexRequest, [
549
+ {
550
+ credentialSubject: {
551
+ age: 25,
552
+ graduationDate: '2023-06-15',
553
+ },
554
+ },
555
+ ]);
556
+
557
+ expect(bounds).toEqual([
558
+ [
559
+ {
560
+ attributeName: 'credentialSubject.age',
561
+ min: 18,
562
+ max: 65,
563
+ proofRequestMax: 65,
564
+ proofRequestMin: 18,
565
+ format: undefined,
566
+ type: 'number',
567
+ },
568
+ {
569
+ attributeName: 'credentialSubject.graduationDate',
570
+ min: new Date('2020-01-01'),
571
+ max: new Date('2025-12-31'),
572
+ proofRequestMax: '2025-12-31',
573
+ proofRequestMin: '2020-01-01',
574
+ format: 'date',
575
+ type: undefined,
576
+ },
577
+ ],
578
+ ]);
579
+ });
580
+
467
581
  it('should not have undefined attributeNames, exclude not found bounds', () => {
468
582
  const pexRequest = {
469
583
  id: '3cb2c1db-54d7-427a-a6a2-4b8f73a33700',