Skip to content

Commit f0f2086

Browse files
committed
fixed credential status
1 parent 9267716 commit f0f2086

File tree

5 files changed

+147
-36
lines changed

5 files changed

+147
-36
lines changed

src/credential/credential.module.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,30 @@ import { TrimMiddleware } from 'src/utils/middleware/trim.middleware';
1717
import { credentialProviders } from './providers/credential.provider';
1818
import { databaseProviders } from '../mongoose/tenant-mongoose-connections';
1919
import { TxSendModuleModule } from 'src/tx-send-module/tx-send-module.module';
20+
import { StatusModule } from 'src/status/status.module';
21+
import { StatusService } from 'src/status/status.service';
22+
import { TxnStatusRepository } from 'src/status/repository/status.repository';
23+
import { statusProviders } from 'src/status/providers/registration-status.provider';
2024

2125
@Module({
22-
imports: [EdvModule, HidWalletModule, DidModule, TxSendModuleModule],
26+
imports: [
27+
EdvModule,
28+
HidWalletModule,
29+
DidModule,
30+
TxSendModuleModule,
31+
StatusModule,
32+
],
2333
controllers: [CredentialController],
2434
providers: [
2535
CredentialService,
2636
CredentialSSIService,
2737
HidWalletService,
38+
StatusService,
2839
CredentialRepository,
40+
TxnStatusRepository,
2941
...databaseProviders,
3042
...credentialProviders,
43+
...statusProviders,
3144
],
3245
})
3346
export class CredentialModule implements NestModule {

src/credential/dto/create-credential.dto.ts

+60-15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ValidateIf,
1111
ArrayNotEmpty,
1212
IsEnum,
13+
IsObject,
1314
} from 'class-validator';
1415
import { Type } from 'class-transformer';
1516
import { ValidateVerificationMethodId } from 'src/utils/customDecorator/vmId.decorator';
@@ -18,6 +19,56 @@ import { IsSchemaId } from 'src/utils/customDecorator/schemaId.deceorator';
1819
import { IsVcId } from 'src/utils/customDecorator/vc.decorator';
1920
import { subjectDID } from 'src/utils/customDecorator/SubjectDid.decorator';
2021

22+
export class ResolveCredentialMetadata {
23+
@ApiProperty({
24+
name: 'credentialId',
25+
description: 'credentialId of credential',
26+
example: 'vc:hid:testnet:z6MkqexphEhpi9jKZi8XLYiwCEsSWMdUt6YzjCfqdxKecJXM',
27+
})
28+
@IsString()
29+
credentialId: string;
30+
31+
@ApiProperty({
32+
name: 'type',
33+
description: 'schema type of credential',
34+
example: '{ schemaId, schemaType }',
35+
})
36+
@IsObject()
37+
@IsOptional()
38+
type?: object;
39+
40+
@ApiProperty({
41+
name: 'issuerDid',
42+
description: 'issuerDid of credential',
43+
example: 'did:hid:testnet:asdasd',
44+
})
45+
@IsString()
46+
issuerDid: string;
47+
48+
@ApiProperty({
49+
name: 'persist',
50+
description:
51+
'return credentialDocument if persist is set to true at the time of issuing credential',
52+
example: true,
53+
})
54+
persist: boolean;
55+
56+
@ApiProperty({
57+
name: 'registerCredentialStatus',
58+
description: 'if crendetialstatus was sent to blockchain',
59+
example: true,
60+
})
61+
registerCredentialStatus: boolean;
62+
63+
@ApiProperty({
64+
name: 'transactionStatus',
65+
description: 'transactionStatus of credential',
66+
required: false,
67+
})
68+
@IsOptional()
69+
@IsObject()
70+
transactionStatus: object;
71+
}
2172
export enum Namespace {
2273
testnet = 'testnet',
2374
// mainnet = '',
@@ -399,12 +450,13 @@ export class CreateCredentialResponse {
399450
type: CredStatus,
400451
})
401452
credentialStatus: CredStatus;
453+
402454
@ApiProperty({
403-
name: 'persist',
404-
description: 'Define whether to store cred or ust store its meta',
405-
example: true,
455+
name: 'metadata',
456+
description: 'metadata for this credential',
406457
})
407-
persist: boolean;
458+
@IsOptional()
459+
metadata?: ResolveCredentialMetadata;
408460
}
409461

410462
export class ResolvedCredentialStatus extends CredStatus {
@@ -448,16 +500,9 @@ export class ResolveCredential {
448500
@ValidateNested({ each: true })
449501
credentialStatus: ResolvedCredentialStatus;
450502
@ApiProperty({
451-
name: 'persist',
452-
description:
453-
'return credentialDocument if persist is set to true at the time of issuing credential',
454-
example: true,
503+
name: 'metadata',
504+
description: 'metadata for this credential',
455505
})
456-
persist: boolean;
457-
@ApiProperty({
458-
description: 'If set true then return credential Document also',
459-
name: 'retrieveCredential',
460-
example: true,
461-
})
462-
retrieveCredential: boolean;
506+
@IsOptional()
507+
metadata?: ResolveCredentialMetadata;
463508
}

src/credential/schemas/credntial.schema.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
2-
import { IsBoolean, IsOptional, IsString } from 'class-validator';
2+
import { IsBoolean, IsObject, IsOptional, IsString } from 'class-validator';
33
import { IsDid } from 'src/utils/customDecorator/did.decorator';
44
import { IsVcId } from 'src/utils/customDecorator/vc.decorator';
55

@@ -30,13 +30,17 @@ export class Credential {
3030
@Prop({ required: true })
3131
persist: boolean;
3232

33+
@IsBoolean()
34+
@Prop({ required: true })
35+
registerCredentialStatus: boolean;
36+
3337
@IsString()
3438
@Prop()
3539
transactionHash: string;
3640

37-
@IsString()
38-
@Prop()
39-
type: string;
41+
@IsObject()
42+
@Prop({ type: 'object' })
43+
type: object;
4044
}
4145

4246
const CredentialSchema = SchemaFactory.createForClass(Credential);

src/credential/services/credential.service.ts

+65-15
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import {
44
Logger,
55
NotFoundException,
66
} from '@nestjs/common';
7-
import { CreateCredentialDto } from '../dto/create-credential.dto';
7+
import {
8+
CreateCredentialDto,
9+
ResolveCredentialMetadata,
10+
} from '../dto/create-credential.dto';
811
import { UpdateCredentialDto } from '../dto/update-credential.dto';
912
import { ConfigService } from '@nestjs/config';
1013
import { CredentialSSIService } from './credential.ssi.service';
@@ -24,6 +27,7 @@ import {
2427
import { getAppVault, getAppMenemonic } from '../../utils/app-vault-service';
2528
import { TxSendModuleService } from 'src/tx-send-module/tx-send-module.service';
2629
import * as NodeCache from 'node-cache';
30+
import { StatusService } from 'src/status/status.service';
2731
const myCache = new NodeCache();
2832
@Injectable()
2933
export class CredentialService {
@@ -34,6 +38,7 @@ export class CredentialService {
3438
private credentialRepository: CredentialRepository,
3539
private readonly didRepositiory: DidRepository,
3640
private readonly txnService: TxSendModuleService,
41+
private readonly statusService: StatusService,
3742
) {}
3843

3944
async checkAllowence(address) {
@@ -244,7 +249,7 @@ export class CredentialService {
244249
'create() method: before creating credential doc in db',
245250
'CredentialService',
246251
);
247-
await this.credentialRepository.create({
252+
const credentialDetail = await this.credentialRepository.create({
248253
appId: appDetail.appId,
249254
credentialId: signedCredential.id,
250255
issuerDid,
@@ -253,14 +258,25 @@ export class CredentialService {
253258
transactionHash: credentialStatusRegistrationResult
254259
? credentialStatusRegistrationResult.transactionHash
255260
: '',
256-
type: signedCredential.type[1], // TODO : MAYBE REMOVE HARDCODING MAYBE NOT
261+
type: { schemaType: signedCredential.type[1], schemaId }, // TODO : MAYBE REMOVE HARDCODING MAYBE NOT
262+
registerCredentialStatus: registerCredentialStatus
263+
? registerCredentialStatus
264+
: false,
257265
});
258266
Logger.log('create() method: ends....', 'CredentialService');
259267

268+
const metadata = {
269+
credentialId: credentialDetail.credentialId,
270+
persist: credentialDetail.persist,
271+
type: credentialDetail.type,
272+
issuerDid: credentialDetail.issuerDid,
273+
registerCredentialStatus: credentialDetail.registerCredentialStatus,
274+
} as ResolveCredentialMetadata;
275+
260276
return {
261277
credentialDocument: signedCredential,
262278
credentialStatus: credStatusTemp,
263-
persist,
279+
metadata,
264280
};
265281
} catch (e) {
266282
throw new BadRequestException([e.message]);
@@ -316,22 +332,56 @@ export class CredentialService {
316332
'resolveCredential() method: before initialising HypersignVerifiableCredential',
317333
'CredentialService',
318334
);
319-
const hypersignCredential = new HypersignVerifiableCredential();
320-
let credentialStatus;
321-
try {
322-
credentialStatus = await hypersignCredential.resolveCredentialStatus({
323-
credentialId,
324-
});
325-
} catch (e) {
326-
credentialStatus = undefined;
335+
336+
const metadata = {
337+
credentialId: credentialDetail.credentialId,
338+
persist: credentialDetail.persist,
339+
type: credentialDetail.type,
340+
issuerDid: credentialDetail.issuerDid,
341+
registerCredentialStatus: credentialDetail.registerCredentialStatus,
342+
} as ResolveCredentialMetadata;
343+
let credentialStatus = undefined;
344+
// If user had registered the credential on the blockchain
345+
// Only then we will go ahead with credential status retrival
346+
const shouldRetriveCredential = credentialDetail.registerCredentialStatus
347+
? credentialDetail.registerCredentialStatus
348+
: true; // making default true for backwards compatibility
349+
if (shouldRetriveCredential) {
350+
/// First check this transaction was successful in lcoal db or there was some error
351+
const statusResponse = await this.statusService.findBySsiId(credentialId);
352+
let wasTransactionSuccess = false;
353+
if (statusResponse) {
354+
const firstResponse = statusResponse[0];
355+
if (
356+
firstResponse &&
357+
firstResponse.data &&
358+
firstResponse.totalCount > 0
359+
) {
360+
metadata['transactionStatus'] = firstResponse.data;
361+
if (firstResponse.data.findIndex((x) => x['status'] == 0) >= 0) {
362+
wasTransactionSuccess = true;
363+
}
364+
}
365+
}
366+
367+
/// Retrive status from the blockchain only when status = 0, otherwise skip
368+
if (wasTransactionSuccess) {
369+
try {
370+
const hypersignCredential = new HypersignVerifiableCredential();
371+
credentialStatus = await hypersignCredential.resolveCredentialStatus({
372+
credentialId,
373+
});
374+
} catch (e) {
375+
credentialStatus = undefined;
376+
}
377+
Logger.log('resolveCredential() method: ends....', 'CredentialService');
378+
}
327379
}
328-
Logger.log('resolveCredential() method: ends....', 'CredentialService');
329380

330381
return {
331382
credentialDocument: credential ? credential : undefined,
332383
credentialStatus,
333-
persist: credentialDetail.persist,
334-
retrieveCredential,
384+
metadata,
335385
};
336386
}
337387

src/schema/services/schema.service.ts

-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ export class SchemaService {
205205
);
206206

207207
const statusResponse = await this.statusService.findBySsiId(schemaId);
208-
Logger.log(statusResponse);
209208
if (statusResponse) {
210209
const firstResponse = statusResponse[0];
211210
if (firstResponse && firstResponse.data) {

0 commit comments

Comments
 (0)